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::PeripheralType;
8use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
9use embassy_sync::channel::Channel;
10use embassy_sync::waitqueue::AtomicWaker;
11
12use crate::can::fd::peripheral::Registers;
13use crate::gpio::{AfType, OutputType, Pull, SealedPin as _, Speed};
14use crate::interrupt::typelevel::Interrupt;
15use crate::rcc::{self, RccPeripheral};
16use crate::{interrupt, peripherals, Peri};
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::common::{InfoRef, RxInfoRef, TxInfoRef};
25use super::enums::*;
26use super::frame::*;
27use super::util;
28
29#[cfg(feature = "time")]
31pub type Timestamp = embassy_time::Instant;
32
33#[cfg(not(feature = "time"))]
35pub type Timestamp = u16;
36
37pub struct IT0InterruptHandler<T: Instance> {
39 _phantom: PhantomData<T>,
40}
41
42impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0InterruptHandler<T> {
44 unsafe fn on_interrupt() {
45 let regs = T::registers().regs;
46
47 let ir = regs.ir().read();
48
49 if ir.tc() {
50 regs.ir().write(|w| w.set_tc(true));
51 }
52 if ir.tefn() {
53 regs.ir().write(|w| w.set_tefn(true));
54 }
55
56 T::info().state.lock(|s| {
57 let state = s.borrow_mut();
58 match &state.tx_mode {
59 TxMode::NonBuffered(waker) => waker.wake(),
60 TxMode::ClassicBuffered(buf) => {
61 if !T::registers().tx_queue_is_full() {
62 match buf.tx_receiver.try_receive() {
63 Ok(frame) => {
64 _ = T::registers().write(&frame);
65 }
66 Err(_) => {}
67 }
68 }
69 }
70 TxMode::FdBuffered(buf) => {
71 if !T::registers().tx_queue_is_full() {
72 match buf.tx_receiver.try_receive() {
73 Ok(frame) => {
74 _ = T::registers().write(&frame);
75 }
76 Err(_) => {}
77 }
78 }
79 }
80 }
81
82 if ir.rfn(0) {
83 state.rx_mode.on_interrupt::<T>(0, state.ns_per_timer_tick);
84 }
85 if ir.rfn(1) {
86 state.rx_mode.on_interrupt::<T>(1, state.ns_per_timer_tick);
87 }
88 });
89
90 if ir.bo() {
91 regs.ir().write(|w| w.set_bo(true));
92 if regs.psr().read().bo() {
93 regs.cccr().modify(|w| w.set_init(false));
95 }
96 }
97 }
98}
99
100pub struct IT1InterruptHandler<T: Instance> {
102 _phantom: PhantomData<T>,
103}
104
105impl<T: Instance> interrupt::typelevel::Handler<T::IT1Interrupt> for IT1InterruptHandler<T> {
106 unsafe fn on_interrupt() {}
107}
108
109#[derive(Debug, Copy, Clone, Eq, PartialEq)]
110#[cfg_attr(feature = "defmt", derive(defmt::Format))]
111pub enum OperatingMode {
113 InternalLoopbackMode,
120 ExternalLoopbackMode,
127 NormalOperationMode,
129 RestrictedOperationMode,
136 BusMonitoringMode,
145 }
147
148fn calc_ns_per_timer_tick(
149 info: &'static Info,
150 freq: crate::time::Hertz,
151 mode: crate::can::fd::config::FrameTransmissionConfig,
152) -> u64 {
153 match mode {
154 crate::can::fd::config::FrameTransmissionConfig::ClassicCanOnly => {
156 let prescale: u64 = ({ info.regs.regs.nbtp().read().nbrp() } + 1) as u64
157 * ({ info.regs.regs.tscc().read().tcp() } + 1) as u64;
158 1_000_000_000 as u64 / (freq.0 as u64 * prescale)
159 }
160 _ => 0,
163 }
164}
165
166pub struct CanConfigurator<'d> {
169 _phantom: PhantomData<&'d ()>,
170 config: crate::can::fd::config::FdCanConfig,
171 properties: Properties,
173 periph_clock: crate::time::Hertz,
174 info: InfoRef,
175}
176
177impl<'d> CanConfigurator<'d> {
178 pub fn new<T: Instance>(
181 _peri: Peri<'d, T>,
182 rx: Peri<'d, impl RxPin<T>>,
183 tx: Peri<'d, impl TxPin<T>>,
184 _irqs: impl interrupt::typelevel::Binding<T::IT0Interrupt, IT0InterruptHandler<T>>
185 + interrupt::typelevel::Binding<T::IT1Interrupt, IT1InterruptHandler<T>>
186 + 'd,
187 ) -> CanConfigurator<'d> {
188 rx.set_as_af(rx.af_num(), AfType::input(Pull::None));
189 tx.set_as_af(tx.af_num(), AfType::output(OutputType::PushPull, Speed::VeryHigh));
190
191 rcc::enable_and_reset::<T>();
192
193 let info = T::info();
194 T::info().state.lock(|s| {
195 s.borrow_mut().tx_pin_port = Some(tx.pin_port());
196 s.borrow_mut().rx_pin_port = Some(rx.pin_port());
197 });
198
199 let mut config = crate::can::fd::config::FdCanConfig::default();
200 config.timestamp_source = TimestampSource::Prescaler(TimestampPrescaler::_1);
201 T::registers().into_config_mode(config);
202
203 unsafe {
204 T::IT0Interrupt::unpend(); T::IT0Interrupt::enable();
206
207 T::IT1Interrupt::unpend(); T::IT1Interrupt::enable();
209 }
210 Self {
211 _phantom: PhantomData,
212 config,
213 properties: Properties::new(T::info()),
214 periph_clock: T::frequency(),
215 info: InfoRef::new(info),
216 }
217 }
218
219 pub fn properties(&self) -> &Properties {
221 &self.properties
222 }
223
224 pub fn config(&self) -> crate::can::fd::config::FdCanConfig {
226 return self.config;
227 }
228
229 pub fn set_config(&mut self, config: crate::can::fd::config::FdCanConfig) {
231 self.config = config;
232 }
233
234 pub fn set_bitrate(&mut self, bitrate: u32) {
236 let bit_timing = util::calc_can_timings(self.periph_clock, bitrate).unwrap();
237
238 let nbtr = crate::can::fd::config::NominalBitTiming {
239 sync_jump_width: bit_timing.sync_jump_width,
240 prescaler: bit_timing.prescaler,
241 seg1: bit_timing.seg1,
242 seg2: bit_timing.seg2,
243 };
244 self.config = self.config.set_nominal_bit_timing(nbtr);
245 }
246
247 pub fn set_fd_data_bitrate(&mut self, bitrate: u32, transceiver_delay_compensation: bool) {
249 let bit_timing = util::calc_can_timings(self.periph_clock, bitrate).unwrap();
250 let nbtr = crate::can::fd::config::DataBitTiming {
252 transceiver_delay_compensation,
253 sync_jump_width: bit_timing.sync_jump_width,
254 prescaler: bit_timing.prescaler,
255 seg1: bit_timing.seg1,
256 seg2: bit_timing.seg2,
257 };
258 self.config.frame_transmit = FrameTransmissionConfig::AllowFdCanAndBRS;
259 self.config = self.config.set_data_bit_timing(nbtr);
260 }
261
262 pub fn start(self, mode: OperatingMode) -> Can<'d> {
264 let ns_per_timer_tick = calc_ns_per_timer_tick(&self.info, self.periph_clock, self.config.frame_transmit);
265 self.info.state.lock(|s| {
266 s.borrow_mut().ns_per_timer_tick = ns_per_timer_tick;
267 });
268 self.info.regs.into_mode(self.config, mode);
269 Can {
270 _phantom: PhantomData,
271 config: self.config,
272 _mode: mode,
273 properties: Properties::new(&self.info),
274 info: InfoRef::new(&self.info),
275 }
276 }
277
278 pub fn into_normal_mode(self) -> Can<'d> {
280 self.start(OperatingMode::NormalOperationMode)
281 }
282
283 pub fn into_internal_loopback_mode(self) -> Can<'d> {
285 self.start(OperatingMode::InternalLoopbackMode)
286 }
287
288 pub fn into_external_loopback_mode(self) -> Can<'d> {
290 self.start(OperatingMode::ExternalLoopbackMode)
291 }
292}
293
294pub struct Can<'d> {
296 _phantom: PhantomData<&'d ()>,
297 config: crate::can::fd::config::FdCanConfig,
298 _mode: OperatingMode,
299 properties: Properties,
300 info: InfoRef,
301}
302
303impl<'d> Can<'d> {
304 pub fn properties(&self) -> &Properties {
306 &self.properties
307 }
308
309 pub async fn flush(&self, idx: usize) {
311 poll_fn(|cx| {
312 self.info.state.lock(|s| {
313 s.borrow_mut().tx_mode.register(cx.waker());
314 });
315
316 if idx > 3 {
317 panic!("Bad mailbox");
318 }
319 let idx = 1 << idx;
320 if !self.info.regs.regs.txbrp().read().trp(idx) {
321 return Poll::Ready(());
322 }
323
324 Poll::Pending
325 })
326 .await;
327 }
328
329 pub async fn write(&mut self, frame: &Frame) -> Option<Frame> {
334 TxMode::write(&self.info, frame).await
335 }
336
337 pub async fn read(&mut self) -> Result<Envelope, BusError> {
339 RxMode::read_classic(&self.info).await
340 }
341
342 pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> {
347 TxMode::write_fd(&self.info, frame).await
348 }
349
350 pub async fn read_fd(&mut self) -> Result<FdEnvelope, BusError> {
352 RxMode::read_fd(&self.info).await
353 }
354
355 pub fn split(self) -> (CanTx<'d>, CanRx<'d>, Properties) {
357 (
358 CanTx {
359 _phantom: PhantomData,
360 config: self.config,
361 _mode: self._mode,
362 info: TxInfoRef::new(&self.info),
363 },
364 CanRx {
365 _phantom: PhantomData,
366 _mode: self._mode,
367 info: RxInfoRef::new(&self.info),
368 },
369 Properties {
370 info: self.properties.info,
371 },
372 )
373 }
374 pub fn join(tx: CanTx<'d>, rx: CanRx<'d>) -> Self {
376 Can {
377 _phantom: PhantomData,
378 config: tx.config,
379 _mode: rx._mode,
380 properties: Properties::new(&tx.info),
381 info: InfoRef::new(&tx.info),
382 }
383 }
384
385 pub fn buffered<const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>(
387 self,
388 tx_buf: &'static mut TxBuf<TX_BUF_SIZE>,
389 rxb: &'static mut RxBuf<RX_BUF_SIZE>,
390 ) -> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
391 BufferedCan::new(&self.info, self._mode, tx_buf, rxb)
392 }
393
394 pub fn buffered_fd<const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize>(
396 self,
397 tx_buf: &'static mut TxFdBuf<TX_BUF_SIZE>,
398 rxb: &'static mut RxFdBuf<RX_BUF_SIZE>,
399 ) -> BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
400 BufferedCanFd::new(&self.info, self._mode, tx_buf, rxb)
401 }
402}
403
404pub type RxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Result<Envelope, BusError>, BUF_SIZE>;
406
407pub type TxBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Frame, BUF_SIZE>;
409
410pub struct BufferedCan<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> {
412 _phantom: PhantomData<&'d ()>,
413 _mode: OperatingMode,
414 tx_buf: &'static TxBuf<TX_BUF_SIZE>,
415 rx_buf: &'static RxBuf<RX_BUF_SIZE>,
416 properties: Properties,
417 info: InfoRef,
418}
419
420impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCan<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
421 fn new(
422 info: &'static Info,
423 _mode: OperatingMode,
424 tx_buf: &'static TxBuf<TX_BUF_SIZE>,
425 rx_buf: &'static RxBuf<RX_BUF_SIZE>,
426 ) -> Self {
427 BufferedCan {
428 _phantom: PhantomData,
429 _mode,
430 tx_buf,
431 rx_buf,
432 properties: Properties::new(info),
433 info: InfoRef::new(info),
434 }
435 .setup()
436 }
437
438 pub fn properties(&self) -> &Properties {
440 &self.properties
441 }
442
443 fn setup(self) -> Self {
444 self.info.state.lock(|s| {
446 let rx_inner = super::common::ClassicBufferedRxInner {
447 rx_sender: self.rx_buf.sender().into(),
448 };
449 let tx_inner = super::common::ClassicBufferedTxInner {
450 tx_receiver: self.tx_buf.receiver().into(),
451 };
452 s.borrow_mut().rx_mode = RxMode::ClassicBuffered(rx_inner);
453 s.borrow_mut().tx_mode = TxMode::ClassicBuffered(tx_inner);
454 });
455 self
456 }
457
458 pub async fn write(&mut self, frame: Frame) {
460 self.tx_buf.send(frame).await;
461 self.info.interrupt0.pend(); }
464
465 pub async fn read(&mut self) -> Result<Envelope, BusError> {
467 self.rx_buf.receive().await
468 }
469
470 pub fn writer(&self) -> BufferedCanSender {
472 BufferedCanSender {
473 tx_buf: self.tx_buf.sender().into(),
474 info: TxInfoRef::new(&self.info),
475 }
476 }
477
478 pub fn reader(&self) -> BufferedCanReceiver {
480 BufferedCanReceiver {
481 rx_buf: self.rx_buf.receiver().into(),
482 info: RxInfoRef::new(&self.info),
483 }
484 }
485}
486
487pub type RxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, Result<FdEnvelope, BusError>, BUF_SIZE>;
489
490pub type TxFdBuf<const BUF_SIZE: usize> = Channel<CriticalSectionRawMutex, FdFrame, BUF_SIZE>;
492
493pub type BufferedFdCanSender = super::common::BufferedSender<'static, FdFrame>;
495
496pub type BufferedFdCanReceiver = super::common::BufferedReceiver<'static, FdEnvelope>;
498
499pub struct BufferedCanFd<'d, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> {
501 _phantom: PhantomData<&'d ()>,
502 _mode: OperatingMode,
503 tx_buf: &'static TxFdBuf<TX_BUF_SIZE>,
504 rx_buf: &'static RxFdBuf<RX_BUF_SIZE>,
505 properties: Properties,
506 info: InfoRef,
507}
508
509impl<'c, 'd, const TX_BUF_SIZE: usize, const RX_BUF_SIZE: usize> BufferedCanFd<'d, TX_BUF_SIZE, RX_BUF_SIZE> {
510 fn new(
511 info: &'static Info,
512 _mode: OperatingMode,
513 tx_buf: &'static TxFdBuf<TX_BUF_SIZE>,
514 rx_buf: &'static RxFdBuf<RX_BUF_SIZE>,
515 ) -> Self {
516 BufferedCanFd {
517 _phantom: PhantomData,
518 _mode,
519 tx_buf,
520 rx_buf,
521 properties: Properties::new(info),
522 info: InfoRef::new(info),
523 }
524 .setup()
525 }
526
527 pub fn properties(&self) -> &Properties {
529 &self.properties
530 }
531
532 fn setup(self) -> Self {
533 self.info.state.lock(|s| {
535 let rx_inner = super::common::FdBufferedRxInner {
536 rx_sender: self.rx_buf.sender().into(),
537 };
538 let tx_inner = super::common::FdBufferedTxInner {
539 tx_receiver: self.tx_buf.receiver().into(),
540 };
541 s.borrow_mut().rx_mode = RxMode::FdBuffered(rx_inner);
542 s.borrow_mut().tx_mode = TxMode::FdBuffered(tx_inner);
543 });
544 self
545 }
546
547 pub async fn write(&mut self, frame: FdFrame) {
549 self.tx_buf.send(frame).await;
550 self.info.interrupt0.pend(); }
553
554 pub async fn read(&mut self) -> Result<FdEnvelope, BusError> {
556 self.rx_buf.receive().await
557 }
558
559 pub fn writer(&self) -> BufferedFdCanSender {
561 BufferedFdCanSender {
562 tx_buf: self.tx_buf.sender().into(),
563 info: TxInfoRef::new(&self.info),
564 }
565 }
566
567 pub fn reader(&self) -> BufferedFdCanReceiver {
569 BufferedFdCanReceiver {
570 rx_buf: self.rx_buf.receiver().into(),
571 info: RxInfoRef::new(&self.info),
572 }
573 }
574}
575
576pub struct CanRx<'d> {
578 _phantom: PhantomData<&'d ()>,
579 _mode: OperatingMode,
580 info: RxInfoRef,
581}
582
583impl<'d> CanRx<'d> {
584 pub async fn read(&mut self) -> Result<Envelope, BusError> {
586 RxMode::read_classic(&self.info).await
587 }
588
589 pub async fn read_fd(&mut self) -> Result<FdEnvelope, BusError> {
591 RxMode::read_fd(&self.info).await
592 }
593}
594
595pub struct CanTx<'d> {
597 _phantom: PhantomData<&'d ()>,
598 config: crate::can::fd::config::FdCanConfig,
599 _mode: OperatingMode,
600 info: TxInfoRef,
601}
602
603impl<'c, 'd> CanTx<'d> {
604 pub async fn write(&mut self, frame: &Frame) -> Option<Frame> {
609 TxMode::write(&self.info, frame).await
610 }
611
612 pub async fn write_fd(&mut self, frame: &FdFrame) -> Option<FdFrame> {
617 TxMode::write_fd(&self.info, frame).await
618 }
619}
620
621enum RxMode {
622 NonBuffered(AtomicWaker),
623 ClassicBuffered(super::common::ClassicBufferedRxInner),
624 FdBuffered(super::common::FdBufferedRxInner),
625}
626
627impl RxMode {
628 fn register(&self, arg: &core::task::Waker) {
629 match self {
630 RxMode::NonBuffered(waker) => waker.register(arg),
631 _ => {
632 panic!("Bad Mode")
633 }
634 }
635 }
636
637 fn on_interrupt<T: Instance>(&self, fifonr: usize, ns_per_timer_tick: u64) {
638 T::registers().regs.ir().write(|w| w.set_rfn(fifonr, true));
639 match self {
640 RxMode::NonBuffered(waker) => {
641 waker.wake();
642 }
643 RxMode::ClassicBuffered(buf) => {
644 if let Some(result) = self.try_read::<T>(ns_per_timer_tick) {
645 let _ = buf.rx_sender.try_send(result);
646 }
647 }
648 RxMode::FdBuffered(buf) => {
649 if let Some(result) = self.try_read_fd::<T>(ns_per_timer_tick) {
650 let _ = buf.rx_sender.try_send(result);
651 }
652 }
653 }
654 }
655
656 fn try_read<T: Instance>(&self, ns_per_timer_tick: u64) -> Option<Result<Envelope, BusError>> {
658 if let Some((frame, ts)) = T::registers().read(0) {
659 let ts = T::registers().calc_timestamp(ns_per_timer_tick, ts);
660 Some(Ok(Envelope { ts, frame }))
661 } else if let Some((frame, ts)) = T::registers().read(1) {
662 let ts = T::registers().calc_timestamp(ns_per_timer_tick, ts);
663 Some(Ok(Envelope { ts, frame }))
664 } else if let Some(err) = T::registers().curr_error() {
665 Some(Err(err))
667 } else {
668 None
669 }
670 }
671
672 fn try_read_fd<T: Instance>(&self, ns_per_timer_tick: u64) -> Option<Result<FdEnvelope, BusError>> {
673 if let Some((frame, ts)) = T::registers().read(0) {
674 let ts = T::registers().calc_timestamp(ns_per_timer_tick, ts);
675 Some(Ok(FdEnvelope { ts, frame }))
676 } else if let Some((frame, ts)) = T::registers().read(1) {
677 let ts = T::registers().calc_timestamp(ns_per_timer_tick, ts);
678 Some(Ok(FdEnvelope { ts, frame }))
679 } else if let Some(err) = T::registers().curr_error() {
680 Some(Err(err))
682 } else {
683 None
684 }
685 }
686
687 fn read<F: CanHeader>(info: &'static Info, ns_per_timer_tick: u64) -> Option<Result<(F, Timestamp), BusError>> {
688 if let Some((msg, ts)) = info.regs.read(0) {
689 let ts = info.regs.calc_timestamp(ns_per_timer_tick, ts);
690 Some(Ok((msg, ts)))
691 } else if let Some((msg, ts)) = info.regs.read(1) {
692 let ts = info.regs.calc_timestamp(ns_per_timer_tick, ts);
693 Some(Ok((msg, ts)))
694 } else if let Some(err) = info.regs.curr_error() {
695 Some(Err(err))
697 } else {
698 None
699 }
700 }
701
702 async fn read_async<F: CanHeader>(info: &'static Info) -> Result<(F, Timestamp), BusError> {
703 poll_fn(move |cx| {
704 let ns_per_timer_tick = info.state.lock(|s| {
705 let state = s.borrow_mut();
706 state.err_waker.register(cx.waker());
707 state.rx_mode.register(cx.waker());
708 state.ns_per_timer_tick
709 });
710 match RxMode::read::<_>(info, ns_per_timer_tick) {
711 Some(result) => Poll::Ready(result),
712 None => Poll::Pending,
713 }
714 })
715 .await
716 }
717
718 async fn read_classic(info: &'static Info) -> Result<Envelope, BusError> {
719 match RxMode::read_async::<_>(info).await {
720 Ok((frame, ts)) => Ok(Envelope { ts, frame }),
721 Err(e) => Err(e),
722 }
723 }
724
725 async fn read_fd(info: &'static Info) -> Result<FdEnvelope, BusError> {
726 match RxMode::read_async::<_>(info).await {
727 Ok((frame, ts)) => Ok(FdEnvelope { ts, frame }),
728 Err(e) => Err(e),
729 }
730 }
731}
732
733enum TxMode {
734 NonBuffered(AtomicWaker),
735 ClassicBuffered(super::common::ClassicBufferedTxInner),
736 FdBuffered(super::common::FdBufferedTxInner),
737}
738
739impl TxMode {
740 fn register(&self, arg: &core::task::Waker) {
741 match self {
742 TxMode::NonBuffered(waker) => {
743 waker.register(arg);
744 }
745 _ => {
746 panic!("Bad mode");
747 }
748 }
749 }
750
751 async fn write_generic<F: embedded_can::Frame + CanHeader>(info: &'static Info, frame: &F) -> Option<F> {
756 poll_fn(|cx| {
757 info.state.lock(|s| {
758 s.borrow_mut().tx_mode.register(cx.waker());
759 });
760
761 if let Ok(dropped) = info.regs.write(frame) {
762 return Poll::Ready(dropped);
763 }
764
765 Poll::Pending
768 })
769 .await
770 }
771
772 async fn write(info: &'static Info, frame: &Frame) -> Option<Frame> {
777 TxMode::write_generic::<_>(info, frame).await
778 }
779
780 async fn write_fd(info: &'static Info, frame: &FdFrame) -> Option<FdFrame> {
785 TxMode::write_generic::<_>(info, frame).await
786 }
787}
788
789pub struct Properties {
791 info: &'static Info,
792 }
795
796impl Properties {
797 fn new(info: &'static Info) -> Self {
798 Self {
799 info,
800 }
802 }
803
804 #[inline]
806 pub fn set_standard_filter(&self, slot: StandardFilterSlot, filter: StandardFilter) {
807 self.info.regs.msg_ram_mut().filters.flssa[slot as usize].activate(filter);
808 }
809
810 pub fn set_standard_filters(&self, filters: &[StandardFilter; STANDARD_FILTER_MAX as usize]) {
813 for (i, f) in filters.iter().enumerate() {
814 self.info.regs.msg_ram_mut().filters.flssa[i].activate(*f);
815 }
816 }
817
818 #[inline]
820 pub fn set_extended_filter(&self, slot: ExtendedFilterSlot, filter: ExtendedFilter) {
821 self.info.regs.msg_ram_mut().filters.flesa[slot as usize].activate(filter);
822 }
823
824 pub fn set_extended_filters(&self, filters: &[ExtendedFilter; EXTENDED_FILTER_MAX as usize]) {
827 for (i, f) in filters.iter().enumerate() {
828 self.info.regs.msg_ram_mut().filters.flesa[i].activate(*f);
829 }
830 }
831
832 pub fn rx_error_count(&self) -> u8 {
834 self.info.regs.regs.ecr().read().rec()
835 }
836
837 pub fn tx_error_count(&self) -> u8 {
839 self.info.regs.regs.ecr().read().tec()
840 }
841
842 pub fn bus_error_mode(&self) -> BusErrorMode {
844 let psr = self.info.regs.regs.psr().read();
848 match (psr.bo(), psr.ep()) {
849 (false, false) => BusErrorMode::ErrorActive,
850 (false, true) => BusErrorMode::ErrorPassive,
851 (true, _) => BusErrorMode::BusOff,
852 }
853 }
854}
855
856struct State {
857 pub rx_mode: RxMode,
858 pub tx_mode: TxMode,
859 pub ns_per_timer_tick: u64,
860 receiver_instance_count: usize,
861 sender_instance_count: usize,
862 tx_pin_port: Option<u8>,
863 rx_pin_port: Option<u8>,
864
865 pub err_waker: AtomicWaker,
866}
867
868impl State {
869 const fn new() -> Self {
870 Self {
871 rx_mode: RxMode::NonBuffered(AtomicWaker::new()),
872 tx_mode: TxMode::NonBuffered(AtomicWaker::new()),
873 ns_per_timer_tick: 0,
874 err_waker: AtomicWaker::new(),
875 receiver_instance_count: 0,
876 sender_instance_count: 0,
877 tx_pin_port: None,
878 rx_pin_port: None,
879 }
880 }
881}
882
883type SharedState = embassy_sync::blocking_mutex::Mutex<CriticalSectionRawMutex, core::cell::RefCell<State>>;
884pub(crate) struct Info {
885 regs: Registers,
886 interrupt0: crate::interrupt::Interrupt,
887 _interrupt1: crate::interrupt::Interrupt,
888 pub(crate) tx_waker: fn(),
889 state: SharedState,
890}
891
892impl Info {
893 pub(crate) fn adjust_reference_counter(&self, val: RefCountOp) {
894 self.state.lock(|s| {
895 let mut mut_state = s.borrow_mut();
896 match val {
897 RefCountOp::NotifySenderCreated => {
898 mut_state.sender_instance_count += 1;
899 }
900 RefCountOp::NotifySenderDestroyed => {
901 mut_state.sender_instance_count -= 1;
902 if 0 == mut_state.sender_instance_count {
903 (*mut_state).tx_mode = TxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
904 }
905 }
906 RefCountOp::NotifyReceiverCreated => {
907 mut_state.receiver_instance_count += 1;
908 }
909 RefCountOp::NotifyReceiverDestroyed => {
910 mut_state.receiver_instance_count -= 1;
911 if 0 == mut_state.receiver_instance_count {
912 (*mut_state).rx_mode = RxMode::NonBuffered(embassy_sync::waitqueue::AtomicWaker::new());
913 }
914 }
915 }
916 if mut_state.sender_instance_count == 0 && mut_state.receiver_instance_count == 0 {
917 unsafe {
918 let tx_pin = crate::gpio::AnyPin::steal(mut_state.tx_pin_port.unwrap());
919 tx_pin.set_as_disconnected();
920 let rx_pin = crate::gpio::AnyPin::steal(mut_state.rx_pin_port.unwrap());
921 rx_pin.set_as_disconnected();
922 self.interrupt0.disable();
923 }
924 }
925 });
926 }
927}
928
929trait SealedInstance {
930 const MSG_RAM_OFFSET: usize;
931
932 fn info() -> &'static Info;
933 fn registers() -> crate::can::fd::peripheral::Registers;
934}
935
936#[allow(private_bounds)]
938pub trait Instance: SealedInstance + PeripheralType + RccPeripheral + 'static {
939 type IT0Interrupt: crate::interrupt::typelevel::Interrupt;
941 type IT1Interrupt: crate::interrupt::typelevel::Interrupt;
943}
944
945pub struct FdcanInstance<'a, T: Instance>(Peri<'a, T>);
947
948macro_rules! impl_fdcan {
949 ($inst:ident,
950 $msg_ram_inst:ident, $msg_ram_offset:literal) => {
952 impl SealedInstance for peripherals::$inst {
953 const MSG_RAM_OFFSET: usize = $msg_ram_offset;
954
955 fn info() -> &'static Info {
956
957 static INFO: Info = Info {
958 regs: Registers{regs: crate::pac::$inst, msgram: crate::pac::$msg_ram_inst, msg_ram_offset: $msg_ram_offset},
959 interrupt0: crate::_generated::peripheral_interrupts::$inst::IT0::IRQ,
960 _interrupt1: crate::_generated::peripheral_interrupts::$inst::IT1::IRQ,
961 tx_waker: crate::_generated::peripheral_interrupts::$inst::IT0::pend,
962 state: embassy_sync::blocking_mutex::Mutex::new(core::cell::RefCell::new(State::new())),
963 };
964 &INFO
965 }
966 fn registers() -> Registers {
967 Registers{regs: crate::pac::$inst, msgram: crate::pac::$msg_ram_inst, msg_ram_offset: Self::MSG_RAM_OFFSET}
968 }
969
970 }
971
972 #[allow(non_snake_case)]
973 pub(crate) mod $inst {
974
975 foreach_interrupt!(
976 ($inst,can,FDCAN,IT0,$irq:ident) => {
977 pub type Interrupt0 = crate::interrupt::typelevel::$irq;
978 };
979 ($inst,can,FDCAN,IT1,$irq:ident) => {
980 pub type Interrupt1 = crate::interrupt::typelevel::$irq;
981 };
982 );
983 }
984 impl Instance for peripherals::$inst {
985 type IT0Interrupt = $inst::Interrupt0;
986 type IT1Interrupt = $inst::Interrupt1;
987 }
988 };
989
990 ($inst:ident, $msg_ram_inst:ident) => {
991 impl_fdcan!($inst, $msg_ram_inst, 0);
992 };
993}
994
995#[cfg(not(can_fdcan_h7))]
996foreach_peripheral!(
997 (can, FDCAN) => { impl_fdcan!(FDCAN, FDCANRAM); };
998 (can, FDCAN1) => { impl_fdcan!(FDCAN1, FDCANRAM1); };
999 (can, FDCAN2) => { impl_fdcan!(FDCAN2, FDCANRAM2); };
1000 (can, FDCAN3) => { impl_fdcan!(FDCAN3, FDCANRAM3); };
1001);
1002
1003#[cfg(can_fdcan_h7)]
1004foreach_peripheral!(
1005 (can, FDCAN1) => { impl_fdcan!(FDCAN1, FDCANRAM, 0x0000); };
1006 (can, FDCAN2) => { impl_fdcan!(FDCAN2, FDCANRAM, 0x0C00); };
1007 (can, FDCAN3) => { impl_fdcan!(FDCAN3, FDCANRAM, 0x1800); };
1008);
1009
1010pin_trait!(RxPin, Instance);
1011pin_trait!(TxPin, Instance);