From f5daa50a7baceb44f2aad44bf6ce055bccb08433 Mon Sep 17 00:00:00 2001 From: Corey Schuhen Date: Sun, 24 Mar 2024 14:15:46 +1000 Subject: [PATCH] BXCAN: Add struct that combines Buffered RX and Buffered TX. --- embassy-stm32/src/can/bxcan.rs | 55 +++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/embassy-stm32/src/can/bxcan.rs b/embassy-stm32/src/can/bxcan.rs index 45a3836c0..be2e34963 100644 --- a/embassy-stm32/src/can/bxcan.rs +++ b/embassy-stm32/src/can/bxcan.rs @@ -236,6 +236,19 @@ impl<'d, T: Instance> Can<'d, T> { let (tx, rx) = self.can.split_by_ref(); (CanTx { tx }, CanRx { rx }) } + + /// Return a buffered instance of driver. User must supply Buffers + pub fn buffered<'c, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>( + &'c mut self, + txb: &'static mut TxBuf, + rxb: &'static mut RxBuf, + ) -> BufferedCan<'d, T, TX_BUF_SIZE, RX_BUF_SIZE> { + let (tx, rx) = self.split(); + BufferedCan { + tx: tx.buffered(txb), + rx: rx.buffered(rxb), + } + } } impl<'d, T: Instance> AsMut>> for Can<'d, T> { @@ -245,6 +258,46 @@ impl<'d, T: Instance> AsMut>> for Can<' } } +/// Buffered CAN driver. +pub struct BufferedCan<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> { + tx: BufferedCanTx<'d, T, TX_BUF_SIZE>, + rx: BufferedCanRx<'d, T, RX_BUF_SIZE>, +} + +impl<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, T, TX_BUF_SIZE, RX_BUF_SIZE> { + /// Async write frame to TX buffer. + pub async fn write(&mut self, frame: &Frame) { + self.tx.write(frame).await + } + + /// Returns a sender that can be used for sending CAN frames. + pub fn writer(&self) -> BufferedCanSender { + self.tx.writer() + } + + /// Async read frame from RX buffer. + pub async fn read(&mut self) -> Result<(Frame, Timestamp), BusError> { + self.rx.read().await + } + + /// Attempts to read a CAN frame without blocking. + /// + /// Returns [Err(TryReadError::Empty)] if there are no frames in the rx queue. + pub fn try_read(&mut self) -> Result { + self.rx.try_read() + } + + /// Waits while receive queue is empty. + pub async fn wait_not_empty(&mut self) { + self.rx.wait_not_empty().await + } + + /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. + pub fn reader(&self) -> BufferedCanReceiver { + self.rx.reader() + } +} + /// CAN driver, transmit half. pub struct CanTx<'d, T: Instance> { tx: crate::can::bx::Tx>, @@ -346,7 +399,7 @@ impl<'d, T: Instance> CanTx<'d, T> { /// User supplied buffer for TX buffering pub type TxBuf = Channel; -/// CAN driver, transmit half. +/// Buffered CAN driver, transmit half. pub struct BufferedCanTx<'d, T: Instance, const TX_BUF_SIZE: usize> { _tx: crate::can::bx::Tx>, tx_buf: &'static TxBuf,