diff options
| author | Torin Cooper-Bennun <[email protected]> | 2024-04-18 09:59:39 +0100 |
|---|---|---|
| committer | Torin Cooper-Bennun <[email protected]> | 2024-04-22 13:14:32 +0100 |
| commit | 7f55a28a50bf5ac8acbeac4e47ad4e2fc73895f4 (patch) | |
| tree | ccc389950a9b0745fc96f90fdf8da23e438b88b1 /embassy-stm32/src | |
| parent | a9878a243d6a913c1fb7244e91b048011f272fc7 (diff) | |
stm32: can: fd: Properties for common runtime get/set operations
Diffstat (limited to 'embassy-stm32/src')
| -rw-r--r-- | embassy-stm32/src/can/fdcan.rs | 132 |
1 files changed, 105 insertions, 27 deletions
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs index 563f542d4..cec94e78a 100644 --- a/embassy-stm32/src/can/fdcan.rs +++ b/embassy-stm32/src/can/fdcan.rs | |||
| @@ -146,6 +146,7 @@ pub struct CanConfigurator<'d, T: Instance> { | |||
| 146 | config: crate::can::fd::config::FdCanConfig, | 146 | config: crate::can::fd::config::FdCanConfig, |
| 147 | /// Reference to internals. | 147 | /// Reference to internals. |
| 148 | instance: FdcanInstance<'d, T>, | 148 | instance: FdcanInstance<'d, T>, |
| 149 | properties: Properties<T>, | ||
| 149 | } | 150 | } |
| 150 | 151 | ||
| 151 | fn calc_ns_per_timer_tick<T: Instance>(mode: crate::can::fd::config::FrameTransmissionConfig) -> u64 { | 152 | fn calc_ns_per_timer_tick<T: Instance>(mode: crate::can::fd::config::FrameTransmissionConfig) -> u64 { |
| @@ -199,9 +200,20 @@ impl<'d, T: Instance> CanConfigurator<'d, T> { | |||
| 199 | Self { | 200 | Self { |
| 200 | config, | 201 | config, |
| 201 | instance: FdcanInstance(peri), | 202 | instance: FdcanInstance(peri), |
| 203 | properties: Properties::new(), | ||
| 202 | } | 204 | } |
| 203 | } | 205 | } |
| 204 | 206 | ||
| 207 | /// Get driver properties | ||
| 208 | pub fn properties(&self) -> &Properties<T> { | ||
| 209 | &self.properties | ||
| 210 | } | ||
| 211 | |||
| 212 | /// Get mutable driver properties | ||
| 213 | pub fn properties_mut(&mut self) -> &mut Properties<T> { | ||
| 214 | &mut self.properties | ||
| 215 | } | ||
| 216 | |||
| 205 | /// Get configuration | 217 | /// Get configuration |
| 206 | pub fn config(&self) -> crate::can::fd::config::FdCanConfig { | 218 | pub fn config(&self) -> crate::can::fd::config::FdCanConfig { |
| 207 | return self.config; | 219 | return self.config; |
| @@ -240,32 +252,6 @@ impl<'d, T: Instance> CanConfigurator<'d, T> { | |||
| 240 | self.config = self.config.set_data_bit_timing(nbtr); | 252 | self.config = self.config.set_data_bit_timing(nbtr); |
| 241 | } | 253 | } |
| 242 | 254 | ||
| 243 | /// Set an Standard Address CAN filter into slot 'id' | ||
| 244 | #[inline] | ||
| 245 | pub fn set_standard_filter(&mut self, slot: StandardFilterSlot, filter: StandardFilter) { | ||
| 246 | T::registers().msg_ram_mut().filters.flssa[slot as usize].activate(filter); | ||
| 247 | } | ||
| 248 | |||
| 249 | /// Set an array of Standard Address CAN filters and overwrite the current set | ||
| 250 | pub fn set_standard_filters(&mut self, filters: &[StandardFilter; STANDARD_FILTER_MAX as usize]) { | ||
| 251 | for (i, f) in filters.iter().enumerate() { | ||
| 252 | T::registers().msg_ram_mut().filters.flssa[i].activate(*f); | ||
| 253 | } | ||
| 254 | } | ||
| 255 | |||
| 256 | /// Set an Extended Address CAN filter into slot 'id' | ||
| 257 | #[inline] | ||
| 258 | pub fn set_extended_filter(&mut self, slot: ExtendedFilterSlot, filter: ExtendedFilter) { | ||
| 259 | T::registers().msg_ram_mut().filters.flesa[slot as usize].activate(filter); | ||
| 260 | } | ||
| 261 | |||
| 262 | /// Set an array of Extended Address CAN filters and overwrite the current set | ||
| 263 | pub fn set_extended_filters(&mut self, filters: &[ExtendedFilter; EXTENDED_FILTER_MAX as usize]) { | ||
| 264 | for (i, f) in filters.iter().enumerate() { | ||
| 265 | T::registers().msg_ram_mut().filters.flesa[i].activate(*f); | ||
| 266 | } | ||
| 267 | } | ||
| 268 | |||
| 269 | /// Start in mode. | 255 | /// Start in mode. |
| 270 | pub fn start(self, mode: OperatingMode) -> Can<'d, T> { | 256 | pub fn start(self, mode: OperatingMode) -> Can<'d, T> { |
| 271 | let ns_per_timer_tick = calc_ns_per_timer_tick::<T>(self.config.frame_transmit); | 257 | let ns_per_timer_tick = calc_ns_per_timer_tick::<T>(self.config.frame_transmit); |
| @@ -277,6 +263,7 @@ impl<'d, T: Instance> CanConfigurator<'d, T> { | |||
| 277 | config: self.config, | 263 | config: self.config, |
| 278 | instance: self.instance, | 264 | instance: self.instance, |
| 279 | _mode: mode, | 265 | _mode: mode, |
| 266 | properties: self.properties, | ||
| 280 | }; | 267 | }; |
| 281 | ret | 268 | ret |
| 282 | } | 269 | } |
| @@ -303,9 +290,20 @@ pub struct Can<'d, T: Instance> { | |||
| 303 | /// Reference to internals. | 290 | /// Reference to internals. |
| 304 | instance: FdcanInstance<'d, T>, | 291 | instance: FdcanInstance<'d, T>, |
| 305 | _mode: OperatingMode, | 292 | _mode: OperatingMode, |
| 293 | properties: Properties<T>, | ||
| 306 | } | 294 | } |
| 307 | 295 | ||
| 308 | impl<'d, T: Instance> Can<'d, T> { | 296 | impl<'d, T: Instance> Can<'d, T> { |
| 297 | /// Get properties | ||
| 298 | pub fn properties(&self) -> &Properties<T> { | ||
| 299 | &self.properties | ||
| 300 | } | ||
| 301 | |||
| 302 | /// Get mutable driver properties | ||
| 303 | pub fn properties_mut(&mut self) -> &mut Properties<T> { | ||
| 304 | &mut self.properties | ||
| 305 | } | ||
| 306 | |||
| 309 | /// Flush one of the TX mailboxes. | 307 | /// Flush one of the TX mailboxes. |
| 310 | pub async fn flush(&self, idx: usize) { | 308 | pub async fn flush(&self, idx: usize) { |
| 311 | poll_fn(|cx| { | 309 | poll_fn(|cx| { |
| @@ -351,7 +349,7 @@ impl<'d, T: Instance> Can<'d, T> { | |||
| 351 | } | 349 | } |
| 352 | 350 | ||
| 353 | /// Split instance into separate Tx(write) and Rx(read) portions | 351 | /// Split instance into separate Tx(write) and Rx(read) portions |
| 354 | pub fn split(self) -> (CanTx<'d, T>, CanRx<'d, T>) { | 352 | pub fn split(self) -> (CanTx<'d, T>, CanRx<'d, T>, Properties<T>) { |
| 355 | ( | 353 | ( |
| 356 | CanTx { | 354 | CanTx { |
| 357 | config: self.config, | 355 | config: self.config, |
| @@ -363,6 +361,7 @@ impl<'d, T: Instance> Can<'d, T> { | |||
| 363 | _instance2: T::regs(), | 361 | _instance2: T::regs(), |
| 364 | _mode: self._mode, | 362 | _mode: self._mode, |
| 365 | }, | 363 | }, |
| 364 | self.properties, | ||
| 366 | ) | 365 | ) |
| 367 | } | 366 | } |
| 368 | 367 | ||
| @@ -373,6 +372,7 @@ impl<'d, T: Instance> Can<'d, T> { | |||
| 373 | //_instance2: T::regs(), | 372 | //_instance2: T::regs(), |
| 374 | instance: tx._instance, | 373 | instance: tx._instance, |
| 375 | _mode: rx._mode, | 374 | _mode: rx._mode, |
| 375 | properties: Properties::new(), | ||
| 376 | } | 376 | } |
| 377 | } | 377 | } |
| 378 | 378 | ||
| @@ -408,6 +408,7 @@ pub struct BufferedCan<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_S | |||
| 408 | _mode: OperatingMode, | 408 | _mode: OperatingMode, |
| 409 | tx_buf: &'static TxBuf<TX_BUF_SIZE>, | 409 | tx_buf: &'static TxBuf<TX_BUF_SIZE>, |
| 410 | rx_buf: &'static RxBuf<RX_BUF_SIZE>, | 410 | rx_buf: &'static RxBuf<RX_BUF_SIZE>, |
| 411 | properties: Properties<T>, | ||
| 411 | } | 412 | } |
| 412 | 413 | ||
| 413 | impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> | 414 | impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> |
| @@ -426,10 +427,21 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> | |||
| 426 | _mode, | 427 | _mode, |
| 427 | tx_buf, | 428 | tx_buf, |
| 428 | rx_buf, | 429 | rx_buf, |
| 430 | properties: Properties::new(), | ||
| 429 | } | 431 | } |
| 430 | .setup() | 432 | .setup() |
| 431 | } | 433 | } |
| 432 | 434 | ||
| 435 | /// Get driver properties | ||
| 436 | pub fn properties(&self) -> &Properties<T> { | ||
| 437 | &self.properties | ||
| 438 | } | ||
| 439 | |||
| 440 | /// Get mutable driver properties | ||
| 441 | pub fn properties_mut(&mut self) -> &mut Properties<T> { | ||
| 442 | &mut self.properties | ||
| 443 | } | ||
| 444 | |||
| 433 | fn setup(self) -> Self { | 445 | fn setup(self) -> Self { |
| 434 | // We don't want interrupts being processed while we change modes. | 446 | // We don't want interrupts being processed while we change modes. |
| 435 | critical_section::with(|_| unsafe { | 447 | critical_section::with(|_| unsafe { |
| @@ -494,6 +506,7 @@ pub struct BufferedCanFd<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF | |||
| 494 | _mode: OperatingMode, | 506 | _mode: OperatingMode, |
| 495 | tx_buf: &'static TxFdBuf<TX_BUF_SIZE>, | 507 | tx_buf: &'static TxFdBuf<TX_BUF_SIZE>, |
| 496 | rx_buf: &'static RxFdBuf<RX_BUF_SIZE>, | 508 | rx_buf: &'static RxFdBuf<RX_BUF_SIZE>, |
| 509 | properties: Properties<T>, | ||
| 497 | } | 510 | } |
| 498 | 511 | ||
| 499 | /// Sender that can be used for sending CAN frames. | 512 | /// Sender that can be used for sending CAN frames. |
| @@ -542,10 +555,21 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> | |||
| 542 | _mode, | 555 | _mode, |
| 543 | tx_buf, | 556 | tx_buf, |
| 544 | rx_buf, | 557 | rx_buf, |
| 558 | properties: Properties::new(), | ||
| 545 | } | 559 | } |
| 546 | .setup() | 560 | .setup() |
| 547 | } | 561 | } |
| 548 | 562 | ||
| 563 | /// Get driver properties | ||
| 564 | pub fn properties(&self) -> &Properties<T> { | ||
| 565 | &self.properties | ||
| 566 | } | ||
| 567 | |||
| 568 | /// Get mutable driver properties | ||
| 569 | pub fn properties_mut(&mut self) -> &mut Properties<T> { | ||
| 570 | &mut self.properties | ||
| 571 | } | ||
| 572 | |||
| 549 | fn setup(self) -> Self { | 573 | fn setup(self) -> Self { |
| 550 | // We don't want interrupts being processed while we change modes. | 574 | // We don't want interrupts being processed while we change modes. |
| 551 | critical_section::with(|_| unsafe { | 575 | critical_section::with(|_| unsafe { |
| @@ -804,6 +828,60 @@ impl TxMode { | |||
| 804 | } | 828 | } |
| 805 | } | 829 | } |
| 806 | 830 | ||
| 831 | /// Common driver properties, including filters and error counters | ||
| 832 | pub struct Properties<T> { | ||
| 833 | instance: PhantomData<T>, | ||
| 834 | } | ||
| 835 | |||
| 836 | impl<T: Instance> Properties<T> { | ||
| 837 | fn new() -> Self { | ||
| 838 | Self { | ||
| 839 | instance: Default::default(), | ||
| 840 | } | ||
| 841 | } | ||
| 842 | |||
| 843 | /// Set an Standard Address CAN filter into slot 'id' | ||
| 844 | #[inline] | ||
| 845 | pub fn set_standard_filter(&mut self, slot: StandardFilterSlot, filter: StandardFilter) { | ||
| 846 | T::registers().msg_ram_mut().filters.flssa[slot as usize].activate(filter); | ||
| 847 | } | ||
| 848 | |||
| 849 | /// Set an array of Standard Address CAN filters and overwrite the current set | ||
| 850 | pub fn set_standard_filters(&mut self, filters: &[StandardFilter; STANDARD_FILTER_MAX as usize]) { | ||
| 851 | for (i, f) in filters.iter().enumerate() { | ||
| 852 | T::registers().msg_ram_mut().filters.flssa[i].activate(*f); | ||
| 853 | } | ||
| 854 | } | ||
| 855 | |||
| 856 | /// Set an Extended Address CAN filter into slot 'id' | ||
| 857 | #[inline] | ||
| 858 | pub fn set_extended_filter(&mut self, slot: ExtendedFilterSlot, filter: ExtendedFilter) { | ||
| 859 | T::registers().msg_ram_mut().filters.flesa[slot as usize].activate(filter); | ||
| 860 | } | ||
| 861 | |||
| 862 | /// Set an array of Extended Address CAN filters and overwrite the current set | ||
| 863 | pub fn set_extended_filters(&mut self, filters: &[ExtendedFilter; EXTENDED_FILTER_MAX as usize]) { | ||
| 864 | for (i, f) in filters.iter().enumerate() { | ||
| 865 | T::registers().msg_ram_mut().filters.flesa[i].activate(*f); | ||
| 866 | } | ||
| 867 | } | ||
| 868 | |||
| 869 | /// Get the CAN RX error counter | ||
| 870 | pub fn get_rx_error_count(&self) -> u8 { | ||
| 871 | T::registers().regs.ecr().read().rec() | ||
| 872 | } | ||
| 873 | |||
| 874 | /// Get the CAN TX error counter | ||
| 875 | pub fn get_tx_error_count(&self) -> u8 { | ||
| 876 | T::registers().regs.ecr().read().tec() | ||
| 877 | } | ||
| 878 | |||
| 879 | /// Get the current Bus-Off state | ||
| 880 | pub fn get_bus_off(&self) -> bool { | ||
| 881 | T::registers().regs.psr().read().bo() | ||
| 882 | } | ||
| 883 | } | ||
| 884 | |||
| 807 | struct State { | 885 | struct State { |
| 808 | pub rx_mode: RxMode, | 886 | pub rx_mode: RxMode, |
| 809 | pub tx_mode: TxMode, | 887 | pub tx_mode: TxMode, |
