aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2025-06-01 12:37:12 +0000
committerGitHub <[email protected]>2025-06-01 12:37:12 +0000
commitc637ee7d79552d9b9bfa0c0f4199372975acc343 (patch)
treea8ce06445ddaf61152fe8c7ac65ce596d0b18e38
parentd23d5d6a4ce44056d6340b37f6145a061f2f2889 (diff)
parent010744802fc4a1fda51f259cce874aac7294a79e (diff)
Merge pull request #4271 from cschuhen/fdcan_critical_section
Use a critical section mutex in CAN Fdcan driver.
-rw-r--r--embassy-stm32/src/can/common.rs14
-rw-r--r--embassy-stm32/src/can/fd/peripheral.rs17
-rw-r--r--embassy-stm32/src/can/fdcan.rs283
3 files changed, 132 insertions, 182 deletions
diff --git a/embassy-stm32/src/can/common.rs b/embassy-stm32/src/can/common.rs
index e12111910..386d4467c 100644
--- a/embassy-stm32/src/can/common.rs
+++ b/embassy-stm32/src/can/common.rs
@@ -1,29 +1,29 @@
1use embassy_sync::channel::{DynamicReceiver, DynamicSender}; 1use embassy_sync::channel::{SendDynamicReceiver, SendDynamicSender};
2 2
3use super::enums::*; 3use super::enums::*;
4use super::frame::*; 4use super::frame::*;
5 5
6pub(crate) struct ClassicBufferedRxInner { 6pub(crate) struct ClassicBufferedRxInner {
7 pub rx_sender: DynamicSender<'static, Result<Envelope, BusError>>, 7 pub rx_sender: SendDynamicSender<'static, Result<Envelope, BusError>>,
8} 8}
9pub(crate) struct ClassicBufferedTxInner { 9pub(crate) struct ClassicBufferedTxInner {
10 pub tx_receiver: DynamicReceiver<'static, Frame>, 10 pub tx_receiver: SendDynamicReceiver<'static, Frame>,
11} 11}
12 12
13#[cfg(any(can_fdcan_v1, can_fdcan_h7))] 13#[cfg(any(can_fdcan_v1, can_fdcan_h7))]
14 14
15pub(crate) struct FdBufferedRxInner { 15pub(crate) struct FdBufferedRxInner {
16 pub rx_sender: DynamicSender<'static, Result<FdEnvelope, BusError>>, 16 pub rx_sender: SendDynamicSender<'static, Result<FdEnvelope, BusError>>,
17} 17}
18 18
19#[cfg(any(can_fdcan_v1, can_fdcan_h7))] 19#[cfg(any(can_fdcan_v1, can_fdcan_h7))]
20pub(crate) struct FdBufferedTxInner { 20pub(crate) struct FdBufferedTxInner {
21 pub tx_receiver: DynamicReceiver<'static, FdFrame>, 21 pub tx_receiver: SendDynamicReceiver<'static, FdFrame>,
22} 22}
23 23
24/// Sender that can be used for sending CAN frames. 24/// Sender that can be used for sending CAN frames.
25pub struct BufferedSender<'ch, FRAME> { 25pub struct BufferedSender<'ch, FRAME> {
26 pub(crate) tx_buf: embassy_sync::channel::DynamicSender<'ch, FRAME>, 26 pub(crate) tx_buf: embassy_sync::channel::SendDynamicSender<'ch, FRAME>,
27 pub(crate) waker: fn(), 27 pub(crate) waker: fn(),
28 pub(crate) internal_operation: fn(InternalOperation), 28 pub(crate) internal_operation: fn(InternalOperation),
29} 29}
@@ -70,7 +70,7 @@ pub type BufferedCanSender = BufferedSender<'static, Frame>;
70 70
71/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver. 71/// Receiver that can be used for receiving CAN frames. Note, each CAN frame will only be received by one receiver.
72pub struct BufferedReceiver<'ch, ENVELOPE> { 72pub struct BufferedReceiver<'ch, ENVELOPE> {
73 pub(crate) rx_buf: embassy_sync::channel::DynamicReceiver<'ch, Result<ENVELOPE, BusError>>, 73 pub(crate) rx_buf: embassy_sync::channel::SendDynamicReceiver<'ch, Result<ENVELOPE, BusError>>,
74 pub(crate) internal_operation: fn(InternalOperation), 74 pub(crate) internal_operation: fn(InternalOperation),
75} 75}
76 76
diff --git a/embassy-stm32/src/can/fd/peripheral.rs b/embassy-stm32/src/can/fd/peripheral.rs
index 4873ee444..0a22f2c91 100644
--- a/embassy-stm32/src/can/fd/peripheral.rs
+++ b/embassy-stm32/src/can/fd/peripheral.rs
@@ -71,6 +71,23 @@ impl Registers {
71 } 71 }
72 } 72 }
73 73
74 #[cfg(feature = "time")]
75 pub fn calc_timestamp(&self, ns_per_timer_tick: u64, ts_val: u16) -> Timestamp {
76 let now_embassy = embassy_time::Instant::now();
77 if ns_per_timer_tick == 0 {
78 return now_embassy;
79 }
80 let cantime = { self.regs.tscv().read().tsc() };
81 let delta = cantime.overflowing_sub(ts_val).0 as u64;
82 let ns = ns_per_timer_tick * delta as u64;
83 now_embassy - embassy_time::Duration::from_nanos(ns)
84 }
85
86 #[cfg(not(feature = "time"))]
87 pub fn calc_timestamp(&self, _ns_per_timer_tick: u64, ts_val: u16) -> Timestamp {
88 ts_val
89 }
90
74 pub fn put_tx_frame(&self, bufidx: usize, header: &Header, buffer: &[u8]) { 91 pub fn put_tx_frame(&self, bufidx: usize, header: &Header, buffer: &[u8]) {
75 let mailbox = self.tx_buffer_element(bufidx); 92 let mailbox = self.tx_buffer_element(bufidx);
76 mailbox.reset(); 93 mailbox.reset();
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs
index a7815f79b..97d22315a 100644
--- a/embassy-stm32/src/can/fdcan.rs
+++ b/embassy-stm32/src/can/fdcan.rs
@@ -52,36 +52,39 @@ impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0Interrup
52 regs.ir().write(|w| w.set_tefn(true)); 52 regs.ir().write(|w| w.set_tefn(true));
53 } 53 }
54 54
55 match &T::state().tx_mode { 55 T::info().state.lock(|s| {
56 TxMode::NonBuffered(waker) => waker.wake(), 56 let state = s.borrow_mut();
57 TxMode::ClassicBuffered(buf) => { 57 match &state.tx_mode {
58 if !T::registers().tx_queue_is_full() { 58 TxMode::NonBuffered(waker) => waker.wake(),
59 match buf.tx_receiver.try_receive() { 59 TxMode::ClassicBuffered(buf) => {
60 Ok(frame) => { 60 if !T::registers().tx_queue_is_full() {
61 _ = T::registers().write(&frame); 61 match buf.tx_receiver.try_receive() {
62 Ok(frame) => {
63 _ = T::registers().write(&frame);
64 }
65 Err(_) => {}
62 } 66 }
63 Err(_) => {}
64 } 67 }
65 } 68 }
66 } 69 TxMode::FdBuffered(buf) => {
67 TxMode::FdBuffered(buf) => { 70 if !T::registers().tx_queue_is_full() {
68 if !T::registers().tx_queue_is_full() { 71 match buf.tx_receiver.try_receive() {
69 match buf.tx_receiver.try_receive() { 72 Ok(frame) => {
70 Ok(frame) => { 73 _ = T::registers().write(&frame);
71 _ = T::registers().write(&frame); 74 }
75 Err(_) => {}
72 } 76 }
73 Err(_) => {}
74 } 77 }
75 } 78 }
76 } 79 }
77 }
78 80
79 if ir.rfn(0) { 81 if ir.rfn(0) {
80 T::state().rx_mode.on_interrupt::<T>(0); 82 state.rx_mode.on_interrupt::<T>(0, state.ns_per_timer_tick);
81 } 83 }
82 if ir.rfn(1) { 84 if ir.rfn(1) {
83 T::state().rx_mode.on_interrupt::<T>(1); 85 state.rx_mode.on_interrupt::<T>(1, state.ns_per_timer_tick);
84 } 86 }
87 });
85 88
86 if ir.bo() { 89 if ir.bo() {
87 regs.ir().write(|w| w.set_bo(true)); 90 regs.ir().write(|w| w.set_bo(true));
@@ -165,7 +168,6 @@ pub struct CanConfigurator<'d> {
165 _phantom: PhantomData<&'d ()>, 168 _phantom: PhantomData<&'d ()>,
166 config: crate::can::fd::config::FdCanConfig, 169 config: crate::can::fd::config::FdCanConfig,
167 info: &'static Info, 170 info: &'static Info,
168 state: &'static State,
169 /// Reference to internals. 171 /// Reference to internals.
170 properties: Properties, 172 properties: Properties,
171 periph_clock: crate::time::Hertz, 173 periph_clock: crate::time::Hertz,
@@ -188,9 +190,10 @@ impl<'d> CanConfigurator<'d> {
188 rcc::enable_and_reset::<T>(); 190 rcc::enable_and_reset::<T>();
189 191
190 let info = T::info(); 192 let info = T::info();
191 let state = unsafe { T::mut_state() }; 193 T::info().state.lock(|s| {
192 state.tx_pin_port = Some(tx.pin_port()); 194 s.borrow_mut().tx_pin_port = Some(tx.pin_port());
193 state.rx_pin_port = Some(rx.pin_port()); 195 s.borrow_mut().rx_pin_port = Some(rx.pin_port());
196 });
194 (info.internal_operation)(InternalOperation::NotifySenderCreated); 197 (info.internal_operation)(InternalOperation::NotifySenderCreated);
195 (info.internal_operation)(InternalOperation::NotifyReceiverCreated); 198 (info.internal_operation)(InternalOperation::NotifyReceiverCreated);
196 199
@@ -209,7 +212,6 @@ impl<'d> CanConfigurator<'d> {
209 _phantom: PhantomData, 212 _phantom: PhantomData,
210 config, 213 config,
211 info, 214 info,
212 state,
213 properties: Properties::new(T::info()), 215 properties: Properties::new(T::info()),
214 periph_clock: T::frequency(), 216 periph_clock: T::frequency(),
215 } 217 }
@@ -261,12 +263,8 @@ impl<'d> CanConfigurator<'d> {
261 /// Start in mode. 263 /// Start in mode.
262 pub fn start(self, mode: OperatingMode) -> Can<'d> { 264 pub fn start(self, mode: OperatingMode) -> Can<'d> {
263 let ns_per_timer_tick = calc_ns_per_timer_tick(self.info, self.periph_clock, self.config.frame_transmit); 265 let ns_per_timer_tick = calc_ns_per_timer_tick(self.info, self.periph_clock, self.config.frame_transmit);
264 critical_section::with(|_| { 266 self.info.state.lock(|s| {
265 let state = self.state as *const State; 267 s.borrow_mut().ns_per_timer_tick = ns_per_timer_tick;
266 unsafe {
267 let mut_state = state as *mut State;
268 (*mut_state).ns_per_timer_tick = ns_per_timer_tick;
269 }
270 }); 268 });
271 self.info.regs.into_mode(self.config, mode); 269 self.info.regs.into_mode(self.config, mode);
272 (self.info.internal_operation)(InternalOperation::NotifySenderCreated); 270 (self.info.internal_operation)(InternalOperation::NotifySenderCreated);
@@ -275,7 +273,6 @@ impl<'d> CanConfigurator<'d> {
275 _phantom: PhantomData, 273 _phantom: PhantomData,
276 config: self.config, 274 config: self.config,
277 info: self.info, 275 info: self.info,
278 state: self.state,
279 _mode: mode, 276 _mode: mode,
280 properties: Properties::new(self.info), 277 properties: Properties::new(self.info),
281 } 278 }
@@ -309,7 +306,6 @@ pub struct Can<'d> {
309 _phantom: PhantomData<&'d ()>, 306 _phantom: PhantomData<&'d ()>,
310 config: crate::can::fd::config::FdCanConfig, 307 config: crate::can::fd::config::FdCanConfig,
311 info: &'static Info, 308 info: &'static Info,
312 state: &'static State,
313 _mode: OperatingMode, 309 _mode: OperatingMode,
314 properties: Properties, 310 properties: Properties,
315} 311}
@@ -323,7 +319,9 @@ impl<'d> Can<'d> {
323 /// Flush one of the TX mailboxes. 319 /// Flush one of the TX mailboxes.
324 pub async fn flush(&self, idx: usize) { 320 pub async fn flush(&self, idx: usize) {
325 poll_fn(|cx| { 321 poll_fn(|cx| {
326 self.state.tx_mode.register(cx.waker()); 322 self.info.state.lock(|s| {
323 s.borrow_mut().tx_mode.register(cx.waker());
324 });
327 325
328 if idx > 3 { 326 if idx > 3 {
329 panic!("Bad mailbox"); 327 panic!("Bad mailbox");
@@ -343,12 +341,12 @@ impl<'d> Can<'d> {
343 /// can be replaced, this call asynchronously waits for a frame to be successfully 341 /// can be replaced, this call asynchronously waits for a frame to be successfully
344 /// transmitted, then tries again. 342 /// transmitted, then tries again.
345 pub async fn write(&mut self, frame: &Frame) -> Option<Frame> { 343 pub async fn write(&mut self, frame: &Frame) -> Option<Frame> {
346 self.state.tx_mode.write(self.info, frame).await 344 TxMode::write(self.info, frame).await
347 } 345 }
348 346
349 /// Returns the next received message frame 347 /// Returns the next received message frame
350 pub async fn read(&mut self) -> Result<Envelope, BusError> { 348 pub async fn read(&mut self) -> Result<Envelope, BusError> {
351 self.state.rx_mode.read_classic(self.info, self.state).await 349 RxMode::read_classic(self.info).await
352 } 350 }
353 351
354 /// Queues the message to be sent but exerts backpressure. If a lower-priority 352 /// Queues the message to be sent but exerts backpressure. If a lower-priority
@@ -356,12 +354,12 @@ impl<'d> Can<'d> {
356 /// can be replaced, this call asynchronously waits for a frame to be successfully 354 /// can be replaced, this call asynchronously waits for a frame to be successfully
357 /// transmitted, then tries again. 355 /// transmitted, then tries again.
358 pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> { 356 pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> {
359 self.state.tx_mode.write_fd(self.info, frame).await 357 TxMode::write_fd(self.info, frame).await
360 } 358 }
361 359
362 /// Returns the next received message frame 360 /// Returns the next received message frame
363 pub async fn read_fd(&mut self) -> Result<FdEnvelope, BusError> { 361 pub async fn read_fd(&mut self) -> Result<FdEnvelope, BusError> {
364 self.state.rx_mode.read_fd(self.info, self.state).await 362 RxMode::read_fd(self.info).await
365 } 363 }
366 364
367 /// Split instance into separate portions: Tx(write), Rx(read), common properties 365 /// Split instance into separate portions: Tx(write), Rx(read), common properties
@@ -372,14 +370,12 @@ impl<'d> Can<'d> {
372 CanTx { 370 CanTx {
373 _phantom: PhantomData, 371 _phantom: PhantomData,
374 info: self.info, 372 info: self.info,
375 state: self.state,
376 config: self.config, 373 config: self.config,
377 _mode: self._mode, 374 _mode: self._mode,
378 }, 375 },
379 CanRx { 376 CanRx {
380 _phantom: PhantomData, 377 _phantom: PhantomData,
381 info: self.info, 378 info: self.info,
382 state: self.state,
383 _mode: self._mode, 379 _mode: self._mode,
384 }, 380 },
385 Properties { 381 Properties {
@@ -395,7 +391,6 @@ impl<'d> Can<'d> {
395 _phantom: PhantomData, 391 _phantom: PhantomData,
396 config: tx.config, 392 config: tx.config,
397 info: tx.info, 393 info: tx.info,
398 state: tx.state,
399 _mode: rx._mode, 394 _mode: rx._mode,
400 properties: Properties::new(tx.info), 395 properties: Properties::new(tx.info),
401 } 396 }
@@ -407,7 +402,7 @@ impl<'d> Can<'d> {
407 tx_buf: &'static mut TxBuf<TX_BUF_SIZE>, 402 tx_buf: &'static mut TxBuf<TX_BUF_SIZE>,
408 rxb: &'static mut RxBuf<RX_BUF_SIZE>, 403 rxb: &'static mut RxBuf<RX_BUF_SIZE>,
409 ) -> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> { 404 ) -> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
410 BufferedCan::new(self.info, self.state, self._mode, tx_buf, rxb) 405 BufferedCan::new(self.info, self._mode, tx_buf, rxb)
411 } 406 }
412 407
413 /// Return a buffered instance of driver with CAN FD support. User must supply Buffers 408 /// Return a buffered instance of driver with CAN FD support. User must supply Buffers
@@ -416,7 +411,7 @@ impl<'d> Can<'d> {
416 tx_buf: &'static mut TxFdBuf<TX_BUF_SIZE>, 411 tx_buf: &'static mut TxFdBuf<TX_BUF_SIZE>,
417 rxb: &'static mut RxFdBuf<RX_BUF_SIZE>, 412 rxb: &'static mut RxFdBuf<RX_BUF_SIZE>,
418 ) -> BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> { 413 ) -> BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
419 BufferedCanFd::new(self.info, self.state, self._mode, tx_buf, rxb) 414 BufferedCanFd::new(self.info, self._mode, tx_buf, rxb)
420 } 415 }
421} 416}
422 417
@@ -437,7 +432,6 @@ pub type TxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Frame,
437pub struct BufferedCan<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> { 432pub struct BufferedCan<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> {
438 _phantom: PhantomData<&'d ()>, 433 _phantom: PhantomData<&'d ()>,
439 info: &'static Info, 434 info: &'static Info,
440 state: &'static State,
441 _mode: OperatingMode, 435 _mode: OperatingMode,
442 tx_buf: &'static TxBuf<TX_BUF_SIZE>, 436 tx_buf: &'static TxBuf<TX_BUF_SIZE>,
443 rx_buf: &'static RxBuf<RX_BUF_SIZE>, 437 rx_buf: &'static RxBuf<RX_BUF_SIZE>,
@@ -447,7 +441,6 @@ pub struct BufferedCan<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> {
447impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> { 441impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
448 fn new( 442 fn new(
449 info: &'static Info, 443 info: &'static Info,
450 state: &'static State,
451 _mode: OperatingMode, 444 _mode: OperatingMode,
452 tx_buf: &'static TxBuf<TX_BUF_SIZE>, 445 tx_buf: &'static TxBuf<TX_BUF_SIZE>,
453 rx_buf: &'static RxBuf<RX_BUF_SIZE>, 446 rx_buf: &'static RxBuf<RX_BUF_SIZE>,
@@ -457,7 +450,6 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d,
457 BufferedCan { 450 BufferedCan {
458 _phantom: PhantomData, 451 _phantom: PhantomData,
459 info, 452 info,
460 state,
461 _mode, 453 _mode,
462 tx_buf, 454 tx_buf,
463 rx_buf, 455 rx_buf,
@@ -473,19 +465,15 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d,
473 465
474 fn setup(self) -> Self { 466 fn setup(self) -> Self {
475 // We don't want interrupts being processed while we change modes. 467 // We don't want interrupts being processed while we change modes.
476 critical_section::with(|_| { 468 self.info.state.lock(|s| {
477 let rx_inner = super::common::ClassicBufferedRxInner { 469 let rx_inner = super::common::ClassicBufferedRxInner {
478 rx_sender: self.rx_buf.sender().into(), 470 rx_sender: self.rx_buf.sender().into(),
479 }; 471 };
480 let tx_inner = super::common::ClassicBufferedTxInner { 472 let tx_inner = super::common::ClassicBufferedTxInner {
481 tx_receiver: self.tx_buf.receiver().into(), 473 tx_receiver: self.tx_buf.receiver().into(),
482 }; 474 };
483 let state = self.state as *const State; 475 s.borrow_mut().rx_mode = RxMode::ClassicBuffered(rx_inner);
484 unsafe { 476 s.borrow_mut().tx_mode = TxMode::ClassicBuffered(tx_inner);
485 let mut_state = state as *mut State;
486 (*mut_state).rx_mode = RxMode::ClassicBuffered(rx_inner);
487 (*mut_state).tx_mode = TxMode::ClassicBuffered(tx_inner);
488 }
489 }); 477 });
490 self 478 self
491 } 479 }
@@ -545,7 +533,6 @@ pub type BufferedFdCanReceiver = super::common::BufferedReceiver<'static, FdEnve
545pub struct BufferedCanFd<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> { 533pub struct BufferedCanFd<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> {
546 _phantom: PhantomData<&'d ()>, 534 _phantom: PhantomData<&'d ()>,
547 info: &'static Info, 535 info: &'static Info,
548 state: &'static State,
549 _mode: OperatingMode, 536 _mode: OperatingMode,
550 tx_buf: &'static TxFdBuf<TX_BUF_SIZE>, 537 tx_buf: &'static TxFdBuf<TX_BUF_SIZE>,
551 rx_buf: &'static RxFdBuf<RX_BUF_SIZE>, 538 rx_buf: &'static RxFdBuf<RX_BUF_SIZE>,
@@ -555,7 +542,6 @@ pub struct BufferedCanFd<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>
555impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> { 542impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
556 fn new( 543 fn new(
557 info: &'static Info, 544 info: &'static Info,
558 state: &'static State,
559 _mode: OperatingMode, 545 _mode: OperatingMode,
560 tx_buf: &'static TxFdBuf<TX_BUF_SIZE>, 546 tx_buf: &'static TxFdBuf<TX_BUF_SIZE>,
561 rx_buf: &'static RxFdBuf<RX_BUF_SIZE>, 547 rx_buf: &'static RxFdBuf<RX_BUF_SIZE>,
@@ -565,7 +551,6 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'
565 BufferedCanFd { 551 BufferedCanFd {
566 _phantom: PhantomData, 552 _phantom: PhantomData,
567 info, 553 info,
568 state,
569 _mode, 554 _mode,
570 tx_buf, 555 tx_buf,
571 rx_buf, 556 rx_buf,
@@ -581,19 +566,15 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'
581 566
582 fn setup(self) -> Self { 567 fn setup(self) -> Self {
583 // We don't want interrupts being processed while we change modes. 568 // We don't want interrupts being processed while we change modes.
584 critical_section::with(|_| { 569 self.info.state.lock(|s| {
585 let rx_inner = super::common::FdBufferedRxInner { 570 let rx_inner = super::common::FdBufferedRxInner {
586 rx_sender: self.rx_buf.sender().into(), 571 rx_sender: self.rx_buf.sender().into(),
587 }; 572 };
588 let tx_inner = super::common::FdBufferedTxInner { 573 let tx_inner = super::common::FdBufferedTxInner {
589 tx_receiver: self.tx_buf.receiver().into(), 574 tx_receiver: self.tx_buf.receiver().into(),
590 }; 575 };
591 let state = self.state as *const State; 576 s.borrow_mut().rx_mode = RxMode::FdBuffered(rx_inner);
592 unsafe { 577 s.borrow_mut().tx_mode = TxMode::FdBuffered(tx_inner);
593 let mut_state = state as *mut State;
594 (*mut_state).rx_mode = RxMode::FdBuffered(rx_inner);
595 (*mut_state).tx_mode = TxMode::FdBuffered(tx_inner);
596 }
597 }); 578 });
598 self 579 self
599 } 580 }
@@ -641,19 +622,18 @@ impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop for Buffer
641pub struct CanRx<'d> { 622pub struct CanRx<'d> {
642 _phantom: PhantomData<&'d ()>, 623 _phantom: PhantomData<&'d ()>,
643 info: &'static Info, 624 info: &'static Info,
644 state: &'static State,
645 _mode: OperatingMode, 625 _mode: OperatingMode,
646} 626}
647 627
648impl<'d> CanRx<'d> { 628impl<'d> CanRx<'d> {
649 /// Returns the next received message frame 629 /// Returns the next received message frame
650 pub async fn read(&mut self) -> Result<Envelope, BusError> { 630 pub async fn read(&mut self) -> Result<Envelope, BusError> {
651 self.state.rx_mode.read_classic(&self.info, &self.state).await 631 RxMode::read_classic(&self.info).await
652 } 632 }
653 633
654 /// Returns the next received message frame 634 /// Returns the next received message frame
655 pub async fn read_fd(&mut self) -> Result<FdEnvelope, BusError> { 635 pub async fn read_fd(&mut self) -> Result<FdEnvelope, BusError> {
656 self.state.rx_mode.read_fd(&self.info, &self.state).await 636 RxMode::read_fd(&self.info).await
657 } 637 }
658} 638}
659 639
@@ -667,7 +647,6 @@ impl<'d> Drop for CanRx<'d> {
667pub struct CanTx<'d> { 647pub struct CanTx<'d> {
668 _phantom: PhantomData<&'d ()>, 648 _phantom: PhantomData<&'d ()>,
669 info: &'static Info, 649 info: &'static Info,
670 state: &'static State,
671 config: crate::can::fd::config::FdCanConfig, 650 config: crate::can::fd::config::FdCanConfig,
672 _mode: OperatingMode, 651 _mode: OperatingMode,
673} 652}
@@ -678,7 +657,7 @@ impl<'c, 'd> CanTx<'d> {
678 /// can be replaced, this call asynchronously waits for a frame to be successfully 657 /// can be replaced, this call asynchronously waits for a frame to be successfully
679 /// transmitted, then tries again. 658 /// transmitted, then tries again.
680 pub async fn write(&mut self, frame: &Frame) -> Option<Frame> { 659 pub async fn write(&mut self, frame: &Frame) -> Option<Frame> {
681 self.state.tx_mode.write(self.info, frame).await 660 TxMode::write(self.info, frame).await
682 } 661 }
683 662
684 /// Queues the message to be sent but exerts backpressure. If a lower-priority 663 /// Queues the message to be sent but exerts backpressure. If a lower-priority
@@ -686,7 +665,7 @@ impl<'c, 'd> CanTx<'d> {
686 /// can be replaced, this call asynchronously waits for a frame to be successfully 665 /// can be replaced, this call asynchronously waits for a frame to be successfully
687 /// transmitted, then tries again. 666 /// transmitted, then tries again.
688 pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> { 667 pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> {
689 self.state.tx_mode.write_fd(self.info, frame).await 668 TxMode::write_fd(self.info, frame).await
690 } 669 }
691} 670}
692 671
@@ -712,19 +691,19 @@ impl RxMode {
712 } 691 }
713 } 692 }
714 693
715 fn on_interrupt<T: Instance>(&self, fifonr: usize) { 694 fn on_interrupt<T: Instance>(&self, fifonr: usize, ns_per_timer_tick: u64) {
716 T::registers().regs.ir().write(|w| w.set_rfn(fifonr, true)); 695 T::registers().regs.ir().write(|w| w.set_rfn(fifonr, true));
717 match self { 696 match self {
718 RxMode::NonBuffered(waker) => { 697 RxMode::NonBuffered(waker) => {
719 waker.wake(); 698 waker.wake();
720 } 699 }
721 RxMode::ClassicBuffered(buf) => { 700 RxMode::ClassicBuffered(buf) => {
722 if let Some(result) = self.try_read::<T>() { 701 if let Some(result) = self.try_read::<T>(ns_per_timer_tick) {
723 let _ = buf.rx_sender.try_send(result); 702 let _ = buf.rx_sender.try_send(result);
724 } 703 }
725 } 704 }
726 RxMode::FdBuffered(buf) => { 705 RxMode::FdBuffered(buf) => {
727 if let Some(result) = self.try_read_fd::<T>() { 706 if let Some(result) = self.try_read_fd::<T>(ns_per_timer_tick) {
728 let _ = buf.rx_sender.try_send(result); 707 let _ = buf.rx_sender.try_send(result);
729 } 708 }
730 } 709 }
@@ -732,12 +711,12 @@ impl RxMode {
732 } 711 }
733 712
734 //async fn read_classic<T: Instance>(&self) -> Result<Envelope, BusError> { 713 //async fn read_classic<T: Instance>(&self) -> Result<Envelope, BusError> {
735 fn try_read<T: Instance>(&self) -> Option<Result<Envelope, BusError>> { 714 fn try_read<T: Instance>(&self, ns_per_timer_tick: u64) -> Option<Result<Envelope, BusError>> {
736 if let Some((frame, ts)) = T::registers().read(0) { 715 if let Some((frame, ts)) = T::registers().read(0) {
737 let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts); 716 let ts = T::registers().calc_timestamp(ns_per_timer_tick, ts);
738 Some(Ok(Envelope { ts, frame })) 717 Some(Ok(Envelope { ts, frame }))
739 } else if let Some((frame, ts)) = T::registers().read(1) { 718 } else if let Some((frame, ts)) = T::registers().read(1) {
740 let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts); 719 let ts = T::registers().calc_timestamp(ns_per_timer_tick, ts);
741 Some(Ok(Envelope { ts, frame })) 720 Some(Ok(Envelope { ts, frame }))
742 } else if let Some(err) = T::registers().curr_error() { 721 } else if let Some(err) = T::registers().curr_error() {
743 // TODO: this is probably wrong 722 // TODO: this is probably wrong
@@ -747,12 +726,12 @@ impl RxMode {
747 } 726 }
748 } 727 }
749 728
750 fn try_read_fd<T: Instance>(&self) -> Option<Result<FdEnvelope, BusError>> { 729 fn try_read_fd<T: Instance>(&self, ns_per_timer_tick: u64) -> Option<Result<FdEnvelope, BusError>> {
751 if let Some((frame, ts)) = T::registers().read(0) { 730 if let Some((frame, ts)) = T::registers().read(0) {
752 let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts); 731 let ts = T::registers().calc_timestamp(ns_per_timer_tick, ts);
753 Some(Ok(FdEnvelope { ts, frame })) 732 Some(Ok(FdEnvelope { ts, frame }))
754 } else if let Some((frame, ts)) = T::registers().read(1) { 733 } else if let Some((frame, ts)) = T::registers().read(1) {
755 let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts); 734 let ts = T::registers().calc_timestamp(ns_per_timer_tick, ts);
756 Some(Ok(FdEnvelope { ts, frame })) 735 Some(Ok(FdEnvelope { ts, frame }))
757 } else if let Some(err) = T::registers().curr_error() { 736 } else if let Some(err) = T::registers().curr_error() {
758 // TODO: this is probably wrong 737 // TODO: this is probably wrong
@@ -762,16 +741,12 @@ impl RxMode {
762 } 741 }
763 } 742 }
764 743
765 fn read<F: CanHeader>( 744 fn read<F: CanHeader>(info: &'static Info, ns_per_timer_tick: u64) -> Option<Result<(F, Timestamp), BusError>> {
766 &self,
767 info: &'static Info,
768 state: &'static State,
769 ) -> Option<Result<(F, Timestamp), BusError>> {
770 if let Some((msg, ts)) = info.regs.read(0) { 745 if let Some((msg, ts)) = info.regs.read(0) {
771 let ts = info.calc_timestamp(state.ns_per_timer_tick, ts); 746 let ts = info.regs.calc_timestamp(ns_per_timer_tick, ts);
772 Some(Ok((msg, ts))) 747 Some(Ok((msg, ts)))
773 } else if let Some((msg, ts)) = info.regs.read(1) { 748 } else if let Some((msg, ts)) = info.regs.read(1) {
774 let ts = info.calc_timestamp(state.ns_per_timer_tick, ts); 749 let ts = info.regs.calc_timestamp(ns_per_timer_tick, ts);
775 Some(Ok((msg, ts))) 750 Some(Ok((msg, ts)))
776 } else if let Some(err) = info.regs.curr_error() { 751 } else if let Some(err) = info.regs.curr_error() {
777 // TODO: this is probably wrong 752 // TODO: this is probably wrong
@@ -781,16 +756,15 @@ impl RxMode {
781 } 756 }
782 } 757 }
783 758
784 async fn read_async<F: CanHeader>( 759 async fn read_async<F: CanHeader>(info: &'static Info) -> Result<(F, Timestamp), BusError> {
785 &self,
786 info: &'static Info,
787 state: &'static State,
788 ) -> Result<(F, Timestamp), BusError> {
789 //let _ = self.read::<F>(info, state);
790 poll_fn(move |cx| { 760 poll_fn(move |cx| {
791 state.err_waker.register(cx.waker()); 761 let ns_per_timer_tick = info.state.lock(|s| {
792 self.register(cx.waker()); 762 let state = s.borrow_mut();
793 match self.read::<_>(info, state) { 763 state.err_waker.register(cx.waker());
764 state.rx_mode.register(cx.waker());
765 state.ns_per_timer_tick
766 });
767 match RxMode::read::<_>(info, ns_per_timer_tick) {
794 Some(result) => Poll::Ready(result), 768 Some(result) => Poll::Ready(result),
795 None => Poll::Pending, 769 None => Poll::Pending,
796 } 770 }
@@ -798,15 +772,15 @@ impl RxMode {
798 .await 772 .await
799 } 773 }
800 774
801 async fn read_classic(&self, info: &'static Info, state: &'static State) -> Result<Envelope, BusError> { 775 async fn read_classic(info: &'static Info) -> Result<Envelope, BusError> {
802 match self.read_async::<_>(info, state).await { 776 match RxMode::read_async::<_>(info).await {
803 Ok((frame, ts)) => Ok(Envelope { ts, frame }), 777 Ok((frame, ts)) => Ok(Envelope { ts, frame }),
804 Err(e) => Err(e), 778 Err(e) => Err(e),
805 } 779 }
806 } 780 }
807 781
808 async fn read_fd(&self, info: &'static Info, state: &'static State) -> Result<FdEnvelope, BusError> { 782 async fn read_fd(info: &'static Info) -> Result<FdEnvelope, BusError> {
809 match self.read_async::<_>(info, state).await { 783 match RxMode::read_async::<_>(info).await {
810 Ok((frame, ts)) => Ok(FdEnvelope { ts, frame }), 784 Ok((frame, ts)) => Ok(FdEnvelope { ts, frame }),
811 Err(e) => Err(e), 785 Err(e) => Err(e),
812 } 786 }
@@ -835,9 +809,11 @@ impl TxMode {
835 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames 809 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames
836 /// can be replaced, this call asynchronously waits for a frame to be successfully 810 /// can be replaced, this call asynchronously waits for a frame to be successfully
837 /// transmitted, then tries again. 811 /// transmitted, then tries again.
838 async fn write_generic<F: embedded_can::Frame + CanHeader>(&self, info: &'static Info, frame: &F) -> Option<F> { 812 async fn write_generic<F: embedded_can::Frame + CanHeader>(info: &'static Info, frame: &F) -> Option<F> {
839 poll_fn(|cx| { 813 poll_fn(|cx| {
840 self.register(cx.waker()); 814 info.state.lock(|s| {
815 s.borrow_mut().tx_mode.register(cx.waker());
816 });
841 817
842 if let Ok(dropped) = info.regs.write(frame) { 818 if let Ok(dropped) = info.regs.write(frame) {
843 return Poll::Ready(dropped); 819 return Poll::Ready(dropped);
@@ -854,16 +830,16 @@ impl TxMode {
854 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames 830 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames
855 /// can be replaced, this call asynchronously waits for a frame to be successfully 831 /// can be replaced, this call asynchronously waits for a frame to be successfully
856 /// transmitted, then tries again. 832 /// transmitted, then tries again.
857 async fn write(&self, info: &'static Info, frame: &Frame) -> Option<Frame> { 833 async fn write(info: &'static Info, frame: &Frame) -> Option<Frame> {
858 self.write_generic::<_>(info, frame).await 834 TxMode::write_generic::<_>(info, frame).await
859 } 835 }
860 836
861 /// Queues the message to be sent but exerts backpressure. If a lower-priority 837 /// Queues the message to be sent but exerts backpressure. If a lower-priority
862 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames 838 /// frame is dropped from the mailbox, it is returned. If no lower-priority frames
863 /// can be replaced, this call asynchronously waits for a frame to be successfully 839 /// can be replaced, this call asynchronously waits for a frame to be successfully
864 /// transmitted, then tries again. 840 /// transmitted, then tries again.
865 async fn write_fd(&self, info: &'static Info, frame: &FdFrame) -> Option<FdFrame> { 841 async fn write_fd(info: &'static Info, frame: &FdFrame) -> Option<FdFrame> {
866 self.write_generic::<_>(info, frame).await 842 TxMode::write_generic::<_>(info, frame).await
867 } 843 }
868} 844}
869 845
@@ -961,31 +937,14 @@ impl State {
961 } 937 }
962} 938}
963 939
940type SharedState = embassy_sync::blocking_mutex::Mutex<CriticalSectionRawMutex, core::cell::RefCell<State>>;
964struct Info { 941struct Info {
965 regs: Registers, 942 regs: Registers,
966 interrupt0: crate::interrupt::Interrupt, 943 interrupt0: crate::interrupt::Interrupt,
967 _interrupt1: crate::interrupt::Interrupt, 944 _interrupt1: crate::interrupt::Interrupt,
968 tx_waker: fn(), 945 tx_waker: fn(),
969 internal_operation: fn(InternalOperation), 946 internal_operation: fn(InternalOperation),
970} 947 state: SharedState,
971
972impl Info {
973 #[cfg(feature = "time")]
974 fn calc_timestamp(&self, ns_per_timer_tick: u64, ts_val: u16) -> Timestamp {
975 let now_embassy = embassy_time::Instant::now();
976 if ns_per_timer_tick == 0 {
977 return now_embassy;
978 }
979 let cantime = { self.regs.regs.tscv().read().tsc() };
980 let delta = cantime.overflowing_sub(ts_val).0 as u64;
981 let ns = ns_per_timer_tick * delta as u64;
982 now_embassy - embassy_time::Duration::from_nanos(ns)
983 }
984
985 #[cfg(not(feature = "time"))]
986 fn calc_timestamp(&self, _ns_per_timer_tick: u64, ts_val: u16) -> Timestamp {
987 ts_val
988 }
989} 948}
990 949
991trait SealedInstance { 950trait SealedInstance {
@@ -993,10 +952,7 @@ trait SealedInstance {
993 952
994 fn info() -> &'static Info; 953 fn info() -> &'static Info;
995 fn registers() -> crate::can::fd::peripheral::Registers; 954 fn registers() -> crate::can::fd::peripheral::Registers;
996 fn state() -> &'static State;
997 unsafe fn mut_state() -> &'static mut State;
998 fn internal_operation(val: InternalOperation); 955 fn internal_operation(val: InternalOperation);
999 fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp;
1000} 956}
1001 957
1002/// Instance trait 958/// Instance trait
@@ -1019,32 +975,30 @@ macro_rules! impl_fdcan {
1019 const MSG_RAM_OFFSET: usize = $msg_ram_offset; 975 const MSG_RAM_OFFSET: usize = $msg_ram_offset;
1020 976
1021 fn internal_operation(val: InternalOperation) { 977 fn internal_operation(val: InternalOperation) {
1022 critical_section::with(|_| { 978 peripherals::$inst::info().state.lock(|s| {
1023 //let state = self.state as *const State; 979 let mut mut_state = s.borrow_mut();
1024 unsafe { 980 match val {
1025 //let mut_state = state as *mut State; 981 InternalOperation::NotifySenderCreated => {
1026 let mut_state = peripherals::$inst::mut_state(); 982 mut_state.sender_instance_count += 1;
1027 match val { 983 }
1028 InternalOperation::NotifySenderCreated => { 984 InternalOperation::NotifySenderDestroyed => {
1029 mut_state.sender_instance_count += 1; 985 mut_state.sender_instance_count -= 1;
1030 } 986 if ( 0 == mut_state.sender_instance_count) {
1031 InternalOperation::NotifySenderDestroyed => { 987 (*mut_state).tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
1032 mut_state.sender_instance_count -= 1;
1033 if ( 0 == mut_state.sender_instance_count) {
1034 (*mut_state).tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
1035 }
1036 }
1037 InternalOperation::NotifyReceiverCreated => {
1038 mut_state.receiver_instance_count += 1;
1039 } 988 }
1040 InternalOperation::NotifyReceiverDestroyed => { 989 }
1041 mut_state.receiver_instance_count -= 1; 990 InternalOperation::NotifyReceiverCreated => {
1042 if ( 0 == mut_state.receiver_instance_count) { 991 mut_state.receiver_instance_count += 1;
1043 (*mut_state).rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new()); 992 }
1044 } 993 InternalOperation::NotifyReceiverDestroyed => {
994 mut_state.receiver_instance_count -= 1;
995 if ( 0 == mut_state.receiver_instance_count) {
996 (*mut_state).rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
1045 } 997 }
1046 } 998 }
1047 if mut_state.sender_instance_count == 0 && mut_state.receiver_instance_count == 0 { 999 }
1000 if mut_state.sender_instance_count == 0 && mut_state.receiver_instance_count == 0 {
1001 unsafe {
1048 let tx_pin = crate::gpio::AnyPin::steal(mut_state.tx_pin_port.unwrap()); 1002 let tx_pin = crate::gpio::AnyPin::steal(mut_state.tx_pin_port.unwrap());
1049 tx_pin.set_as_disconnected(); 1003 tx_pin.set_as_disconnected();
1050 let rx_pin = crate::gpio::AnyPin::steal(mut_state.rx_pin_port.unwrap()); 1004 let rx_pin = crate::gpio::AnyPin::steal(mut_state.rx_pin_port.unwrap());
@@ -1054,43 +1008,22 @@ macro_rules! impl_fdcan {
1054 } 1008 }
1055 }); 1009 });
1056 } 1010 }
1011
1057 fn info() -> &'static Info { 1012 fn info() -> &'static Info {
1013
1058 static INFO: Info = Info { 1014 static INFO: Info = Info {
1059 regs: Registers{regs: crate::pac::$inst, msgram: crate::pac::$msg_ram_inst, msg_ram_offset: $msg_ram_offset}, 1015 regs: Registers{regs: crate::pac::$inst, msgram: crate::pac::$msg_ram_inst, msg_ram_offset: $msg_ram_offset},
1060 interrupt0: crate::_generated::peripheral_interrupts::$inst::IT0::IRQ, 1016 interrupt0: crate::_generated::peripheral_interrupts::$inst::IT0::IRQ,
1061 _interrupt1: crate::_generated::peripheral_interrupts::$inst::IT1::IRQ, 1017 _interrupt1: crate::_generated::peripheral_interrupts::$inst::IT1::IRQ,
1062 tx_waker: crate::_generated::peripheral_interrupts::$inst::IT0::pend, 1018 tx_waker: crate::_generated::peripheral_interrupts::$inst::IT0::pend,
1063 internal_operation: peripherals::$inst::internal_operation, 1019 internal_operation: peripherals::$inst::internal_operation,
1020 state: embassy_sync::blocking_mutex::Mutex::new(core::cell::RefCell::new(State::new())),
1064 }; 1021 };
1065 &INFO 1022 &INFO
1066 } 1023 }
1067 fn registers() -> Registers { 1024 fn registers() -> Registers {
1068 Registers{regs: crate::pac::$inst, msgram: crate::pac::$msg_ram_inst, msg_ram_offset: Self::MSG_RAM_OFFSET} 1025 Registers{regs: crate::pac::$inst, msgram: crate::pac::$msg_ram_inst, msg_ram_offset: Self::MSG_RAM_OFFSET}
1069 } 1026 }
1070 unsafe fn mut_state() -> &'static mut State {
1071 static mut STATE: State = State::new();
1072 &mut *core::ptr::addr_of_mut!(STATE)
1073 }
1074 fn state() -> &'static State {
1075 unsafe { peripherals::$inst::mut_state() }
1076 }
1077
1078 #[cfg(feature = "time")]
1079 fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp {
1080 let now_embassy = embassy_time::Instant::now();
1081 if ns_per_timer_tick == 0 {
1082 return now_embassy;
1083 }
1084 let cantime = { Self::registers().regs.tscv().read().tsc() };
1085 let delta = cantime.overflowing_sub(ts_val).0 as u64;
1086 let ns = ns_per_timer_tick * delta as u64;
1087 now_embassy - embassy_time::Duration::from_nanos(ns)
1088 }
1089
1090 #[cfg(not(feature = "time"))]
1091 fn calc_timestamp(_ns_per_timer_tick: u64, ts_val: u16) -> Timestamp {
1092 ts_val
1093 }
1094 1027
1095 } 1028 }
1096 1029