aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorey Schuhen <[email protected]>2024-03-24 07:19:00 +1000
committerCorey Schuhen <[email protected]>2024-03-28 09:30:58 +1000
commitfcfcfce4007768578c3a6a1b744a5efd97f14376 (patch)
treecf3fb0d551e6e4b0216912b1be7430fd2e9566e4
parent8f6c07c7750647edf9acea76cf6fe0ca1bc4da87 (diff)
CAN: Move some FDCAN definitions into a module to share with BXCAN.
-rw-r--r--embassy-stm32/src/can/common.rs51
-rw-r--r--embassy-stm32/src/can/fdcan.rs62
2 files changed, 61 insertions, 52 deletions
diff --git a/embassy-stm32/src/can/common.rs b/embassy-stm32/src/can/common.rs
new file mode 100644
index 000000000..1de54e5a1
--- /dev/null
+++ b/embassy-stm32/src/can/common.rs
@@ -0,0 +1,51 @@
1use embassy_sync::channel::{DynamicReceiver, DynamicSender};
2
3use crate::can::_version::frame::*;
4use crate::can::_version::Timestamp;
5use crate::can::_version::enums::*;
6
7pub(crate) struct ClassicBufferedRxInner {
8 pub rx_sender: DynamicSender<'static, Result<(ClassicFrame, Timestamp), BusError>>,
9}
10pub(crate) struct ClassicBufferedTxInner {
11 pub tx_receiver: DynamicReceiver<'static, ClassicFrame>,
12}
13
14pub(crate) struct FdBufferedRxInner {
15 pub rx_sender: DynamicSender<'static, Result<(FdFrame, Timestamp), BusError>>,
16}
17pub(crate) struct FdBufferedTxInner {
18 pub tx_receiver: DynamicReceiver<'static, FdFrame>,
19}
20
21/// Sender that can be used for sending CAN frames.
22#[derive(Copy, Clone)]
23pub struct BufferedCanSender {
24 pub(crate) tx_buf: embassy_sync::channel::DynamicSender<'static, ClassicFrame>,
25 pub(crate) waker: fn(),
26}
27
28impl BufferedCanSender {
29 /// Async write frame to TX buffer.
30 pub fn try_write(&mut self, frame: ClassicFrame) -> Result<(), embassy_sync::channel::TrySendError<ClassicFrame>> {
31 self.tx_buf.try_send(frame)?;
32 (self.waker)();
33 Ok(())
34 }
35
36 /// Async write frame to TX buffer.
37 pub async fn write(&mut self, frame: ClassicFrame) {
38 self.tx_buf.send(frame).await;
39 (self.waker)();
40 }
41
42 /// Allows a poll_fn to poll until the channel is ready to write
43 pub fn poll_ready_to_send(&self, cx: &mut core::task::Context<'_>) -> core::task::Poll<()> {
44 self.tx_buf.poll_ready_to_send(cx)
45 }
46}
47
48/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
49pub type BufferedCanReceiver =
50 embassy_sync::channel::DynamicReceiver<'static, Result<(ClassicFrame, Timestamp), BusError>>;
51
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs
index 4ea036ab4..c42c42853 100644
--- a/embassy-stm32/src/can/fdcan.rs
+++ b/embassy-stm32/src/can/fdcan.rs
@@ -14,6 +14,7 @@ use crate::interrupt::typelevel::Interrupt;
14use crate::rcc::RccPeripheral; 14use crate::rcc::RccPeripheral;
15use crate::{interrupt, peripherals, Peripheral}; 15use crate::{interrupt, peripherals, Peripheral};
16 16
17mod common;
17pub mod enums; 18pub mod enums;
18pub(crate) mod fd; 19pub(crate) mod fd;
19pub mod frame; 20pub mod frame;
@@ -24,6 +25,7 @@ use fd::config::*;
24use fd::filter::*; 25use fd::filter::*;
25pub use fd::{config, filter}; 26pub use fd::{config, filter};
26use frame::*; 27use frame::*;
28pub use self::common::{BufferedCanSender, BufferedCanReceiver};
27 29
28/// Timestamp for incoming packets. Use Embassy time when enabled. 30/// Timestamp for incoming packets. Use Embassy time when enabled.
29#[cfg(feature = "time")] 31#[cfg(feature = "time")]
@@ -414,36 +416,6 @@ pub struct BufferedCan<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_S
414 rx_buf: &'static RxBuf<RX_BUF_SIZE>, 416 rx_buf: &'static RxBuf<RX_BUF_SIZE>,
415} 417}
416 418
417/// Sender that can be used for sending CAN frames.
418#[derive(Copy, Clone)]
419pub struct BufferedCanSender {
420 tx_buf: embassy_sync::channel::DynamicSender<'static, ClassicFrame>,
421 waker: fn(),
422}
423
424impl BufferedCanSender {
425 /// Async write frame to TX buffer.
426 pub fn try_write(&mut self, frame: ClassicFrame) -> Result<(), embassy_sync::channel::TrySendError<ClassicFrame>> {
427 self.tx_buf.try_send(frame)?;
428 (self.waker)();
429 Ok(())
430 }
431
432 /// Async write frame to TX buffer.
433 pub async fn write(&mut self, frame: ClassicFrame) {
434 self.tx_buf.send(frame).await;
435 (self.waker)();
436 }
437
438 /// Allows a poll_fn to poll until the channel is ready to write
439 pub fn poll_ready_to_send(&self, cx: &mut core::task::Context<'_>) -> core::task::Poll<()> {
440 self.tx_buf.poll_ready_to_send(cx)
441 }
442}
443
444/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
445pub type BufferedCanReceiver =
446 embassy_sync::channel::DynamicReceiver<'static, Result<(ClassicFrame, Timestamp), BusError>>;
447 419
448impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> 420impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
449 BufferedCan<'d, T, TX_BUF_SIZE, RX_BUF_SIZE> 421 BufferedCan<'d, T, TX_BUF_SIZE, RX_BUF_SIZE>
@@ -468,10 +440,10 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
468 fn setup(self) -> Self { 440 fn setup(self) -> Self {
469 // We don't want interrupts being processed while we change modes. 441 // We don't want interrupts being processed while we change modes.
470 critical_section::with(|_| unsafe { 442 critical_section::with(|_| unsafe {
471 let rx_inner = ClassicBufferedRxInner { 443 let rx_inner = self::common::ClassicBufferedRxInner {
472 rx_sender: self.rx_buf.sender().into(), 444 rx_sender: self.rx_buf.sender().into(),
473 }; 445 };
474 let tx_inner = ClassicBufferedTxInner { 446 let tx_inner = self::common::ClassicBufferedTxInner {
475 tx_receiver: self.tx_buf.receiver().into(), 447 tx_receiver: self.tx_buf.receiver().into(),
476 }; 448 };
477 T::mut_state().rx_mode = RxMode::ClassicBuffered(rx_inner); 449 T::mut_state().rx_mode = RxMode::ClassicBuffered(rx_inner);
@@ -586,10 +558,10 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
586 fn setup(self) -> Self { 558 fn setup(self) -> Self {
587 // We don't want interrupts being processed while we change modes. 559 // We don't want interrupts being processed while we change modes.
588 critical_section::with(|_| unsafe { 560 critical_section::with(|_| unsafe {
589 let rx_inner = FdBufferedRxInner { 561 let rx_inner = self::common::FdBufferedRxInner {
590 rx_sender: self.rx_buf.sender().into(), 562 rx_sender: self.rx_buf.sender().into(),
591 }; 563 };
592 let tx_inner = FdBufferedTxInner { 564 let tx_inner = self::common::FdBufferedTxInner {
593 tx_receiver: self.tx_buf.receiver().into(), 565 tx_receiver: self.tx_buf.receiver().into(),
594 }; 566 };
595 T::mut_state().rx_mode = RxMode::FdBuffered(rx_inner); 567 T::mut_state().rx_mode = RxMode::FdBuffered(rx_inner);
@@ -678,24 +650,10 @@ impl<'c, 'd, T: Instance> FdcanRx<'d, T> {
678 } 650 }
679} 651}
680 652
681struct ClassicBufferedRxInner {
682 rx_sender: DynamicSender<'static, Result<(ClassicFrame, Timestamp), BusError>>,
683}
684struct ClassicBufferedTxInner {
685 tx_receiver: DynamicReceiver<'static, ClassicFrame>,
686}
687
688struct FdBufferedRxInner {
689 rx_sender: DynamicSender<'static, Result<(FdFrame, Timestamp), BusError>>,
690}
691struct FdBufferedTxInner {
692 tx_receiver: DynamicReceiver<'static, FdFrame>,
693}
694
695enum RxMode { 653enum RxMode {
696 NonBuffered(AtomicWaker), 654 NonBuffered(AtomicWaker),
697 ClassicBuffered(ClassicBufferedRxInner), 655 ClassicBuffered(self::common::ClassicBufferedRxInner),
698 FdBuffered(FdBufferedRxInner), 656 FdBuffered(self::common::FdBufferedRxInner),
699} 657}
700 658
701impl RxMode { 659impl RxMode {
@@ -765,8 +723,8 @@ impl RxMode {
765 723
766enum TxMode { 724enum TxMode {
767 NonBuffered(AtomicWaker), 725 NonBuffered(AtomicWaker),
768 ClassicBuffered(ClassicBufferedTxInner), 726 ClassicBuffered(self::common::ClassicBufferedTxInner),
769 FdBuffered(FdBufferedTxInner), 727 FdBuffered(self::common::FdBufferedTxInner),
770} 728}
771 729
772impl TxMode { 730impl TxMode {