diff options
| -rw-r--r-- | embassy-stm32/src/can/fdcan.rs | 62 | ||||
| -rw-r--r-- | examples/stm32g4/src/bin/can.rs | 6 |
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. |
| 439 | pub type BufferedCanSender = embassy_sync::channel::DynamicSender<'static, ClassicFrame>; | 439 | #[derive(Copy, Clone)] |
| 440 | pub struct BufferedCanSender { | ||
| 441 | tx_buf: embassy_sync::channel::DynamicSender<'static, ClassicFrame>, | ||
| 442 | waker: fn(), | ||
| 443 | } | ||
| 444 | |||
| 445 | impl 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. |
| 442 | pub type BufferedCanReceiver = embassy_sync::channel::DynamicReceiver<'static, (ClassicFrame, Timestamp)>; | 466 | pub 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. |
| 528 | pub type BufferedFdCanSender = embassy_sync::channel::DynamicSender<'static, FdFrame>; | 555 | #[derive(Copy, Clone)] |
| 556 | pub struct BufferedFdCanSender { | ||
| 557 | tx_buf: embassy_sync::channel::DynamicSender<'static, FdFrame>, | ||
| 558 | waker: fn(), | ||
| 559 | } | ||
| 560 | |||
| 561 | impl 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. |
| 531 | pub type BufferedFdCanReceiver = embassy_sync::channel::DynamicReceiver<'static, (FdFrame, Timestamp)>; | 582 | pub 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 7551b2a55..93b206de8 100644 --- a/examples/stm32g4/src/bin/can.rs +++ b/examples/stm32g4/src/bin/can.rs | |||
| @@ -201,7 +201,11 @@ async fn main(_spawner: Spawner) { | |||
| 201 | let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap(); | 201 | let frame = can::frame::ClassicFrame::new_extended(0x123456F, &[i; 8]).unwrap(); |
| 202 | info!("Writing frame"); | 202 | info!("Writing frame"); |
| 203 | 203 | ||
| 204 | _ = can.write(frame).await; | 204 | // You can use any of these approaches to send. The writer makes it |
| 205 | // easy to share sending from multiple tasks. | ||
| 206 | //_ = can.write(frame).await; | ||
| 207 | //can.writer().try_write(frame).unwrap(); | ||
| 208 | can.writer().write(frame).await; | ||
| 205 | 209 | ||
| 206 | match can.read().await { | 210 | match can.read().await { |
| 207 | Ok((rx_frame, ts)) => { | 211 | Ok((rx_frame, ts)) => { |
