From e0018c6f4f56cdef286934fb368cd4053c209461 Mon Sep 17 00:00:00 2001 From: Torin Cooper-Bennun <tcbennun@maxiluxsystems.com> Date: Mon, 4 Mar 2024 12:22:59 +0000 Subject: [PATCH] stm32: can:fd: merge read impls; buffered RX returns Result<_, BusError> --- embassy-stm32/src/can/fdcan.rs | 65 +++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs index 20d00ccb5..fe8969a5a 100644 --- a/embassy-stm32/src/can/fdcan.rs +++ b/embassy-stm32/src/can/fdcan.rs @@ -398,7 +398,8 @@ impl<'d, T: Instance> Fdcan<'d, T> { } /// 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 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. -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> 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. 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. @@ -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 -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 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. -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> 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. 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. @@ -685,14 +689,14 @@ pub(crate) mod sealed { use crate::can::frame::{ClassicFrame, FdFrame}; pub struct ClassicBufferedRxInner { - pub rx_sender: DynamicSender<'static, (ClassicFrame, Timestamp)>, + pub rx_sender: DynamicSender<'static, Result<(ClassicFrame, Timestamp), BusError>>, } pub struct ClassicBufferedTxInner { pub tx_receiver: DynamicReceiver<'static, ClassicFrame>, } pub struct FdBufferedRxInner { - pub rx_sender: DynamicSender<'static, (FdFrame, Timestamp)>, + pub rx_sender: DynamicSender<'static, Result<(FdFrame, Timestamp), BusError>>, } pub struct FdBufferedTxInner { pub tx_receiver: DynamicReceiver<'static, FdFrame>, @@ -721,46 +725,51 @@ pub(crate) mod sealed { waker.wake(); } RxMode::ClassicBuffered(buf) => { - if let Some(r) = T::registers().read(fifonr) { - let ts = T::calc_timestamp(T::state().ns_per_timer_tick, r.1); - let _ = buf.rx_sender.try_send((r.0, ts)); + if let Some(result) = self.read::<T, _>() { + let _ = buf.rx_sender.try_send(result); } } RxMode::FdBuffered(buf) => { - if let Some(r) = T::registers().read(fifonr) { - let ts = T::calc_timestamp(T::state().ns_per_timer_tick, r.1); - let _ = buf.rx_sender.try_send((r.0, ts)); + if let Some(result) = self.read::<T, _>() { + let _ = buf.rx_sender.try_send(result); } } } } - 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| { T::state().err_waker.register(cx.waker()); self.register(cx.waker()); - - if let Some((msg, ts)) = T::registers().read(0) { - let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts); - 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)); + match self.read::<T, _>() { + Some(result) => Poll::Ready(result), + None => Poll::Pending, } - Poll::Pending }) .await } 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> { - self.read::<T, _>().await + self.read_async::<T, _>().await } }