aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/can/bxcan/filter.rs70
-rw-r--r--embassy-stm32/src/can/bxcan/mod.rs85
-rw-r--r--embassy-stm32/src/can/bxcan/registers.rs12
-rw-r--r--tests/stm32/src/bin/can.rs6
-rw-r--r--tests/stm32/src/bin/can_common.rs4
-rw-r--r--tests/stm32/src/bin/fdcan.rs4
6 files changed, 99 insertions, 82 deletions
diff --git a/embassy-stm32/src/can/bxcan/filter.rs b/embassy-stm32/src/can/bxcan/filter.rs
index 9940c7f50..167c6c572 100644
--- a/embassy-stm32/src/can/bxcan/filter.rs
+++ b/embassy-stm32/src/can/bxcan/filter.rs
@@ -2,7 +2,7 @@
2 2
3use core::marker::PhantomData; 3use core::marker::PhantomData;
4 4
5use super::{ExtendedId, Fifo, FilterOwner, Id, Instance, MasterInstance, StandardId}; 5use super::{ExtendedId, Fifo, Id, StandardId};
6 6
7const F32_RTR: u32 = 0b010; // set the RTR bit to match remote frames 7const F32_RTR: u32 = 0b010; // set the RTR bit to match remote frames
8const F32_IDE: u32 = 0b100; // set the IDE bit to match extended identifiers 8const F32_IDE: u32 = 0b100; // set the IDE bit to match extended identifiers
@@ -210,24 +210,24 @@ impl From<Mask32> for BankConfig {
210} 210}
211 211
212/// Interface to the filter banks of a CAN peripheral. 212/// Interface to the filter banks of a CAN peripheral.
213pub struct MasterFilters<'a, I: FilterOwner> { 213pub struct MasterFilters<'a> {
214 /// Number of assigned filter banks. 214 /// Number of assigned filter banks.
215 /// 215 ///
216 /// On chips with splittable filter banks, this value can be dynamic. 216 /// On chips with splittable filter banks, this value can be dynamic.
217 bank_count: u8, 217 bank_count: u8,
218 _can: PhantomData<&'a mut I>, 218 _phantom: PhantomData<&'a ()>,
219 canregs: crate::pac::can::Can, 219 info: &'static crate::can::Info,
220} 220}
221 221
222// NOTE: This type mutably borrows the CAN instance and has unique access to the registers while it 222// NOTE: This type mutably borrows the CAN instance and has unique access to the registers while it
223// exists. 223// exists.
224impl<I: FilterOwner> MasterFilters<'_, I> { 224impl MasterFilters<'_> {
225 pub(crate) unsafe fn new(canregs: crate::pac::can::Can) -> Self { 225 pub(crate) unsafe fn new(info: &'static crate::can::Info) -> Self {
226 // Enable initialization mode. 226 // Enable initialization mode.
227 canregs.fmr().modify(|reg| reg.set_finit(true)); 227 info.regs.0.fmr().modify(|reg| reg.set_finit(true));
228 228
229 // Read the filter split value. 229 // Read the filter split value.
230 let bank_count = canregs.fmr().read().can2sb(); 230 let bank_count = info.regs.0.fmr().read().can2sb();
231 231
232 // (Reset value of CAN2SB is 0x0E, 14, which, in devices with 14 filter banks, assigns all 232 // (Reset value of CAN2SB is 0x0E, 14, which, in devices with 14 filter banks, assigns all
233 // of them to the master peripheral, and in devices with 28, assigns them 50/50 to 233 // of them to the master peripheral, and in devices with 28, assigns them 50/50 to
@@ -235,8 +235,8 @@ impl<I: FilterOwner> MasterFilters<'_, I> {
235 235
236 Self { 236 Self {
237 bank_count, 237 bank_count,
238 _can: PhantomData, 238 _phantom: PhantomData,
239 canregs, 239 info,
240 } 240 }
241 } 241 }
242 242
@@ -244,7 +244,7 @@ impl<I: FilterOwner> MasterFilters<'_, I> {
244 FilterBanks { 244 FilterBanks {
245 start_idx: 0, 245 start_idx: 0,
246 bank_count: self.bank_count, 246 bank_count: self.bank_count,
247 canregs: self.canregs, 247 info: self.info,
248 } 248 }
249 } 249 }
250 250
@@ -291,49 +291,49 @@ impl<I: FilterOwner> MasterFilters<'_, I> {
291 } 291 }
292} 292}
293 293
294impl<I: MasterInstance> MasterFilters<'_, I> { 294impl MasterFilters<'_> {
295 /// Sets the index at which the filter banks owned by the slave peripheral start. 295 /// Sets the index at which the filter banks owned by the slave peripheral start.
296 pub fn set_split(&mut self, split_index: u8) -> &mut Self { 296 pub fn set_split(&mut self, split_index: u8) -> &mut Self {
297 assert!(split_index <= I::NUM_FILTER_BANKS); 297 assert!(split_index <= self.info.num_filter_banks);
298 self.canregs.fmr().modify(|reg| reg.set_can2sb(split_index)); 298 self.info.regs.0.fmr().modify(|reg| reg.set_can2sb(split_index));
299 self.bank_count = split_index; 299 self.bank_count = split_index;
300 self 300 self
301 } 301 }
302 302
303 /// Accesses the filters assigned to the slave peripheral. 303 /// Accesses the filters assigned to the slave peripheral.
304 pub fn slave_filters(&mut self) -> SlaveFilters<'_, I> { 304 pub fn slave_filters(&mut self) -> SlaveFilters<'_> {
305 // NB: This mutably borrows `self`, so it has full access to the filter bank registers. 305 // NB: This mutably borrows `self`, so it has full access to the filter bank registers.
306 SlaveFilters { 306 SlaveFilters {
307 start_idx: self.bank_count, 307 start_idx: self.bank_count,
308 bank_count: I::NUM_FILTER_BANKS - self.bank_count, 308 bank_count: self.info.num_filter_banks - self.bank_count,
309 _can: PhantomData, 309 _phantom: PhantomData,
310 canregs: self.canregs, 310 info: self.info,
311 } 311 }
312 } 312 }
313} 313}
314 314
315impl<I: FilterOwner> Drop for MasterFilters<'_, I> { 315impl Drop for MasterFilters<'_> {
316 #[inline] 316 #[inline]
317 fn drop(&mut self) { 317 fn drop(&mut self) {
318 // Leave initialization mode. 318 // Leave initialization mode.
319 self.canregs.fmr().modify(|regs| regs.set_finit(false)); 319 self.info.regs.0.fmr().modify(|regs| regs.set_finit(false));
320 } 320 }
321} 321}
322 322
323/// Interface to the filter banks assigned to a slave peripheral. 323/// Interface to the filter banks assigned to a slave peripheral.
324pub struct SlaveFilters<'a, I: Instance> { 324pub struct SlaveFilters<'a> {
325 start_idx: u8, 325 start_idx: u8,
326 bank_count: u8, 326 bank_count: u8,
327 _can: PhantomData<&'a mut I>, 327 _phantom: PhantomData<&'a ()>,
328 canregs: crate::pac::can::Can, 328 info: &'static crate::can::Info,
329} 329}
330 330
331impl<I: Instance> SlaveFilters<'_, I> { 331impl SlaveFilters<'_> {
332 fn banks_imm(&self) -> FilterBanks { 332 fn banks_imm(&self) -> FilterBanks {
333 FilterBanks { 333 FilterBanks {
334 start_idx: self.start_idx, 334 start_idx: self.start_idx,
335 bank_count: self.bank_count, 335 bank_count: self.bank_count,
336 canregs: self.canregs, 336 info: self.info,
337 } 337 }
338 } 338 }
339 339
@@ -377,14 +377,14 @@ impl<I: Instance> SlaveFilters<'_, I> {
377struct FilterBanks { 377struct FilterBanks {
378 start_idx: u8, 378 start_idx: u8,
379 bank_count: u8, 379 bank_count: u8,
380 canregs: crate::pac::can::Can, 380 info: &'static crate::can::Info,
381} 381}
382 382
383impl FilterBanks { 383impl FilterBanks {
384 fn clear(&mut self) { 384 fn clear(&mut self) {
385 let mask = filter_bitmask(self.start_idx, self.bank_count); 385 let mask = filter_bitmask(self.start_idx, self.bank_count);
386 386
387 self.canregs.fa1r().modify(|reg| { 387 self.info.regs.0.fa1r().modify(|reg| {
388 for i in 0..28usize { 388 for i in 0..28usize {
389 if (0x01u32 << i) & mask != 0 { 389 if (0x01u32 << i) & mask != 0 {
390 reg.set_fact(i, false); 390 reg.set_fact(i, false);
@@ -399,7 +399,11 @@ impl FilterBanks {
399 399
400 fn disable(&mut self, index: u8) { 400 fn disable(&mut self, index: u8) {
401 self.assert_bank_index(index); 401 self.assert_bank_index(index);
402 self.canregs.fa1r().modify(|reg| reg.set_fact(index as usize, false)) 402 self.info
403 .regs
404 .0
405 .fa1r()
406 .modify(|reg| reg.set_fact(index as usize, false))
403 } 407 }
404 408
405 fn enable(&mut self, index: u8, fifo: Fifo, config: BankConfig) { 409 fn enable(&mut self, index: u8, fifo: Fifo, config: BankConfig) {
@@ -407,11 +411,11 @@ impl FilterBanks {
407 411
408 // Configure mode. 412 // Configure mode.
409 let mode = matches!(config, BankConfig::List16(_) | BankConfig::List32(_)); 413 let mode = matches!(config, BankConfig::List16(_) | BankConfig::List32(_));
410 self.canregs.fm1r().modify(|reg| reg.set_fbm(index as usize, mode)); 414 self.info.regs.0.fm1r().modify(|reg| reg.set_fbm(index as usize, mode));
411 415
412 // Configure scale. 416 // Configure scale.
413 let scale = matches!(config, BankConfig::List32(_) | BankConfig::Mask32(_)); 417 let scale = matches!(config, BankConfig::List32(_) | BankConfig::Mask32(_));
414 self.canregs.fs1r().modify(|reg| reg.set_fsc(index as usize, scale)); 418 self.info.regs.0.fs1r().modify(|reg| reg.set_fsc(index as usize, scale));
415 419
416 // Configure filter register. 420 // Configure filter register.
417 let (fxr1, fxr2); 421 let (fxr1, fxr2);
@@ -433,12 +437,12 @@ impl FilterBanks {
433 fxr2 = a.mask; 437 fxr2 = a.mask;
434 } 438 }
435 }; 439 };
436 let bank = self.canregs.fb(index as usize); 440 let bank = self.info.regs.0.fb(index as usize);
437 bank.fr1().write(|w| w.0 = fxr1); 441 bank.fr1().write(|w| w.0 = fxr1);
438 bank.fr2().write(|w| w.0 = fxr2); 442 bank.fr2().write(|w| w.0 = fxr2);
439 443
440 // Assign to the right FIFO 444 // Assign to the right FIFO
441 self.canregs.ffa1r().modify(|reg| { 445 self.info.regs.0.ffa1r().modify(|reg| {
442 reg.set_ffa( 446 reg.set_ffa(
443 index as usize, 447 index as usize,
444 match fifo { 448 match fifo {
@@ -449,7 +453,7 @@ impl FilterBanks {
449 }); 453 });
450 454
451 // Set active. 455 // Set active.
452 self.canregs.fa1r().modify(|reg| reg.set_fact(index as usize, true)) 456 self.info.regs.0.fa1r().modify(|reg| reg.set_fact(index as usize, true))
453 } 457 }
454} 458}
455 459
diff --git a/embassy-stm32/src/can/bxcan/mod.rs b/embassy-stm32/src/can/bxcan/mod.rs
index 9f7df1e71..53b94b9e2 100644
--- a/embassy-stm32/src/can/bxcan/mod.rs
+++ b/embassy-stm32/src/can/bxcan/mod.rs
@@ -6,7 +6,7 @@ use core::marker::PhantomData;
6use core::task::Poll; 6use core::task::Poll;
7 7
8use embassy_hal_internal::interrupt::InterruptExt; 8use embassy_hal_internal::interrupt::InterruptExt;
9use embassy_hal_internal::{into_ref, PeripheralRef}; 9use embassy_hal_internal::into_ref;
10use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 10use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
11use embassy_sync::channel::Channel; 11use embassy_sync::channel::Channel;
12use embassy_sync::waitqueue::AtomicWaker; 12use embassy_sync::waitqueue::AtomicWaker;
@@ -91,11 +91,13 @@ impl<T: Instance> interrupt::typelevel::Handler<T::SCEInterrupt> for SceInterrup
91} 91}
92 92
93/// Configuration proxy returned by [`Can::modify_config`]. 93/// Configuration proxy returned by [`Can::modify_config`].
94pub struct CanConfig<'a, T: Instance> { 94pub struct CanConfig<'a> {
95 can: PhantomData<&'a mut T>, 95 phantom: PhantomData<&'a ()>,
96 info: &'static Info,
97 periph_clock: crate::time::Hertz,
96} 98}
97 99
98impl<T: Instance> CanConfig<'_, T> { 100impl CanConfig<'_> {
99 /// Configures the bit timings. 101 /// Configures the bit timings.
100 /// 102 ///
101 /// You can use <http://www.bittiming.can-wiki.info/> to calculate the `btr` parameter. Enter 103 /// You can use <http://www.bittiming.can-wiki.info/> to calculate the `btr` parameter. Enter
@@ -109,7 +111,7 @@ impl<T: Instance> CanConfig<'_, T> {
109 /// Then copy the `CAN_BUS_TIME` register value from the table and pass it as the `btr` 111 /// Then copy the `CAN_BUS_TIME` register value from the table and pass it as the `btr`
110 /// parameter to this method. 112 /// parameter to this method.
111 pub fn set_bit_timing(self, bt: crate::can::util::NominalBitTiming) -> Self { 113 pub fn set_bit_timing(self, bt: crate::can::util::NominalBitTiming) -> Self {
112 Registers(T::regs()).set_bit_timing(bt); 114 self.info.regs.set_bit_timing(bt);
113 self 115 self
114 } 116 }
115 117
@@ -117,20 +119,20 @@ impl<T: Instance> CanConfig<'_, T> {
117 /// 119 ///
118 /// This is a helper that internally calls `set_bit_timing()`[Self::set_bit_timing]. 120 /// This is a helper that internally calls `set_bit_timing()`[Self::set_bit_timing].
119 pub fn set_bitrate(self, bitrate: u32) -> Self { 121 pub fn set_bitrate(self, bitrate: u32) -> Self {
120 let bit_timing = util::calc_can_timings(T::frequency(), bitrate).unwrap(); 122 let bit_timing = util::calc_can_timings(self.periph_clock, bitrate).unwrap();
121 self.set_bit_timing(bit_timing) 123 self.set_bit_timing(bit_timing)
122 } 124 }
123 125
124 /// Enables or disables loopback mode: Internally connects the TX and RX 126 /// Enables or disables loopback mode: Internally connects the TX and RX
125 /// signals together. 127 /// signals together.
126 pub fn set_loopback(self, enabled: bool) -> Self { 128 pub fn set_loopback(self, enabled: bool) -> Self {
127 Registers(T::regs()).set_loopback(enabled); 129 self.info.regs.set_loopback(enabled);
128 self 130 self
129 } 131 }
130 132
131 /// Enables or disables silent mode: Disconnects the TX signal from the pin. 133 /// Enables or disables silent mode: Disconnects the TX signal from the pin.
132 pub fn set_silent(self, enabled: bool) -> Self { 134 pub fn set_silent(self, enabled: bool) -> Self {
133 Registers(T::regs()).set_silent(enabled); 135 self.info.regs.set_silent(enabled);
134 self 136 self
135 } 137 }
136 138
@@ -141,23 +143,24 @@ impl<T: Instance> CanConfig<'_, T> {
141 /// 143 ///
142 /// Automatic retransmission is enabled by default. 144 /// Automatic retransmission is enabled by default.
143 pub fn set_automatic_retransmit(self, enabled: bool) -> Self { 145 pub fn set_automatic_retransmit(self, enabled: bool) -> Self {
144 Registers(T::regs()).set_automatic_retransmit(enabled); 146 self.info.regs.set_automatic_retransmit(enabled);
145 self 147 self
146 } 148 }
147} 149}
148 150
149impl<T: Instance> Drop for CanConfig<'_, T> { 151impl Drop for CanConfig<'_> {
150 #[inline] 152 #[inline]
151 fn drop(&mut self) { 153 fn drop(&mut self) {
152 Registers(T::regs()).leave_init_mode(); 154 self.info.regs.leave_init_mode();
153 } 155 }
154} 156}
155 157
156/// CAN driver 158/// CAN driver
157pub struct Can<'d, T: Instance> { 159pub struct Can<'d> {
158 _peri: PeripheralRef<'d, T>, 160 phantom: PhantomData<&'d ()>,
159 info: &'static Info, 161 info: &'static Info,
160 state: &'static State, 162 state: &'static State,
163 periph_clock: crate::time::Hertz,
161} 164}
162 165
163/// Error returned by `try_write` 166/// Error returned by `try_write`
@@ -168,11 +171,11 @@ pub enum TryWriteError {
168 Full, 171 Full,
169} 172}
170 173
171impl<'d, T: Instance> Can<'d, T> { 174impl<'d> Can<'d> {
172 /// Creates a new Bxcan instance, keeping the peripheral in sleep mode. 175 /// Creates a new Bxcan instance, keeping the peripheral in sleep mode.
173 /// You must call [Can::enable_non_blocking] to use the peripheral. 176 /// You must call [Can::enable_non_blocking] to use the peripheral.
174 pub fn new( 177 pub fn new<T: Instance>(
175 peri: impl Peripheral<P = T> + 'd, 178 _peri: impl Peripheral<P = T> + 'd,
176 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 179 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
177 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 180 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
178 _irqs: impl interrupt::typelevel::Binding<T::TXInterrupt, TxInterruptHandler<T>> 181 _irqs: impl interrupt::typelevel::Binding<T::TXInterrupt, TxInterruptHandler<T>>
@@ -181,7 +184,7 @@ impl<'d, T: Instance> Can<'d, T> {
181 + interrupt::typelevel::Binding<T::SCEInterrupt, SceInterruptHandler<T>> 184 + interrupt::typelevel::Binding<T::SCEInterrupt, SceInterruptHandler<T>>
182 + 'd, 185 + 'd,
183 ) -> Self { 186 ) -> Self {
184 into_ref!(peri, rx, tx); 187 into_ref!(_peri, rx, tx);
185 let info = T::info(); 188 let info = T::info();
186 let regs = &T::info().regs; 189 let regs = &T::info().regs;
187 190
@@ -226,15 +229,16 @@ impl<'d, T: Instance> Can<'d, T> {
226 Registers(T::regs()).leave_init_mode(); 229 Registers(T::regs()).leave_init_mode();
227 230
228 Self { 231 Self {
229 _peri: peri, 232 phantom: PhantomData,
230 info: T::info(), 233 info: T::info(),
231 state: T::state(), 234 state: T::state(),
235 periph_clock: T::frequency(),
232 } 236 }
233 } 237 }
234 238
235 /// Set CAN bit rate. 239 /// Set CAN bit rate.
236 pub fn set_bitrate(&mut self, bitrate: u32) { 240 pub fn set_bitrate(&mut self, bitrate: u32) {
237 let bit_timing = util::calc_can_timings(T::frequency(), bitrate).unwrap(); 241 let bit_timing = util::calc_can_timings(self.periph_clock, bitrate).unwrap();
238 self.modify_config().set_bit_timing(bit_timing); 242 self.modify_config().set_bit_timing(bit_timing);
239 } 243 }
240 244
@@ -242,10 +246,14 @@ impl<'d, T: Instance> Can<'d, T> {
242 /// 246 ///
243 /// Calling this method will enter initialization mode. You must enable the peripheral 247 /// Calling this method will enter initialization mode. You must enable the peripheral
244 /// again afterwards with [`enable`](Self::enable). 248 /// again afterwards with [`enable`](Self::enable).
245 pub fn modify_config(&mut self) -> CanConfig<'_, T> { 249 pub fn modify_config(&mut self) -> CanConfig<'_> {
246 Registers(T::regs()).enter_init_mode(); 250 self.info.regs.enter_init_mode();
247 251
248 CanConfig { can: PhantomData } 252 CanConfig {
253 phantom: self.phantom,
254 info: self.info,
255 periph_clock: self.periph_clock,
256 }
249 } 257 }
250 258
251 /// Enables the peripheral and synchronizes with the bus. 259 /// Enables the peripheral and synchronizes with the bus.
@@ -253,7 +261,7 @@ impl<'d, T: Instance> Can<'d, T> {
253 /// This will wait for 11 consecutive recessive bits (bus idle state). 261 /// This will wait for 11 consecutive recessive bits (bus idle state).
254 /// Contrary to enable method from bxcan library, this will not freeze the executor while waiting. 262 /// Contrary to enable method from bxcan library, this will not freeze the executor while waiting.
255 pub async fn enable(&mut self) { 263 pub async fn enable(&mut self) {
256 while Registers(T::regs()).enable_non_blocking().is_err() { 264 while self.info.regs.enable_non_blocking().is_err() {
257 // SCE interrupt is only generated for entering sleep mode, but not leaving. 265 // SCE interrupt is only generated for entering sleep mode, but not leaving.
258 // Yield to allow other tasks to execute while can bus is initializing. 266 // Yield to allow other tasks to execute while can bus is initializing.
259 embassy_futures::yield_now().await; 267 embassy_futures::yield_now().await;
@@ -263,7 +271,7 @@ impl<'d, T: Instance> Can<'d, T> {
263 /// Enables or disables the peripheral from automatically wakeup when a SOF is detected on the bus 271 /// Enables or disables the peripheral from automatically wakeup when a SOF is detected on the bus
264 /// while the peripheral is in sleep mode 272 /// while the peripheral is in sleep mode
265 pub fn set_automatic_wakeup(&mut self, enabled: bool) { 273 pub fn set_automatic_wakeup(&mut self, enabled: bool) {
266 Registers(T::regs()).set_automatic_wakeup(enabled); 274 self.info.regs.set_automatic_wakeup(enabled);
267 } 275 }
268 276
269 /// Manually wake the peripheral from sleep mode. 277 /// Manually wake the peripheral from sleep mode.
@@ -313,12 +321,12 @@ impl<'d, T: Instance> Can<'d, T> {
313 /// 321 ///
314 /// FIFO scheduling is disabled by default. 322 /// FIFO scheduling is disabled by default.
315 pub fn set_tx_fifo_scheduling(&mut self, enabled: bool) { 323 pub fn set_tx_fifo_scheduling(&mut self, enabled: bool) {
316 Registers(T::regs()).set_tx_fifo_scheduling(enabled) 324 self.info.regs.set_tx_fifo_scheduling(enabled)
317 } 325 }
318 326
319 /// Checks if FIFO scheduling of outgoing frames is enabled. 327 /// Checks if FIFO scheduling of outgoing frames is enabled.
320 pub fn tx_fifo_scheduling_enabled(&self) -> bool { 328 pub fn tx_fifo_scheduling_enabled(&self) -> bool {
321 Registers(T::regs()).tx_fifo_scheduling_enabled() 329 self.info.regs.tx_fifo_scheduling_enabled()
322 } 330 }
323 331
324 /// Queues the message to be sent. 332 /// Queues the message to be sent.
@@ -448,13 +456,13 @@ impl<'d, T: Instance> Can<'d, T> {
448 } 456 }
449} 457}
450 458
451impl<'d, T: FilterOwner> Can<'d, T> { 459impl<'d> Can<'d> {
452 /// Accesses the filter banks owned by this CAN peripheral. 460 /// Accesses the filter banks owned by this CAN peripheral.
453 /// 461 ///
454 /// To modify filters of a slave peripheral, `modify_filters` has to be called on the master 462 /// To modify filters of a slave peripheral, `modify_filters` has to be called on the master
455 /// peripheral instead. 463 /// peripheral instead.
456 pub fn modify_filters(&mut self) -> MasterFilters<'_, T> { 464 pub fn modify_filters(&mut self) -> MasterFilters<'_> {
457 unsafe { MasterFilters::new(self.info.regs.0) } 465 unsafe { MasterFilters::new(self.info) }
458 } 466 }
459} 467}
460 468
@@ -819,12 +827,14 @@ impl<'d, const RX_BUF_SIZE: usize> Drop for BufferedCanRx<'d, RX_BUF_SIZE> {
819 } 827 }
820} 828}
821 829
822impl<'d, T: Instance> Drop for Can<'d, T> { 830impl Drop for Can<'_> {
823 fn drop(&mut self) { 831 fn drop(&mut self) {
824 // Cannot call `free()` because it moves the instance. 832 // Cannot call `free()` because it moves the instance.
825 // Manually reset the peripheral. 833 // Manually reset the peripheral.
826 T::regs().mcr().write(|w| w.set_reset(true)); 834 self.info.regs.0.mcr().write(|w| w.set_reset(true));
827 rcc::disable::<T>(); 835 self.info.regs.enter_init_mode();
836 self.info.regs.leave_init_mode();
837 //rcc::disable::<T>();
828 } 838 }
829} 839}
830 840
@@ -1031,6 +1041,11 @@ pub(crate) struct Info {
1031 rx1_interrupt: crate::interrupt::Interrupt, 1041 rx1_interrupt: crate::interrupt::Interrupt,
1032 sce_interrupt: crate::interrupt::Interrupt, 1042 sce_interrupt: crate::interrupt::Interrupt,
1033 tx_waker: fn(), 1043 tx_waker: fn(),
1044
1045 /// The total number of filter banks available to the instance.
1046 ///
1047 /// This is usually either 14 or 28, and should be specified in the chip's reference manual or datasheet.
1048 num_filter_banks: u8,
1034} 1049}
1035 1050
1036trait SealedInstance { 1051trait SealedInstance {
@@ -1095,6 +1110,7 @@ foreach_peripheral!(
1095 rx1_interrupt: crate::_generated::peripheral_interrupts::$inst::RX1::IRQ, 1110 rx1_interrupt: crate::_generated::peripheral_interrupts::$inst::RX1::IRQ,
1096 sce_interrupt: crate::_generated::peripheral_interrupts::$inst::SCE::IRQ, 1111 sce_interrupt: crate::_generated::peripheral_interrupts::$inst::SCE::IRQ,
1097 tx_waker: crate::_generated::peripheral_interrupts::$inst::TX::pend, 1112 tx_waker: crate::_generated::peripheral_interrupts::$inst::TX::pend,
1113 num_filter_banks: peripherals::$inst::NUM_FILTER_BANKS,
1098 }; 1114 };
1099 &INFO 1115 &INFO
1100 } 1116 }
@@ -1148,6 +1164,11 @@ foreach_peripheral!(
1148 } 1164 }
1149 } 1165 }
1150 }; 1166 };
1167 (can, CAN2) => {
1168 unsafe impl FilterOwner for peripherals::CAN2 {
1169 const NUM_FILTER_BANKS: u8 = 0;
1170 }
1171 };
1151 (can, CAN3) => { 1172 (can, CAN3) => {
1152 unsafe impl FilterOwner for peripherals::CAN3 { 1173 unsafe impl FilterOwner for peripherals::CAN3 {
1153 const NUM_FILTER_BANKS: u8 = 14; 1174 const NUM_FILTER_BANKS: u8 = 14;
diff --git a/embassy-stm32/src/can/bxcan/registers.rs b/embassy-stm32/src/can/bxcan/registers.rs
index e7c7525d8..5f3d70e25 100644
--- a/embassy-stm32/src/can/bxcan/registers.rs
+++ b/embassy-stm32/src/can/bxcan/registers.rs
@@ -11,7 +11,7 @@ use crate::can::frame::{Envelope, Frame, Header};
11pub(crate) struct Registers(pub crate::pac::can::Can); 11pub(crate) struct Registers(pub crate::pac::can::Can);
12 12
13impl Registers { 13impl Registers {
14 pub fn enter_init_mode(&mut self) { 14 pub fn enter_init_mode(&self) {
15 self.0.mcr().modify(|reg| { 15 self.0.mcr().modify(|reg| {
16 reg.set_sleep(false); 16 reg.set_sleep(false);
17 reg.set_inrq(true); 17 reg.set_inrq(true);
@@ -25,7 +25,7 @@ impl Registers {
25 } 25 }
26 26
27 // Leaves initialization mode, enters sleep mode. 27 // Leaves initialization mode, enters sleep mode.
28 pub fn leave_init_mode(&mut self) { 28 pub fn leave_init_mode(&self) {
29 self.0.mcr().modify(|reg| { 29 self.0.mcr().modify(|reg| {
30 reg.set_sleep(true); 30 reg.set_sleep(true);
31 reg.set_inrq(false); 31 reg.set_inrq(false);
@@ -38,7 +38,7 @@ impl Registers {
38 } 38 }
39 } 39 }
40 40
41 pub fn set_bit_timing(&mut self, bt: crate::can::util::NominalBitTiming) { 41 pub fn set_bit_timing(&self, bt: crate::can::util::NominalBitTiming) {
42 let prescaler = u16::from(bt.prescaler) & 0x1FF; 42 let prescaler = u16::from(bt.prescaler) & 0x1FF;
43 let seg1 = u8::from(bt.seg1); 43 let seg1 = u8::from(bt.seg1);
44 let seg2 = u8::from(bt.seg2) & 0x7F; 44 let seg2 = u8::from(bt.seg2) & 0x7F;
@@ -84,7 +84,7 @@ impl Registers {
84 /// receive the frame. If enabled, [`Interrupt::Wakeup`] will also be triggered by the incoming 84 /// receive the frame. If enabled, [`Interrupt::Wakeup`] will also be triggered by the incoming
85 /// frame. 85 /// frame.
86 #[allow(dead_code)] 86 #[allow(dead_code)]
87 pub fn set_automatic_wakeup(&mut self, enabled: bool) { 87 pub fn set_automatic_wakeup(&self, enabled: bool) {
88 self.0.mcr().modify(|reg| reg.set_awum(enabled)); 88 self.0.mcr().modify(|reg| reg.set_awum(enabled));
89 } 89 }
90 90
@@ -96,7 +96,7 @@ impl Registers {
96 /// If this returns [`WouldBlock`][nb::Error::WouldBlock], the peripheral will enable itself 96 /// If this returns [`WouldBlock`][nb::Error::WouldBlock], the peripheral will enable itself
97 /// in the background. The peripheral is enabled and ready to use when this method returns 97 /// in the background. The peripheral is enabled and ready to use when this method returns
98 /// successfully. 98 /// successfully.
99 pub fn enable_non_blocking(&mut self) -> nb::Result<(), Infallible> { 99 pub fn enable_non_blocking(&self) -> nb::Result<(), Infallible> {
100 let msr = self.0.msr().read(); 100 let msr = self.0.msr().read();
101 if msr.slak() { 101 if msr.slak() {
102 self.0.mcr().modify(|reg| { 102 self.0.mcr().modify(|reg| {
@@ -186,7 +186,7 @@ impl Registers {
186 /// If this is enabled, mailboxes are scheduled based on the time when the transmit request bit of the mailbox was set. 186 /// If this is enabled, mailboxes are scheduled based on the time when the transmit request bit of the mailbox was set.
187 /// 187 ///
188 /// If this is disabled, mailboxes are scheduled based on the priority of the frame in the mailbox. 188 /// If this is disabled, mailboxes are scheduled based on the priority of the frame in the mailbox.
189 pub fn set_tx_fifo_scheduling(&mut self, enabled: bool) { 189 pub fn set_tx_fifo_scheduling(&self, enabled: bool) {
190 self.0.mcr().modify(|w| w.set_txfp(enabled)) 190 self.0.mcr().modify(|w| w.set_txfp(enabled))
191 } 191 }
192 192
diff --git a/tests/stm32/src/bin/can.rs b/tests/stm32/src/bin/can.rs
index f63076512..ba8a33e34 100644
--- a/tests/stm32/src/bin/can.rs
+++ b/tests/stm32/src/bin/can.rs
@@ -18,10 +18,6 @@ use {defmt_rtt as _, panic_probe as _};
18mod can_common; 18mod can_common;
19use can_common::*; 19use can_common::*;
20 20
21type Can<'d> = embassy_stm32::can::Can<'d, embassy_stm32::peripherals::CAN1>;
22type CanTx<'d> = embassy_stm32::can::CanTx<'d>;
23type CanRx<'d> = embassy_stm32::can::CanRx<'d>;
24
25bind_interrupts!(struct Irqs { 21bind_interrupts!(struct Irqs {
26 CAN1_RX0 => Rx0InterruptHandler<CAN1>; 22 CAN1_RX0 => Rx0InterruptHandler<CAN1>;
27 CAN1_RX1 => Rx1InterruptHandler<CAN1>; 23 CAN1_RX1 => Rx1InterruptHandler<CAN1>;
@@ -50,7 +46,7 @@ async fn main(_spawner: Spawner) {
50 let rx_pin = Input::new(&mut rx, Pull::Up); 46 let rx_pin = Input::new(&mut rx, Pull::Up);
51 core::mem::forget(rx_pin); 47 core::mem::forget(rx_pin);
52 48
53 let mut can = Can::new(can, rx, tx, Irqs); 49 let mut can = embassy_stm32::can::Can::new(can, rx, tx, Irqs);
54 50
55 info!("Configuring can..."); 51 info!("Configuring can...");
56 52
diff --git a/tests/stm32/src/bin/can_common.rs b/tests/stm32/src/bin/can_common.rs
index fbfbcdc21..4e1740ad5 100644
--- a/tests/stm32/src/bin/can_common.rs
+++ b/tests/stm32/src/bin/can_common.rs
@@ -8,7 +8,7 @@ pub struct TestOptions {
8 pub max_buffered: u8, 8 pub max_buffered: u8,
9} 9}
10 10
11pub async fn run_can_tests<'d>(can: &mut crate::Can<'d>, options: &TestOptions) { 11pub async fn run_can_tests<'d>(can: &mut can::Can<'d>, options: &TestOptions) {
12 //pub async fn run_can_tests<'d, T: can::Instance>(can: &mut can::Can<'d, T>, options: &TestOptions) { 12 //pub async fn run_can_tests<'d, T: can::Instance>(can: &mut can::Can<'d, T>, options: &TestOptions) {
13 let mut i: u8 = 0; 13 let mut i: u8 = 0;
14 loop { 14 loop {
@@ -80,7 +80,7 @@ pub async fn run_can_tests<'d>(can: &mut crate::Can<'d>, options: &TestOptions)
80 } 80 }
81} 81}
82 82
83pub async fn run_split_can_tests<'d>(tx: &mut crate::CanTx<'d>, rx: &mut crate::CanRx<'d>, options: &TestOptions) { 83pub async fn run_split_can_tests<'d>(tx: &mut can::CanTx<'d>, rx: &mut can::CanRx<'d>, options: &TestOptions) {
84 for i in 0..options.max_buffered { 84 for i in 0..options.max_buffered {
85 // Try filling up the RX FIFO0 buffers 85 // Try filling up the RX FIFO0 buffers
86 //let tx_frame = if 0 != (i & 0x01) { 86 //let tx_frame = if 0 != (i & 0x01) {
diff --git a/tests/stm32/src/bin/fdcan.rs b/tests/stm32/src/bin/fdcan.rs
index 8a397f661..bc2b7edd4 100644
--- a/tests/stm32/src/bin/fdcan.rs
+++ b/tests/stm32/src/bin/fdcan.rs
@@ -15,10 +15,6 @@ use {defmt_rtt as _, panic_probe as _};
15mod can_common; 15mod can_common;
16use can_common::*; 16use can_common::*;
17 17
18type Can<'d> = can::Can<'d>;
19type CanTx<'d> = can::CanTx<'d>;
20type CanRx<'d> = can::CanRx<'d>;
21
22bind_interrupts!(struct Irqs2 { 18bind_interrupts!(struct Irqs2 {
23 FDCAN2_IT0 => can::IT0InterruptHandler<FDCAN2>; 19 FDCAN2_IT0 => can::IT0InterruptHandler<FDCAN2>;
24 FDCAN2_IT1 => can::IT1InterruptHandler<FDCAN2>; 20 FDCAN2_IT1 => can::IT1InterruptHandler<FDCAN2>;