1#, "/api-reference/peripherals/twai.html#twai-protocol-summary)")]
11#![doc = crate::before_snippet!()]
28#![doc = crate::before_snippet!()]
76use core::marker::PhantomData;
122
123use self::filter::{Filter, FilterType};
124use crate::{
125 Async,
126 Blocking,
127 DriverMode,
128 gpio::{
129 DriveMode,
130 InputConfig,
131 InputSignal,
132 OutputConfig,
133 OutputSignal,
134 Pull,
135 interconnect::{PeripheralInput, PeripheralOutput},
136 },
137 interrupt::InterruptHandler,
138 pac::twai0::RegisterBlock,
139 system::{Cpu, PeripheralGuard},
140 twai::filter::SingleStandardFilter,
141};
142
143pub mod filter;
144
145#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
152#[non_exhaustive]
153pub enum ErrorKind {
154 Overrun,
156 Bit,
160 Stuff,
164 Crc,
166 Form,
169 Acknowledge,
172 Other,
175}
176
177macro_rules! impl_display {
178 ($($kind:ident => $msg:expr),* $(,)?) => {
179 impl core::fmt::Display for ErrorKind {
180 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
181 match self {
182 $(Self::$kind => write!(f, $msg)),*
183 }
184 }
185 }
186
187 #[cfg(feature = "defmt")]
188 impl defmt::Format for ErrorKind {
189 fn format(&self, f: defmt::Formatter<'_>) {
190 match self {
191 $(Self::$kind => defmt::write!(f, $msg)),*
192 }
193 }
194 }
195 };
196}
197
198impl_display! {
199 Overrun => "The peripheral receive buffer was overrun",
200 Bit => "Bit value that is monitored differs from the bit value sent",
201 Stuff => "Sixth consecutive equal bits detected",
202 Crc => "Calculated CRC sequence does not equal the received one",
203 Form => "A fixed-form bit field contains one or more illegal bits",
204 Acknowledge => "Transmitted frame was not acknowledged",
205 Other => "A different error occurred. The original error may contain more information",
206}
207
208#[instability::unstable]
209impl From<ErrorKind> for embedded_can::ErrorKind {
210 fn from(value: ErrorKind) -> Self {
211 match value {
212 ErrorKind::Overrun => embedded_can::ErrorKind::Overrun,
213 ErrorKind::Bit => embedded_can::ErrorKind::Bit,
214 ErrorKind::Stuff => embedded_can::ErrorKind::Stuff,
215 ErrorKind::Crc => embedded_can::ErrorKind::Crc,
216 ErrorKind::Form => embedded_can::ErrorKind::Form,
217 ErrorKind::Acknowledge => embedded_can::ErrorKind::Acknowledge,
218 ErrorKind::Other => embedded_can::ErrorKind::Other,
219 }
220 }
221}
222
223#[instability::unstable]
224impl embedded_can::Error for ErrorKind {
225 fn kind(&self) -> embedded_can::ErrorKind {
226 (*self).into()
227 }
228}
229
230#[derive(Debug, Copy, Clone, Eq, PartialEq)]
232#[cfg_attr(feature = "defmt", derive(defmt::Format))]
233pub enum TwaiMode {
234 Normal,
236 SelfTest,
239 ListenOnly,
241}
242
243#[derive(Debug, Copy, Clone, Eq, PartialEq)]
245#[cfg_attr(feature = "defmt", derive(defmt::Format))]
246pub struct StandardId(u16);
247
248impl StandardId {
249 pub const ZERO: Self = StandardId(0);
251
252 pub const MAX: Self = StandardId(0x7FF);
254
255 #[inline]
260 pub fn new(raw: u16) -> Option<Self> {
261 if raw <= 0x7FF {
262 Some(StandardId(raw))
263 } else {
264 None
265 }
266 }
267
268 #[inline]
274 pub const unsafe fn new_unchecked(raw: u16) -> Self {
275 StandardId(raw)
276 }
277
278 #[inline]
280 pub fn as_raw(&self) -> u16 {
281 self.0
282 }
283}
284
285#[instability::unstable]
286impl From<StandardId> for embedded_can::StandardId {
287 fn from(value: StandardId) -> Self {
288 embedded_can::StandardId::new(value.as_raw()).unwrap()
289 }
290}
291
292#[instability::unstable]
293impl From<embedded_can::StandardId> for StandardId {
294 fn from(value: embedded_can::StandardId) -> Self {
295 StandardId::new(value.as_raw()).unwrap()
296 }
297}
298
299#[derive(Debug, Copy, Clone, Eq, PartialEq)]
301#[cfg_attr(feature = "defmt", derive(defmt::Format))]
302pub struct ExtendedId(u32);
303
304impl ExtendedId {
305 pub const ZERO: Self = ExtendedId(0);
307
308 pub const MAX: Self = ExtendedId(0x1FFF_FFFF);
310
311 #[inline]
316 pub fn new(raw: u32) -> Option<Self> {
317 if raw <= 0x1FFF_FFFF {
318 Some(ExtendedId(raw))
319 } else {
320 None
321 }
322 }
323
324 #[inline]
330 pub const unsafe fn new_unchecked(raw: u32) -> Self {
331 ExtendedId(raw)
332 }
333
334 #[inline]
336 pub fn as_raw(&self) -> u32 {
337 self.0
338 }
339
340 pub fn standard_id(&self) -> StandardId {
342 StandardId((self.0 >> 18) as u16)
344 }
345}
346
347#[instability::unstable]
348impl From<ExtendedId> for embedded_can::ExtendedId {
349 fn from(value: ExtendedId) -> Self {
350 embedded_can::ExtendedId::new(value.0).unwrap()
351 }
352}
353
354#[instability::unstable]
355impl From<embedded_can::ExtendedId> for ExtendedId {
356 fn from(value: embedded_can::ExtendedId) -> Self {
357 ExtendedId::new(value.as_raw()).unwrap()
358 }
359}
360
361#[derive(Debug, Copy, Clone, Eq, PartialEq)]
363#[cfg_attr(feature = "defmt", derive(defmt::Format))]
364pub enum Id {
365 Standard(StandardId),
367 Extended(ExtendedId),
369}
370
371impl From<StandardId> for Id {
372 #[inline]
373 fn from(id: StandardId) -> Self {
374 Id::Standard(id)
375 }
376}
377
378impl From<ExtendedId> for Id {
379 #[inline]
380 fn from(id: ExtendedId) -> Self {
381 Id::Extended(id)
382 }
383}
384
385#[instability::unstable]
386impl From<Id> for embedded_can::Id {
387 fn from(value: Id) -> Self {
388 match value {
389 Id::Standard(id) => embedded_can::Id::Standard(id.into()),
390 Id::Extended(id) => embedded_can::Id::Extended(id.into()),
391 }
392 }
393}
394
395#[instability::unstable]
396impl From<embedded_can::Id> for Id {
397 fn from(value: embedded_can::Id) -> Self {
398 match value {
399 embedded_can::Id::Standard(id) => Id::Standard(id.into()),
400 embedded_can::Id::Extended(id) => Id::Extended(id.into()),
401 }
402 }
403}
404
405#[derive(Clone, Copy, Debug)]
407#[cfg_attr(feature = "defmt", derive(defmt::Format))]
408pub struct EspTwaiFrame {
409 id: Id,
410 dlc: usize,
411 data: [u8; 8],
412 is_remote: bool,
413 self_reception: bool,
414}
415
416impl EspTwaiFrame {
417 pub fn new(id: impl Into<Id>, data: &[u8]) -> Option<Self> {
419 if data.len() > 8 {
421 return None;
422 }
423
424 let mut d: [u8; 8] = [0; 8];
425 d[..data.len()].copy_from_slice(data);
426
427 Some(EspTwaiFrame {
428 id: id.into(),
429 data: d,
430 dlc: data.len(),
431 is_remote: false,
432 self_reception: false,
433 })
434 }
435
436 pub fn new_remote(id: impl Into<Id>, dlc: usize) -> Option<Self> {
439 if dlc > 8 {
441 return None;
442 }
443
444 Some(EspTwaiFrame {
445 id: id.into(),
446 data: [0; 8],
447 dlc,
448 is_remote: true,
449 self_reception: false,
450 })
451 }
452
453 pub fn new_self_reception(id: impl Into<Id>, data: &[u8]) -> Option<Self> {
456 if data.len() > 8 {
457 return None;
458 }
459
460 let mut d: [u8; 8] = [0; 8];
461 d[..data.len()].copy_from_slice(data);
462
463 Some(EspTwaiFrame {
464 id: id.into(),
465 data: d,
466 dlc: data.len(),
467 is_remote: false,
468 self_reception: true,
469 })
470 }
471
472 unsafe fn new_from_data_registers(
478 id: impl Into<Id>,
479 registers: *const u32,
480 dlc: usize,
481 ) -> Self {
482 let mut data: [u8; 8] = [0; 8];
483
484 unsafe {
486 copy_from_data_register(&mut data[..dlc], registers);
487 }
488
489 Self {
490 id: id.into(),
491 data,
492 dlc,
493 is_remote: false,
494 self_reception: false,
495 }
496 }
497}
498
499#[instability::unstable]
500impl embedded_can::Frame for EspTwaiFrame {
501 fn new(id: impl Into<embedded_can::Id>, data: &[u8]) -> Option<Self> {
502 Self::new(id.into(), data)
503 }
504
505 fn new_remote(id: impl Into<embedded_can::Id>, dlc: usize) -> Option<Self> {
506 Self::new_remote(id.into(), dlc)
507 }
508
509 fn is_extended(&self) -> bool {
510 matches!(self.id, Id::Extended(_))
511 }
512
513 fn is_remote_frame(&self) -> bool {
514 self.is_remote
515 }
516
517 fn id(&self) -> embedded_can::Id {
518 self.id.into()
519 }
520
521 fn dlc(&self) -> usize {
522 self.dlc
523 }
524
525 fn data(&self) -> &[u8] {
526 match self.is_remote {
529 true => &[],
530 false => &self.data[0..self.dlc],
531 }
532 }
533}
534
535#[derive(Debug, Copy, Clone, Eq, PartialEq)]
537#[cfg_attr(feature = "defmt", derive(defmt::Format))]
538pub struct TimingConfig {
539 pub baud_rate_prescaler: u16,
542
543 pub sync_jump_width: u8,
547
548 pub tseg_1: u8,
550
551 pub tseg_2: u8,
553
554 pub triple_sample: bool,
557}
558
559#[derive(Debug, Copy, Clone, Eq, PartialEq)]
563#[cfg_attr(feature = "defmt", derive(defmt::Format))]
564pub enum BaudRate {
565 B125K,
567 B250K,
569 B500K,
571 B1000K,
573 Custom(TimingConfig),
578}
579
580impl BaudRate {
581 const fn timing(self) -> TimingConfig {
584 #[cfg(not(esp32h2))]
585 let timing = match self {
586 Self::B125K => TimingConfig {
587 baud_rate_prescaler: 32,
588 sync_jump_width: 3,
589 tseg_1: 15,
590 tseg_2: 4,
591 triple_sample: false,
592 },
593 Self::B250K => TimingConfig {
594 baud_rate_prescaler: 16,
595 sync_jump_width: 3,
596 tseg_1: 15,
597 tseg_2: 4,
598 triple_sample: false,
599 },
600 Self::B500K => TimingConfig {
601 baud_rate_prescaler: 8,
602 sync_jump_width: 3,
603 tseg_1: 15,
604 tseg_2: 4,
605 triple_sample: false,
606 },
607 Self::B1000K => TimingConfig {
608 baud_rate_prescaler: 4,
609 sync_jump_width: 3,
610 tseg_1: 15,
611 tseg_2: 4,
612 triple_sample: false,
613 },
614 Self::Custom(timing_config) => timing_config,
615 };
616
617 #[cfg(esp32h2)]
618 let timing = match self {
619 Self::B125K => TimingConfig {
620 baud_rate_prescaler: 16,
621 sync_jump_width: 3,
622 tseg_1: 11,
623 tseg_2: 4,
624 triple_sample: false,
625 },
626 Self::B250K => TimingConfig {
627 baud_rate_prescaler: 8,
628 sync_jump_width: 3,
629 tseg_1: 11,
630 tseg_2: 4,
631 triple_sample: false,
632 },
633 Self::B500K => TimingConfig {
634 baud_rate_prescaler: 4,
635 sync_jump_width: 3,
636 tseg_1: 11,
637 tseg_2: 4,
638 triple_sample: false,
639 },
640 Self::B1000K => TimingConfig {
641 baud_rate_prescaler: 2,
642 sync_jump_width: 3,
643 tseg_1: 11,
644 tseg_2: 4,
645 triple_sample: false,
646 },
647 Self::Custom(timing_config) => timing_config,
648 };
649
650 #[cfg(esp32c6)]
652 let timing = TimingConfig {
653 baud_rate_prescaler: timing.baud_rate_prescaler / 2,
654 ..timing
655 };
656
657 timing
658 }
659}
660
661pub struct TwaiConfiguration<'d, Dm: DriverMode> {
663 twai: AnyTwai<'d>,
664 filter: Option<(FilterType, [u8; 8])>,
665 phantom: PhantomData<Dm>,
666 mode: TwaiMode,
667 _guard: PeripheralGuard,
668}
669
670impl<'d, Dm> TwaiConfiguration<'d, Dm>
671where
672 Dm: DriverMode,
673{
674 fn new_internal(
675 twai: AnyTwai<'d>,
676 rx_pin: impl PeripheralInput<'d>,
677 tx_pin: impl PeripheralOutput<'d>,
678 baud_rate: BaudRate,
679 no_transceiver: bool,
680 mode: TwaiMode,
681 ) -> Self {
682 let rx_pin = rx_pin.into();
683 let tx_pin = tx_pin.into();
684
685 let guard = PeripheralGuard::new(twai.peripheral());
686
687 let mut this = TwaiConfiguration {
688 twai,
689 filter: None, phantom: PhantomData,
691 mode,
692 _guard: guard,
693 };
694
695 this.set_filter(
697 const { SingleStandardFilter::new(b"xxxxxxxxxxx", b"x", [b"xxxxxxxx", b"xxxxxxxx"]) },
698 );
699
700 this.regs().mode().write(|w| w.reset_mode().set_bit());
702
703 #[cfg(esp32)]
705 this.regs()
706 .clock_divider()
707 .modify(|_, w| w.ext_mode().set_bit());
708
709 let tx_config = if no_transceiver {
711 OutputConfig::default()
712 .with_drive_mode(DriveMode::OpenDrain)
713 .with_pull(Pull::Up)
714 } else {
715 OutputConfig::default()
716 };
717
718 tx_pin.apply_output_config(&tx_config);
719 rx_pin.apply_input_config(&InputConfig::default().with_pull(if no_transceiver {
720 Pull::Up
721 } else {
722 Pull::None
723 }));
724
725 tx_pin.set_output_enable(true);
726 rx_pin.set_input_enable(true);
727
728 this.twai.output_signal().connect_to(&tx_pin);
729 this.twai.input_signal().connect_to(&rx_pin);
730
731 this.set_mode(TwaiMode::ListenOnly);
733
734 this.regs()
736 .tx_err_cnt()
737 .write(|w| unsafe { w.tx_err_cnt().bits(0) });
738
739 this.regs()
741 .rx_err_cnt()
742 .write(|w| unsafe { w.rx_err_cnt().bits(0) });
743
744 this.regs()
746 .err_warning_limit()
747 .write(|w| unsafe { w.err_warning_limit().bits(96) });
748
749 this.set_baud_rate(baud_rate);
750 this
751 }
752
753 fn regs(&self) -> &RegisterBlock {
754 self.twai.register_block()
755 }
756
757 fn internal_set_interrupt_handler(&mut self, handler: InterruptHandler) {
758 for core in Cpu::other() {
759 crate::interrupt::disable(core, self.twai.interrupt());
760 }
761 unsafe { crate::interrupt::bind_interrupt(self.twai.interrupt(), handler.handler()) };
762
763 unwrap!(crate::interrupt::enable(
764 self.twai.interrupt(),
765 handler.priority()
766 ));
767 }
768
769 fn set_baud_rate(&mut self, baud_rate: BaudRate) {
773 #[cfg(not(any(esp32h2, esp32c6)))]
776 {
777 let apb_clock = crate::clock::Clocks::get().apb_clock;
778 assert!(apb_clock.as_mhz() == 80);
779 }
780
781 let timing = baud_rate.timing();
786
787 #[cfg_attr(not(esp32), allow(unused_mut))]
788 let mut prescaler = timing.baud_rate_prescaler;
789
790 #[cfg(esp32)]
791 {
792 if timing.baud_rate_prescaler > 128 {
795 self.regs().int_ena().modify(|_, w| w.brp_div().set_bit());
799 prescaler = timing.baud_rate_prescaler / 2;
800 } else {
801 self.regs().int_ena().modify(|_, w| w.brp_div().clear_bit());
803 }
804 }
805
806 let prescale = (prescaler / 2) - 1;
807 let sjw = timing.sync_jump_width - 1;
808 let tseg_1 = timing.tseg_1 - 1;
809 let tseg_2 = timing.tseg_2 - 1;
810 let triple_sample = timing.triple_sample;
811
812 self.regs().bus_timing_0().modify(|_, w| unsafe {
814 w.baud_presc().bits(prescale as _);
815 w.sync_jump_width().bits(sjw)
816 });
817
818 self.regs().bus_timing_1().modify(|_, w| unsafe {
820 w.time_seg1().bits(tseg_1);
821 w.time_seg2().bits(tseg_2);
822 w.time_samp().bit(triple_sample)
823 });
824
825 self.regs()
827 .clock_divider()
828 .modify(|_, w| w.clock_off().set_bit());
829 }
830
831 pub fn set_filter(&mut self, filter: impl Filter) {
846 self.filter = Some((filter.filter_type(), filter.to_registers()));
849 }
850
851 fn apply_filter(&self) {
852 let Some((filter_type, registers)) = self.filter.as_ref() else {
853 return;
854 };
855
856 self.regs()
858 .mode()
859 .modify(|_, w| w.rx_filter_mode().bit(*filter_type == FilterType::Single));
860
861 unsafe {
863 copy_to_data_register(self.regs().data_0().as_ptr(), registers);
864 }
865 }
866
867 pub fn set_error_warning_limit(&mut self, limit: u8) {
874 self.regs()
875 .err_warning_limit()
876 .write(|w| unsafe { w.err_warning_limit().bits(limit) });
877 }
878
879 fn set_mode(&self, mode: TwaiMode) {
881 self.regs().mode().modify(|_, w| {
882 w.self_test_mode().bit(mode == TwaiMode::SelfTest);
884 w.listen_only_mode().bit(mode == TwaiMode::ListenOnly)
885 });
886 }
887
888 pub fn start(self) -> Twai<'d, Dm> {
891 self.apply_filter();
892 self.set_mode(self.mode);
893
894 self.regs()
896 .tx_err_cnt()
897 .write(|w| unsafe { w.tx_err_cnt().bits(0) });
898
899 let rec =
900 if cfg!(any(esp32, esp32s2, esp32s3, esp32c3)) && self.mode == TwaiMode::ListenOnly {
901 128
907 } else {
908 0
909 };
910 self.regs()
911 .rx_err_cnt()
912 .write(|w| unsafe { w.rx_err_cnt().bits(rec) });
913
914 cfg_if::cfg_if! {
916 if #[cfg(any(esp32, esp32c3, esp32s2, esp32s3))] {
917 let _ = self.regs().int_raw().read();
918 } else {
919 let _ = self.regs().interrupt().read();
920 }
921 }
922
923 self.regs().mode().modify(|_, w| w.reset_mode().clear_bit());
925
926 Twai {
927 rx: TwaiRx {
928 twai: unsafe { self.twai.clone_unchecked() },
929 phantom: PhantomData,
930 _guard: PeripheralGuard::new(self.twai.peripheral()),
931 },
932 tx: TwaiTx {
933 twai: unsafe { self.twai.clone_unchecked() },
934 phantom: PhantomData,
935 _guard: PeripheralGuard::new(self.twai.peripheral()),
936 },
937 twai: unsafe { self.twai.clone_unchecked() },
938 phantom: PhantomData,
939 }
940 }
941}
942
943impl<'d> TwaiConfiguration<'d, Blocking> {
944 pub fn new(
948 peripheral: impl Instance + 'd,
949 rx_pin: impl PeripheralInput<'d>,
950 tx_pin: impl PeripheralOutput<'d>,
951 baud_rate: BaudRate,
952 mode: TwaiMode,
953 ) -> Self {
954 Self::new_internal(peripheral.degrade(), rx_pin, tx_pin, baud_rate, false, mode)
955 }
956
957 pub fn new_no_transceiver(
963 peripheral: impl Instance + 'd,
964 rx_pin: impl PeripheralInput<'d>,
965 tx_pin: impl PeripheralOutput<'d>,
966 baud_rate: BaudRate,
967 mode: TwaiMode,
968 ) -> Self {
969 Self::new_internal(peripheral.degrade(), rx_pin, tx_pin, baud_rate, true, mode)
970 }
971
972 pub fn into_async(mut self) -> TwaiConfiguration<'d, Async> {
974 self.set_interrupt_handler(self.twai.async_handler());
975 TwaiConfiguration {
976 twai: self.twai,
977 filter: self.filter,
978 phantom: PhantomData,
979 mode: self.mode,
980 _guard: self._guard,
981 }
982 }
983
984 #[instability::unstable]
989 pub fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
990 self.internal_set_interrupt_handler(handler);
991 }
992}
993
994impl<'d> TwaiConfiguration<'d, Async> {
995 pub fn into_blocking(self) -> TwaiConfiguration<'d, Blocking> {
997 use crate::{interrupt, system::Cpu};
998
999 interrupt::disable(Cpu::current(), self.twai.interrupt());
1000
1001 TwaiConfiguration {
1003 twai: self.twai,
1004 filter: self.filter,
1005 phantom: PhantomData,
1006 mode: self.mode,
1007 _guard: self._guard,
1008 }
1009 }
1010}
1011
1012impl crate::private::Sealed for TwaiConfiguration<'_, Blocking> {}
1013
1014#[instability::unstable]
1015impl crate::interrupt::InterruptConfigurable for TwaiConfiguration<'_, Blocking> {
1016 fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
1017 self.internal_set_interrupt_handler(handler);
1018 }
1019}
1020
1021pub struct Twai<'d, Dm: DriverMode> {
1026 twai: AnyTwai<'d>,
1027 tx: TwaiTx<'d, Dm>,
1028 rx: TwaiRx<'d, Dm>,
1029 phantom: PhantomData<Dm>,
1030}
1031
1032impl<'d, Dm> Twai<'d, Dm>
1033where
1034 Dm: DriverMode,
1035{
1036 fn regs(&self) -> &RegisterBlock {
1037 self.twai.register_block()
1038 }
1039
1040 fn mode(&self) -> TwaiMode {
1041 let mode = self.regs().mode().read();
1042
1043 if mode.self_test_mode().bit_is_set() {
1044 TwaiMode::SelfTest
1045 } else if mode.listen_only_mode().bit_is_set() {
1046 TwaiMode::ListenOnly
1047 } else {
1048 TwaiMode::Normal
1049 }
1050 }
1051
1052 pub fn stop(self) -> TwaiConfiguration<'d, Dm> {
1055 self.regs().mode().modify(|_, w| w.reset_mode().set_bit());
1058
1059 let mode = self.mode();
1060
1061 let guard = PeripheralGuard::new(self.twai.peripheral());
1062 TwaiConfiguration {
1063 twai: self.twai,
1064 filter: None, phantom: PhantomData,
1066 mode,
1067 _guard: guard,
1068 }
1069 }
1070
1071 pub fn receive_error_count(&self) -> u8 {
1073 self.regs().rx_err_cnt().read().rx_err_cnt().bits()
1074 }
1075
1076 pub fn transmit_error_count(&self) -> u8 {
1078 self.regs().tx_err_cnt().read().tx_err_cnt().bits()
1079 }
1080
1081 pub fn is_bus_off(&self) -> bool {
1083 self.regs().status().read().bus_off_st().bit_is_set()
1084 }
1085
1086 pub fn num_available_messages(&self) -> u8 {
1092 self.regs()
1093 .rx_message_cnt()
1094 .read()
1095 .rx_message_counter()
1096 .bits()
1097 }
1098
1099 pub fn clear_receive_fifo(&self) {
1107 while self.num_available_messages() > 0 {
1108 release_receive_fifo(self.regs());
1109 }
1110 }
1111
1112 pub fn transmit(&mut self, frame: &EspTwaiFrame) -> nb::Result<(), EspTwaiError> {
1114 self.tx.transmit(frame)
1115 }
1116
1117 pub fn receive(&mut self) -> nb::Result<EspTwaiFrame, EspTwaiError> {
1119 self.rx.receive()
1120 }
1121
1122 pub fn split(self) -> (TwaiRx<'d, Dm>, TwaiTx<'d, Dm>) {
1125 (self.rx, self.tx)
1126 }
1127}
1128
1129pub struct TwaiTx<'d, Dm: DriverMode> {
1131 twai: AnyTwai<'d>,
1132 phantom: PhantomData<Dm>,
1133 _guard: PeripheralGuard,
1134}
1135
1136impl<Dm> TwaiTx<'_, Dm>
1137where
1138 Dm: DriverMode,
1139{
1140 fn regs(&self) -> &RegisterBlock {
1141 self.twai.register_block()
1142 }
1143
1144 pub fn transmit(&mut self, frame: &EspTwaiFrame) -> nb::Result<(), EspTwaiError> {
1157 let status = self.regs().status().read();
1158
1159 if status.bus_off_st().bit_is_set() {
1161 return nb::Result::Err(nb::Error::Other(EspTwaiError::BusOff));
1162 }
1163 if !status.tx_buf_st().bit_is_set() {
1165 return nb::Result::Err(nb::Error::WouldBlock);
1166 }
1167
1168 write_frame(self.regs(), frame);
1169
1170 Ok(())
1171 }
1172}
1173
1174pub struct TwaiRx<'d, Dm: DriverMode> {
1176 twai: AnyTwai<'d>,
1177 phantom: PhantomData<Dm>,
1178 _guard: PeripheralGuard,
1179}
1180
1181impl<Dm> TwaiRx<'_, Dm>
1182where
1183 Dm: DriverMode,
1184{
1185 fn regs(&self) -> &RegisterBlock {
1186 self.twai.register_block()
1187 }
1188
1189 pub fn receive(&mut self) -> nb::Result<EspTwaiFrame, EspTwaiError> {
1191 let status = self.regs().status().read();
1192
1193 if status.bus_off_st().bit_is_set() {
1195 return nb::Result::Err(nb::Error::Other(EspTwaiError::BusOff));
1196 }
1197
1198 if !status.rx_buf_st().bit_is_set() {
1200 return nb::Result::Err(nb::Error::WouldBlock);
1201 }
1202
1203 if status.miss_st().bit_is_set() {
1205 return nb::Result::Err(nb::Error::Other(EspTwaiError::EmbeddedHAL(
1206 ErrorKind::Overrun,
1207 )));
1208 }
1209
1210 Ok(read_frame(self.regs())?)
1211 }
1212}
1213
1214#[derive(Debug, Copy, Clone, Eq, PartialEq)]
1218#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1219pub enum EspTwaiError {
1220 BusOff,
1222 NonCompliantDlc(u8),
1224 EmbeddedHAL(ErrorKind),
1226}
1227
1228#[instability::unstable]
1229impl embedded_can::Error for EspTwaiError {
1230 fn kind(&self) -> embedded_can::ErrorKind {
1231 if let Self::EmbeddedHAL(kind) = self {
1232 (*kind).into()
1233 } else {
1234 embedded_can::ErrorKind::Other
1235 }
1236 }
1237}
1238
1239#[inline(always)]
1248unsafe fn copy_from_data_register(dest: &mut [u8], src: *const u32) {
1249 for (i, dest) in dest.iter_mut().enumerate() {
1250 unsafe {
1252 *dest = src.add(i).read_volatile() as u8;
1253 }
1254 }
1255}
1256
1257#[inline(always)]
1266unsafe fn copy_to_data_register(dest: *mut u32, src: &[u8]) {
1267 for (i, src) in src.iter().enumerate() {
1268 unsafe {
1270 dest.add(i).write_volatile(*src as u32);
1271 }
1272 }
1273}
1274
1275#[instability::unstable]
1276impl<Dm> embedded_can::nb::Can for Twai<'_, Dm>
1277where
1278 Dm: DriverMode,
1279{
1280 type Frame = EspTwaiFrame;
1281 type Error = EspTwaiError;
1282
1283 fn transmit(&mut self, frame: &Self::Frame) -> nb::Result<Option<Self::Frame>, Self::Error> {
1285 self.tx.transmit(frame)?;
1286
1287 nb::Result::Ok(None)
1291 }
1292
1293 fn receive(&mut self) -> nb::Result<Self::Frame, Self::Error> {
1295 self.rx.receive()
1296 }
1297}
1298
1299#[doc(hidden)]
1301pub trait PrivateInstance: crate::private::Sealed {
1302 fn number(&self) -> usize;
1304
1305 fn peripheral(&self) -> crate::system::Peripheral;
1307
1308 fn input_signal(&self) -> InputSignal;
1310 fn output_signal(&self) -> OutputSignal;
1312 fn interrupt(&self) -> crate::peripherals::Interrupt;
1314
1315 fn async_handler(&self) -> InterruptHandler;
1317
1318 fn register_block(&self) -> &RegisterBlock;
1320
1321 fn enable_interrupts(&self) {
1323 cfg_if::cfg_if! {
1324 if #[cfg(any(esp32, esp32c3, esp32s2, esp32s3))] {
1325 self.register_block().int_ena().modify(|_, w| {
1326 w.rx_int_ena().set_bit();
1327 w.tx_int_ena().set_bit();
1328 w.bus_err_int_ena().set_bit();
1329 w.arb_lost_int_ena().set_bit();
1330 w.err_passive_int_ena().set_bit()
1331 });
1332 } else {
1333 self.register_block().interrupt_enable().modify(|_, w| {
1334 w.ext_receive_int_ena().set_bit();
1335 w.ext_transmit_int_ena().set_bit();
1336 w.bus_err_int_ena().set_bit();
1337 w.arbitration_lost_int_ena().set_bit();
1338 w.err_passive_int_ena().set_bit()
1339 });
1340 }
1341 }
1342 }
1343
1344 fn async_state(&self) -> &asynch::TwaiAsyncState;
1346}
1347
1348fn read_frame(register_block: &RegisterBlock) -> Result<EspTwaiFrame, EspTwaiError> {
1350 let data_0 = register_block.data_0().read().tx_byte_0().bits();
1352
1353 let is_standard_format = data_0 & (0b1 << 7) == 0;
1354 let is_data_frame = data_0 & (0b1 << 6) == 0;
1355 let self_reception = data_0 & (0b1 << 4) != 0;
1356 let dlc = data_0 & 0b1111;
1357
1358 if dlc > 8 {
1359 release_receive_fifo(register_block);
1362
1363 return Err(EspTwaiError::NonCompliantDlc(dlc));
1364 }
1365 let dlc = dlc as usize;
1366
1367 let (id, data_ptr) = if is_standard_format {
1369 let data_1 = register_block.data_1().read().tx_byte_1().bits();
1371 let data_2 = register_block.data_2().read().tx_byte_2().bits();
1372
1373 let raw_id: u16 = ((data_1 as u16) << 3) | ((data_2 as u16) >> 5);
1374
1375 let id = Id::from(StandardId::new(raw_id).unwrap());
1376 (id, register_block.data_3().as_ptr())
1377 } else {
1378 let data_1 = register_block.data_1().read().tx_byte_1().bits();
1380 let data_2 = register_block.data_2().read().tx_byte_2().bits();
1381 let data_3 = register_block.data_3().read().tx_byte_3().bits();
1382 let data_4 = register_block.data_4().read().tx_byte_4().bits();
1383
1384 let raw_id: u32 = ((data_1 as u32) << 21)
1385 | ((data_2 as u32) << 13)
1386 | ((data_3 as u32) << 5)
1387 | ((data_4 as u32) >> 3);
1388
1389 let id = Id::from(ExtendedId::new(raw_id).unwrap());
1390 (id, register_block.data_5().as_ptr())
1391 };
1392
1393 let mut frame = if is_data_frame {
1394 unsafe { EspTwaiFrame::new_from_data_registers(id, data_ptr, dlc) }
1395 } else {
1396 EspTwaiFrame::new_remote(id, dlc).unwrap()
1397 };
1398 frame.self_reception = self_reception;
1399
1400 release_receive_fifo(register_block);
1403
1404 Ok(frame)
1405}
1406
1407fn release_receive_fifo(register_block: &RegisterBlock) {
1411 register_block.cmd().write(|w| w.release_buf().set_bit());
1412}
1413
1414fn write_frame(register_block: &RegisterBlock, frame: &EspTwaiFrame) {
1416 let frame_format: u8 = matches!(frame.id, Id::Extended(_)) as u8;
1418 let self_reception: u8 = frame.self_reception as u8;
1419 let rtr_bit: u8 = frame.is_remote as u8;
1420 let dlc_bits: u8 = frame.dlc as u8 & 0b1111;
1421
1422 let data_0: u8 = (frame_format << 7) | (rtr_bit << 6) | (self_reception << 4) | dlc_bits;
1423
1424 register_block
1425 .data_0()
1426 .write(|w| unsafe { w.tx_byte_0().bits(data_0) });
1427
1428 let data_ptr = match frame.id {
1431 Id::Standard(id) => {
1432 let id = id.as_raw();
1433
1434 register_block
1435 .data_1()
1436 .write(|w| unsafe { w.tx_byte_1().bits((id >> 3) as u8) });
1437
1438 register_block
1439 .data_2()
1440 .write(|w| unsafe { w.tx_byte_2().bits((id << 5) as u8) });
1441
1442 register_block.data_3().as_ptr()
1443 }
1444 Id::Extended(id) => {
1445 let id = id.as_raw();
1446
1447 register_block
1448 .data_1()
1449 .write(|w| unsafe { w.tx_byte_1().bits((id >> 21) as u8) });
1450 register_block
1451 .data_2()
1452 .write(|w| unsafe { w.tx_byte_2().bits((id >> 13) as u8) });
1453 register_block
1454 .data_3()
1455 .write(|w| unsafe { w.tx_byte_3().bits((id >> 5) as u8) });
1456 register_block
1457 .data_4()
1458 .write(|w| unsafe { w.tx_byte_4().bits((id << 3) as u8) });
1459
1460 register_block.data_5().as_ptr()
1461 }
1462 };
1463
1464 unsafe {
1466 copy_to_data_register(
1467 data_ptr,
1468 match frame.is_remote {
1469 true => &[], false => &frame.data[0..frame.dlc],
1471 },
1472 )
1473 }
1474
1475 if frame.self_reception {
1477 register_block.cmd().write(|w| w.self_rx_req().set_bit());
1478 } else {
1479 register_block.cmd().write(|w| w.tx_req().set_bit());
1482 }
1483}
1484
1485impl PrivateInstance for crate::peripherals::TWAI0<'_> {
1486 fn number(&self) -> usize {
1487 0
1488 }
1489
1490 fn peripheral(&self) -> crate::system::Peripheral {
1491 crate::system::Peripheral::Twai0
1492 }
1493
1494 fn input_signal(&self) -> InputSignal {
1495 cfg_if::cfg_if! {
1496 if #[cfg(any(esp32, esp32c3, esp32s2, esp32s3))] {
1497 InputSignal::TWAI_RX
1498 } else {
1499 InputSignal::TWAI0_RX
1500 }
1501 }
1502 }
1503
1504 fn output_signal(&self) -> OutputSignal {
1505 cfg_if::cfg_if! {
1506 if #[cfg(any(esp32, esp32c3, esp32s2, esp32s3))] {
1507 OutputSignal::TWAI_TX
1508 } else {
1509 OutputSignal::TWAI0_TX
1510 }
1511 }
1512 }
1513
1514 fn interrupt(&self) -> crate::peripherals::Interrupt {
1515 crate::peripherals::Interrupt::TWAI0
1516 }
1517
1518 fn async_handler(&self) -> InterruptHandler {
1519 asynch::twai0
1520 }
1521
1522 #[inline(always)]
1523 fn register_block(&self) -> &RegisterBlock {
1524 crate::peripherals::TWAI0::regs()
1525 }
1526
1527 fn async_state(&self) -> &asynch::TwaiAsyncState {
1528 static STATE: asynch::TwaiAsyncState = asynch::TwaiAsyncState::new();
1529 &STATE
1530 }
1531}
1532
1533#[cfg(twai1)]
1534impl PrivateInstance for crate::peripherals::TWAI1<'_> {
1535 fn number(&self) -> usize {
1536 1
1537 }
1538
1539 fn peripheral(&self) -> crate::system::Peripheral {
1540 crate::system::Peripheral::Twai1
1541 }
1542
1543 fn input_signal(&self) -> InputSignal {
1544 InputSignal::TWAI1_RX
1545 }
1546
1547 fn output_signal(&self) -> OutputSignal {
1548 OutputSignal::TWAI1_TX
1549 }
1550
1551 fn interrupt(&self) -> crate::peripherals::Interrupt {
1552 crate::peripherals::Interrupt::TWAI1
1553 }
1554
1555 fn async_handler(&self) -> InterruptHandler {
1556 asynch::twai1
1557 }
1558
1559 #[inline(always)]
1560 fn register_block(&self) -> &RegisterBlock {
1561 crate::peripherals::TWAI1::regs()
1562 }
1563
1564 fn async_state(&self) -> &asynch::TwaiAsyncState {
1565 static STATE: asynch::TwaiAsyncState = asynch::TwaiAsyncState::new();
1566 &STATE
1567 }
1568}
1569
1570crate::any_peripheral! {
1571 pub peripheral AnyTwai<'d> {
1573 #[cfg(twai0)]
1574 Twai0(crate::peripherals::TWAI0<'d>),
1575 #[cfg(twai1)]
1576 Twai1(crate::peripherals::TWAI1<'d>),
1577 }
1578}
1579
1580impl PrivateInstance for AnyTwai<'_> {
1581 delegate::delegate! {
1582 to match &self.0 {
1583 #[cfg(twai0)]
1584 AnyTwaiInner::Twai0(twai) => twai,
1585 #[cfg(twai1)]
1586 AnyTwaiInner::Twai1(twai) => twai,
1587 } {
1588 fn number(&self) -> usize;
1589 fn peripheral(&self) -> crate::system::Peripheral;
1590 fn input_signal(&self) -> InputSignal;
1591 fn output_signal(&self) -> OutputSignal;
1592 fn interrupt(&self) -> crate::peripherals::Interrupt;
1593 fn async_handler(&self) -> InterruptHandler;
1594 fn register_block(&self) -> &RegisterBlock;
1595 fn async_state(&self) -> &asynch::TwaiAsyncState;
1596 }
1597 }
1598}
1599
1600pub trait Instance: PrivateInstance + IntoAnyTwai {}
1602
1603impl Instance for crate::peripherals::TWAI0<'_> {}
1604#[cfg(twai1)]
1605impl Instance for crate::peripherals::TWAI1<'_> {}
1606impl Instance for AnyTwai<'_> {}
1607
1608mod asynch {
1609 use core::{future::poll_fn, task::Poll};
1610
1611 use embassy_sync::{
1612 blocking_mutex::raw::CriticalSectionRawMutex,
1613 channel::Channel,
1614 waitqueue::AtomicWaker,
1615 };
1616 use procmacros::handler;
1617
1618 use super::*;
1619 use crate::peripherals::TWAI0;
1620 #[cfg(twai1)]
1621 use crate::peripherals::TWAI1;
1622
1623 pub struct TwaiAsyncState {
1624 pub tx_waker: AtomicWaker,
1625 pub err_waker: AtomicWaker,
1626 pub rx_queue: Channel<CriticalSectionRawMutex, Result<EspTwaiFrame, EspTwaiError>, 32>,
1627 }
1628
1629 impl Default for TwaiAsyncState {
1630 fn default() -> Self {
1631 Self::new()
1632 }
1633 }
1634
1635 impl TwaiAsyncState {
1636 pub const fn new() -> Self {
1637 Self {
1638 tx_waker: AtomicWaker::new(),
1639 err_waker: AtomicWaker::new(),
1640 rx_queue: Channel::new(),
1641 }
1642 }
1643 }
1644
1645 impl Twai<'_, Async> {
1646 pub async fn transmit_async(&mut self, frame: &EspTwaiFrame) -> Result<(), EspTwaiError> {
1654 self.tx.transmit_async(frame).await
1655 }
1656 pub async fn receive_async(&mut self) -> Result<EspTwaiFrame, EspTwaiError> {
1658 self.rx.receive_async().await
1659 }
1660 }
1661
1662 #[must_use = "futures do nothing unless you `.await` or poll them"]
1663 pub struct TransmitFuture<'d, 'f> {
1664 twai: AnyTwai<'d>,
1665 frame: &'f EspTwaiFrame,
1666 in_flight: bool,
1667 }
1668
1669 impl<'d, 'f> TransmitFuture<'d, 'f> {
1670 pub fn new(twai: AnyTwai<'d>, frame: &'f EspTwaiFrame) -> Self {
1671 Self {
1672 twai,
1673 frame,
1674 in_flight: false,
1675 }
1676 }
1677 }
1678
1679 impl core::future::Future for TransmitFuture<'_, '_> {
1680 type Output = Result<(), EspTwaiError>;
1681
1682 fn poll(
1683 mut self: core::pin::Pin<&mut Self>,
1684 cx: &mut core::task::Context<'_>,
1685 ) -> Poll<Self::Output> {
1686 self.twai.async_state().tx_waker.register(cx.waker());
1687
1688 let regs = self.twai.register_block();
1689 let status = regs.status().read();
1690
1691 if status.bus_off_st().bit_is_set() {
1693 return Poll::Ready(Err(EspTwaiError::BusOff));
1694 }
1695
1696 if !status.tx_buf_st().bit_is_set() {
1698 return Poll::Pending;
1699 }
1700
1701 if !self.in_flight {
1702 write_frame(regs, self.frame);
1703 self.in_flight = true;
1704 return Poll::Pending;
1705 }
1706
1707 Poll::Ready(Ok(()))
1708 }
1709 }
1710
1711 impl Drop for TransmitFuture<'_, '_> {
1712 fn drop(&mut self) {
1713 self.twai
1714 .register_block()
1715 .cmd()
1716 .write(|w| w.abort_tx().set_bit());
1717 }
1718 }
1719
1720 impl TwaiTx<'_, Async> {
1721 pub async fn transmit_async(&mut self, frame: &EspTwaiFrame) -> Result<(), EspTwaiError> {
1729 self.twai.enable_interrupts();
1730 TransmitFuture::new(self.twai.reborrow(), frame).await
1731 }
1732 }
1733
1734 impl TwaiRx<'_, Async> {
1735 pub async fn receive_async(&mut self) -> Result<EspTwaiFrame, EspTwaiError> {
1737 self.twai.enable_interrupts();
1738 poll_fn(|cx| {
1739 self.twai.async_state().err_waker.register(cx.waker());
1740
1741 if let Poll::Ready(result) = self.twai.async_state().rx_queue.poll_receive(cx) {
1742 return Poll::Ready(result);
1743 }
1744
1745 let status = self.regs().status().read();
1746
1747 if status.bus_off_st().bit_is_set() {
1749 return Poll::Ready(Err(EspTwaiError::BusOff));
1750 }
1751
1752 if status.miss_st().bit_is_set() {
1754 return Poll::Ready(Err(EspTwaiError::EmbeddedHAL(ErrorKind::Overrun)));
1755 }
1756
1757 Poll::Pending
1758 })
1759 .await
1760 }
1761 }
1762
1763 fn handle_interrupt(register_block: &RegisterBlock, async_state: &TwaiAsyncState) {
1764 cfg_if::cfg_if! {
1765 if #[cfg(any(esp32, esp32c3, esp32s2, esp32s3))] {
1766 let intr_enable = register_block.int_ena().read();
1767 let intr_status = register_block.int_raw().read();
1768
1769 let int_ena_reg = register_block.int_ena();
1770
1771 let tx_int_status = intr_status.tx_int_st();
1772 let rx_int_status = intr_status.rx_int_st();
1773 } else {
1774 let intr_enable = register_block.interrupt_enable().read();
1775 let intr_status = register_block.interrupt().read();
1776
1777 let int_ena_reg = register_block.interrupt_enable();
1778
1779 let tx_int_status = intr_status.transmit_int_st();
1780 let rx_int_status = intr_status.receive_int_st();
1781 }
1782 }
1783
1784 if tx_int_status.bit_is_set() {
1785 async_state.tx_waker.wake();
1786 }
1787
1788 if rx_int_status.bit_is_set() {
1789 let status = register_block.status().read();
1790
1791 let rx_queue = &async_state.rx_queue;
1792
1793 if status.bus_off_st().bit_is_set() {
1794 let _ = rx_queue.try_send(Err(EspTwaiError::BusOff));
1795 }
1796
1797 if status.miss_st().bit_is_set() {
1798 let _ = rx_queue.try_send(Err(EspTwaiError::EmbeddedHAL(ErrorKind::Overrun)));
1799 }
1800
1801 match read_frame(register_block) {
1802 Ok(frame) => {
1803 let _ = rx_queue.try_send(Ok(frame));
1804 }
1805 Err(e) => warn!("Error reading frame: {:?}", e),
1806 }
1807 }
1808
1809 if intr_status.bits() & 0b11111100 > 0 {
1810 let err_capture = register_block.err_code_cap().read();
1811 let status = register_block.status().read();
1812
1813 let ecc_direction = err_capture.ecc_direction().bit_is_set();
1815
1816 if !ecc_direction && !status.tx_buf_st().bit_is_set() {
1818 register_block.cmd().write(|w| w.abort_tx().set_bit());
1820 }
1821
1822 async_state.err_waker.wake();
1823 }
1824
1825 unsafe {
1827 int_ena_reg.modify(|_, w| w.bits(intr_enable.bits() & (!intr_status.bits() | 1)));
1828 }
1829 }
1830
1831 #[handler]
1832 pub(super) fn twai0() {
1833 let twai = unsafe { TWAI0::steal() };
1834 handle_interrupt(twai.register_block(), twai.async_state());
1835 }
1836
1837 #[cfg(twai1)]
1838 #[handler]
1839 pub(super) fn twai1() {
1840 let twai = unsafe { TWAI1::steal() };
1841 handle_interrupt(twai.register_block(), twai.async_state());
1842 }
1843}