1#[allow(unused_variables)]
2use core::future::poll_fn;
3use core::marker::PhantomData;
4use core::task::Poll;
5
6use embassy_hal_internal::interrupt::InterruptExt;
7use embassy_hal_internal::{into_ref, PeripheralRef};
8use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
9use embassy_sync::channel::{Channel, DynamicReceiver, DynamicSender};
10use embassy_sync::waitqueue::AtomicWaker;
11
12use crate::can::fd::peripheral::Registers;
13use crate::gpio::{AfType, OutputType, Pull, Speed};
14use crate::interrupt::typelevel::Interrupt;
15use crate::rcc::{self, RccPeripheral};
16use crate::{interrupt, peripherals, Peripheral};
17
18pub(crate) mod fd;
19
20use self::fd::config::*;
21use self::fd::filter::*;
22pub use self::fd::{config, filter};
23pub use super::common::{BufferedCanReceiver, BufferedCanSender};
24use super::enums::*;
25use super::frame::*;
26use super::util;
27
28#[cfg(feature = "time")]
30pub type Timestamp = embassy_time::Instant;
31
32#[cfg(not(feature = "time"))]
34pub type Timestamp = u16;
35
36pub struct IT0InterruptHandler<T: Instance> {
38 _phantom: PhantomData<T>,
39}
40
41impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0InterruptHandler<T> {
43 unsafe fn on_interrupt() {
44 let regs = T::registers().regs;
45
46 let ir = regs.ir().read();
47
48 if ir.tc() {
49 regs.ir().write(|w| w.set_tc(true));
50 }
51 if ir.tefn() {
52 regs.ir().write(|w| w.set_tefn(true));
53 }
54
55 match &T::state().tx_mode {
56 TxMode::NonBuffered(waker) => waker.wake(),
57 TxMode::ClassicBuffered(buf) => {
58 if !T::registers().tx_queue_is_full() {
59 match buf.tx_receiver.try_receive() {
60 Ok(frame) => {
61 _ = T::registers().write(&frame);
62 }
63 Err(_) => {}
64 }
65 }
66 }
67 TxMode::FdBuffered(buf) => {
68 if !T::registers().tx_queue_is_full() {
69 match buf.tx_receiver.try_receive() {
70 Ok(frame) => {
71 _ = T::registers().write(&frame);
72 }
73 Err(_) => {}
74 }
75 }
76 }
77 }
78
79 if ir.rfn(0) {
80 T::state().rx_mode.on_interrupt::<T>(0);
81 }
82 if ir.rfn(1) {
83 T::state().rx_mode.on_interrupt::<T>(1);
84 }
85
86 if ir.bo() {
87 regs.ir().write(|w| w.set_bo(true));
88 if regs.psr().read().bo() {
89 regs.cccr().modify(|w| w.set_init(false));
91 }
92 }
93 }
94}
95
96pub struct IT1InterruptHandler<T: Instance> {
98 _phantom: PhantomData<T>,
99}
100
101impl<T: Instance> interrupt::typelevel::Handler<T::IT1Interrupt> for IT1InterruptHandler<T> {
102 unsafe fn on_interrupt() {}
103}
104
105#[derive(Debug, Copy, Clone, Eq, PartialEq)]
106#[cfg_attr(feature = "defmt", derive(defmt::Format))]
107pub enum OperatingMode {
109 InternalLoopbackMode,
116 ExternalLoopbackMode,
123 NormalOperationMode,
125 RestrictedOperationMode,
132 BusMonitoringMode,
141 }
143
144fn calc_ns_per_timer_tick(
145 info: &'static Info,
146 freq: crate::time::Hertz,
147 mode: crate::can::fd::config::FrameTransmissionConfig,
148) -> u64 {
149 match mode {
150 crate::can::fd::config::FrameTransmissionConfig::ClassicCanOnly => {
152 let prescale: u64 = ({ info.regs.regs.nbtp().read().nbrp() } + 1) as u64
153 * ({ info.regs.regs.tscc().read().tcp() } + 1) as u64;
154 1_000_000_000 as u64 / (freq.0 as u64 * prescale)
155 }
156 _ => 0,
159 }
160}
161
162pub struct CanConfigurator<'d> {
165 _phantom: PhantomData<&'d ()>,
166 config: crate::can::fd::config::FdCanConfig,
167 info: &'static Info,
168 state: &'static State,
169 properties: Properties,
171 periph_clock: crate::time::Hertz,
172}
173
174impl<'d> CanConfigurator<'d> {
175 pub fn new<T: Instance>(
178 _peri: impl Peripheral<P = T> + 'd,
179 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
180 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
181 _irqs: impl interrupt::typelevel::Binding<T::IT0Interrupt, IT0InterruptHandler<T>>
182 + interrupt::typelevel::Binding<T::IT1Interrupt, IT1InterruptHandler<T>>
183 + 'd,
184 ) -> CanConfigurator<'d> {
185 into_ref!(_peri, rx, tx);
186
187 rx.set_as_af(rx.af_num(), AfType::input(Pull::None));
188 tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
189
190 rcc::enable_and_reset::<T>();
191
192 let mut config = crate::can::fd::config::FdCanConfig::default();
193 config.timestamp_source = TimestampSource::Prescaler(TimestampPrescaler::_1);
194 T::registers().into_config_mode(config);
195
196 rx.set_as_af(rx.af_num(), AfType::input(Pull::None));
197 tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
198
199 unsafe {
200 T::IT0Interrupt::unpend(); T::IT0Interrupt::enable();
202
203 T::IT1Interrupt::unpend(); T::IT1Interrupt::enable();
205 }
206 Self {
207 _phantom: PhantomData,
208 config,
209 info: T::info(),
210 state: T::state(),
211 properties: Properties::new(T::info()),
212 periph_clock: T::frequency(),
213 }
214 }
215
216 pub fn properties(&self) -> &Properties {
218 &self.properties
219 }
220
221 pub fn config(&self) -> crate::can::fd::config::FdCanConfig {
223 return self.config;
224 }
225
226 pub fn set_config(&mut self, config: crate::can::fd::config::FdCanConfig) {
228 self.config = config;
229 }
230
231 pub fn set_bitrate(&mut self, bitrate: u32) {
233 let bit_timing = util::calc_can_timings(self.periph_clock, bitrate).unwrap();
234
235 let nbtr = crate::can::fd::config::NominalBitTiming {
236 sync_jump_width: bit_timing.sync_jump_width,
237 prescaler: bit_timing.prescaler,
238 seg1: bit_timing.seg1,
239 seg2: bit_timing.seg2,
240 };
241 self.config = self.config.set_nominal_bit_timing(nbtr);
242 }
243
244 pub fn set_fd_data_bitrate(&mut self, bitrate: u32, transceiver_delay_compensation: bool) {
246 let bit_timing = util::calc_can_timings(self.periph_clock, bitrate).unwrap();
247 let nbtr = crate::can::fd::config::DataBitTiming {
249 transceiver_delay_compensation,
250 sync_jump_width: bit_timing.sync_jump_width,
251 prescaler: bit_timing.prescaler,
252 seg1: bit_timing.seg1,
253 seg2: bit_timing.seg2,
254 };
255 self.config.frame_transmit = FrameTransmissionConfig::AllowFdCanAndBRS;
256 self.config = self.config.set_data_bit_timing(nbtr);
257 }
258
259 pub fn start(self, mode: OperatingMode) -> Can<'d> {
261 let ns_per_timer_tick = calc_ns_per_timer_tick(self.info, self.periph_clock, self.config.frame_transmit);
262 critical_section::with(|_| {
263 let state = self.state as *const State;
264 unsafe {
265 let mut_state = state as *mut State;
266 (*mut_state).ns_per_timer_tick = ns_per_timer_tick;
267 }
268 });
269 self.info.regs.into_mode(self.config, mode);
270 Can {
271 _phantom: PhantomData,
272 config: self.config,
273 info: self.info,
274 state: self.state,
275 _mode: mode,
276 properties: Properties::new(self.info),
277 }
278 }
279
280 pub fn into_normal_mode(self) -> Can<'d> {
282 self.start(OperatingMode::NormalOperationMode)
283 }
284
285 pub fn into_internal_loopback_mode(self) -> Can<'d> {
287 self.start(OperatingMode::InternalLoopbackMode)
288 }
289
290 pub fn into_external_loopback_mode(self) -> Can<'d> {
292 self.start(OperatingMode::ExternalLoopbackMode)
293 }
294}
295
296pub struct Can<'d> {
298 _phantom: PhantomData<&'d ()>,
299 config: crate::can::fd::config::FdCanConfig,
300 info: &'static Info,
301 state: &'static State,
302 _mode: OperatingMode,
303 properties: Properties,
304}
305
306impl<'d> Can<'d> {
307 pub fn properties(&self) -> &Properties {
309 &self.properties
310 }
311
312 pub async fn flush(&self, idx: usize) {
314 poll_fn(|cx| {
315 self.state.tx_mode.register(cx.waker());
316
317 if idx > 3 {
318 panic!("Bad mailbox");
319 }
320 let idx = 1 << idx;
321 if !self.info.regs.regs.txbrp().read().trp(idx) {
322 return Poll::Ready(());
323 }
324
325 Poll::Pending
326 })
327 .await;
328 }
329
330 pub async fn write(&mut self, frame: &Frame) -> Option<Frame> {
335 self.state.tx_mode.write(self.info, frame).await
336 }
337
338 pub async fn read(&mut self) -> Result<Envelope, BusError> {
340 self.state.rx_mode.read_classic(self.info, self.state).await
341 }
342
343 pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> {
348 self.state.tx_mode.write_fd(self.info, frame).await
349 }
350
351 pub async fn read_fd(&mut self) -> Result<FdEnvelope, BusError> {
353 self.state.rx_mode.read_fd(self.info, self.state).await
354 }
355
356 pub fn split(self) -> (CanTx<'d>, CanRx<'d>, Properties) {
358 (
359 CanTx {
360 _phantom: PhantomData,
361 info: self.info,
362 state: self.state,
363 config: self.config,
364 _mode: self._mode,
365 },
366 CanRx {
367 _phantom: PhantomData,
368 info: self.info,
369 state: self.state,
370 _mode: self._mode,
371 },
372 self.properties,
373 )
374 }
375 pub fn join(tx: CanTx<'d>, rx: CanRx<'d>) -> Self {
377 Can {
378 _phantom: PhantomData,
379 config: tx.config,
380 info: tx.info,
381 state: tx.state,
382 _mode: rx._mode,
383 properties: Properties::new(tx.info),
384 }
385 }
386
387 pub fn buffered<const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>(
389 self,
390 tx_buf: &'static mut TxBuf<TX_BUF_SIZE>,
391 rxb: &'static mut RxBuf<RX_BUF_SIZE>,
392 ) -> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
393 BufferedCan::new(self.info, self.state, self._mode, tx_buf, rxb)
394 }
395
396 pub fn buffered_fd<const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>(
398 self,
399 tx_buf: &'static mut TxFdBuf<TX_BUF_SIZE>,
400 rxb: &'static mut RxFdBuf<RX_BUF_SIZE>,
401 ) -> BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
402 BufferedCanFd::new(self.info, self.state, self._mode, tx_buf, rxb)
403 }
404}
405
406pub type RxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Result<Envelope, BusError>, BUF_SIZE>;
408
409pub type TxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Frame, BUF_SIZE>;
411
412pub struct BufferedCan<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> {
414 _phantom: PhantomData<&'d ()>,
415 info: &'static Info,
416 state: &'static State,
417 _mode: OperatingMode,
418 tx_buf: &'static TxBuf<TX_BUF_SIZE>,
419 rx_buf: &'static RxBuf<RX_BUF_SIZE>,
420 properties: Properties,
421}
422
423impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
424 fn new(
425 info: &'static Info,
426 state: &'static State,
427 _mode: OperatingMode,
428 tx_buf: &'static TxBuf<TX_BUF_SIZE>,
429 rx_buf: &'static RxBuf<RX_BUF_SIZE>,
430 ) -> Self {
431 BufferedCan {
432 _phantom: PhantomData,
433 info,
434 state,
435 _mode,
436 tx_buf,
437 rx_buf,
438 properties: Properties::new(info),
439 }
440 .setup()
441 }
442
443 pub fn properties(&self) -> &Properties {
445 &self.properties
446 }
447
448 fn setup(self) -> Self {
449 critical_section::with(|_| {
451 let rx_inner = super::common::ClassicBufferedRxInner {
452 rx_sender: self.rx_buf.sender().into(),
453 };
454 let tx_inner = super::common::ClassicBufferedTxInner {
455 tx_receiver: self.tx_buf.receiver().into(),
456 };
457 let state = self.state as *const State;
458 unsafe {
459 let mut_state = state as *mut State;
460 (*mut_state).rx_mode = RxMode::ClassicBuffered(rx_inner);
461 (*mut_state).tx_mode = TxMode::ClassicBuffered(tx_inner);
462 }
463 });
464 self
465 }
466
467 pub async fn write(&mut self, frame: Frame) {
469 self.tx_buf.send(frame).await;
470 self.info.interrupt0.pend(); }
473
474 pub async fn read(&mut self) -> Result<Envelope, BusError> {
476 self.rx_buf.receive().await
477 }
478
479 pub fn writer(&self) -> BufferedCanSender {
481 BufferedCanSender {
482 tx_buf: self.tx_buf.sender().into(),
483 waker: self.info.tx_waker,
484 }
485 }
486
487 pub fn reader(&self) -> BufferedCanReceiver {
489 self.rx_buf.receiver().into()
490 }
491}
492
493impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop for BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
494 fn drop(&mut self) {
495 critical_section::with(|_| {
496 let state = self.state as *const State;
497 unsafe {
498 let mut_state = state as *mut State;
499 (*mut_state).rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
500 (*mut_state).tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
501 }
502 });
503 }
504}
505
506pub type RxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Result<FdEnvelope, BusError>, BUF_SIZE>;
508
509pub type TxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, FdFrame, BUF_SIZE>;
511
512#[derive(Copy, Clone)]
514pub struct BufferedFdCanSender {
515 tx_buf: DynamicSender<'static, FdFrame>,
516 waker: fn(),
517}
518
519impl BufferedFdCanSender {
520 pub fn try_write(&mut self, frame: FdFrame) -> Result<(), embassy_sync::channel::TrySendError<FdFrame>> {
522 self.tx_buf.try_send(frame)?;
523 (self.waker)();
524 Ok(())
525 }
526
527 pub async fn write(&mut self, frame: FdFrame) {
529 self.tx_buf.send(frame).await;
530 (self.waker)();
531 }
532
533 pub fn poll_ready_to_send(&self, cx: &mut core::task::Context<'_>) -> core::task::Poll<()> {
535 self.tx_buf.poll_ready_to_send(cx)
536 }
537}
538
539pub type BufferedFdCanReceiver = DynamicReceiver<'static, Result<FdEnvelope, BusError>>;
541
542pub struct BufferedCanFd<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> {
544 _phantom: PhantomData<&'d ()>,
545 info: &'static Info,
546 state: &'static State,
547 _mode: OperatingMode,
548 tx_buf: &'static TxFdBuf<TX_BUF_SIZE>,
549 rx_buf: &'static RxFdBuf<RX_BUF_SIZE>,
550 properties: Properties,
551}
552
553impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
554 fn new(
555 info: &'static Info,
556 state: &'static State,
557 _mode: OperatingMode,
558 tx_buf: &'static TxFdBuf<TX_BUF_SIZE>,
559 rx_buf: &'static RxFdBuf<RX_BUF_SIZE>,
560 ) -> Self {
561 BufferedCanFd {
562 _phantom: PhantomData,
563 info,
564 state,
565 _mode,
566 tx_buf,
567 rx_buf,
568 properties: Properties::new(info),
569 }
570 .setup()
571 }
572
573 pub fn properties(&self) -> &Properties {
575 &self.properties
576 }
577
578 fn setup(self) -> Self {
579 critical_section::with(|_| {
581 let rx_inner = super::common::FdBufferedRxInner {
582 rx_sender: self.rx_buf.sender().into(),
583 };
584 let tx_inner = super::common::FdBufferedTxInner {
585 tx_receiver: self.tx_buf.receiver().into(),
586 };
587 let state = self.state as *const State;
588 unsafe {
589 let mut_state = state as *mut State;
590 (*mut_state).rx_mode = RxMode::FdBuffered(rx_inner);
591 (*mut_state).tx_mode = TxMode::FdBuffered(tx_inner);
592 }
593 });
594 self
595 }
596
597 pub async fn write(&mut self, frame: FdFrame) {
599 self.tx_buf.send(frame).await;
600 self.info.interrupt0.pend(); }
603
604 pub async fn read(&mut self) -> Result<FdEnvelope, BusError> {
606 self.rx_buf.receive().await
607 }
608
609 pub fn writer(&self) -> BufferedFdCanSender {
611 BufferedFdCanSender {
612 tx_buf: self.tx_buf.sender().into(),
613 waker: self.info.tx_waker,
614 }
615 }
616
617 pub fn reader(&self) -> BufferedFdCanReceiver {
619 self.rx_buf.receiver().into()
620 }
621}
622
623impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> Drop for BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
624 fn drop(&mut self) {
625 critical_section::with(|_| {
626 let state = self.state as *const State;
627 unsafe {
628 let mut_state = state as *mut State;
629 (*mut_state).rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
630 (*mut_state).tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
631 }
632 });
633 }
634}
635
636pub struct CanRx<'d> {
638 _phantom: PhantomData<&'d ()>,
639 info: &'static Info,
640 state: &'static State,
641 _mode: OperatingMode,
642}
643
644impl<'d> CanRx<'d> {
645 pub async fn read(&mut self) -> Result<Envelope, BusError> {
647 self.state.rx_mode.read_classic(&self.info, &self.state).await
648 }
649
650 pub async fn read_fd(&mut self) -> Result<FdEnvelope, BusError> {
652 self.state.rx_mode.read_fd(&self.info, &self.state).await
653 }
654}
655
656pub struct CanTx<'d> {
658 _phantom: PhantomData<&'d ()>,
659 info: &'static Info,
660 state: &'static State,
661 config: crate::can::fd::config::FdCanConfig,
662 _mode: OperatingMode,
663}
664
665impl<'c, 'd> CanTx<'d> {
666 pub async fn write(&mut self, frame: &Frame) -> Option<Frame> {
671 self.state.tx_mode.write(self.info, frame).await
672 }
673
674 pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> {
679 self.state.tx_mode.write_fd(self.info, frame).await
680 }
681}
682
683enum RxMode {
684 NonBuffered(AtomicWaker),
685 ClassicBuffered(super::common::ClassicBufferedRxInner),
686 FdBuffered(super::common::FdBufferedRxInner),
687}
688
689impl RxMode {
690 fn register(&self, arg: &core::task::Waker) {
691 match self {
692 RxMode::NonBuffered(waker) => waker.register(arg),
693 _ => {
694 panic!("Bad Mode")
695 }
696 }
697 }
698
699 fn on_interrupt<T: Instance>(&self, fifonr: usize) {
700 T::registers().regs.ir().write(|w| w.set_rfn(fifonr, true));
701 match self {
702 RxMode::NonBuffered(waker) => {
703 waker.wake();
704 }
705 RxMode::ClassicBuffered(buf) => {
706 if let Some(result) = self.try_read::<T>() {
707 let _ = buf.rx_sender.try_send(result);
708 }
709 }
710 RxMode::FdBuffered(buf) => {
711 if let Some(result) = self.try_read_fd::<T>() {
712 let _ = buf.rx_sender.try_send(result);
713 }
714 }
715 }
716 }
717
718 fn try_read<T: Instance>(&self) -> Option<Result<Envelope, BusError>> {
720 if let Some((frame, ts)) = T::registers().read(0) {
721 let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
722 Some(Ok(Envelope { ts, frame }))
723 } else if let Some((frame, ts)) = T::registers().read(1) {
724 let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
725 Some(Ok(Envelope { ts, frame }))
726 } else if let Some(err) = T::registers().curr_error() {
727 Some(Err(err))
729 } else {
730 None
731 }
732 }
733
734 fn try_read_fd<T: Instance>(&self) -> Option<Result<FdEnvelope, BusError>> {
735 if let Some((frame, ts)) = T::registers().read(0) {
736 let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
737 Some(Ok(FdEnvelope { ts, frame }))
738 } else if let Some((frame, ts)) = T::registers().read(1) {
739 let ts = T::calc_timestamp(T::state().ns_per_timer_tick, ts);
740 Some(Ok(FdEnvelope { ts, frame }))
741 } else if let Some(err) = T::registers().curr_error() {
742 Some(Err(err))
744 } else {
745 None
746 }
747 }
748
749 fn read<F: CanHeader>(
750 &self,
751 info: &'static Info,
752 state: &'static State,
753 ) -> Option<Result<(F, Timestamp), BusError>> {
754 if let Some((msg, ts)) = info.regs.read(0) {
755 let ts = info.calc_timestamp(state.ns_per_timer_tick, ts);
756 Some(Ok((msg, ts)))
757 } else if let Some((msg, ts)) = info.regs.read(1) {
758 let ts = info.calc_timestamp(state.ns_per_timer_tick, ts);
759 Some(Ok((msg, ts)))
760 } else if let Some(err) = info.regs.curr_error() {
761 Some(Err(err))
763 } else {
764 None
765 }
766 }
767
768 async fn read_async<F: CanHeader>(
769 &self,
770 info: &'static Info,
771 state: &'static State,
772 ) -> Result<(F, Timestamp), BusError> {
773 poll_fn(move |cx| {
775 state.err_waker.register(cx.waker());
776 self.register(cx.waker());
777 match self.read::<_>(info, state) {
778 Some(result) => Poll::Ready(result),
779 None => Poll::Pending,
780 }
781 })
782 .await
783 }
784
785 async fn read_classic(&self, info: &'static Info, state: &'static State) -> Result<Envelope, BusError> {
786 match self.read_async::<_>(info, state).await {
787 Ok((frame, ts)) => Ok(Envelope { ts, frame }),
788 Err(e) => Err(e),
789 }
790 }
791
792 async fn read_fd(&self, info: &'static Info, state: &'static State) -> Result<FdEnvelope, BusError> {
793 match self.read_async::<_>(info, state).await {
794 Ok((frame, ts)) => Ok(FdEnvelope { ts, frame }),
795 Err(e) => Err(e),
796 }
797 }
798}
799
800enum TxMode {
801 NonBuffered(AtomicWaker),
802 ClassicBuffered(super::common::ClassicBufferedTxInner),
803 FdBuffered(super::common::FdBufferedTxInner),
804}
805
806impl TxMode {
807 fn register(&self, arg: &core::task::Waker) {
808 match self {
809 TxMode::NonBuffered(waker) => {
810 waker.register(arg);
811 }
812 _ => {
813 panic!("Bad mode");
814 }
815 }
816 }
817
818 async fn write_generic<F: embedded_can::Frame + CanHeader>(&self, info: &'static Info, frame: &F) -> Option<F> {
823 poll_fn(|cx| {
824 self.register(cx.waker());
825
826 if let Ok(dropped) = info.regs.write(frame) {
827 return Poll::Ready(dropped);
828 }
829
830 Poll::Pending
833 })
834 .await
835 }
836
837 async fn write(&self, info: &'static Info, frame: &Frame) -> Option<Frame> {
842 self.write_generic::<_>(info, frame).await
843 }
844
845 async fn write_fd(&self, info: &'static Info, frame: &FdFrame) -> Option<FdFrame> {
850 self.write_generic::<_>(info, frame).await
851 }
852}
853
854pub struct Properties {
856 info: &'static Info,
857 }
860
861impl Properties {
862 fn new(info: &'static Info) -> Self {
863 Self {
864 info,
865 }
867 }
868
869 #[inline]
871 pub fn set_standard_filter(&self, slot: StandardFilterSlot, filter: StandardFilter) {
872 self.info.regs.msg_ram_mut().filters.flssa[slot as usize].activate(filter);
873 }
874
875 pub fn set_standard_filters(&self, filters: &[StandardFilter; STANDARD_FILTER_MAX as usize]) {
878 for (i, f) in filters.iter().enumerate() {
879 self.info.regs.msg_ram_mut().filters.flssa[i].activate(*f);
880 }
881 }
882
883 #[inline]
885 pub fn set_extended_filter(&self, slot: ExtendedFilterSlot, filter: ExtendedFilter) {
886 self.info.regs.msg_ram_mut().filters.flesa[slot as usize].activate(filter);
887 }
888
889 pub fn set_extended_filters(&self, filters: &[ExtendedFilter; EXTENDED_FILTER_MAX as usize]) {
892 for (i, f) in filters.iter().enumerate() {
893 self.info.regs.msg_ram_mut().filters.flesa[i].activate(*f);
894 }
895 }
896
897 pub fn rx_error_count(&self) -> u8 {
899 self.info.regs.regs.ecr().read().rec()
900 }
901
902 pub fn tx_error_count(&self) -> u8 {
904 self.info.regs.regs.ecr().read().tec()
905 }
906
907 pub fn bus_error_mode(&self) -> BusErrorMode {
909 let psr = self.info.regs.regs.psr().read();
913 match (psr.bo(), psr.ep()) {
914 (false, false) => BusErrorMode::ErrorActive,
915 (false, true) => BusErrorMode::ErrorPassive,
916 (true, _) => BusErrorMode::BusOff,
917 }
918 }
919}
920
921struct State {
922 pub rx_mode: RxMode,
923 pub tx_mode: TxMode,
924 pub ns_per_timer_tick: u64,
925
926 pub err_waker: AtomicWaker,
927}
928
929impl State {
930 const fn new() -> Self {
931 Self {
932 rx_mode: RxMode::NonBuffered(AtomicWaker::new()),
933 tx_mode: TxMode::NonBuffered(AtomicWaker::new()),
934 ns_per_timer_tick: 0,
935 err_waker: AtomicWaker::new(),
936 }
937 }
938}
939
940struct Info {
941 regs: Registers,
942 interrupt0: crate::interrupt::Interrupt,
943 _interrupt1: crate::interrupt::Interrupt,
944 tx_waker: fn(),
945}
946
947impl Info {
948 #[cfg(feature = "time")]
949 fn calc_timestamp(&self, ns_per_timer_tick: u64, ts_val: u16) -> Timestamp {
950 let now_embassy = embassy_time::Instant::now();
951 if ns_per_timer_tick == 0 {
952 return now_embassy;
953 }
954 let cantime = { self.regs.regs.tscv().read().tsc() };
955 let delta = cantime.overflowing_sub(ts_val).0 as u64;
956 let ns = ns_per_timer_tick * delta as u64;
957 now_embassy - embassy_time::Duration::from_nanos(ns)
958 }
959
960 #[cfg(not(feature = "time"))]
961 fn calc_timestamp(&self, _ns_per_timer_tick: u64, ts_val: u16) -> Timestamp {
962 ts_val
963 }
964}
965
966trait SealedInstance {
967 const MSG_RAM_OFFSET: usize;
968
969 fn info() -> &'static Info;
970 fn registers() -> crate::can::fd::peripheral::Registers;
971 fn state() -> &'static State;
972 unsafe fn mut_state() -> &'static mut State;
973 fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp;
974}
975
976#[allow(private_bounds)]
978pub trait Instance: SealedInstance + RccPeripheral + 'static {
979 type IT0Interrupt: crate::interrupt::typelevel::Interrupt;
981 type IT1Interrupt: crate::interrupt::typelevel::Interrupt;
983}
984
985pub struct FdcanInstance<'a, T>(PeripheralRef<'a, T>);
987
988macro_rules! impl_fdcan {
989 ($inst:ident,
990 $msg_ram_inst:ident, $msg_ram_offset:literal) => {
992 impl SealedInstance for peripherals::$inst {
993 const MSG_RAM_OFFSET: usize = $msg_ram_offset;
994
995 fn info() -> &'static Info {
996 static INFO: Info = Info {
997 regs: Registers{regs: crate::pac::$inst, msgram: crate::pac::$msg_ram_inst, msg_ram_offset: $msg_ram_offset},
998 interrupt0: crate::_generated::peripheral_interrupts::$inst::IT0::IRQ,
999 _interrupt1: crate::_generated::peripheral_interrupts::$inst::IT1::IRQ,
1000 tx_waker: crate::_generated::peripheral_interrupts::$inst::IT0::pend,
1001 };
1002 &INFO
1003 }
1004 fn registers() -> Registers {
1005 Registers{regs: crate::pac::$inst, msgram: crate::pac::$msg_ram_inst, msg_ram_offset: Self::MSG_RAM_OFFSET}
1006 }
1007 unsafe fn mut_state() -> &'static mut State {
1008 static mut STATE: State = State::new();
1009 &mut *core::ptr::addr_of_mut!(STATE)
1010 }
1011 fn state() -> &'static State {
1012 unsafe { peripherals::$inst::mut_state() }
1013 }
1014
1015 #[cfg(feature = "time")]
1016 fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp {
1017 let now_embassy = embassy_time::Instant::now();
1018 if ns_per_timer_tick == 0 {
1019 return now_embassy;
1020 }
1021 let cantime = { Self::registers().regs.tscv().read().tsc() };
1022 let delta = cantime.overflowing_sub(ts_val).0 as u64;
1023 let ns = ns_per_timer_tick * delta as u64;
1024 now_embassy - embassy_time::Duration::from_nanos(ns)
1025 }
1026
1027 #[cfg(not(feature = "time"))]
1028 fn calc_timestamp(_ns_per_timer_tick: u64, ts_val: u16) -> Timestamp {
1029 ts_val
1030 }
1031
1032 }
1033
1034 #[allow(non_snake_case)]
1035 pub(crate) mod $inst {
1036
1037 foreach_interrupt!(
1038 ($inst,can,FDCAN,IT0,$irq:ident) => {
1039 pub type Interrupt0 = crate::interrupt::typelevel::$irq;
1040 };
1041 ($inst,can,FDCAN,IT1,$irq:ident) => {
1042 pub type Interrupt1 = crate::interrupt::typelevel::$irq;
1043 };
1044 );
1045 }
1046 impl Instance for peripherals::$inst {
1047 type IT0Interrupt = $inst::Interrupt0;
1048 type IT1Interrupt = $inst::Interrupt1;
1049 }
1050 };
1051
1052 ($inst:ident, $msg_ram_inst:ident) => {
1053 impl_fdcan!($inst, $msg_ram_inst, 0);
1054 };
1055}
1056
1057#[cfg(not(can_fdcan_h7))]
1058foreach_peripheral!(
1059 (can, FDCAN) => { impl_fdcan!(FDCAN, FDCANRAM); };
1060 (can, FDCAN1) => { impl_fdcan!(FDCAN1, FDCANRAM1); };
1061 (can, FDCAN2) => { impl_fdcan!(FDCAN2, FDCANRAM2); };
1062 (can, FDCAN3) => { impl_fdcan!(FDCAN3, FDCANRAM3); };
1063);
1064
1065#[cfg(can_fdcan_h7)]
1066foreach_peripheral!(
1067 (can, FDCAN1) => { impl_fdcan!(FDCAN1, FDCANRAM, 0x0000); };
1068 (can, FDCAN2) => { impl_fdcan!(FDCAN2, FDCANRAM, 0x0C00); };
1069 (can, FDCAN3) => { impl_fdcan!(FDCAN3, FDCANRAM, 0x1800); };
1070);
1071
1072pin_trait!(RxPin, Instance);
1073pin_trait!(TxPin, Instance);