aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/can/fdcan.rs62
-rw-r--r--examples/stm32g4/src/bin/can.rs6
2 files changed, 63 insertions, 5 deletions
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs
index 6a4a25cb7..77db774fc 100644
--- a/embassy-stm32/src/can/fdcan.rs
+++ b/embassy-stm32/src/can/fdcan.rs
@@ -436,7 +436,31 @@ pub struct BufferedCan<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_S
436} 436}
437 437
438/// Sender that can be used for sending CAN frames. 438/// Sender that can be used for sending CAN frames.
439pub type BufferedCanSender = embassy_sync::channel::DynamicSender<'static, ClassicFrame>; 439#[derive(Copy, Clone)]
440pub struct BufferedCanSender {
441 tx_buf: embassy_sync::channel::DynamicSender<'static, ClassicFrame>,
442 waker: fn(),
443}
444
445impl BufferedCanSender {
446 /// Async write frame to TX buffer.
447 pub fn try_write(&mut self, frame: ClassicFrame) -> Result<(), embassy_sync::channel::TrySendError<ClassicFrame>> {
448 self.tx_buf.try_send(frame)?;
449 (self.waker)();
450 Ok(())
451 }
452
453 /// Async write frame to TX buffer.
454 pub async fn write(&mut self, frame: ClassicFrame) {
455 self.tx_buf.send(frame).await;
456 (self.waker)();
457 }
458
459 /// Allows a poll_fn to poll until the channel is ready to write
460 pub fn poll_ready_to_send(&self, cx: &mut core::task::Context<'_>) -> core::task::Poll<()> {
461 self.tx_buf.poll_ready_to_send(cx)
462 }
463}
440 464
441/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. 465/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
442pub type BufferedCanReceiver = embassy_sync::channel::DynamicReceiver<'static, (ClassicFrame, Timestamp)>; 466pub type BufferedCanReceiver = embassy_sync::channel::DynamicReceiver<'static, (ClassicFrame, Timestamp)>;
@@ -489,7 +513,10 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
489 513
490 /// Returns a sender that can be used for sending CAN frames. 514 /// Returns a sender that can be used for sending CAN frames.
491 pub fn writer(&self) -> BufferedCanSender { 515 pub fn writer(&self) -> BufferedCanSender {
492 self.tx_buf.sender().into() 516 BufferedCanSender {
517 tx_buf: self.tx_buf.sender().into(),
518 waker: T::IT0Interrupt::pend,
519 }
493 } 520 }
494 521
495 /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. 522 /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
@@ -525,7 +552,31 @@ pub struct BufferedCanFd<'d, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF
525} 552}
526 553
527/// Sender that can be used for sending CAN frames. 554/// Sender that can be used for sending CAN frames.
528pub type BufferedFdCanSender = embassy_sync::channel::DynamicSender<'static, FdFrame>; 555#[derive(Copy, Clone)]
556pub struct BufferedFdCanSender {
557 tx_buf: embassy_sync::channel::DynamicSender<'static, FdFrame>,
558 waker: fn(),
559}
560
561impl BufferedFdCanSender {
562 /// Async write frame to TX buffer.
563 pub fn try_write(&mut self, frame: FdFrame) -> Result<(), embassy_sync::channel::TrySendError<FdFrame>> {
564 self.tx_buf.try_send(frame)?;
565 (self.waker)();
566 Ok(())
567 }
568
569 /// Async write frame to TX buffer.
570 pub async fn write(&mut self, frame: FdFrame) {
571 self.tx_buf.send(frame).await;
572 (self.waker)();
573 }
574
575 /// Allows a poll_fn to poll until the channel is ready to write
576 pub fn poll_ready_to_send(&self, cx: &mut core::task::Context<'_>) -> core::task::Poll<()> {
577 self.tx_buf.poll_ready_to_send(cx)
578 }
579}
529 580
530/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. 581/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
531pub type BufferedFdCanReceiver = embassy_sync::channel::DynamicReceiver<'static, (FdFrame, Timestamp)>; 582pub type BufferedFdCanReceiver = embassy_sync::channel::DynamicReceiver<'static, (FdFrame, Timestamp)>;
@@ -578,7 +629,10 @@ impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
578 629
579 /// Returns a sender that can be used for sending CAN frames. 630 /// Returns a sender that can be used for sending CAN frames.
580 pub fn writer(&self) -> BufferedFdCanSender { 631 pub fn writer(&self) -> BufferedFdCanSender {
581 self.tx_buf.sender().into() 632 BufferedFdCanSender {
633 tx_buf: self.tx_buf.sender().into(),
634 waker: T::IT0Interrupt::pend,
635 }
582 } 636 }
583 637
584 /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. 638 /// Returns a receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
diff --git a/examples/stm32g4/src/bin/can.rs b/examples/stm32g4/src/bin/can.rs
index a41f765c1..11e96361e 100644
--- a/examples/stm32g4/src/bin/can.rs
+++ b/examples/stm32g4/src/bin/can.rs
@@ -184,7 +184,11 @@ async fn main(_spawner: Spawner) {
184 let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap(); 184 let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap();
185 info!("Writing frame"); 185 info!("Writing frame");
186 186
187 _ = can.write(frame).await; 187 // You can use any of these approaches to send. The writer makes it
188 // easy to share sending from multiple tasks.
189 //_ = can.write(frame).await;
190 //can.writer().try_write(frame).unwrap();
191 can.writer().write(frame).await;
188 192
189 match can.read().await { 193 match can.read().await {
190 Ok((rx_frame, ts)) => { 194 Ok((rx_frame, ts)) => {