diff options
| author | Corey Schuhen <[email protected]> | 2024-03-03 20:27:08 +1000 |
|---|---|---|
| committer | Corey Schuhen <[email protected]> | 2024-03-07 17:45:01 +1000 |
| commit | 455cc40261884b0a358e775fd4f411fa77ce27c9 (patch) | |
| tree | 315c8fe84e2c6fa589fb0dfe2acfbddc3e8c4967 | |
| parent | b0f05e768225ae321cb08a469fa4a384cb8523ab (diff) | |
Port registers access to using Embassy PAC
Use stm32-metapac for filters module.
| -rw-r--r-- | embassy-stm32/src/can/bx/filter.rs | 99 | ||||
| -rw-r--r-- | embassy-stm32/src/can/bx/frame.rs | 1 | ||||
| -rw-r--r-- | embassy-stm32/src/can/bx/mod.rs | 370 | ||||
| -rw-r--r-- | embassy-stm32/src/can/bxcan.rs | 27 |
4 files changed, 218 insertions, 279 deletions
diff --git a/embassy-stm32/src/can/bx/filter.rs b/embassy-stm32/src/can/bx/filter.rs index c149d37ea..64f020fc7 100644 --- a/embassy-stm32/src/can/bx/filter.rs +++ b/embassy-stm32/src/can/bx/filter.rs | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | 2 | ||
| 3 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| 4 | 4 | ||
| 5 | use crate::can::bx::pac::can::RegisterBlock; | ||
| 6 | use crate::can::bx::{ExtendedId, Fifo, FilterOwner, Id, Instance, MasterInstance, StandardId}; | 5 | use crate::can::bx::{ExtendedId, Fifo, FilterOwner, Id, Instance, MasterInstance, StandardId}; |
| 7 | 6 | ||
| 8 | 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 |
| @@ -213,19 +212,18 @@ pub struct MasterFilters<'a, I: FilterOwner> { | |||
| 213 | /// On chips with splittable filter banks, this value can be dynamic. | 212 | /// On chips with splittable filter banks, this value can be dynamic. |
| 214 | bank_count: u8, | 213 | bank_count: u8, |
| 215 | _can: PhantomData<&'a mut I>, | 214 | _can: PhantomData<&'a mut I>, |
| 215 | canregs: crate::pac::can::Can, | ||
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | // NOTE: This type mutably borrows the CAN instance and has unique access to the registers while it | 218 | // NOTE: This type mutably borrows the CAN instance and has unique access to the registers while it |
| 219 | // exists. | 219 | // exists. |
| 220 | impl<I: FilterOwner> MasterFilters<'_, I> { | 220 | impl<I: FilterOwner> MasterFilters<'_, I> { |
| 221 | pub(crate) unsafe fn new() -> Self { | 221 | pub(crate) unsafe fn new(canregs: crate::pac::can::Can) -> Self { |
| 222 | let can = &*I::REGISTERS; | ||
| 223 | |||
| 224 | // Enable initialization mode. | 222 | // Enable initialization mode. |
| 225 | can.fmr.modify(|_, w| w.finit().set_bit()); | 223 | canregs.fmr().modify(|reg| reg.set_finit(true)); |
| 226 | 224 | ||
| 227 | // Read the filter split value. | 225 | // Read the filter split value. |
| 228 | let bank_count = can.fmr.read().can2sb().bits(); | 226 | let bank_count = canregs.fmr().read().can2sb(); |
| 229 | 227 | ||
| 230 | // (Reset value of CAN2SB is 0x0E, 14, which, in devices with 14 filter banks, assigns all | 228 | // (Reset value of CAN2SB is 0x0E, 14, which, in devices with 14 filter banks, assigns all |
| 231 | // of them to the master peripheral, and in devices with 28, assigns them 50/50 to | 229 | // of them to the master peripheral, and in devices with 28, assigns them 50/50 to |
| @@ -234,18 +232,15 @@ impl<I: FilterOwner> MasterFilters<'_, I> { | |||
| 234 | Self { | 232 | Self { |
| 235 | bank_count, | 233 | bank_count, |
| 236 | _can: PhantomData, | 234 | _can: PhantomData, |
| 235 | canregs, | ||
| 237 | } | 236 | } |
| 238 | } | 237 | } |
| 239 | 238 | ||
| 240 | fn registers(&self) -> &RegisterBlock { | 239 | fn banks_imm(&self) -> FilterBanks { |
| 241 | unsafe { &*I::REGISTERS } | ||
| 242 | } | ||
| 243 | |||
| 244 | fn banks_imm(&self) -> FilterBanks<'_> { | ||
| 245 | FilterBanks { | 240 | FilterBanks { |
| 246 | start_idx: 0, | 241 | start_idx: 0, |
| 247 | bank_count: self.bank_count, | 242 | bank_count: self.bank_count, |
| 248 | can: self.registers(), | 243 | canregs: self.canregs, |
| 249 | } | 244 | } |
| 250 | } | 245 | } |
| 251 | 246 | ||
| @@ -296,9 +291,7 @@ impl<I: MasterInstance> MasterFilters<'_, I> { | |||
| 296 | /// Sets the index at which the filter banks owned by the slave peripheral start. | 291 | /// Sets the index at which the filter banks owned by the slave peripheral start. |
| 297 | pub fn set_split(&mut self, split_index: u8) -> &mut Self { | 292 | pub fn set_split(&mut self, split_index: u8) -> &mut Self { |
| 298 | assert!(split_index <= I::NUM_FILTER_BANKS); | 293 | assert!(split_index <= I::NUM_FILTER_BANKS); |
| 299 | self.registers() | 294 | self.canregs.fmr().modify(|reg| reg.set_can2sb(split_index)); |
| 300 | .fmr | ||
| 301 | .modify(|_, w| unsafe { w.can2sb().bits(split_index) }); | ||
| 302 | self.bank_count = split_index; | 295 | self.bank_count = split_index; |
| 303 | self | 296 | self |
| 304 | } | 297 | } |
| @@ -310,6 +303,7 @@ impl<I: MasterInstance> MasterFilters<'_, I> { | |||
| 310 | start_idx: self.bank_count, | 303 | start_idx: self.bank_count, |
| 311 | bank_count: I::NUM_FILTER_BANKS - self.bank_count, | 304 | bank_count: I::NUM_FILTER_BANKS - self.bank_count, |
| 312 | _can: PhantomData, | 305 | _can: PhantomData, |
| 306 | canregs: self.canregs, | ||
| 313 | } | 307 | } |
| 314 | } | 308 | } |
| 315 | } | 309 | } |
| @@ -317,10 +311,8 @@ impl<I: MasterInstance> MasterFilters<'_, I> { | |||
| 317 | impl<I: FilterOwner> Drop for MasterFilters<'_, I> { | 311 | impl<I: FilterOwner> Drop for MasterFilters<'_, I> { |
| 318 | #[inline] | 312 | #[inline] |
| 319 | fn drop(&mut self) { | 313 | fn drop(&mut self) { |
| 320 | let can = self.registers(); | ||
| 321 | |||
| 322 | // Leave initialization mode. | 314 | // Leave initialization mode. |
| 323 | can.fmr.modify(|_, w| w.finit().clear_bit()); | 315 | self.canregs.fmr().modify(|regs| regs.set_finit(false)); |
| 324 | } | 316 | } |
| 325 | } | 317 | } |
| 326 | 318 | ||
| @@ -329,18 +321,15 @@ pub struct SlaveFilters<'a, I: Instance> { | |||
| 329 | start_idx: u8, | 321 | start_idx: u8, |
| 330 | bank_count: u8, | 322 | bank_count: u8, |
| 331 | _can: PhantomData<&'a mut I>, | 323 | _can: PhantomData<&'a mut I>, |
| 324 | canregs: crate::pac::can::Can, | ||
| 332 | } | 325 | } |
| 333 | 326 | ||
| 334 | impl<I: Instance> SlaveFilters<'_, I> { | 327 | impl<I: Instance> SlaveFilters<'_, I> { |
| 335 | fn registers(&self) -> &RegisterBlock { | 328 | fn banks_imm(&self) -> FilterBanks { |
| 336 | unsafe { &*I::REGISTERS } | ||
| 337 | } | ||
| 338 | |||
| 339 | fn banks_imm(&self) -> FilterBanks<'_> { | ||
| 340 | FilterBanks { | 329 | FilterBanks { |
| 341 | start_idx: self.start_idx, | 330 | start_idx: self.start_idx, |
| 342 | bank_count: self.bank_count, | 331 | bank_count: self.bank_count, |
| 343 | can: self.registers(), | 332 | canregs: self.canregs, |
| 344 | } | 333 | } |
| 345 | } | 334 | } |
| 346 | 335 | ||
| @@ -381,20 +370,22 @@ impl<I: Instance> SlaveFilters<'_, I> { | |||
| 381 | } | 370 | } |
| 382 | } | 371 | } |
| 383 | 372 | ||
| 384 | struct FilterBanks<'a> { | 373 | struct FilterBanks { |
| 385 | start_idx: u8, | 374 | start_idx: u8, |
| 386 | bank_count: u8, | 375 | bank_count: u8, |
| 387 | can: &'a RegisterBlock, | 376 | canregs: crate::pac::can::Can, |
| 388 | } | 377 | } |
| 389 | 378 | ||
| 390 | impl FilterBanks<'_> { | 379 | impl FilterBanks { |
| 391 | fn clear(&mut self) { | 380 | fn clear(&mut self) { |
| 392 | let mask = filter_bitmask(self.start_idx, self.bank_count); | 381 | let mask = filter_bitmask(self.start_idx, self.bank_count); |
| 393 | 382 | ||
| 394 | self.can.fa1r.modify(|r, w| { | 383 | self.canregs.fa1r().modify(|reg| { |
| 395 | let bits = r.bits(); | 384 | for i in 0..28usize { |
| 396 | // Clear all bits in `mask`. | 385 | if (0x01u32 << i) & mask != 0 { |
| 397 | unsafe { w.bits(bits & !mask) } | 386 | reg.set_fact(i, false); |
| 387 | } | ||
| 388 | } | ||
| 398 | }); | 389 | }); |
| 399 | } | 390 | } |
| 400 | 391 | ||
| @@ -404,8 +395,7 @@ impl FilterBanks<'_> { | |||
| 404 | 395 | ||
| 405 | fn disable(&mut self, index: u8) { | 396 | fn disable(&mut self, index: u8) { |
| 406 | self.assert_bank_index(index); | 397 | self.assert_bank_index(index); |
| 407 | 398 | self.canregs.fa1r().modify(|reg| reg.set_fact(index as usize, false)) | |
| 408 | self.can.fa1r.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << index)) }) | ||
| 409 | } | 399 | } |
| 410 | 400 | ||
| 411 | fn enable(&mut self, index: u8, fifo: Fifo, config: BankConfig) { | 401 | fn enable(&mut self, index: u8, fifo: Fifo, config: BankConfig) { |
| @@ -413,27 +403,11 @@ impl FilterBanks<'_> { | |||
| 413 | 403 | ||
| 414 | // Configure mode. | 404 | // Configure mode. |
| 415 | let mode = matches!(config, BankConfig::List16(_) | BankConfig::List32(_)); | 405 | let mode = matches!(config, BankConfig::List16(_) | BankConfig::List32(_)); |
| 416 | self.can.fm1r.modify(|r, w| { | 406 | self.canregs.fm1r().modify(|reg| reg.set_fbm(index as usize, mode)); |
| 417 | let mut bits = r.bits(); | ||
| 418 | if mode { | ||
| 419 | bits |= 1 << index; | ||
| 420 | } else { | ||
| 421 | bits &= !(1 << index); | ||
| 422 | } | ||
| 423 | unsafe { w.bits(bits) } | ||
| 424 | }); | ||
| 425 | 407 | ||
| 426 | // Configure scale. | 408 | // Configure scale. |
| 427 | let scale = matches!(config, BankConfig::List32(_) | BankConfig::Mask32(_)); | 409 | let scale = matches!(config, BankConfig::List32(_) | BankConfig::Mask32(_)); |
| 428 | self.can.fs1r.modify(|r, w| { | 410 | self.canregs.fs1r().modify(|reg| reg.set_fsc(index as usize, scale)); |
| 429 | let mut bits = r.bits(); | ||
| 430 | if scale { | ||
| 431 | bits |= 1 << index; | ||
| 432 | } else { | ||
| 433 | bits &= !(1 << index); | ||
| 434 | } | ||
| 435 | unsafe { w.bits(bits) } | ||
| 436 | }); | ||
| 437 | 411 | ||
| 438 | // Configure filter register. | 412 | // Configure filter register. |
| 439 | let (fxr1, fxr2); | 413 | let (fxr1, fxr2); |
| @@ -455,22 +429,23 @@ impl FilterBanks<'_> { | |||
| 455 | fxr2 = a.mask; | 429 | fxr2 = a.mask; |
| 456 | } | 430 | } |
| 457 | }; | 431 | }; |
| 458 | let bank = &self.can.fb[usize::from(index)]; | 432 | let bank = self.canregs.fb(index as usize); |
| 459 | bank.fr1.write(|w| unsafe { w.bits(fxr1) }); | 433 | bank.fr1().write(|w| w.0 = fxr1); |
| 460 | bank.fr2.write(|w| unsafe { w.bits(fxr2) }); | 434 | bank.fr2().write(|w| w.0 = fxr2); |
| 461 | 435 | ||
| 462 | // Assign to the right FIFO | 436 | // Assign to the right FIFO |
| 463 | self.can.ffa1r.modify(|r, w| unsafe { | 437 | self.canregs.ffa1r().modify(|reg| { |
| 464 | let mut bits = r.bits(); | 438 | reg.set_ffa( |
| 465 | match fifo { | 439 | index as usize, |
| 466 | Fifo::Fifo0 => bits &= !(1 << index), | 440 | match fifo { |
| 467 | Fifo::Fifo1 => bits |= 1 << index, | 441 | Fifo::Fifo0 => false, |
| 468 | } | 442 | Fifo::Fifo1 => true, |
| 469 | w.bits(bits) | 443 | }, |
| 444 | ) | ||
| 470 | }); | 445 | }); |
| 471 | 446 | ||
| 472 | // Set active. | 447 | // Set active. |
| 473 | self.can.fa1r.modify(|r, w| unsafe { w.bits(r.bits() | (1 << index)) }) | 448 | self.canregs.fa1r().modify(|reg| reg.set_fact(index as usize, true)) |
| 474 | } | 449 | } |
| 475 | } | 450 | } |
| 476 | 451 | ||
diff --git a/embassy-stm32/src/can/bx/frame.rs b/embassy-stm32/src/can/bx/frame.rs index 2a51d1b15..828f375be 100644 --- a/embassy-stm32/src/can/bx/frame.rs +++ b/embassy-stm32/src/can/bx/frame.rs | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | #[cfg(test)] | 1 | #[cfg(test)] |
| 2 | |||
| 3 | use core::cmp::Ordering; | 2 | use core::cmp::Ordering; |
| 4 | use core::ops::{Deref, DerefMut}; | 3 | use core::ops::{Deref, DerefMut}; |
| 5 | 4 | ||
diff --git a/embassy-stm32/src/can/bx/mod.rs b/embassy-stm32/src/can/bx/mod.rs index c5801abec..eee8a33a6 100644 --- a/embassy-stm32/src/can/bx/mod.rs +++ b/embassy-stm32/src/can/bx/mod.rs | |||
| @@ -35,7 +35,6 @@ use core::cmp::{Ord, Ordering}; | |||
| 35 | use core::convert::{Infallible, TryInto}; | 35 | use core::convert::{Infallible, TryInto}; |
| 36 | use core::marker::PhantomData; | 36 | use core::marker::PhantomData; |
| 37 | use core::mem; | 37 | use core::mem; |
| 38 | use core::ptr::NonNull; | ||
| 39 | 38 | ||
| 40 | pub use id::{ExtendedId, Id, StandardId}; | 39 | pub use id::{ExtendedId, Id, StandardId}; |
| 41 | 40 | ||
| @@ -125,7 +124,7 @@ pub struct OverrunError { | |||
| 125 | /// priority than remote frames. | 124 | /// priority than remote frames. |
| 126 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] | 125 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
| 127 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 126 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 128 | struct IdReg(u32); | 127 | pub(crate) struct IdReg(u32); |
| 129 | 128 | ||
| 130 | impl IdReg { | 129 | impl IdReg { |
| 131 | const STANDARD_SHIFT: u32 = 21; | 130 | const STANDARD_SHIFT: u32 = 21; |
| @@ -243,23 +242,25 @@ impl<I: Instance> CanConfig<'_, I> { | |||
| 243 | /// | 242 | /// |
| 244 | /// Then copy the `CAN_BUS_TIME` register value from the table and pass it as the `btr` | 243 | /// Then copy the `CAN_BUS_TIME` register value from the table and pass it as the `btr` |
| 245 | /// parameter to this method. | 244 | /// parameter to this method. |
| 246 | pub fn set_bit_timing(self, btr: u32) -> Self { | 245 | pub fn set_bit_timing(self, bt: crate::can::util::NominalBitTiming) -> Self { |
| 247 | self.can.set_bit_timing(btr); | 246 | self.can.set_bit_timing(bt); |
| 248 | self | 247 | self |
| 249 | } | 248 | } |
| 250 | 249 | ||
| 251 | /// Enables or disables loopback mode: Internally connects the TX and RX | 250 | /// Enables or disables loopback mode: Internally connects the TX and RX |
| 252 | /// signals together. | 251 | /// signals together. |
| 253 | pub fn set_loopback(self, enabled: bool) -> Self { | 252 | pub fn set_loopback(self, enabled: bool) -> Self { |
| 254 | let can = self.can.registers(); | 253 | self.can.canregs.btr().modify(|reg| reg.set_lbkm(enabled)); |
| 255 | can.btr.modify(|_, w| w.lbkm().bit(enabled)); | ||
| 256 | self | 254 | self |
| 257 | } | 255 | } |
| 258 | 256 | ||
| 259 | /// Enables or disables silent mode: Disconnects the TX signal from the pin. | 257 | /// Enables or disables silent mode: Disconnects the TX signal from the pin. |
| 260 | pub fn set_silent(self, enabled: bool) -> Self { | 258 | pub fn set_silent(self, enabled: bool) -> Self { |
| 261 | let can = self.can.registers(); | 259 | let mode = match enabled { |
| 262 | can.btr.modify(|_, w| w.silm().bit(enabled)); | 260 | false => stm32_metapac::can::vals::Silm::NORMAL, |
| 261 | true => stm32_metapac::can::vals::Silm::SILENT, | ||
| 262 | }; | ||
| 263 | self.can.canregs.btr().modify(|reg| reg.set_silm(mode)); | ||
| 263 | self | 264 | self |
| 264 | } | 265 | } |
| 265 | 266 | ||
| @@ -270,8 +271,7 @@ impl<I: Instance> CanConfig<'_, I> { | |||
| 270 | /// | 271 | /// |
| 271 | /// Automatic retransmission is enabled by default. | 272 | /// Automatic retransmission is enabled by default. |
| 272 | pub fn set_automatic_retransmit(self, enabled: bool) -> Self { | 273 | pub fn set_automatic_retransmit(self, enabled: bool) -> Self { |
| 273 | let can = self.can.registers(); | 274 | self.can.canregs.mcr().modify(|reg| reg.set_nart(enabled)); |
| 274 | can.mcr.modify(|_, w| w.nart().bit(!enabled)); | ||
| 275 | self | 275 | self |
| 276 | } | 276 | } |
| 277 | 277 | ||
| @@ -304,11 +304,13 @@ impl<I: Instance> CanConfig<'_, I> { | |||
| 304 | 304 | ||
| 305 | /// Leaves initialization mode, enters sleep mode. | 305 | /// Leaves initialization mode, enters sleep mode. |
| 306 | fn leave_init_mode(&mut self) { | 306 | fn leave_init_mode(&mut self) { |
| 307 | let can = self.can.registers(); | 307 | self.can.canregs.mcr().modify(|reg| { |
| 308 | can.mcr.modify(|_, w| w.sleep().set_bit().inrq().clear_bit()); | 308 | reg.set_sleep(true); |
| 309 | reg.set_inrq(false); | ||
| 310 | }); | ||
| 309 | loop { | 311 | loop { |
| 310 | let msr = can.msr.read(); | 312 | let msr = self.can.canregs.msr().read(); |
| 311 | if msr.slak().bit_is_set() && msr.inak().bit_is_clear() { | 313 | if msr.slak() && !msr.inak() { |
| 312 | break; | 314 | break; |
| 313 | } | 315 | } |
| 314 | } | 316 | } |
| @@ -341,23 +343,24 @@ impl<I: Instance> CanBuilder<I> { | |||
| 341 | /// | 343 | /// |
| 342 | /// Then copy the `CAN_BUS_TIME` register value from the table and pass it as the `btr` | 344 | /// Then copy the `CAN_BUS_TIME` register value from the table and pass it as the `btr` |
| 343 | /// parameter to this method. | 345 | /// parameter to this method. |
| 344 | pub fn set_bit_timing(mut self, btr: u32) -> Self { | 346 | pub fn set_bit_timing(mut self, bt: crate::can::util::NominalBitTiming) -> Self { |
| 345 | self.can.set_bit_timing(btr); | 347 | self.can.set_bit_timing(bt); |
| 346 | self | 348 | self |
| 347 | } | 349 | } |
| 348 | |||
| 349 | /// Enables or disables loopback mode: Internally connects the TX and RX | 350 | /// Enables or disables loopback mode: Internally connects the TX and RX |
| 350 | /// signals together. | 351 | /// signals together. |
| 351 | pub fn set_loopback(self, enabled: bool) -> Self { | 352 | pub fn set_loopback(self, enabled: bool) -> Self { |
| 352 | let can = self.can.registers(); | 353 | self.can.canregs.btr().modify(|reg| reg.set_lbkm(enabled)); |
| 353 | can.btr.modify(|_, w| w.lbkm().bit(enabled)); | ||
| 354 | self | 354 | self |
| 355 | } | 355 | } |
| 356 | 356 | ||
| 357 | /// Enables or disables silent mode: Disconnects the TX signal from the pin. | 357 | /// Enables or disables silent mode: Disconnects the TX signal from the pin. |
| 358 | pub fn set_silent(self, enabled: bool) -> Self { | 358 | pub fn set_silent(self, enabled: bool) -> Self { |
| 359 | let can = self.can.registers(); | 359 | let mode = match enabled { |
| 360 | can.btr.modify(|_, w| w.silm().bit(enabled)); | 360 | false => stm32_metapac::can::vals::Silm::NORMAL, |
| 361 | true => stm32_metapac::can::vals::Silm::SILENT, | ||
| 362 | }; | ||
| 363 | self.can.canregs.btr().modify(|reg| reg.set_silm(mode)); | ||
| 361 | self | 364 | self |
| 362 | } | 365 | } |
| 363 | 366 | ||
| @@ -368,8 +371,7 @@ impl<I: Instance> CanBuilder<I> { | |||
| 368 | /// | 371 | /// |
| 369 | /// Automatic retransmission is enabled by default. | 372 | /// Automatic retransmission is enabled by default. |
| 370 | pub fn set_automatic_retransmit(self, enabled: bool) -> Self { | 373 | pub fn set_automatic_retransmit(self, enabled: bool) -> Self { |
| 371 | let can = self.can.registers(); | 374 | self.can.canregs.mcr().modify(|reg| reg.set_nart(enabled)); |
| 372 | can.mcr.modify(|_, w| w.nart().bit(!enabled)); | ||
| 373 | self | 375 | self |
| 374 | } | 376 | } |
| 375 | 377 | ||
| @@ -403,11 +405,13 @@ impl<I: Instance> CanBuilder<I> { | |||
| 403 | 405 | ||
| 404 | /// Leaves initialization mode, enters sleep mode. | 406 | /// Leaves initialization mode, enters sleep mode. |
| 405 | fn leave_init_mode(&mut self) { | 407 | fn leave_init_mode(&mut self) { |
| 406 | let can = self.can.registers(); | 408 | self.can.canregs.mcr().modify(|reg| { |
| 407 | can.mcr.modify(|_, w| w.sleep().set_bit().inrq().clear_bit()); | 409 | reg.set_sleep(true); |
| 410 | reg.set_inrq(false); | ||
| 411 | }); | ||
| 408 | loop { | 412 | loop { |
| 409 | let msr = can.msr.read(); | 413 | let msr = self.can.canregs.msr().read(); |
| 410 | if msr.slak().bit_is_set() && msr.inak().bit_is_clear() { | 414 | if msr.slak() && !msr.inak() { |
| 411 | break; | 415 | break; |
| 412 | } | 416 | } |
| 413 | } | 417 | } |
| @@ -417,6 +421,7 @@ impl<I: Instance> CanBuilder<I> { | |||
| 417 | /// Interface to a bxCAN peripheral. | 421 | /// Interface to a bxCAN peripheral. |
| 418 | pub struct Can<I: Instance> { | 422 | pub struct Can<I: Instance> { |
| 419 | instance: I, | 423 | instance: I, |
| 424 | canregs: crate::pac::can::Can, | ||
| 420 | } | 425 | } |
| 421 | 426 | ||
| 422 | impl<I> Can<I> | 427 | impl<I> Can<I> |
| @@ -424,15 +429,18 @@ where | |||
| 424 | I: Instance, | 429 | I: Instance, |
| 425 | { | 430 | { |
| 426 | /// Creates a [`CanBuilder`] for constructing a CAN interface. | 431 | /// Creates a [`CanBuilder`] for constructing a CAN interface. |
| 427 | pub fn builder(instance: I) -> CanBuilder<I> { | 432 | pub fn builder(instance: I, canregs: crate::pac::can::Can) -> CanBuilder<I> { |
| 428 | let can_builder = CanBuilder { can: Can { instance } }; | 433 | let can_builder = CanBuilder { |
| 434 | can: Can { instance, canregs }, | ||
| 435 | }; | ||
| 429 | 436 | ||
| 430 | let can_reg = can_builder.can.registers(); | 437 | canregs.mcr().modify(|reg| { |
| 431 | // Enter init mode. | 438 | reg.set_sleep(false); |
| 432 | can_reg.mcr.modify(|_, w| w.sleep().clear_bit().inrq().set_bit()); | 439 | reg.set_inrq(true); |
| 440 | }); | ||
| 433 | loop { | 441 | loop { |
| 434 | let msr = can_reg.msr.read(); | 442 | let msr = canregs.msr().read(); |
| 435 | if msr.slak().bit_is_clear() && msr.inak().bit_is_set() { | 443 | if !msr.slak() && msr.inak() { |
| 436 | break; | 444 | break; |
| 437 | } | 445 | } |
| 438 | } | 446 | } |
| @@ -440,18 +448,16 @@ where | |||
| 440 | can_builder | 448 | can_builder |
| 441 | } | 449 | } |
| 442 | 450 | ||
| 443 | fn registers(&self) -> &RegisterBlock { | 451 | fn set_bit_timing(&mut self, bt: crate::can::util::NominalBitTiming) { |
| 444 | unsafe { &*I::REGISTERS } | 452 | let prescaler = u16::from(bt.prescaler) & 0x1FF; |
| 445 | } | 453 | let seg1 = u8::from(bt.seg1); |
| 446 | 454 | let seg2 = u8::from(bt.seg2) & 0x7F; | |
| 447 | fn set_bit_timing(&mut self, btr: u32) { | 455 | let sync_jump_width = u8::from(bt.sync_jump_width) & 0x7F; |
| 448 | // Mask of all non-reserved BTR bits, except the mode flags. | 456 | self.canregs.btr().modify(|reg| { |
| 449 | const MASK: u32 = 0x037F_03FF; | 457 | reg.set_brp(prescaler - 1); |
| 450 | 458 | reg.set_ts(0, seg1 - 1); | |
| 451 | let can = self.registers(); | 459 | reg.set_ts(1, seg2 - 1); |
| 452 | can.btr.modify(|r, w| unsafe { | 460 | reg.set_sjw(sync_jump_width - 1); |
| 453 | let mode_bits = r.bits() & 0xC000_0000; | ||
| 454 | w.bits(mode_bits | (btr & MASK)) | ||
| 455 | }); | 461 | }); |
| 456 | } | 462 | } |
| 457 | 463 | ||
| @@ -467,7 +473,7 @@ where | |||
| 467 | /// The peripheral is disabled by setting `RESET` in `CAN_MCR`, which causes the peripheral to | 473 | /// The peripheral is disabled by setting `RESET` in `CAN_MCR`, which causes the peripheral to |
| 468 | /// enter sleep mode. | 474 | /// enter sleep mode. |
| 469 | pub fn free(self) -> I { | 475 | pub fn free(self) -> I { |
| 470 | self.registers().mcr.write(|w| w.reset().set_bit()); | 476 | self.canregs.mcr().write(|reg| reg.set_reset(true)); |
| 471 | self.instance | 477 | self.instance |
| 472 | } | 478 | } |
| 473 | 479 | ||
| @@ -475,13 +481,13 @@ where | |||
| 475 | /// | 481 | /// |
| 476 | /// Calling this method will enter initialization mode. | 482 | /// Calling this method will enter initialization mode. |
| 477 | pub fn modify_config(&mut self) -> CanConfig<'_, I> { | 483 | pub fn modify_config(&mut self) -> CanConfig<'_, I> { |
| 478 | let can = self.registers(); | 484 | self.canregs.mcr().modify(|reg| { |
| 479 | 485 | reg.set_sleep(false); | |
| 480 | // Enter init mode. | 486 | reg.set_inrq(true); |
| 481 | can.mcr.modify(|_, w| w.sleep().clear_bit().inrq().set_bit()); | 487 | }); |
| 482 | loop { | 488 | loop { |
| 483 | let msr = can.msr.read(); | 489 | let msr = self.canregs.msr().read(); |
| 484 | if msr.slak().bit_is_clear() && msr.inak().bit_is_set() { | 490 | if !msr.slak() && msr.inak() { |
| 485 | break; | 491 | break; |
| 486 | } | 492 | } |
| 487 | } | 493 | } |
| @@ -497,8 +503,7 @@ where | |||
| 497 | /// receive the frame. If enabled, [`Interrupt::Wakeup`] will also be triggered by the incoming | 503 | /// receive the frame. If enabled, [`Interrupt::Wakeup`] will also be triggered by the incoming |
| 498 | /// frame. | 504 | /// frame. |
| 499 | pub fn set_automatic_wakeup(&mut self, enabled: bool) { | 505 | pub fn set_automatic_wakeup(&mut self, enabled: bool) { |
| 500 | let can = self.registers(); | 506 | self.canregs.mcr().modify(|reg| reg.set_awum(enabled)); |
| 501 | can.mcr.modify(|_, w| w.awum().bit(enabled)); | ||
| 502 | } | 507 | } |
| 503 | 508 | ||
| 504 | /// Leaves initialization mode and enables the peripheral (non-blocking version). | 509 | /// Leaves initialization mode and enables the peripheral (non-blocking version). |
| @@ -510,10 +515,12 @@ where | |||
| 510 | /// in the background. The peripheral is enabled and ready to use when this method returns | 515 | /// in the background. The peripheral is enabled and ready to use when this method returns |
| 511 | /// successfully. | 516 | /// successfully. |
| 512 | pub fn enable_non_blocking(&mut self) -> nb::Result<(), Infallible> { | 517 | pub fn enable_non_blocking(&mut self) -> nb::Result<(), Infallible> { |
| 513 | let can = self.registers(); | 518 | let msr = self.canregs.msr().read(); |
| 514 | let msr = can.msr.read(); | 519 | if msr.slak() { |
| 515 | if msr.slak().bit_is_set() { | 520 | self.canregs.mcr().modify(|reg| { |
| 516 | can.mcr.modify(|_, w| w.abom().set_bit().sleep().clear_bit()); | 521 | reg.set_abom(true); |
| 522 | reg.set_sleep(false); | ||
| 523 | }); | ||
| 517 | Err(nb::Error::WouldBlock) | 524 | Err(nb::Error::WouldBlock) |
| 518 | } else { | 525 | } else { |
| 519 | Ok(()) | 526 | Ok(()) |
| @@ -524,11 +531,13 @@ where | |||
| 524 | /// | 531 | /// |
| 525 | /// While in sleep mode, an incoming CAN frame will trigger [`Interrupt::Wakeup`] if enabled. | 532 | /// While in sleep mode, an incoming CAN frame will trigger [`Interrupt::Wakeup`] if enabled. |
| 526 | pub fn sleep(&mut self) { | 533 | pub fn sleep(&mut self) { |
| 527 | let can = self.registers(); | 534 | self.canregs.mcr().modify(|reg| { |
| 528 | can.mcr.modify(|_, w| w.sleep().set_bit().inrq().clear_bit()); | 535 | reg.set_sleep(true); |
| 536 | reg.set_inrq(false); | ||
| 537 | }); | ||
| 529 | loop { | 538 | loop { |
| 530 | let msr = can.msr.read(); | 539 | let msr = self.canregs.msr().read(); |
| 531 | if msr.slak().bit_is_set() && msr.inak().bit_is_clear() { | 540 | if msr.slak() && !msr.inak() { |
| 532 | break; | 541 | break; |
| 533 | } | 542 | } |
| 534 | } | 543 | } |
| @@ -539,11 +548,13 @@ where | |||
| 539 | /// Note that this will not trigger [`Interrupt::Wakeup`], only reception of an incoming CAN | 548 | /// Note that this will not trigger [`Interrupt::Wakeup`], only reception of an incoming CAN |
| 540 | /// frame will cause that interrupt. | 549 | /// frame will cause that interrupt. |
| 541 | pub fn wakeup(&mut self) { | 550 | pub fn wakeup(&mut self) { |
| 542 | let can = self.registers(); | 551 | self.canregs.mcr().modify(|reg| { |
| 543 | can.mcr.modify(|_, w| w.sleep().clear_bit().inrq().clear_bit()); | 552 | reg.set_sleep(false); |
| 553 | reg.set_inrq(false); | ||
| 554 | }); | ||
| 544 | loop { | 555 | loop { |
| 545 | let msr = can.msr.read(); | 556 | let msr = self.canregs.msr().read(); |
| 546 | if msr.slak().bit_is_clear() && msr.inak().bit_is_clear() { | 557 | if !msr.slak() && !msr.inak() { |
| 547 | break; | 558 | break; |
| 548 | } | 559 | } |
| 549 | } | 560 | } |
| @@ -560,13 +571,13 @@ where | |||
| 560 | /// [`TransmitStatus::dequeued_frame`]. | 571 | /// [`TransmitStatus::dequeued_frame`]. |
| 561 | pub fn transmit(&mut self, frame: &Frame) -> nb::Result<TransmitStatus, Infallible> { | 572 | pub fn transmit(&mut self, frame: &Frame) -> nb::Result<TransmitStatus, Infallible> { |
| 562 | // Safety: We have a `&mut self` and have unique access to the peripheral. | 573 | // Safety: We have a `&mut self` and have unique access to the peripheral. |
| 563 | unsafe { Tx::<I>::conjure().transmit(frame) } | 574 | unsafe { Tx::<I>::conjure(self.canregs).transmit(frame) } |
| 564 | } | 575 | } |
| 565 | 576 | ||
| 566 | /// Returns `true` if no frame is pending for transmission. | 577 | /// Returns `true` if no frame is pending for transmission. |
| 567 | pub fn is_transmitter_idle(&self) -> bool { | 578 | pub fn is_transmitter_idle(&self) -> bool { |
| 568 | // Safety: Read-only operation. | 579 | // Safety: Read-only operation. |
| 569 | unsafe { Tx::<I>::conjure().is_idle() } | 580 | unsafe { Tx::<I>::conjure(self.canregs).is_idle() } |
| 570 | } | 581 | } |
| 571 | 582 | ||
| 572 | /// Attempts to abort the sending of a frame that is pending in a mailbox. | 583 | /// Attempts to abort the sending of a frame that is pending in a mailbox. |
| @@ -578,7 +589,7 @@ where | |||
| 578 | /// returns `true`. | 589 | /// returns `true`. |
| 579 | pub fn abort(&mut self, mailbox: Mailbox) -> bool { | 590 | pub fn abort(&mut self, mailbox: Mailbox) -> bool { |
| 580 | // Safety: We have a `&mut self` and have unique access to the peripheral. | 591 | // Safety: We have a `&mut self` and have unique access to the peripheral. |
| 581 | unsafe { Tx::<I>::conjure().abort(mailbox) } | 592 | unsafe { Tx::<I>::conjure(self.canregs).abort(mailbox) } |
| 582 | } | 593 | } |
| 583 | 594 | ||
| 584 | /// Returns a received frame if available. | 595 | /// Returns a received frame if available. |
| @@ -589,8 +600,8 @@ where | |||
| 589 | /// Returns `Err` when a frame was lost due to buffer overrun. | 600 | /// Returns `Err` when a frame was lost due to buffer overrun. |
| 590 | pub fn receive(&mut self) -> nb::Result<Frame, OverrunError> { | 601 | pub fn receive(&mut self) -> nb::Result<Frame, OverrunError> { |
| 591 | // Safety: We have a `&mut self` and have unique access to the peripheral. | 602 | // Safety: We have a `&mut self` and have unique access to the peripheral. |
| 592 | let mut rx0 = unsafe { Rx0::<I>::conjure() }; | 603 | let mut rx0 = unsafe { Rx0::<I>::conjure(self.canregs) }; |
| 593 | let mut rx1 = unsafe { Rx1::<I>::conjure() }; | 604 | let mut rx1 = unsafe { Rx1::<I>::conjure(self.canregs) }; |
| 594 | 605 | ||
| 595 | match rx0.receive() { | 606 | match rx0.receive() { |
| 596 | Err(nb::Error::WouldBlock) => rx1.receive(), | 607 | Err(nb::Error::WouldBlock) => rx1.receive(), |
| @@ -599,30 +610,35 @@ where | |||
| 599 | } | 610 | } |
| 600 | 611 | ||
| 601 | /// Returns a reference to the RX FIFO 0. | 612 | /// Returns a reference to the RX FIFO 0. |
| 602 | pub fn rx0(&mut self) -> &mut Rx0<I> { | 613 | pub fn rx0(&mut self) -> Rx0<I> { |
| 603 | // Safety: We take `&mut self` and the return value lifetimes are tied to `self`'s lifetime. | 614 | // Safety: We take `&mut self` and the return value lifetimes are tied to `self`'s lifetime. |
| 604 | unsafe { Rx0::conjure_by_ref() } | 615 | unsafe { Rx0::conjure(self.canregs) } |
| 605 | } | 616 | } |
| 606 | 617 | ||
| 607 | /// Returns a reference to the RX FIFO 1. | 618 | /// Returns a reference to the RX FIFO 1. |
| 608 | pub fn rx1(&mut self) -> &mut Rx1<I> { | 619 | pub fn rx1(&mut self) -> Rx1<I> { |
| 609 | // Safety: We take `&mut self` and the return value lifetimes are tied to `self`'s lifetime. | 620 | // Safety: We take `&mut self` and the return value lifetimes are tied to `self`'s lifetime. |
| 610 | unsafe { Rx1::conjure_by_ref() } | 621 | unsafe { Rx1::conjure(self.canregs) } |
| 611 | } | 622 | } |
| 612 | 623 | ||
| 613 | /// Splits this `Can` instance into transmitting and receiving halves, by reference. | 624 | pub fn split_by_ref(&mut self) -> (Tx<I>, Rx0<I>, Rx1<I>) { |
| 614 | pub fn split_by_ref(&mut self) -> (&mut Tx<I>, &mut Rx0<I>, &mut Rx1<I>) { | ||
| 615 | // Safety: We take `&mut self` and the return value lifetimes are tied to `self`'s lifetime. | 625 | // Safety: We take `&mut self` and the return value lifetimes are tied to `self`'s lifetime. |
| 616 | let tx = unsafe { Tx::conjure_by_ref() }; | 626 | let tx = unsafe { Tx::conjure(self.canregs) }; |
| 617 | let rx0 = unsafe { Rx0::conjure_by_ref() }; | 627 | let rx0 = unsafe { Rx0::conjure(self.canregs) }; |
| 618 | let rx1 = unsafe { Rx1::conjure_by_ref() }; | 628 | let rx1 = unsafe { Rx1::conjure(self.canregs) }; |
| 619 | (tx, rx0, rx1) | 629 | (tx, rx0, rx1) |
| 620 | } | 630 | } |
| 621 | 631 | ||
| 622 | /// Consumes this `Can` instance and splits it into transmitting and receiving halves. | 632 | /// Consumes this `Can` instance and splits it into transmitting and receiving halves. |
| 623 | pub fn split(self) -> (Tx<I>, Rx0<I>, Rx1<I>) { | 633 | pub fn split(self) -> (Tx<I>, Rx0<I>, Rx1<I>) { |
| 624 | // Safety: `Self` is not `Copy` and is destroyed by moving it into this method. | 634 | // Safety: `Self` is not `Copy` and is destroyed by moving it into this method. |
| 625 | unsafe { (Tx::conjure(), Rx0::conjure(), Rx1::conjure()) } | 635 | unsafe { |
| 636 | ( | ||
| 637 | Tx::conjure(self.canregs), | ||
| 638 | Rx0::conjure(self.canregs), | ||
| 639 | Rx1::conjure(self.canregs), | ||
| 640 | ) | ||
| 641 | } | ||
| 626 | } | 642 | } |
| 627 | } | 643 | } |
| 628 | 644 | ||
| @@ -632,46 +648,25 @@ impl<I: FilterOwner> Can<I> { | |||
| 632 | /// To modify filters of a slave peripheral, `modify_filters` has to be called on the master | 648 | /// To modify filters of a slave peripheral, `modify_filters` has to be called on the master |
| 633 | /// peripheral instead. | 649 | /// peripheral instead. |
| 634 | pub fn modify_filters(&mut self) -> MasterFilters<'_, I> { | 650 | pub fn modify_filters(&mut self) -> MasterFilters<'_, I> { |
| 635 | unsafe { MasterFilters::new() } | 651 | unsafe { MasterFilters::new(self.canregs) } |
| 636 | } | 652 | } |
| 637 | } | 653 | } |
| 638 | 654 | ||
| 639 | /// Interface to the CAN transmitter part. | 655 | /// Interface to the CAN transmitter part. |
| 640 | pub struct Tx<I> { | 656 | pub struct Tx<I> { |
| 641 | _can: PhantomData<I>, | 657 | _can: PhantomData<I>, |
| 642 | } | 658 | canregs: crate::pac::can::Can, |
| 643 | |||
| 644 | #[inline] | ||
| 645 | const fn ok_mask(idx: usize) -> u32 { | ||
| 646 | 0x02 << (8 * idx) | ||
| 647 | } | ||
| 648 | |||
| 649 | #[inline] | ||
| 650 | const fn abort_mask(idx: usize) -> u32 { | ||
| 651 | 0x80 << (8 * idx) | ||
| 652 | } | 659 | } |
| 653 | 660 | ||
| 654 | impl<I> Tx<I> | 661 | impl<I> Tx<I> |
| 655 | where | 662 | where |
| 656 | I: Instance, | 663 | I: Instance, |
| 657 | { | 664 | { |
| 658 | unsafe fn conjure() -> Self { | 665 | unsafe fn conjure(canregs: crate::pac::can::Can) -> Self { |
| 659 | Self { _can: PhantomData } | 666 | Self { |
| 660 | } | 667 | _can: PhantomData, |
| 661 | 668 | canregs, | |
| 662 | /// Creates a `&mut Self` out of thin air. | 669 | } |
| 663 | /// | ||
| 664 | /// This is only safe if it is the only way to access a `Tx<I>`. | ||
| 665 | unsafe fn conjure_by_ref<'a>() -> &'a mut Self { | ||
| 666 | // Cause out of bounds access when `Self` is not zero-sized. | ||
| 667 | [()][core::mem::size_of::<Self>()]; | ||
| 668 | |||
| 669 | // Any aligned pointer is valid for ZSTs. | ||
| 670 | &mut *NonNull::dangling().as_ptr() | ||
| 671 | } | ||
| 672 | |||
| 673 | fn registers(&self) -> &RegisterBlock { | ||
| 674 | unsafe { &*I::REGISTERS } | ||
| 675 | } | 670 | } |
| 676 | 671 | ||
| 677 | /// Puts a CAN frame in a transmit mailbox for transmission on the bus. | 672 | /// Puts a CAN frame in a transmit mailbox for transmission on the bus. |
| @@ -684,13 +679,11 @@ where | |||
| 684 | /// cancelled and `frame` is enqueued instead. The frame that was replaced is returned as | 679 | /// cancelled and `frame` is enqueued instead. The frame that was replaced is returned as |
| 685 | /// [`TransmitStatus::dequeued_frame`]. | 680 | /// [`TransmitStatus::dequeued_frame`]. |
| 686 | pub fn transmit(&mut self, frame: &Frame) -> nb::Result<TransmitStatus, Infallible> { | 681 | pub fn transmit(&mut self, frame: &Frame) -> nb::Result<TransmitStatus, Infallible> { |
| 687 | let can = self.registers(); | ||
| 688 | |||
| 689 | // Get the index of the next free mailbox or the one with the lowest priority. | 682 | // Get the index of the next free mailbox or the one with the lowest priority. |
| 690 | let tsr = can.tsr.read(); | 683 | let tsr = self.canregs.tsr().read(); |
| 691 | let idx = tsr.code().bits() as usize; | 684 | let idx = tsr.code() as usize; |
| 692 | 685 | ||
| 693 | let frame_is_pending = tsr.tme0().bit_is_clear() || tsr.tme1().bit_is_clear() || tsr.tme2().bit_is_clear(); | 686 | let frame_is_pending = !tsr.tme(0) || !tsr.tme(1) || !tsr.tme(2); |
| 694 | let pending_frame = if frame_is_pending { | 687 | let pending_frame = if frame_is_pending { |
| 695 | // High priority frames are transmitted first by the mailbox system. | 688 | // High priority frames are transmitted first by the mailbox system. |
| 696 | // Frames with identical identifier shall be transmitted in FIFO order. | 689 | // Frames with identical identifier shall be transmitted in FIFO order. |
| @@ -701,8 +694,7 @@ where | |||
| 701 | self.check_priority(1, frame.id)?; | 694 | self.check_priority(1, frame.id)?; |
| 702 | self.check_priority(2, frame.id)?; | 695 | self.check_priority(2, frame.id)?; |
| 703 | 696 | ||
| 704 | let all_frames_are_pending = | 697 | let all_frames_are_pending = !tsr.tme(0) && !tsr.tme(1) && !tsr.tme(2); |
| 705 | tsr.tme0().bit_is_clear() && tsr.tme1().bit_is_clear() && tsr.tme2().bit_is_clear(); | ||
| 706 | if all_frames_are_pending { | 698 | if all_frames_are_pending { |
| 707 | // No free mailbox is available. This can only happen when three frames with | 699 | // No free mailbox is available. This can only happen when three frames with |
| 708 | // ascending priority (descending IDs) were requested for transmission and all | 700 | // ascending priority (descending IDs) were requested for transmission and all |
| @@ -735,15 +727,14 @@ where | |||
| 735 | /// Returns `Ok` when the mailbox is free or if it contains pending frame with a | 727 | /// Returns `Ok` when the mailbox is free or if it contains pending frame with a |
| 736 | /// lower priority (higher ID) than the identifier `id`. | 728 | /// lower priority (higher ID) than the identifier `id`. |
| 737 | fn check_priority(&self, idx: usize, id: IdReg) -> nb::Result<(), Infallible> { | 729 | fn check_priority(&self, idx: usize, id: IdReg) -> nb::Result<(), Infallible> { |
| 738 | let can = self.registers(); | ||
| 739 | |||
| 740 | // Read the pending frame's id to check its priority. | 730 | // Read the pending frame's id to check its priority. |
| 741 | assert!(idx < 3); | 731 | assert!(idx < 3); |
| 742 | let tir = &can.tx[idx].tir.read(); | 732 | let tir = &self.canregs.tx(idx).tir().read(); |
| 733 | //let tir = &can.tx[idx].tir.read(); | ||
| 743 | 734 | ||
| 744 | // Check the priority by comparing the identifiers. But first make sure the | 735 | // Check the priority by comparing the identifiers. But first make sure the |
| 745 | // frame has not finished the transmission (`TXRQ` == 0) in the meantime. | 736 | // frame has not finished the transmission (`TXRQ` == 0) in the meantime. |
| 746 | if tir.txrq().bit_is_set() && id <= IdReg::from_register(tir.bits()) { | 737 | if tir.txrq() && id <= IdReg::from_register(tir.0) { |
| 747 | // There's a mailbox whose priority is higher or equal | 738 | // There's a mailbox whose priority is higher or equal |
| 748 | // the priority of the new frame. | 739 | // the priority of the new frame. |
| 749 | return Err(nb::Error::WouldBlock); | 740 | return Err(nb::Error::WouldBlock); |
| @@ -753,33 +744,34 @@ where | |||
| 753 | } | 744 | } |
| 754 | 745 | ||
| 755 | fn write_mailbox(&mut self, idx: usize, frame: &Frame) { | 746 | fn write_mailbox(&mut self, idx: usize, frame: &Frame) { |
| 756 | let can = self.registers(); | ||
| 757 | |||
| 758 | debug_assert!(idx < 3); | 747 | debug_assert!(idx < 3); |
| 759 | let mb = unsafe { &can.tx.get_unchecked(idx) }; | ||
| 760 | 748 | ||
| 761 | mb.tdtr.write(|w| unsafe { w.dlc().bits(frame.dlc() as u8) }); | 749 | let mb = self.canregs.tx(idx); |
| 762 | mb.tdlr | 750 | mb.tdtr().write(|w| w.set_dlc(frame.dlc() as u8)); |
| 763 | .write(|w| unsafe { w.bits(u32::from_ne_bytes(frame.data.bytes[0..4].try_into().unwrap())) }); | 751 | |
| 764 | mb.tdhr | 752 | mb.tdlr() |
| 765 | .write(|w| unsafe { w.bits(u32::from_ne_bytes(frame.data.bytes[4..8].try_into().unwrap())) }); | 753 | .write(|w| w.0 = u32::from_ne_bytes(frame.data.bytes[0..4].try_into().unwrap())); |
| 766 | mb.tir.write(|w| unsafe { w.bits(frame.id.0).txrq().set_bit() }); | 754 | mb.tdhr() |
| 755 | .write(|w| w.0 = u32::from_ne_bytes(frame.data.bytes[4..8].try_into().unwrap())); | ||
| 756 | mb.tir().write(|w| { | ||
| 757 | w.0 = frame.id.0; | ||
| 758 | w.set_txrq(true); | ||
| 759 | }); | ||
| 767 | } | 760 | } |
| 768 | 761 | ||
| 769 | fn read_pending_mailbox(&mut self, idx: usize) -> Option<Frame> { | 762 | fn read_pending_mailbox(&mut self, idx: usize) -> Option<Frame> { |
| 770 | if self.abort_by_index(idx) { | 763 | if self.abort_by_index(idx) { |
| 771 | let can = self.registers(); | ||
| 772 | debug_assert!(idx < 3); | 764 | debug_assert!(idx < 3); |
| 773 | let mb = unsafe { &can.tx.get_unchecked(idx) }; | ||
| 774 | 765 | ||
| 766 | let mb = self.canregs.tx(idx); | ||
| 775 | // Read back the pending frame. | 767 | // Read back the pending frame. |
| 776 | let mut pending_frame = Frame { | 768 | let mut pending_frame = Frame { |
| 777 | id: IdReg(mb.tir.read().bits()), | 769 | id: IdReg(mb.tir().read().0), |
| 778 | data: Data::empty(), | 770 | data: Data::empty(), |
| 779 | }; | 771 | }; |
| 780 | pending_frame.data.bytes[0..4].copy_from_slice(&mb.tdlr.read().bits().to_ne_bytes()); | 772 | pending_frame.data.bytes[0..4].copy_from_slice(&mb.tdlr().read().0.to_ne_bytes()); |
| 781 | pending_frame.data.bytes[4..8].copy_from_slice(&mb.tdhr.read().bits().to_ne_bytes()); | 773 | pending_frame.data.bytes[4..8].copy_from_slice(&mb.tdhr().read().0.to_ne_bytes()); |
| 782 | pending_frame.data.len = mb.tdtr.read().dlc().bits(); | 774 | pending_frame.data.len = mb.tdtr().read().dlc(); |
| 783 | 775 | ||
| 784 | Some(pending_frame) | 776 | Some(pending_frame) |
| 785 | } else { | 777 | } else { |
| @@ -793,15 +785,13 @@ where | |||
| 793 | 785 | ||
| 794 | /// Tries to abort a pending frame. Returns `true` when aborted. | 786 | /// Tries to abort a pending frame. Returns `true` when aborted. |
| 795 | fn abort_by_index(&mut self, idx: usize) -> bool { | 787 | fn abort_by_index(&mut self, idx: usize) -> bool { |
| 796 | let can = self.registers(); | 788 | self.canregs.tsr().write(|reg| reg.set_abrq(idx, true)); |
| 797 | |||
| 798 | can.tsr.write(|w| unsafe { w.bits(abort_mask(idx)) }); | ||
| 799 | 789 | ||
| 800 | // Wait for the abort request to be finished. | 790 | // Wait for the abort request to be finished. |
| 801 | loop { | 791 | loop { |
| 802 | let tsr = can.tsr.read().bits(); | 792 | let tsr = self.canregs.tsr().read(); |
| 803 | if tsr & abort_mask(idx) == 0 { | 793 | if false == tsr.abrq(idx) { |
| 804 | break tsr & ok_mask(idx) == 0; | 794 | break tsr.txok(idx) == false; |
| 805 | } | 795 | } |
| 806 | } | 796 | } |
| 807 | } | 797 | } |
| @@ -816,11 +806,11 @@ where | |||
| 816 | pub fn abort(&mut self, mailbox: Mailbox) -> bool { | 806 | pub fn abort(&mut self, mailbox: Mailbox) -> bool { |
| 817 | // If the mailbox is empty, the value of TXOKx depends on what happened with the previous | 807 | // If the mailbox is empty, the value of TXOKx depends on what happened with the previous |
| 818 | // frame in that mailbox. Only call abort_by_index() if the mailbox is not empty. | 808 | // frame in that mailbox. Only call abort_by_index() if the mailbox is not empty. |
| 819 | let tsr = self.registers().tsr.read(); | 809 | let tsr = self.canregs.tsr().read(); |
| 820 | let mailbox_empty = match mailbox { | 810 | let mailbox_empty = match mailbox { |
| 821 | Mailbox::Mailbox0 => tsr.tme0().bit_is_set(), | 811 | Mailbox::Mailbox0 => tsr.tme(0), |
| 822 | Mailbox::Mailbox1 => tsr.tme1().bit_is_set(), | 812 | Mailbox::Mailbox1 => tsr.tme(1), |
| 823 | Mailbox::Mailbox2 => tsr.tme2().bit_is_set(), | 813 | Mailbox::Mailbox2 => tsr.tme(2), |
| 824 | }; | 814 | }; |
| 825 | if mailbox_empty { | 815 | if mailbox_empty { |
| 826 | false | 816 | false |
| @@ -831,119 +821,101 @@ where | |||
| 831 | 821 | ||
| 832 | /// Returns `true` if no frame is pending for transmission. | 822 | /// Returns `true` if no frame is pending for transmission. |
| 833 | pub fn is_idle(&self) -> bool { | 823 | pub fn is_idle(&self) -> bool { |
| 834 | let can = self.registers(); | 824 | let tsr = self.canregs.tsr().read(); |
| 835 | let tsr = can.tsr.read(); | 825 | tsr.tme(0) && tsr.tme(1) && tsr.tme(2) |
| 836 | tsr.tme0().bit_is_set() && tsr.tme1().bit_is_set() && tsr.tme2().bit_is_set() | ||
| 837 | } | 826 | } |
| 838 | 827 | ||
| 839 | /// Clears the request complete flag for all mailboxes. | 828 | /// Clears the request complete flag for all mailboxes. |
| 840 | pub fn clear_interrupt_flags(&mut self) { | 829 | pub fn clear_interrupt_flags(&mut self) { |
| 841 | let can = self.registers(); | 830 | self.canregs.tsr().write(|reg| { |
| 842 | can.tsr | 831 | reg.set_rqcp(0, true); |
| 843 | .write(|w| w.rqcp2().set_bit().rqcp1().set_bit().rqcp0().set_bit()); | 832 | reg.set_rqcp(1, true); |
| 833 | reg.set_rqcp(2, true); | ||
| 834 | }); | ||
| 844 | } | 835 | } |
| 845 | } | 836 | } |
| 846 | 837 | ||
| 847 | /// Interface to receiver FIFO 0. | 838 | /// Interface to receiver FIFO 0. |
| 848 | pub struct Rx0<I> { | 839 | pub struct Rx0<I> { |
| 849 | _can: PhantomData<I>, | 840 | _can: PhantomData<I>, |
| 841 | canregs: crate::pac::can::Can, | ||
| 850 | } | 842 | } |
| 851 | 843 | ||
| 852 | impl<I> Rx0<I> | 844 | impl<I> Rx0<I> |
| 853 | where | 845 | where |
| 854 | I: Instance, | 846 | I: Instance, |
| 855 | { | 847 | { |
| 856 | unsafe fn conjure() -> Self { | 848 | unsafe fn conjure(canregs: crate::pac::can::Can) -> Self { |
| 857 | Self { _can: PhantomData } | 849 | Self { |
| 858 | } | 850 | _can: PhantomData, |
| 859 | 851 | canregs, | |
| 860 | /// Creates a `&mut Self` out of thin air. | 852 | } |
| 861 | /// | ||
| 862 | /// This is only safe if it is the only way to access an `Rx<I>`. | ||
| 863 | unsafe fn conjure_by_ref<'a>() -> &'a mut Self { | ||
| 864 | // Cause out of bounds access when `Self` is not zero-sized. | ||
| 865 | [()][core::mem::size_of::<Self>()]; | ||
| 866 | |||
| 867 | // Any aligned pointer is valid for ZSTs. | ||
| 868 | &mut *NonNull::dangling().as_ptr() | ||
| 869 | } | 853 | } |
| 870 | 854 | ||
| 871 | /// Returns a received frame if available. | 855 | /// Returns a received frame if available. |
| 872 | /// | 856 | /// |
| 873 | /// Returns `Err` when a frame was lost due to buffer overrun. | 857 | /// Returns `Err` when a frame was lost due to buffer overrun. |
| 874 | pub fn receive(&mut self) -> nb::Result<Frame, OverrunError> { | 858 | pub fn receive(&mut self) -> nb::Result<Frame, OverrunError> { |
| 875 | receive_fifo(self.registers(), 0) | 859 | receive_fifo(self.canregs, 0) |
| 876 | } | ||
| 877 | |||
| 878 | fn registers(&self) -> &RegisterBlock { | ||
| 879 | unsafe { &*I::REGISTERS } | ||
| 880 | } | 860 | } |
| 881 | } | 861 | } |
| 882 | 862 | ||
| 883 | /// Interface to receiver FIFO 1. | 863 | /// Interface to receiver FIFO 1. |
| 884 | pub struct Rx1<I> { | 864 | pub struct Rx1<I> { |
| 885 | _can: PhantomData<I>, | 865 | _can: PhantomData<I>, |
| 866 | canregs: crate::pac::can::Can, | ||
| 886 | } | 867 | } |
| 887 | 868 | ||
| 888 | impl<I> Rx1<I> | 869 | impl<I> Rx1<I> |
| 889 | where | 870 | where |
| 890 | I: Instance, | 871 | I: Instance, |
| 891 | { | 872 | { |
| 892 | unsafe fn conjure() -> Self { | 873 | unsafe fn conjure(canregs: crate::pac::can::Can) -> Self { |
| 893 | Self { _can: PhantomData } | 874 | Self { |
| 894 | } | 875 | _can: PhantomData, |
| 895 | 876 | canregs, | |
| 896 | /// Creates a `&mut Self` out of thin air. | 877 | } |
| 897 | /// | ||
| 898 | /// This is only safe if it is the only way to access an `Rx<I>`. | ||
| 899 | unsafe fn conjure_by_ref<'a>() -> &'a mut Self { | ||
| 900 | // Cause out of bounds access when `Self` is not zero-sized. | ||
| 901 | [()][core::mem::size_of::<Self>()]; | ||
| 902 | |||
| 903 | // Any aligned pointer is valid for ZSTs. | ||
| 904 | &mut *NonNull::dangling().as_ptr() | ||
| 905 | } | 878 | } |
| 906 | 879 | ||
| 907 | /// Returns a received frame if available. | 880 | /// Returns a received frame if available. |
| 908 | /// | 881 | /// |
| 909 | /// Returns `Err` when a frame was lost due to buffer overrun. | 882 | /// Returns `Err` when a frame was lost due to buffer overrun. |
| 910 | pub fn receive(&mut self) -> nb::Result<Frame, OverrunError> { | 883 | pub fn receive(&mut self) -> nb::Result<Frame, OverrunError> { |
| 911 | receive_fifo(self.registers(), 1) | 884 | receive_fifo(self.canregs, 1) |
| 912 | } | ||
| 913 | |||
| 914 | fn registers(&self) -> &RegisterBlock { | ||
| 915 | unsafe { &*I::REGISTERS } | ||
| 916 | } | 885 | } |
| 917 | } | 886 | } |
| 918 | 887 | ||
| 919 | fn receive_fifo(can: &RegisterBlock, fifo_nr: usize) -> nb::Result<Frame, OverrunError> { | 888 | fn receive_fifo(canregs: crate::pac::can::Can, fifo_nr: usize) -> nb::Result<Frame, OverrunError> { |
| 920 | assert!(fifo_nr < 2); | 889 | assert!(fifo_nr < 2); |
| 921 | let rfr = &can.rfr[fifo_nr]; | 890 | let rfr = canregs.rfr(fifo_nr); |
| 922 | let rx = &can.rx[fifo_nr]; | 891 | let rx = canregs.rx(fifo_nr); |
| 892 | |||
| 893 | //let rfr = &can.rfr[fifo_nr]; | ||
| 894 | //let rx = &can.rx[fifo_nr]; | ||
| 923 | 895 | ||
| 924 | // Check if a frame is available in the mailbox. | 896 | // Check if a frame is available in the mailbox. |
| 925 | let rfr_read = rfr.read(); | 897 | let rfr_read = rfr.read(); |
| 926 | if rfr_read.fmp().bits() == 0 { | 898 | if rfr_read.fmp() == 0 { |
| 927 | return Err(nb::Error::WouldBlock); | 899 | return Err(nb::Error::WouldBlock); |
| 928 | } | 900 | } |
| 929 | 901 | ||
| 930 | // Check for RX FIFO overrun. | 902 | // Check for RX FIFO overrun. |
| 931 | if rfr_read.fovr().bit_is_set() { | 903 | if rfr_read.fovr() { |
| 932 | rfr.write(|w| w.fovr().set_bit()); | 904 | rfr.write(|w| w.set_fovr(true)); |
| 933 | return Err(nb::Error::Other(OverrunError { _priv: () })); | 905 | return Err(nb::Error::Other(OverrunError { _priv: () })); |
| 934 | } | 906 | } |
| 935 | 907 | ||
| 936 | // Read the frame. | 908 | // Read the frame. |
| 937 | let mut frame = Frame { | 909 | let mut frame = Frame { |
| 938 | id: IdReg(rx.rir.read().bits()), | 910 | id: IdReg(rx.rir().read().0), |
| 939 | data: [0; 8].into(), | 911 | data: [0; 8].into(), |
| 940 | }; | 912 | }; |
| 941 | frame.data[0..4].copy_from_slice(&rx.rdlr.read().bits().to_ne_bytes()); | 913 | frame.data[0..4].copy_from_slice(&rx.rdlr().read().0.to_ne_bytes()); |
| 942 | frame.data[4..8].copy_from_slice(&rx.rdhr.read().bits().to_ne_bytes()); | 914 | frame.data[4..8].copy_from_slice(&rx.rdhr().read().0.to_ne_bytes()); |
| 943 | frame.data.len = rx.rdtr.read().dlc().bits(); | 915 | frame.data.len = rx.rdtr().read().dlc(); |
| 944 | 916 | ||
| 945 | // Release the mailbox. | 917 | // Release the mailbox. |
| 946 | rfr.write(|w| w.rfom().set_bit()); | 918 | rfr.write(|w| w.set_rfom(true)); |
| 947 | 919 | ||
| 948 | Ok(frame) | 920 | Ok(frame) |
| 949 | } | 921 | } |
diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs index cd394c951..3a3411aaa 100644 --- a/embassy-stm32/src/can/bxcan.rs +++ b/embassy-stm32/src/can/bxcan.rs | |||
| @@ -167,21 +167,14 @@ impl<'d, T: Instance> Can<'d, T> { | |||
| 167 | rx.set_as_af(rx.af_num(), AFType::Input); | 167 | rx.set_as_af(rx.af_num(), AFType::Input); |
| 168 | tx.set_as_af(tx.af_num(), AFType::OutputPushPull); | 168 | tx.set_as_af(tx.af_num(), AFType::OutputPushPull); |
| 169 | 169 | ||
| 170 | let can = crate::can::bx::Can::builder(BxcanInstance(peri)).leave_disabled(); | 170 | let can = crate::can::bx::Can::builder(BxcanInstance(peri), T::regs()).leave_disabled(); |
| 171 | Self { can } | 171 | Self { can } |
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | /// Set CAN bit rate. | 174 | /// Set CAN bit rate. |
| 175 | pub fn set_bitrate(&mut self, bitrate: u32) { | 175 | pub fn set_bitrate(&mut self, bitrate: u32) { |
| 176 | let bit_timing = util::calc_can_timings(T::frequency(), bitrate).unwrap(); | 176 | let bit_timing = util::calc_can_timings(T::frequency(), bitrate).unwrap(); |
| 177 | let sjw = u8::from(bit_timing.sync_jump_width) as u32; | 177 | self.can.modify_config().set_bit_timing(bit_timing).leave_disabled(); |
| 178 | let seg1 = u8::from(bit_timing.seg1) as u32; | ||
| 179 | let seg2 = u8::from(bit_timing.seg2) as u32; | ||
| 180 | let prescaler = u16::from(bit_timing.prescaler) as u32; | ||
| 181 | self.can | ||
| 182 | .modify_config() | ||
| 183 | .set_bit_timing((sjw - 1) << 24 | (seg1 - 1) << 16 | (seg2 - 1) << 20 | (prescaler - 1)) | ||
| 184 | .leave_disabled(); | ||
| 185 | } | 178 | } |
| 186 | 179 | ||
| 187 | /// Enables the peripheral and synchronizes with the bus. | 180 | /// Enables the peripheral and synchronizes with the bus. |
| @@ -299,7 +292,7 @@ impl<'d, T: Instance> Can<'d, T> { | |||
| 299 | /// Split the CAN driver into transmit and receive halves. | 292 | /// Split the CAN driver into transmit and receive halves. |
| 300 | /// | 293 | /// |
| 301 | /// Useful for doing separate transmit/receive tasks. | 294 | /// Useful for doing separate transmit/receive tasks. |
| 302 | pub fn split<'c>(&'c mut self) -> (CanTx<'c, 'd, T>, CanRx<'c, 'd, T>) { | 295 | pub fn split<'c>(&'c mut self) -> (CanTx<'d, T>, CanRx<'d, T>) { |
| 303 | let (tx, rx0, rx1) = self.can.split_by_ref(); | 296 | let (tx, rx0, rx1) = self.can.split_by_ref(); |
| 304 | (CanTx { tx }, CanRx { rx0, rx1 }) | 297 | (CanTx { tx }, CanRx { rx0, rx1 }) |
| 305 | } | 298 | } |
| @@ -313,11 +306,11 @@ impl<'d, T: Instance> AsMut<crate::can::bx::Can<BxcanInstance<'d, T>>> for Can<' | |||
| 313 | } | 306 | } |
| 314 | 307 | ||
| 315 | /// CAN driver, transmit half. | 308 | /// CAN driver, transmit half. |
| 316 | pub struct CanTx<'c, 'd, T: Instance> { | 309 | pub struct CanTx<'d, T: Instance> { |
| 317 | tx: &'c mut crate::can::bx::Tx<BxcanInstance<'d, T>>, | 310 | tx: crate::can::bx::Tx<BxcanInstance<'d, T>>, |
| 318 | } | 311 | } |
| 319 | 312 | ||
| 320 | impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { | 313 | impl<'d, T: Instance> CanTx<'d, T> { |
| 321 | /// Queues the message to be sent. | 314 | /// Queues the message to be sent. |
| 322 | /// | 315 | /// |
| 323 | /// If the TX queue is full, this will wait until there is space, therefore exerting backpressure. | 316 | /// If the TX queue is full, this will wait until there is space, therefore exerting backpressure. |
| @@ -404,12 +397,12 @@ impl<'c, 'd, T: Instance> CanTx<'c, 'd, T> { | |||
| 404 | 397 | ||
| 405 | /// CAN driver, receive half. | 398 | /// CAN driver, receive half. |
| 406 | #[allow(dead_code)] | 399 | #[allow(dead_code)] |
| 407 | pub struct CanRx<'c, 'd, T: Instance> { | 400 | pub struct CanRx<'d, T: Instance> { |
| 408 | rx0: &'c mut crate::can::bx::Rx0<BxcanInstance<'d, T>>, | 401 | rx0: crate::can::bx::Rx0<BxcanInstance<'d, T>>, |
| 409 | rx1: &'c mut crate::can::bx::Rx1<BxcanInstance<'d, T>>, | 402 | rx1: crate::can::bx::Rx1<BxcanInstance<'d, T>>, |
| 410 | } | 403 | } |
| 411 | 404 | ||
| 412 | impl<'c, 'd, T: Instance> CanRx<'c, 'd, T> { | 405 | impl<'d, T: Instance> CanRx<'d, T> { |
| 413 | /// Read a CAN frame. | 406 | /// Read a CAN frame. |
| 414 | /// | 407 | /// |
| 415 | /// If no CAN frame is in the RX buffer, this will wait until there is one. | 408 | /// If no CAN frame is in the RX buffer, this will wait until there is one. |
