diff options
| author | Torin Cooper-Bennun <[email protected]> | 2024-03-04 12:22:59 +0000 |
|---|---|---|
| committer | Torin Cooper-Bennun <[email protected]> | 2024-03-04 12:38:46 +0000 |
| commit | e0018c6f4f56cdef286934fb368cd4053c209461 (patch) | |
| tree | 4994ab0c967cd2a5ff69798d1ca43e7585add42c | |
| parent | 72c6cdc5d5bd851855975061b1c6713cf482e6fb (diff) | |
stm32: can:fd: merge read impls; buffered RX returns Result<_, BusError>
| -rw-r--r-- | embassy-stm32/src/can/fdcan.rs | 65 |
1 files 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> { | |||
| 398 | } | 398 | } |
| 399 | 399 | ||
| 400 | /// User supplied buffer for RX Buffering | 400 | /// User supplied buffer for RX Buffering |
| 401 | pub type RxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, (ClassicFrame, Timestamp), BUF_SIZE>; | 401 | pub type RxBuf<const BUF_SIZE: usize> = |
| 402 | Channel<CriticalSectionRawMutex, Result<(ClassicFrame, Timestamp), BusError>, BUF_SIZE>; | ||
| 402 | 403 | ||
| 403 | /// User supplied buffer for TX buffering | 404 | /// User supplied buffer for TX buffering |
| 404 | pub type TxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, ClassicFrame, BUF_SIZE>; | 405 | pub type TxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, ClassicFrame, BUF_SIZE>; |
| @@ -440,7 +441,8 @@ impl BufferedCanSender { | |||
| 440 | } | 441 | } |
| 441 | 442 | ||
| 442 | /// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. | 443 | /// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. |
| 443 | pub type BufferedCanReceiver = embassy_sync::channel::DynamicReceiver<'static, (ClassicFrame, Timestamp)>; | 444 | pub type BufferedCanReceiver = |
| 445 | embassy_sync::channel::DynamicReceiver<'static, Result<(ClassicFrame, Timestamp), BusError>>; | ||
| 444 | 446 | ||
| 445 | impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> | 447 | impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> |
| 446 | BufferedCan<'d, T, TX_BUF_SIZE, RX_BUF_SIZE> | 448 | 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> | |||
| 485 | 487 | ||
| 486 | /// Async read frame from RX buffer. | 488 | /// Async read frame from RX buffer. |
| 487 | pub async fn read(&mut self) -> Result<(ClassicFrame, Timestamp), BusError> { | 489 | pub async fn read(&mut self) -> Result<(ClassicFrame, Timestamp), BusError> { |
| 488 | Ok(self.rx_buf.receive().await) | 490 | self.rx_buf.receive().await |
| 489 | } | 491 | } |
| 490 | 492 | ||
| 491 | /// Returns a sender that can be used for sending CAN frames. | 493 | /// 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 | |||
| 514 | } | 516 | } |
| 515 | 517 | ||
| 516 | /// User supplied buffer for RX Buffering | 518 | /// User supplied buffer for RX Buffering |
| 517 | pub type RxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, (FdFrame, Timestamp), BUF_SIZE>; | 519 | pub type RxFdBuf<const BUF_SIZE: usize> = |
| 520 | Channel<CriticalSectionRawMutex, Result<(FdFrame, Timestamp), BusError>, BUF_SIZE>; | ||
| 518 | 521 | ||
| 519 | /// User supplied buffer for TX buffering | 522 | /// User supplied buffer for TX buffering |
| 520 | pub type TxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, FdFrame, BUF_SIZE>; | 523 | pub type TxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, FdFrame, BUF_SIZE>; |
| @@ -556,7 +559,8 @@ impl BufferedFdCanSender { | |||
| 556 | } | 559 | } |
| 557 | 560 | ||
| 558 | /// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. | 561 | /// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. |
| 559 | pub type BufferedFdCanReceiver = embassy_sync::channel::DynamicReceiver<'static, (FdFrame, Timestamp)>; | 562 | pub type BufferedFdCanReceiver = |
| 563 | embassy_sync::channel::DynamicReceiver<'static, Result<(FdFrame, Timestamp), BusError>>; | ||
| 560 | 564 | ||
| 561 | impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> | 565 | impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> |
| 562 | BufferedCanFd<'d, T, TX_BUF_SIZE, RX_BUF_SIZE> | 566 | 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> | |||
| 601 | 605 | ||
| 602 | /// Async read frame from RX buffer. | 606 | /// Async read frame from RX buffer. |
| 603 | pub async fn read(&mut self) -> Result<(FdFrame, Timestamp), BusError> { | 607 | pub async fn read(&mut self) -> Result<(FdFrame, Timestamp), BusError> { |
| 604 | Ok(self.rx_buf.receive().await) | 608 | self.rx_buf.receive().await |
| 605 | } | 609 | } |
| 606 | 610 | ||
| 607 | /// Returns a sender that can be used for sending CAN frames. | 611 | /// Returns a sender that can be used for sending CAN frames. |
| @@ -685,14 +689,14 @@ pub(crate) mod sealed { | |||
| 685 | use crate::can::frame::{ClassicFrame, FdFrame}; | 689 | use crate::can::frame::{ClassicFrame, FdFrame}; |
| 686 | 690 | ||
| 687 | pub struct ClassicBufferedRxInner { | 691 | pub struct ClassicBufferedRxInner { |
| 688 | pub rx_sender: DynamicSender<'static, (ClassicFrame, Timestamp)>, | 692 | pub rx_sender: DynamicSender<'static, Result<(ClassicFrame, Timestamp), BusError>>, |
| 689 | } | 693 | } |
| 690 | pub struct ClassicBufferedTxInner { | 694 | pub struct ClassicBufferedTxInner { |
| 691 | pub tx_receiver: DynamicReceiver<'static, ClassicFrame>, | 695 | pub tx_receiver: DynamicReceiver<'static, ClassicFrame>, |
| 692 | } | 696 | } |
| 693 | 697 | ||
| 694 | pub struct FdBufferedRxInner { | 698 | pub struct FdBufferedRxInner { |
| 695 | pub rx_sender: DynamicSender<'static, (FdFrame, Timestamp)>, | 699 | pub rx_sender: DynamicSender<'static, Result<(FdFrame, Timestamp), BusError>>, |
| 696 | } | 700 | } |
| 697 | pub struct FdBufferedTxInner { | 701 | pub struct FdBufferedTxInner { |
| 698 | pub tx_receiver: DynamicReceiver<'static, FdFrame>, | 702 | pub tx_receiver: DynamicReceiver<'static, FdFrame>, |
| @@ -721,46 +725,51 @@ pub(crate) mod sealed { | |||
| 721 | waker.wake(); | 725 | waker.wake(); |
| 722 | } | 726 | } |
| 723 | RxMode::ClassicBuffered(buf) => { | 727 | RxMode::ClassicBuffered(buf) => { |
| 724 | if let Some(r) = T::registers().read(fifonr) { | 728 | if let Some(result) = self.read::<T, _>() { |
| 725 | let ts = T::calc_timestamp(T::state().ns_per_timer_tick, r.1); | 729 | let _ = buf.rx_sender.try_send(result); |
| 726 | let _ = buf.rx_sender.try_send((r.0, ts)); | ||
| 727 | } | 730 | } |
| 728 | } | 731 | } |
| 729 | RxMode::FdBuffered(buf) => { | 732 | RxMode::FdBuffered(buf) => { |
| 730 | if let Some(r) = T::registers().read(fifonr) { | 733 | if let Some(result) = self.read::<T, _>() { |
| 731 | let ts = T::calc_timestamp(T::state().ns_per_timer_tick, r.1); | 734 | let _ = buf.rx_sender.try_send(result); |
| 732 | let _ = buf.rx_sender.try_send((r.0, ts)); | ||
| 733 | } | 735 | } |
| 734 | } | 736 | } |
| 735 | } | 737 | } |
| 736 | } | 738 | } |
| 737 | 739 | ||
| 738 | async fn read<T: Instance, F: CanHeader>(&self) -> Result<(F, Timestamp), BusError> { | 740 | fn read<T: Instance, F: CanHeader>(&self) -> Option<Result<(F, Timestamp), BusError>> { |
| 741 | if let Some((msg, ts)) = T::registers().read(0) { | ||
| 742 | let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts); | ||
| 743 | Some(Ok((msg, ts))) | ||
| 744 | } else if let Some((msg, ts)) = T::registers().read(1) { | ||
| 745 | let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts); | ||
| 746 | Some(Ok((msg, ts))) | ||
| 747 | } else if let Some(err) = T::registers().curr_error() { | ||
| 748 | // TODO: this is probably wrong | ||
| 749 | Some(Err(err)) | ||
| 750 | } else { | ||
| 751 | None | ||
| 752 | } | ||
| 753 | } | ||
| 754 | |||
| 755 | async fn read_async<T: Instance, F: CanHeader>(&self) -> Result<(F, Timestamp), BusError> { | ||
| 739 | poll_fn(|cx| { | 756 | poll_fn(|cx| { |
| 740 | T::state().err_waker.register(cx.waker()); | 757 | T::state().err_waker.register(cx.waker()); |
| 741 | self.register(cx.waker()); | 758 | self.register(cx.waker()); |
| 742 | 759 | match self.read::<T, _>() { | |
| 743 | if let Some((msg, ts)) = T::registers().read(0) { | 760 | Some(result) => Poll::Ready(result), |
| 744 | let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts); | 761 | None => Poll::Pending, |
| 745 | return Poll::Ready(Ok((msg, ts))); | ||
| 746 | } else if let Some((msg, ts)) = T::registers().read(1) { | ||
| 747 | let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts); | ||
| 748 | return Poll::Ready(Ok((msg, ts))); | ||
| 749 | } else if let Some(err) = T::registers().curr_error() { | ||
| 750 | // TODO: this is probably wrong | ||
| 751 | return Poll::Ready(Err(err)); | ||
| 752 | } | 762 | } |
| 753 | Poll::Pending | ||
| 754 | }) | 763 | }) |
| 755 | .await | 764 | .await |
| 756 | } | 765 | } |
| 757 | 766 | ||
| 758 | pub async fn read_classic<T: Instance>(&self) -> Result<(ClassicFrame, Timestamp), BusError> { | 767 | pub async fn read_classic<T: Instance>(&self) -> Result<(ClassicFrame, Timestamp), BusError> { |
| 759 | self.read::<T, _>().await | 768 | self.read_async::<T, _>().await |
| 760 | } | 769 | } |
| 761 | 770 | ||
| 762 | pub async fn read_fd<T: Instance>(&self) -> Result<(FdFrame, Timestamp), BusError> { | 771 | pub async fn read_fd<T: Instance>(&self) -> Result<(FdFrame, Timestamp), BusError> { |
| 763 | self.read::<T, _>().await | 772 | self.read_async::<T, _>().await |
| 764 | } | 773 | } |
| 765 | } | 774 | } |
| 766 | 775 | ||
