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,
/// Reference to internals.
instance: FdcanInstance<'d, T>,
properties: Properties<T>,
}
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 {
config,
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
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::<T>(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<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.
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<T>) {
(
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<TX_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>
@ -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<T> {
&self.properties
}
/// Get mutable driver properties
pub fn properties_mut(&mut self) -> &mut Properties<T> {
&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<TX_BUF_SIZE>,
rx_buf: &'static RxFdBuf<RX_BUF_SIZE>,
properties: Properties<T>,
}
/// 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<T> {
&self.properties
}
/// Get mutable driver properties
pub fn properties_mut(&mut self) -> &mut Properties<T> {
&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<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 {
pub rx_mode: RxMode,
pub tx_mode: TxMode,