aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src
diff options
context:
space:
mode:
authorTorin Cooper-Bennun <[email protected]>2024-04-18 09:59:39 +0100
committerTorin Cooper-Bennun <[email protected]>2024-04-22 13:14:32 +0100
commit7f55a28a50bf5ac8acbeac4e47ad4e2fc73895f4 (patch)
treeccc389950a9b0745fc96f90fdf8da23e438b88b1 /embassy-stm32/src
parenta9878a243d6a913c1fb7244e91b048011f272fc7 (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.rs132
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
151fn calc_ns_per_timer_tick<T: Instance>(mode: crate::can::fd::config::FrameTransmissionConfig) -> u64 { 152fn 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
308impl<'d, T: Instance> Can<'d, T> { 296impl<'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
413impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> 414impl<'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
832pub struct Properties<T> {
833 instance: PhantomData<T>,
834}
835
836impl<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
807struct State { 885struct State {
808 pub rx_mode: RxMode, 886 pub rx_mode: RxMode,
809 pub tx_mode: TxMode, 887 pub tx_mode: TxMode,