diff options
| author | Corey Schuhen <[email protected]> | 2024-06-02 19:40:25 +1000 |
|---|---|---|
| committer | Corey Schuhen <[email protected]> | 2024-06-02 20:11:56 +1000 |
| commit | 367a22cc0eef61f05061aaadc714990723c25940 (patch) | |
| tree | bfb3ae3637ec2e1f23d037305ce51ad3ecacef7a | |
| parent | e61136fa4ab0261ec9d9e262e1c3295d4549fa5f (diff) | |
Remove more BXCAN generics.
| -rw-r--r-- | embassy-stm32/src/can/bxcan/filter.rs | 70 | ||||
| -rw-r--r-- | embassy-stm32/src/can/bxcan/mod.rs | 85 | ||||
| -rw-r--r-- | embassy-stm32/src/can/bxcan/registers.rs | 12 | ||||
| -rw-r--r-- | tests/stm32/src/bin/can.rs | 6 | ||||
| -rw-r--r-- | tests/stm32/src/bin/can_common.rs | 4 | ||||
| -rw-r--r-- | tests/stm32/src/bin/fdcan.rs | 4 |
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 | ||
| 3 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| 4 | 4 | ||
| 5 | use super::{ExtendedId, Fifo, FilterOwner, Id, Instance, MasterInstance, StandardId}; | 5 | use super::{ExtendedId, Fifo, Id, StandardId}; |
| 6 | 6 | ||
| 7 | const F32_RTR: u32 = 0b010; // set the RTR bit to match remote frames | 7 | const F32_RTR: u32 = 0b010; // set the RTR bit to match remote frames |
| 8 | const F32_IDE: u32 = 0b100; // set the IDE bit to match extended identifiers | 8 | const 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. |
| 213 | pub struct MasterFilters<'a, I: FilterOwner> { | 213 | pub 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. |
| 224 | impl<I: FilterOwner> MasterFilters<'_, I> { | 224 | impl 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 | ||
| 294 | impl<I: MasterInstance> MasterFilters<'_, I> { | 294 | impl 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 | ||
| 315 | impl<I: FilterOwner> Drop for MasterFilters<'_, I> { | 315 | impl 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. |
| 324 | pub struct SlaveFilters<'a, I: Instance> { | 324 | pub 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 | ||
| 331 | impl<I: Instance> SlaveFilters<'_, I> { | 331 | impl 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> { | |||
| 377 | struct FilterBanks { | 377 | struct 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 | ||
| 383 | impl FilterBanks { | 383 | impl 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; | |||
| 6 | use core::task::Poll; | 6 | use core::task::Poll; |
| 7 | 7 | ||
| 8 | use embassy_hal_internal::interrupt::InterruptExt; | 8 | use embassy_hal_internal::interrupt::InterruptExt; |
| 9 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 9 | use embassy_hal_internal::into_ref; |
| 10 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | 10 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; |
| 11 | use embassy_sync::channel::Channel; | 11 | use embassy_sync::channel::Channel; |
| 12 | use embassy_sync::waitqueue::AtomicWaker; | 12 | use 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`]. |
| 94 | pub struct CanConfig<'a, T: Instance> { | 94 | pub 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 | ||
| 98 | impl<T: Instance> CanConfig<'_, T> { | 100 | impl 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 | ||
| 149 | impl<T: Instance> Drop for CanConfig<'_, T> { | 151 | impl 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 |
| 157 | pub struct Can<'d, T: Instance> { | 159 | pub 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 | ||
| 171 | impl<'d, T: Instance> Can<'d, T> { | 174 | impl<'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 | ||
| 451 | impl<'d, T: FilterOwner> Can<'d, T> { | 459 | impl<'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 | ||
| 822 | impl<'d, T: Instance> Drop for Can<'d, T> { | 830 | impl 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 | ||
| 1036 | trait SealedInstance { | 1051 | trait 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}; | |||
| 11 | pub(crate) struct Registers(pub crate::pac::can::Can); | 11 | pub(crate) struct Registers(pub crate::pac::can::Can); |
| 12 | 12 | ||
| 13 | impl Registers { | 13 | impl 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 _}; | |||
| 18 | mod can_common; | 18 | mod can_common; |
| 19 | use can_common::*; | 19 | use can_common::*; |
| 20 | 20 | ||
| 21 | type Can<'d> = embassy_stm32::can::Can<'d, embassy_stm32::peripherals::CAN1>; | ||
| 22 | type CanTx<'d> = embassy_stm32::can::CanTx<'d>; | ||
| 23 | type CanRx<'d> = embassy_stm32::can::CanRx<'d>; | ||
| 24 | |||
| 25 | bind_interrupts!(struct Irqs { | 21 | bind_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 | ||
| 11 | pub async fn run_can_tests<'d>(can: &mut crate::Can<'d>, options: &TestOptions) { | 11 | pub 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 | ||
| 83 | pub async fn run_split_can_tests<'d>(tx: &mut crate::CanTx<'d>, rx: &mut crate::CanRx<'d>, options: &TestOptions) { | 83 | pub 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 _}; | |||
| 15 | mod can_common; | 15 | mod can_common; |
| 16 | use can_common::*; | 16 | use can_common::*; |
| 17 | 17 | ||
| 18 | type Can<'d> = can::Can<'d>; | ||
| 19 | type CanTx<'d> = can::CanTx<'d>; | ||
| 20 | type CanRx<'d> = can::CanRx<'d>; | ||
| 21 | |||
| 22 | bind_interrupts!(struct Irqs2 { | 18 | bind_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>; |
