Merge pull request #2658 from MaxiluxSystems/fdcan-buffered-read-consistent
stm32: fdcan: merge read impls, add setter for TxBufferMode, rename Queue -> Priority
This commit is contained in:
commit
5e92973136
@ -292,14 +292,14 @@ impl Default for GlobalFilter {
|
|||||||
pub enum TxBufferMode {
|
pub enum TxBufferMode {
|
||||||
/// TX FIFO operation - In this mode CAN frames are trasmitted strictly in write order.
|
/// TX FIFO operation - In this mode CAN frames are trasmitted strictly in write order.
|
||||||
Fifo,
|
Fifo,
|
||||||
/// TX queue operation - In this mode CAN frames are transmitted according to CAN priority.
|
/// TX priority queue operation - In this mode CAN frames are transmitted according to CAN priority.
|
||||||
Queue,
|
Priority,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TxBufferMode> for crate::pac::can::vals::Tfqm {
|
impl From<TxBufferMode> for crate::pac::can::vals::Tfqm {
|
||||||
fn from(value: TxBufferMode) -> Self {
|
fn from(value: TxBufferMode) -> Self {
|
||||||
match value {
|
match value {
|
||||||
TxBufferMode::Queue => Self::QUEUE,
|
TxBufferMode::Priority => Self::QUEUE,
|
||||||
TxBufferMode::Fifo => Self::FIFO,
|
TxBufferMode::Fifo => Self::FIFO,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -308,7 +308,7 @@ impl From<TxBufferMode> for crate::pac::can::vals::Tfqm {
|
|||||||
impl From<crate::pac::can::vals::Tfqm> for TxBufferMode {
|
impl From<crate::pac::can::vals::Tfqm> for TxBufferMode {
|
||||||
fn from(value: crate::pac::can::vals::Tfqm) -> Self {
|
fn from(value: crate::pac::can::vals::Tfqm) -> Self {
|
||||||
match value {
|
match value {
|
||||||
crate::pac::can::vals::Tfqm::QUEUE => Self::Queue,
|
crate::pac::can::vals::Tfqm::QUEUE => Self::Priority,
|
||||||
crate::pac::can::vals::Tfqm::FIFO => Self::Fifo,
|
crate::pac::can::vals::Tfqm::FIFO => Self::Fifo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -354,7 +354,7 @@ pub struct FdCanConfig {
|
|||||||
pub timestamp_source: TimestampSource,
|
pub timestamp_source: TimestampSource,
|
||||||
/// Configures the Global Filter
|
/// Configures the Global Filter
|
||||||
pub global_filter: GlobalFilter,
|
pub global_filter: GlobalFilter,
|
||||||
/// TX buffer mode (FIFO or queue)
|
/// TX buffer mode (FIFO or priority queue)
|
||||||
pub tx_buffer_mode: TxBufferMode,
|
pub tx_buffer_mode: TxBufferMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,6 +445,13 @@ impl FdCanConfig {
|
|||||||
self.global_filter = filter;
|
self.global_filter = filter;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the TX buffer mode (FIFO or priority queue)
|
||||||
|
#[inline]
|
||||||
|
pub const fn set_tx_buffer_mode(mut self, txbm: TxBufferMode) -> Self {
|
||||||
|
self.tx_buffer_mode = txbm;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for FdCanConfig {
|
impl Default for FdCanConfig {
|
||||||
@ -462,7 +469,7 @@ impl Default for FdCanConfig {
|
|||||||
clock_divider: ClockDivider::_1,
|
clock_divider: ClockDivider::_1,
|
||||||
timestamp_source: TimestampSource::None,
|
timestamp_source: TimestampSource::None,
|
||||||
global_filter: GlobalFilter::default(),
|
global_filter: GlobalFilter::default(),
|
||||||
tx_buffer_mode: TxBufferMode::Queue,
|
tx_buffer_mode: TxBufferMode::Priority,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -398,7 +398,8 @@ impl<'d, T: Instance> Fdcan<'d, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// User supplied buffer for RX Buffering
|
/// User supplied buffer for RX Buffering
|
||||||
pub type RxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, (ClassicFrame, Timestamp), BUF_SIZE>;
|
pub type RxBuf<const BUF_SIZE: usize> =
|
||||||
|
Channel<CriticalSectionRawMutex, Result<(ClassicFrame, Timestamp), BusError>, BUF_SIZE>;
|
||||||
|
|
||||||
/// User supplied buffer for TX buffering
|
/// User supplied buffer for TX buffering
|
||||||
pub type TxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, ClassicFrame, BUF_SIZE>;
|
pub type TxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, ClassicFrame, BUF_SIZE>;
|
||||||
@ -440,7 +441,8 @@ impl BufferedCanSender {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
|
/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
|
||||||
pub type BufferedCanReceiver = embassy_sync::channel::DynamicReceiver<'static, (ClassicFrame, Timestamp)>;
|
pub type BufferedCanReceiver =
|
||||||
|
embassy_sync::channel::DynamicReceiver<'static, Result<(ClassicFrame, Timestamp), BusError>>;
|
||||||
|
|
||||||
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>
|
||||||
BufferedCan<'d, T, TX_BUF_SIZE, RX_BUF_SIZE>
|
BufferedCan<'d, T, TX_BUF_SIZE, RX_BUF_SIZE>
|
||||||
@ -485,7 +487,7 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
|
|||||||
|
|
||||||
/// Async read frame from RX buffer.
|
/// Async read frame from RX buffer.
|
||||||
pub async fn read(&mut self) -> Result<(ClassicFrame, Timestamp), BusError> {
|
pub async fn read(&mut self) -> Result<(ClassicFrame, Timestamp), BusError> {
|
||||||
Ok(self.rx_buf.receive().await)
|
self.rx_buf.receive().await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a sender that can be used for sending CAN frames.
|
/// Returns a sender that can be used for sending CAN frames.
|
||||||
@ -514,7 +516,8 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Dr
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// User supplied buffer for RX Buffering
|
/// User supplied buffer for RX Buffering
|
||||||
pub type RxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, (FdFrame, Timestamp), BUF_SIZE>;
|
pub type RxFdBuf<const BUF_SIZE: usize> =
|
||||||
|
Channel<CriticalSectionRawMutex, Result<(FdFrame, Timestamp), BusError>, BUF_SIZE>;
|
||||||
|
|
||||||
/// User supplied buffer for TX buffering
|
/// User supplied buffer for TX buffering
|
||||||
pub type TxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, FdFrame, BUF_SIZE>;
|
pub type TxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, FdFrame, BUF_SIZE>;
|
||||||
@ -556,7 +559,8 @@ impl BufferedFdCanSender {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
|
/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
|
||||||
pub type BufferedFdCanReceiver = embassy_sync::channel::DynamicReceiver<'static, (FdFrame, Timestamp)>;
|
pub type BufferedFdCanReceiver =
|
||||||
|
embassy_sync::channel::DynamicReceiver<'static, Result<(FdFrame, Timestamp), BusError>>;
|
||||||
|
|
||||||
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>
|
||||||
BufferedCanFd<'d, T, TX_BUF_SIZE, RX_BUF_SIZE>
|
BufferedCanFd<'d, T, TX_BUF_SIZE, RX_BUF_SIZE>
|
||||||
@ -601,7 +605,7 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
|
|||||||
|
|
||||||
/// Async read frame from RX buffer.
|
/// Async read frame from RX buffer.
|
||||||
pub async fn read(&mut self) -> Result<(FdFrame, Timestamp), BusError> {
|
pub async fn read(&mut self) -> Result<(FdFrame, Timestamp), BusError> {
|
||||||
Ok(self.rx_buf.receive().await)
|
self.rx_buf.receive().await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a sender that can be used for sending CAN frames.
|
/// Returns a sender that can be used for sending CAN frames.
|
||||||
@ -685,14 +689,14 @@ pub(crate) mod sealed {
|
|||||||
use crate::can::frame::{ClassicFrame, FdFrame};
|
use crate::can::frame::{ClassicFrame, FdFrame};
|
||||||
|
|
||||||
pub struct ClassicBufferedRxInner {
|
pub struct ClassicBufferedRxInner {
|
||||||
pub rx_sender: DynamicSender<'static, (ClassicFrame, Timestamp)>,
|
pub rx_sender: DynamicSender<'static, Result<(ClassicFrame, Timestamp), BusError>>,
|
||||||
}
|
}
|
||||||
pub struct ClassicBufferedTxInner {
|
pub struct ClassicBufferedTxInner {
|
||||||
pub tx_receiver: DynamicReceiver<'static, ClassicFrame>,
|
pub tx_receiver: DynamicReceiver<'static, ClassicFrame>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FdBufferedRxInner {
|
pub struct FdBufferedRxInner {
|
||||||
pub rx_sender: DynamicSender<'static, (FdFrame, Timestamp)>,
|
pub rx_sender: DynamicSender<'static, Result<(FdFrame, Timestamp), BusError>>,
|
||||||
}
|
}
|
||||||
pub struct FdBufferedTxInner {
|
pub struct FdBufferedTxInner {
|
||||||
pub tx_receiver: DynamicReceiver<'static, FdFrame>,
|
pub tx_receiver: DynamicReceiver<'static, FdFrame>,
|
||||||
@ -721,46 +725,51 @@ pub(crate) mod sealed {
|
|||||||
waker.wake();
|
waker.wake();
|
||||||
}
|
}
|
||||||
RxMode::ClassicBuffered(buf) => {
|
RxMode::ClassicBuffered(buf) => {
|
||||||
if let Some(r) = T::registers().read(fifonr) {
|
if let Some(result) = self.read::<T, _>() {
|
||||||
let ts = T::calc_timestamp(T::state().ns_per_timer_tick, r.1);
|
let _ = buf.rx_sender.try_send(result);
|
||||||
let _ = buf.rx_sender.try_send((r.0, ts));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RxMode::FdBuffered(buf) => {
|
RxMode::FdBuffered(buf) => {
|
||||||
if let Some(r) = T::registers().read(fifonr) {
|
if let Some(result) = self.read::<T, _>() {
|
||||||
let ts = T::calc_timestamp(T::state().ns_per_timer_tick, r.1);
|
let _ = buf.rx_sender.try_send(result);
|
||||||
let _ = buf.rx_sender.try_send((r.0, ts));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn read<T: Instance, F: CanHeader>(&self) -> Result<(F, Timestamp), BusError> {
|
fn read<T: Instance, F: CanHeader>(&self) -> Option<Result<(F, Timestamp), BusError>> {
|
||||||
|
if let Some((msg, ts)) = T::registers().read(0) {
|
||||||
|
let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
|
||||||
|
Some(Ok((msg, ts)))
|
||||||
|
} else if let Some((msg, ts)) = T::registers().read(1) {
|
||||||
|
let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
|
||||||
|
Some(Ok((msg, ts)))
|
||||||
|
} else if let Some(err) = T::registers().curr_error() {
|
||||||
|
// TODO: this is probably wrong
|
||||||
|
Some(Err(err))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn read_async<T: Instance, F: CanHeader>(&self) -> Result<(F, Timestamp), BusError> {
|
||||||
poll_fn(|cx| {
|
poll_fn(|cx| {
|
||||||
T::state().err_waker.register(cx.waker());
|
T::state().err_waker.register(cx.waker());
|
||||||
self.register(cx.waker());
|
self.register(cx.waker());
|
||||||
|
match self.read::<T, _>() {
|
||||||
if let Some((msg, ts)) = T::registers().read(0) {
|
Some(result) => Poll::Ready(result),
|
||||||
let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
|
None => Poll::Pending,
|
||||||
return Poll::Ready(Ok((msg, ts)));
|
|
||||||
} else if let Some((msg, ts)) = T::registers().read(1) {
|
|
||||||
let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
|
|
||||||
return Poll::Ready(Ok((msg, ts)));
|
|
||||||
} else if let Some(err) = T::registers().curr_error() {
|
|
||||||
// TODO: this is probably wrong
|
|
||||||
return Poll::Ready(Err(err));
|
|
||||||
}
|
}
|
||||||
Poll::Pending
|
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn read_classic<T: Instance>(&self) -> Result<(ClassicFrame, Timestamp), BusError> {
|
pub async fn read_classic<T: Instance>(&self) -> Result<(ClassicFrame, Timestamp), BusError> {
|
||||||
self.read::<T, _>().await
|
self.read_async::<T, _>().await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn read_fd<T: Instance>(&self) -> Result<(FdFrame, Timestamp), BusError> {
|
pub async fn read_fd<T: Instance>(&self) -> Result<(FdFrame, Timestamp), BusError> {
|
||||||
self.read::<T, _>().await
|
self.read_async::<T, _>().await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user