aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-03-06 20:44:48 +0000
committerGitHub <[email protected]>2024-03-06 20:44:48 +0000
commit5e9297313641f1a2b4a868e1fe625543da8fc40a (patch)
tree4eeda7ee76acbe9b10d1b9b2b7bee3a026d353d3
parentaaea056ed16b2fb064a8a4c0985d77336363226e (diff)
parente0018c6f4f56cdef286934fb368cd4053c209461 (diff)
Merge pull request #2658 from MaxiluxSystems/fdcan-buffered-read-consistent
stm32: fdcan: merge read impls, add setter for TxBufferMode, rename Queue -> Priority
-rw-r--r--embassy-stm32/src/can/fd/config.rs19
-rw-r--r--embassy-stm32/src/can/fdcan.rs65
2 files changed, 50 insertions, 34 deletions
diff --git a/embassy-stm32/src/can/fd/config.rs b/embassy-stm32/src/can/fd/config.rs
index adaffe9cc..68161ca50 100644
--- a/embassy-stm32/src/can/fd/config.rs
+++ b/embassy-stm32/src/can/fd/config.rs
@@ -292,14 +292,14 @@ impl Default for GlobalFilter {
292pub enum TxBufferMode { 292pub enum TxBufferMode {
293 /// TX FIFO operation - In this mode CAN frames are trasmitted strictly in write order. 293 /// TX FIFO operation - In this mode CAN frames are trasmitted strictly in write order.
294 Fifo, 294 Fifo,
295 /// TX queue operation - In this mode CAN frames are transmitted according to CAN priority. 295 /// TX priority queue operation - In this mode CAN frames are transmitted according to CAN priority.
296 Queue, 296 Priority,
297} 297}
298 298
299impl From<TxBufferMode> for crate::pac::can::vals::Tfqm { 299impl From<TxBufferMode> for crate::pac::can::vals::Tfqm {
300 fn from(value: TxBufferMode) -> Self { 300 fn from(value: TxBufferMode) -> Self {
301 match value { 301 match value {
302 TxBufferMode::Queue => Self::QUEUE, 302 TxBufferMode::Priority => Self::QUEUE,
303 TxBufferMode::Fifo => Self::FIFO, 303 TxBufferMode::Fifo => Self::FIFO,
304 } 304 }
305 } 305 }
@@ -308,7 +308,7 @@ impl From<TxBufferMode> for crate::pac::can::vals::Tfqm {
308impl From<crate::pac::can::vals::Tfqm> for TxBufferMode { 308impl From<crate::pac::can::vals::Tfqm> for TxBufferMode {
309 fn from(value: crate::pac::can::vals::Tfqm) -> Self { 309 fn from(value: crate::pac::can::vals::Tfqm) -> Self {
310 match value { 310 match value {
311 crate::pac::can::vals::Tfqm::QUEUE => Self::Queue, 311 crate::pac::can::vals::Tfqm::QUEUE => Self::Priority,
312 crate::pac::can::vals::Tfqm::FIFO => Self::Fifo, 312 crate::pac::can::vals::Tfqm::FIFO => Self::Fifo,
313 } 313 }
314 } 314 }
@@ -354,7 +354,7 @@ pub struct FdCanConfig {
354 pub timestamp_source: TimestampSource, 354 pub timestamp_source: TimestampSource,
355 /// Configures the Global Filter 355 /// Configures the Global Filter
356 pub global_filter: GlobalFilter, 356 pub global_filter: GlobalFilter,
357 /// TX buffer mode (FIFO or queue) 357 /// TX buffer mode (FIFO or priority queue)
358 pub tx_buffer_mode: TxBufferMode, 358 pub tx_buffer_mode: TxBufferMode,
359} 359}
360 360
@@ -445,6 +445,13 @@ impl FdCanConfig {
445 self.global_filter = filter; 445 self.global_filter = filter;
446 self 446 self
447 } 447 }
448
449 /// Sets the TX buffer mode (FIFO or priority queue)
450 #[inline]
451 pub const fn set_tx_buffer_mode(mut self, txbm: TxBufferMode) -> Self {
452 self.tx_buffer_mode = txbm;
453 self
454 }
448} 455}
449 456
450impl Default for FdCanConfig { 457impl Default for FdCanConfig {
@@ -462,7 +469,7 @@ impl Default for FdCanConfig {
462 clock_divider: ClockDivider::_1, 469 clock_divider: ClockDivider::_1,
463 timestamp_source: TimestampSource::None, 470 timestamp_source: TimestampSource::None,
464 global_filter: GlobalFilter::default(), 471 global_filter: GlobalFilter::default(),
465 tx_buffer_mode: TxBufferMode::Queue, 472 tx_buffer_mode: TxBufferMode::Priority,
466 } 473 }
467 } 474 }
468} 475}
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
401pub type RxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, (ClassicFrame, Timestamp), BUF_SIZE>; 401pub 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
404pub type TxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, ClassicFrame, BUF_SIZE>; 405pub 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.
443pub type BufferedCanReceiver = embassy_sync::channel::DynamicReceiver<'static, (ClassicFrame, Timestamp)>; 444pub type BufferedCanReceiver =
445 embassy_sync::channel::DynamicReceiver<'static, Result<(ClassicFrame, Timestamp), BusError>>;
444 446
445impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> 447impl<'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
517pub type RxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, (FdFrame, Timestamp), BUF_SIZE>; 519pub 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
520pub type TxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, FdFrame, BUF_SIZE>; 523pub 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.
559pub type BufferedFdCanReceiver = embassy_sync::channel::DynamicReceiver<'static, (FdFrame, Timestamp)>; 562pub type BufferedFdCanReceiver =
563 embassy_sync::channel::DynamicReceiver<'static, Result<(FdFrame, Timestamp), BusError>>;
560 564
561impl<'c, 'd, T: Instance, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> 565impl<'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