stm32: can: fd: Properties for common runtime get/set operations

This commit is contained in:
Torin Cooper-Bennun 2024-04-18 09:59:39 +01:00
parent a9878a243d
commit 7f55a28a50

View File

@ -146,6 +146,7 @@ pub struct CanConfigurator<'d, T: Instance> {
config: crate::can::fd::config::FdCanConfig, config: crate::can::fd::config::FdCanConfig,
/// Reference to internals. /// Reference to internals.
instance: FdcanInstance<'d, T>, instance: FdcanInstance<'d, T>,
properties: Properties<T>,
} }
fn calc_ns_per_timer_tick<T: Instance>(mode: crate::can::fd::config::FrameTransmissionConfig) -> u64 { 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> {
Self { Self {
config, config,
instance: FdcanInstance(peri), instance: FdcanInstance(peri),
properties: Properties::new(),
} }
} }
/// Get driver properties
pub fn properties(&self) -> &Properties<T> {
&self.properties
}
/// Get mutable driver properties
pub fn properties_mut(&mut self) -> &mut Properties<T> {
&mut self.properties
}
/// Get configuration /// Get configuration
pub fn config(&self) -> crate::can::fd::config::FdCanConfig { pub fn config(&self) -> crate::can::fd::config::FdCanConfig {
return self.config; return self.config;
@ -240,32 +252,6 @@ impl<'d, T: Instance> CanConfigurator<'d, T> {
self.config = self.config.set_data_bit_timing(nbtr); 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. /// Start in mode.
pub fn start(self, mode: OperatingMode) -> Can<'d, T> { pub fn start(self, mode: OperatingMode) -> Can<'d, T> {
let ns_per_timer_tick = calc_ns_per_timer_tick::<T>(self.config.frame_transmit); 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> {
config: self.config, config: self.config,
instance: self.instance, instance: self.instance,
_mode: mode, _mode: mode,
properties: self.properties,
}; };
ret ret
} }
@ -303,9 +290,20 @@ pub struct Can<'d, T: Instance> {
/// Reference to internals. /// Reference to internals.
instance: FdcanInstance<'d, T>, instance: FdcanInstance<'d, T>,
_mode: OperatingMode, _mode: OperatingMode,
properties: Properties<T>,
} }
impl<'d, T: Instance> Can<'d, T> { impl<'d, T: Instance> Can<'d, T> {
/// Get properties
pub fn properties(&self) -> &Properties<T> {
&self.properties
}
/// Get mutable driver properties
pub fn properties_mut(&mut self) -> &mut Properties<T> {
&mut self.properties
}
/// Flush one of the TX mailboxes. /// Flush one of the TX mailboxes.
pub async fn flush(&self, idx: usize) { pub async fn flush(&self, idx: usize) {
poll_fn(|cx| { poll_fn(|cx| {
@ -351,7 +349,7 @@ impl<'d, T: Instance> Can<'d, T> {
} }
/// Split instance into separate Tx(write) and Rx(read) portions /// 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<T>) {
( (
CanTx { CanTx {
config: self.config, config: self.config,
@ -363,6 +361,7 @@ impl<'d, T: Instance> Can<'d, T> {
_instance2: T::regs(), _instance2: T::regs(),
_mode: self._mode, _mode: self._mode,
}, },
self.properties,
) )
} }
@ -373,6 +372,7 @@ impl<'d, T: Instance> Can<'d, T> {
//_instance2: T::regs(), //_instance2: T::regs(),
instance: tx._instance, instance: tx._instance,
_mode: rx._mode, _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, _mode: OperatingMode,
tx_buf: &'static TxBuf<TX_BUF_SIZE>, tx_buf: &'static TxBuf<TX_BUF_SIZE>,
rx_buf: &'static RxBuf<RX_BUF_SIZE>, rx_buf: &'static RxBuf<RX_BUF_SIZE>,
properties: Properties<T>,
} }
impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> 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, _mode,
tx_buf, tx_buf,
rx_buf, rx_buf,
properties: Properties::new(),
} }
.setup() .setup()
} }
/// Get driver properties
pub fn properties(&self) -> &Properties<T> {
&self.properties
}
/// Get mutable driver properties
pub fn properties_mut(&mut self) -> &mut Properties<T> {
&mut self.properties
}
fn setup(self) -> Self { fn setup(self) -> Self {
// We don't want interrupts being processed while we change modes. // We don't want interrupts being processed while we change modes.
critical_section::with(|_| unsafe { critical_section::with(|_| unsafe {
@ -494,6 +506,7 @@ pub struct BufferedCanFd<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF
_mode: OperatingMode, _mode: OperatingMode,
tx_buf: &'static TxFdBuf<TX_BUF_SIZE>, tx_buf: &'static TxFdBuf<TX_BUF_SIZE>,
rx_buf: &'static RxFdBuf<RX_BUF_SIZE>, rx_buf: &'static RxFdBuf<RX_BUF_SIZE>,
properties: Properties<T>,
} }
/// Sender that can be used for sending CAN frames. /// 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, _mode,
tx_buf, tx_buf,
rx_buf, rx_buf,
properties: Properties::new(),
} }
.setup() .setup()
} }
/// Get driver properties
pub fn properties(&self) -> &Properties<T> {
&self.properties
}
/// Get mutable driver properties
pub fn properties_mut(&mut self) -> &mut Properties<T> {
&mut self.properties
}
fn setup(self) -> Self { fn setup(self) -> Self {
// We don't want interrupts being processed while we change modes. // We don't want interrupts being processed while we change modes.
critical_section::with(|_| unsafe { critical_section::with(|_| unsafe {
@ -804,6 +828,60 @@ impl TxMode {
} }
} }
/// Common driver properties, including filters and error counters
pub struct Properties<T> {
instance: PhantomData<T>,
}
impl<T: Instance> Properties<T> {
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 { struct State {
pub rx_mode: RxMode, pub rx_mode: RxMode,
pub tx_mode: TxMode, pub tx_mode: TxMode,