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> { config: crate::can::fd::config::FdCanConfig, /// Reference to internals. instance: FdcanInstance<'d, T>, + properties: Properties, } fn calc_ns_per_timer_tick(mode: crate::can::fd::config::FrameTransmissionConfig) -> u64 { @@ -199,9 +200,20 @@ impl<'d, T: Instance> CanConfigurator<'d, T> { Self { config, instance: FdcanInstance(peri), + properties: Properties::new(), } } + /// Get driver properties + pub fn properties(&self) -> &Properties { + &self.properties + } + + /// Get mutable driver properties + pub fn properties_mut(&mut self) -> &mut Properties { + &mut self.properties + } + /// Get configuration pub fn config(&self) -> crate::can::fd::config::FdCanConfig { return self.config; @@ -240,32 +252,6 @@ impl<'d, T: Instance> CanConfigurator<'d, T> { self.config = self.config.set_data_bit_timing(nbtr); } - /// Set an Standard Address CAN filter into slot 'id' - #[inline] - pub fn set_standard_filter(&mut self, slot: StandardFilterSlot, filter: StandardFilter) { - T::registers().msg_ram_mut().filters.flssa[slot as usize].activate(filter); - } - - /// Set an array of Standard Address CAN filters and overwrite the current set - pub fn set_standard_filters(&mut self, filters: &[StandardFilter; STANDARD_FILTER_MAX as usize]) { - for (i, f) in filters.iter().enumerate() { - T::registers().msg_ram_mut().filters.flssa[i].activate(*f); - } - } - - /// Set an Extended Address CAN filter into slot 'id' - #[inline] - pub fn set_extended_filter(&mut self, slot: ExtendedFilterSlot, filter: ExtendedFilter) { - T::registers().msg_ram_mut().filters.flesa[slot as usize].activate(filter); - } - - /// Set an array of Extended Address CAN filters and overwrite the current set - pub fn set_extended_filters(&mut self, filters: &[ExtendedFilter; EXTENDED_FILTER_MAX as usize]) { - for (i, f) in filters.iter().enumerate() { - T::registers().msg_ram_mut().filters.flesa[i].activate(*f); - } - } - /// Start in mode. pub fn start(self, mode: OperatingMode) -> Can<'d, T> { let ns_per_timer_tick = calc_ns_per_timer_tick::(self.config.frame_transmit); @@ -277,6 +263,7 @@ impl<'d, T: Instance> CanConfigurator<'d, T> { config: self.config, instance: self.instance, _mode: mode, + properties: self.properties, }; ret } @@ -303,9 +290,20 @@ pub struct Can<'d, T: Instance> { /// Reference to internals. instance: FdcanInstance<'d, T>, _mode: OperatingMode, + properties: Properties, } impl<'d, T: Instance> Can<'d, T> { + /// Get properties + pub fn properties(&self) -> &Properties { + &self.properties + } + + /// Get mutable driver properties + pub fn properties_mut(&mut self) -> &mut Properties { + &mut self.properties + } + /// Flush one of the TX mailboxes. pub async fn flush(&self, idx: usize) { poll_fn(|cx| { @@ -351,7 +349,7 @@ impl<'d, T: Instance> Can<'d, T> { } /// Split instance into separate Tx(write) and Rx(read) portions - pub fn split(self) -> (CanTx<'d, T>, CanRx<'d, T>) { + pub fn split(self) -> (CanTx<'d, T>, CanRx<'d, T>, Properties) { ( CanTx { config: self.config, @@ -363,6 +361,7 @@ impl<'d, T: Instance> Can<'d, T> { _instance2: T::regs(), _mode: self._mode, }, + self.properties, ) } @@ -373,6 +372,7 @@ impl<'d, T: Instance> Can<'d, T> { //_instance2: T::regs(), instance: tx._instance, _mode: rx._mode, + properties: Properties::new(), } } @@ -408,6 +408,7 @@ pub struct BufferedCan<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_S _mode: OperatingMode, tx_buf: &'static TxBuf, rx_buf: &'static RxBuf, + properties: Properties, } 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> _mode, tx_buf, rx_buf, + properties: Properties::new(), } .setup() } + /// Get driver properties + pub fn properties(&self) -> &Properties { + &self.properties + } + + /// Get mutable driver properties + pub fn properties_mut(&mut self) -> &mut Properties { + &mut self.properties + } + fn setup(self) -> Self { // We don't want interrupts being processed while we change modes. critical_section::with(|_| unsafe { @@ -494,6 +506,7 @@ pub struct BufferedCanFd<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF _mode: OperatingMode, tx_buf: &'static TxFdBuf, rx_buf: &'static RxFdBuf, + properties: Properties, } /// 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> _mode, tx_buf, rx_buf, + properties: Properties::new(), } .setup() } + /// Get driver properties + pub fn properties(&self) -> &Properties { + &self.properties + } + + /// Get mutable driver properties + pub fn properties_mut(&mut self) -> &mut Properties { + &mut self.properties + } + fn setup(self) -> Self { // We don't want interrupts being processed while we change modes. critical_section::with(|_| unsafe { @@ -804,6 +828,60 @@ impl TxMode { } } +/// Common driver properties, including filters and error counters +pub struct Properties { + instance: PhantomData, +} + +impl Properties { + fn new() -> Self { + Self { + instance: Default::default(), + } + } + + /// Set an Standard Address CAN filter into slot 'id' + #[inline] + pub fn set_standard_filter(&mut self, slot: StandardFilterSlot, filter: StandardFilter) { + T::registers().msg_ram_mut().filters.flssa[slot as usize].activate(filter); + } + + /// Set an array of Standard Address CAN filters and overwrite the current set + pub fn set_standard_filters(&mut self, filters: &[StandardFilter; STANDARD_FILTER_MAX as usize]) { + for (i, f) in filters.iter().enumerate() { + T::registers().msg_ram_mut().filters.flssa[i].activate(*f); + } + } + + /// Set an Extended Address CAN filter into slot 'id' + #[inline] + pub fn set_extended_filter(&mut self, slot: ExtendedFilterSlot, filter: ExtendedFilter) { + T::registers().msg_ram_mut().filters.flesa[slot as usize].activate(filter); + } + + /// Set an array of Extended Address CAN filters and overwrite the current set + pub fn set_extended_filters(&mut self, filters: &[ExtendedFilter; EXTENDED_FILTER_MAX as usize]) { + for (i, f) in filters.iter().enumerate() { + T::registers().msg_ram_mut().filters.flesa[i].activate(*f); + } + } + + /// Get the CAN RX error counter + pub fn get_rx_error_count(&self) -> u8 { + T::registers().regs.ecr().read().rec() + } + + /// Get the CAN TX error counter + pub fn get_tx_error_count(&self) -> u8 { + T::registers().regs.ecr().read().tec() + } + + /// Get the current Bus-Off state + pub fn get_bus_off(&self) -> bool { + T::registers().regs.psr().read().bo() + } +} + struct State { pub rx_mode: RxMode, pub tx_mode: TxMode,