mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-22 06:42:32 +00:00
stm32: can: fd: Properties for common runtime get/set operations
This commit is contained in:
parent
a9878a243d
commit
7f55a28a50
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user