1#![cfg_attr(
24 esp32,
25 doc = "8 channels, each of them can be either receiver or transmitter."
26)]
27#![cfg_attr(
28 esp32s2,
29 doc = "4 channels, each of them can be either receiver or transmitter."
30)]
31#![cfg_attr(
32 esp32s3,
33 doc = "8 channels, `Channel<0>`-`Channel<3>` hardcoded for transmitting signals and `Channel<4>`-`Channel<7>` hardcoded for receiving signals."
34)]
35#![cfg_attr(
36 any(esp32c3, esp32c6, esp32h2),
37 doc = "4 channels, `Channel<0>` and `Channel<1>` hardcoded for transmitting signals and `Channel<2>` and `Channel<3>` hardcoded for receiving signals."
38)]
39#![doc = ""]
40#, "/api-reference/peripherals/rmt.html)")]
42#![doc = crate::before_snippet!()]
54#![cfg_attr(esp32h2, doc = "let freq = Rate::from_mhz(32);")]
60#![cfg_attr(not(esp32h2), doc = "let freq = Rate::from_mhz(80);")]
61#![doc = crate::before_snippet!()]
82#![cfg_attr(esp32h2, doc = "let freq = Rate::from_mhz(32);")]
88#![cfg_attr(not(esp32h2), doc = "let freq = Rate::from_mhz(80);")]
89#![doc = crate::before_snippet!()]
114#![cfg_attr(esp32h2, doc = "let freq = Rate::from_mhz(32);")]
128#![cfg_attr(not(esp32h2), doc = "let freq = Rate::from_mhz(80);")]
129#![cfg_attr(
135 any(esp32, esp32s2),
136 doc = "let mut channel = rmt.channel0.configure(peripherals.GPIO4, rx_config)?;"
137)]
138#![cfg_attr(
139 esp32s3,
140 doc = "let mut channel = rmt.channel7.configure(peripherals.GPIO4, rx_config)?;"
141)]
142#![cfg_attr(
143 not(any(esp32, esp32s2, esp32s3)),
144 doc = "let mut channel = rmt.channel2.configure(peripherals.GPIO4, rx_config)?;"
145)]
146use core::{
223 default::Default,
224 marker::PhantomData,
225 pin::Pin,
226 task::{Context, Poll},
227};
228
229use enumset::{EnumSet, EnumSetType};
230
231use crate::{
232 asynch::AtomicWaker,
233 gpio::{
234 interconnect::{PeripheralInput, PeripheralOutput},
235 Level,
236 },
237 handler,
238 peripheral::Peripheral,
239 peripherals::{Interrupt, RMT},
240 soc::constants,
241 system::{self, GenericPeripheralGuard},
242 time::Rate,
243 Async,
244 Blocking,
245};
246
247#[derive(Debug, Clone, Copy, PartialEq)]
249#[cfg_attr(feature = "defmt", derive(defmt::Format))]
250#[allow(clippy::enum_variant_names, reason = "peripheral is unstable")]
251pub enum Error {
252 UnreachableTargetFrequency,
254 Overflow,
256 InvalidArgument,
258 TransmissionError,
260 EndMarkerMissing,
262}
263
264pub trait PulseCode: crate::private::Sealed {
266 fn new(level1: Level, length1: u16, level2: Level, length2: u16) -> Self;
268
269 fn empty() -> Self;
271
272 fn reset(&mut self);
274
275 fn level1(&self) -> Level;
277
278 fn length1(&self) -> u16;
280
281 fn level2(&self) -> Level;
283
284 fn length2(&self) -> u16;
286}
287
288impl PulseCode for u32 {
289 fn new(level1: Level, length1: u16, level2: Level, length2: u16) -> Self {
290 let level1 = ((bool::from(level1) as u32) << 15) | (length1 as u32 & 0b111_1111_1111_1111);
291 let level2 = ((bool::from(level2) as u32) << 15) | (length2 as u32 & 0b111_1111_1111_1111);
292 level1 | (level2 << 16)
293 }
294
295 fn empty() -> Self {
296 0
297 }
298
299 fn reset(&mut self) {
300 *self = 0
301 }
302
303 fn level1(&self) -> Level {
304 (self & (1 << 15) != 0).into()
305 }
306
307 fn length1(&self) -> u16 {
308 (self & 0b111_1111_1111_1111) as u16
309 }
310
311 fn level2(&self) -> Level {
312 (self & (1 << 31) != 0).into()
313 }
314
315 fn length2(&self) -> u16 {
316 ((self >> 16) & 0b111_1111_1111_1111) as u16
317 }
318}
319
320#[derive(Debug, Copy, Clone, procmacros::BuilderLite)]
322#[cfg_attr(feature = "defmt", derive(defmt::Format))]
323pub struct TxChannelConfig {
324 clk_divider: u8,
326 idle_output_level: Level,
328 idle_output: bool,
330 carrier_modulation: bool,
332 carrier_high: u16,
334 carrier_low: u16,
336 carrier_level: Level,
338}
339
340impl Default for TxChannelConfig {
341 fn default() -> Self {
342 Self {
343 clk_divider: Default::default(),
344 idle_output_level: Level::Low,
345 idle_output: Default::default(),
346 carrier_modulation: Default::default(),
347 carrier_high: Default::default(),
348 carrier_low: Default::default(),
349 carrier_level: Level::Low,
350 }
351 }
352}
353
354#[derive(Debug, Copy, Clone, procmacros::BuilderLite)]
356#[cfg_attr(feature = "defmt", derive(defmt::Format))]
357pub struct RxChannelConfig {
358 clk_divider: u8,
360 carrier_modulation: bool,
362 carrier_high: u16,
364 carrier_low: u16,
366 carrier_level: Level,
368 filter_threshold: u8,
370 idle_threshold: u16,
372}
373
374impl Default for RxChannelConfig {
375 fn default() -> Self {
376 Self {
377 clk_divider: Default::default(),
378 carrier_modulation: Default::default(),
379 carrier_high: Default::default(),
380 carrier_low: Default::default(),
381 carrier_level: Level::Low,
382 filter_threshold: Default::default(),
383 idle_threshold: Default::default(),
384 }
385 }
386}
387
388pub use impl_for_chip::{ChannelCreator, Rmt};
389
390impl<'d, Dm> Rmt<'d, Dm>
391where
392 Dm: crate::DriverMode,
393{
394 pub(crate) fn new_internal(
395 peripheral: impl Peripheral<P = RMT> + 'd,
396 frequency: Rate,
397 ) -> Result<Self, Error> {
398 let me = Rmt::create(peripheral);
399 me.configure_clock(frequency)?;
400 Ok(me)
401 }
402
403 #[cfg(any(esp32, esp32s2))]
404 fn configure_clock(&self, frequency: Rate) -> Result<(), Error> {
405 if frequency != Rate::from_mhz(80) {
406 return Err(Error::UnreachableTargetFrequency);
407 }
408
409 self::chip_specific::configure_clock();
410
411 Ok(())
412 }
413
414 #[cfg(not(any(esp32, esp32s2)))]
415 fn configure_clock(&self, frequency: Rate) -> Result<(), Error> {
416 let src_clock = crate::soc::constants::RMT_CLOCK_SRC_FREQ;
417
418 if frequency > src_clock {
419 return Err(Error::UnreachableTargetFrequency);
420 }
421
422 let div = (src_clock / frequency) - 1;
423
424 if div > u8::MAX as u32 {
425 return Err(Error::UnreachableTargetFrequency);
426 }
427
428 self::chip_specific::configure_clock(div);
429
430 Ok(())
431 }
432}
433
434impl<'d> Rmt<'d, Blocking> {
435 pub fn new(peripheral: impl Peripheral<P = RMT> + 'd, frequency: Rate) -> Result<Self, Error> {
437 Self::new_internal(peripheral, frequency)
438 }
439
440 pub fn into_async(mut self) -> Rmt<'d, Async> {
442 self.set_interrupt_handler(async_interrupt_handler);
443 Rmt::create(self.peripheral)
444 }
445
446 #[instability::unstable]
451 pub fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
452 for core in crate::system::Cpu::other() {
453 crate::interrupt::disable(core, Interrupt::RMT);
454 }
455 unsafe { crate::interrupt::bind_interrupt(Interrupt::RMT, handler.handler()) };
456 unwrap!(crate::interrupt::enable(Interrupt::RMT, handler.priority()));
457 }
458}
459
460impl crate::private::Sealed for Rmt<'_, Blocking> {}
461
462#[instability::unstable]
463impl crate::interrupt::InterruptConfigurable for Rmt<'_, Blocking> {
464 fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
465 self.set_interrupt_handler(handler);
466 }
467}
468
469fn configure_rx_channel<'d, P: PeripheralInput, T: RxChannelInternal>(
470 pin: impl Peripheral<P = P> + 'd,
471 config: RxChannelConfig,
472) -> Result<T, Error> {
473 if config.filter_threshold > 0b111_1111 {
474 return Err(Error::InvalidArgument);
475 }
476
477 cfg_if::cfg_if! {
478 if #[cfg(any(esp32, esp32s2))] {
479 let threshold = 0b111_1111_1111_1111;
480 } else {
481 let threshold = 0b11_1111_1111_1111;
482 }
483 }
484
485 if config.idle_threshold > threshold {
486 return Err(Error::InvalidArgument);
487 }
488
489 crate::into_mapped_ref!(pin);
490 pin.init_input(crate::gpio::Pull::None);
491 T::input_signal().connect_to(pin);
492
493 T::set_divider(config.clk_divider);
494 T::set_carrier(
495 config.carrier_modulation,
496 config.carrier_high,
497 config.carrier_low,
498 config.carrier_level,
499 );
500 T::set_filter_threshold(config.filter_threshold);
501 T::set_idle_threshold(config.idle_threshold);
502
503 Ok(T::new())
504}
505
506fn configure_tx_channel<'d, P: PeripheralOutput, T: TxChannelInternal>(
507 pin: impl Peripheral<P = P> + 'd,
508 config: TxChannelConfig,
509) -> Result<T, Error> {
510 crate::into_mapped_ref!(pin);
511 pin.set_to_push_pull_output();
512 T::output_signal().connect_to(pin);
513
514 T::set_divider(config.clk_divider);
515 T::set_carrier(
516 config.carrier_modulation,
517 config.carrier_high,
518 config.carrier_low,
519 config.carrier_level,
520 );
521 T::set_idle_output(config.idle_output, config.idle_output_level);
522
523 Ok(T::new())
524}
525
526pub trait TxChannelCreator<'d, T, P>
528where
529 P: PeripheralOutput,
530 T: TxChannel,
531{
532 fn configure(
534 self,
535 pin: impl Peripheral<P = P> + 'd,
536 config: TxChannelConfig,
537 ) -> Result<T, Error>
538 where
539 Self: Sized,
540 {
541 configure_tx_channel(pin, config)
542 }
543}
544
545pub trait TxChannelCreatorAsync<'d, T, P>
547where
548 P: PeripheralOutput,
549 T: TxChannelAsync,
550{
551 fn configure(
553 self,
554 pin: impl Peripheral<P = P> + 'd,
555 config: TxChannelConfig,
556 ) -> Result<T, Error>
557 where
558 Self: Sized,
559 {
560 configure_tx_channel(pin, config)
561 }
562}
563
564pub trait RxChannelCreator<'d, T, P>
566where
567 P: PeripheralInput,
568 T: RxChannel,
569{
570 fn configure(
572 self,
573 pin: impl Peripheral<P = P> + 'd,
574 config: RxChannelConfig,
575 ) -> Result<T, Error>
576 where
577 Self: Sized,
578 {
579 configure_rx_channel(pin, config)
580 }
581}
582
583pub trait RxChannelCreatorAsync<'d, T, P>
585where
586 P: PeripheralInput,
587 T: RxChannelAsync,
588{
589 fn configure(
591 self,
592 pin: impl Peripheral<P = P> + 'd,
593 config: RxChannelConfig,
594 ) -> Result<T, Error>
595 where
596 Self: Sized,
597 {
598 configure_rx_channel(pin, config)
599 }
600}
601
602pub struct SingleShotTxTransaction<'a, C>
604where
605 C: TxChannel,
606{
607 channel: C,
608 index: usize,
609 data: &'a [u32],
610}
611
612impl<C> SingleShotTxTransaction<'_, C>
613where
614 C: TxChannel,
615{
616 pub fn wait(mut self) -> Result<C, (Error, C)> {
618 loop {
619 if <C as TxChannelInternal>::is_error() {
620 return Err((Error::TransmissionError, self.channel));
621 }
622
623 if self.index >= self.data.len() {
624 break;
625 }
626
627 while !<C as TxChannelInternal>::is_threshold_set() {}
629 <C as TxChannelInternal>::reset_threshold_set();
630
631 let ram_index = (((self.index - constants::RMT_CHANNEL_RAM_SIZE)
633 / (constants::RMT_CHANNEL_RAM_SIZE / 2))
634 % 2)
635 * (constants::RMT_CHANNEL_RAM_SIZE / 2);
636
637 let ptr = (constants::RMT_RAM_START
638 + C::CHANNEL as usize * constants::RMT_CHANNEL_RAM_SIZE * 4
639 + ram_index * 4) as *mut u32;
640 for (idx, entry) in self.data[self.index..]
641 .iter()
642 .take(constants::RMT_CHANNEL_RAM_SIZE / 2)
643 .enumerate()
644 {
645 unsafe {
646 ptr.add(idx).write_volatile(*entry);
647 }
648 }
649
650 self.index += constants::RMT_CHANNEL_RAM_SIZE / 2;
651 }
652
653 loop {
654 if <C as TxChannelInternal>::is_error() {
655 return Err((Error::TransmissionError, self.channel));
656 }
657
658 if <C as TxChannelInternal>::is_done() {
659 break;
660 }
661 }
662
663 Ok(self.channel)
664 }
665}
666
667pub struct ContinuousTxTransaction<C>
669where
670 C: TxChannel,
671{
672 channel: C,
673}
674
675impl<C> ContinuousTxTransaction<C>
676where
677 C: TxChannel,
678{
679 pub fn stop_next(self) -> Result<C, (Error, C)> {
681 <C as TxChannelInternal>::set_continuous(false);
682 <C as TxChannelInternal>::update();
683
684 loop {
685 if <C as TxChannelInternal>::is_error() {
686 return Err((Error::TransmissionError, self.channel));
687 }
688
689 if <C as TxChannelInternal>::is_done() {
690 break;
691 }
692 }
693
694 Ok(self.channel)
695 }
696
697 pub fn stop(self) -> Result<C, (Error, C)> {
699 <C as TxChannelInternal>::set_continuous(false);
700 <C as TxChannelInternal>::update();
701
702 let ptr = (constants::RMT_RAM_START
703 + C::CHANNEL as usize * constants::RMT_CHANNEL_RAM_SIZE * 4)
704 as *mut u32;
705 for idx in 0..constants::RMT_CHANNEL_RAM_SIZE {
706 unsafe {
707 ptr.add(idx).write_volatile(0);
708 }
709 }
710
711 loop {
712 if <C as TxChannelInternal>::is_error() {
713 return Err((Error::TransmissionError, self.channel));
714 }
715
716 if <C as TxChannelInternal>::is_done() {
717 break;
718 }
719 }
720
721 Ok(self.channel)
722 }
723
724 pub fn is_loopcount_interrupt_set(&self) -> bool {
726 <C as TxChannelInternal>::is_loopcount_interrupt_set()
727 }
728}
729
730macro_rules! impl_tx_channel_creator {
731 ($channel:literal) => {
732 impl<'d, P>
733 $crate::rmt::TxChannelCreator<'d, $crate::rmt::Channel<$crate::Blocking, $channel>, P>
734 for ChannelCreator<$crate::Blocking, $channel>
735 where
736 P: $crate::gpio::interconnect::PeripheralOutput,
737 {
738 }
739
740 impl $crate::rmt::TxChannel for $crate::rmt::Channel<$crate::Blocking, $channel> {}
741
742 impl<'d, P>
743 $crate::rmt::TxChannelCreatorAsync<'d, $crate::rmt::Channel<$crate::Async, $channel>, P>
744 for ChannelCreator<$crate::Async, $channel>
745 where
746 P: $crate::gpio::interconnect::PeripheralOutput,
747 {
748 }
749
750 impl $crate::rmt::TxChannelAsync for $crate::rmt::Channel<$crate::Async, $channel> {}
751 };
752}
753
754macro_rules! impl_rx_channel_creator {
755 ($channel:literal) => {
756 impl<'d, P>
757 $crate::rmt::RxChannelCreator<'d, $crate::rmt::Channel<$crate::Blocking, $channel>, P>
758 for ChannelCreator<$crate::Blocking, $channel>
759 where
760 P: $crate::gpio::interconnect::PeripheralInput,
761 {
762 }
763
764 impl $crate::rmt::RxChannel for $crate::rmt::Channel<$crate::Blocking, $channel> {}
765
766 impl<'d, P>
767 $crate::rmt::RxChannelCreatorAsync<'d, $crate::rmt::Channel<$crate::Async, $channel>, P>
768 for ChannelCreator<$crate::Async, $channel>
769 where
770 P: $crate::gpio::interconnect::PeripheralInput,
771 {
772 }
773
774 impl $crate::rmt::RxChannelAsync for $crate::rmt::Channel<$crate::Async, $channel> {}
775 };
776}
777
778#[cfg(not(any(esp32, esp32s2, esp32s3)))]
779mod impl_for_chip {
780 use core::marker::PhantomData;
781
782 use crate::{
783 peripheral::{Peripheral, PeripheralRef},
784 system::GenericPeripheralGuard,
785 };
786
787 pub struct Rmt<'d, Dm>
789 where
790 Dm: crate::DriverMode,
791 {
792 pub(super) peripheral: PeripheralRef<'d, crate::peripherals::RMT>,
793 pub channel0: ChannelCreator<Dm, 0>,
795 pub channel1: ChannelCreator<Dm, 1>,
797 pub channel2: ChannelCreator<Dm, 2>,
799 pub channel3: ChannelCreator<Dm, 3>,
801 phantom: PhantomData<Dm>,
802 }
803
804 impl<'d, Dm> Rmt<'d, Dm>
805 where
806 Dm: crate::DriverMode,
807 {
808 pub(super) fn create(
809 peripheral: impl Peripheral<P = crate::peripherals::RMT> + 'd,
810 ) -> Self {
811 crate::into_ref!(peripheral);
812
813 Self {
814 peripheral,
815 channel0: ChannelCreator {
816 phantom: PhantomData,
817 _guard: GenericPeripheralGuard::new(),
818 },
819 channel1: ChannelCreator {
820 phantom: PhantomData,
821 _guard: GenericPeripheralGuard::new(),
822 },
823 channel2: ChannelCreator {
824 phantom: PhantomData,
825 _guard: GenericPeripheralGuard::new(),
826 },
827 channel3: ChannelCreator {
828 phantom: PhantomData,
829 _guard: GenericPeripheralGuard::new(),
830 },
831 phantom: PhantomData,
832 }
833 }
834 }
835
836 pub struct ChannelCreator<Dm, const CHANNEL: u8>
838 where
839 Dm: crate::DriverMode,
840 {
841 phantom: PhantomData<Dm>,
842 _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Rmt as u8 }>,
843 }
844
845 impl_tx_channel_creator!(0);
846 impl_tx_channel_creator!(1);
847
848 impl_rx_channel_creator!(2);
849 impl_rx_channel_creator!(3);
850
851 super::chip_specific::impl_tx_channel!(RMT_SIG_0, 0);
852 super::chip_specific::impl_tx_channel!(RMT_SIG_1, 1);
853
854 super::chip_specific::impl_rx_channel!(RMT_SIG_0, 2, 0);
855 super::chip_specific::impl_rx_channel!(RMT_SIG_1, 3, 1);
856}
857
858#[cfg(esp32)]
859mod impl_for_chip {
860 use core::marker::PhantomData;
861
862 use crate::{
863 peripheral::{Peripheral, PeripheralRef},
864 peripherals::RMT,
865 system::GenericPeripheralGuard,
866 };
867
868 pub struct Rmt<'d, Dm>
870 where
871 Dm: crate::DriverMode,
872 {
873 pub(super) peripheral: PeripheralRef<'d, RMT>,
874 pub channel0: ChannelCreator<Dm, 0>,
876 pub channel1: ChannelCreator<Dm, 1>,
878 pub channel2: ChannelCreator<Dm, 2>,
880 pub channel3: ChannelCreator<Dm, 3>,
882 pub channel4: ChannelCreator<Dm, 4>,
884 pub channel5: ChannelCreator<Dm, 5>,
886 pub channel6: ChannelCreator<Dm, 6>,
888 pub channel7: ChannelCreator<Dm, 7>,
890 phantom: PhantomData<Dm>,
891 }
892
893 impl<'d, Dm> Rmt<'d, Dm>
894 where
895 Dm: crate::DriverMode,
896 {
897 pub(super) fn create(peripheral: impl Peripheral<P = RMT> + 'd) -> Self {
898 crate::into_ref!(peripheral);
899 Self {
900 peripheral,
901 channel0: ChannelCreator {
902 phantom: PhantomData,
903 _guard: GenericPeripheralGuard::new(),
904 },
905 channel1: ChannelCreator {
906 phantom: PhantomData,
907 _guard: GenericPeripheralGuard::new(),
908 },
909 channel2: ChannelCreator {
910 phantom: PhantomData,
911 _guard: GenericPeripheralGuard::new(),
912 },
913 channel3: ChannelCreator {
914 phantom: PhantomData,
915 _guard: GenericPeripheralGuard::new(),
916 },
917 channel4: ChannelCreator {
918 phantom: PhantomData,
919 _guard: GenericPeripheralGuard::new(),
920 },
921 channel5: ChannelCreator {
922 phantom: PhantomData,
923 _guard: GenericPeripheralGuard::new(),
924 },
925 channel6: ChannelCreator {
926 phantom: PhantomData,
927 _guard: GenericPeripheralGuard::new(),
928 },
929 channel7: ChannelCreator {
930 phantom: PhantomData,
931 _guard: GenericPeripheralGuard::new(),
932 },
933 phantom: PhantomData,
934 }
935 }
936 }
937
938 pub struct ChannelCreator<Dm, const CHANNEL: u8>
940 where
941 Dm: crate::DriverMode,
942 {
943 phantom: PhantomData<Dm>,
944 _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Rmt as u8 }>,
945 }
946
947 impl_tx_channel_creator!(0);
948 impl_tx_channel_creator!(1);
949 impl_tx_channel_creator!(2);
950 impl_tx_channel_creator!(3);
951 impl_tx_channel_creator!(4);
952 impl_tx_channel_creator!(5);
953 impl_tx_channel_creator!(6);
954 impl_tx_channel_creator!(7);
955
956 impl_rx_channel_creator!(0);
957 impl_rx_channel_creator!(1);
958 impl_rx_channel_creator!(2);
959 impl_rx_channel_creator!(3);
960 impl_rx_channel_creator!(4);
961 impl_rx_channel_creator!(5);
962 impl_rx_channel_creator!(6);
963 impl_rx_channel_creator!(7);
964
965 super::chip_specific::impl_tx_channel!(RMT_SIG_0, 0);
966 super::chip_specific::impl_tx_channel!(RMT_SIG_1, 1);
967 super::chip_specific::impl_tx_channel!(RMT_SIG_2, 2);
968 super::chip_specific::impl_tx_channel!(RMT_SIG_3, 3);
969 super::chip_specific::impl_tx_channel!(RMT_SIG_4, 4);
970 super::chip_specific::impl_tx_channel!(RMT_SIG_5, 5);
971 super::chip_specific::impl_tx_channel!(RMT_SIG_6, 6);
972 super::chip_specific::impl_tx_channel!(RMT_SIG_7, 7);
973
974 super::chip_specific::impl_rx_channel!(RMT_SIG_0, 0);
975 super::chip_specific::impl_rx_channel!(RMT_SIG_1, 1);
976 super::chip_specific::impl_rx_channel!(RMT_SIG_2, 2);
977 super::chip_specific::impl_rx_channel!(RMT_SIG_3, 3);
978 super::chip_specific::impl_rx_channel!(RMT_SIG_4, 4);
979 super::chip_specific::impl_rx_channel!(RMT_SIG_5, 5);
980 super::chip_specific::impl_rx_channel!(RMT_SIG_6, 6);
981 super::chip_specific::impl_rx_channel!(RMT_SIG_7, 7);
982}
983
984#[cfg(esp32s2)]
985mod impl_for_chip {
986 use core::marker::PhantomData;
987
988 use crate::{
989 peripheral::{Peripheral, PeripheralRef},
990 peripherals::RMT,
991 system::GenericPeripheralGuard,
992 };
993
994 pub struct Rmt<'d, Dm>
996 where
997 Dm: crate::DriverMode,
998 {
999 pub(super) peripheral: PeripheralRef<'d, RMT>,
1000 pub channel0: ChannelCreator<Dm, 0>,
1002 pub channel1: ChannelCreator<Dm, 1>,
1004 pub channel2: ChannelCreator<Dm, 2>,
1006 pub channel3: ChannelCreator<Dm, 3>,
1008 phantom: PhantomData<Dm>,
1009 }
1010
1011 impl<'d, Dm> Rmt<'d, Dm>
1012 where
1013 Dm: crate::DriverMode,
1014 {
1015 pub(super) fn create(peripheral: impl Peripheral<P = RMT> + 'd) -> Self {
1016 crate::into_ref!(peripheral);
1017
1018 Self {
1019 peripheral,
1020 channel0: ChannelCreator {
1021 phantom: PhantomData,
1022 _guard: GenericPeripheralGuard::new(),
1023 },
1024 channel1: ChannelCreator {
1025 phantom: PhantomData,
1026 _guard: GenericPeripheralGuard::new(),
1027 },
1028 channel2: ChannelCreator {
1029 phantom: PhantomData,
1030 _guard: GenericPeripheralGuard::new(),
1031 },
1032 channel3: ChannelCreator {
1033 phantom: PhantomData,
1034 _guard: GenericPeripheralGuard::new(),
1035 },
1036 phantom: PhantomData,
1037 }
1038 }
1039 }
1040
1041 pub struct ChannelCreator<Dm, const CHANNEL: u8>
1043 where
1044 Dm: crate::DriverMode,
1045 {
1046 phantom: PhantomData<Dm>,
1047 _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Rmt as u8 }>,
1048 }
1049
1050 impl_tx_channel_creator!(0);
1051 impl_tx_channel_creator!(1);
1052 impl_tx_channel_creator!(2);
1053 impl_tx_channel_creator!(3);
1054
1055 impl_rx_channel_creator!(0);
1056 impl_rx_channel_creator!(1);
1057 impl_rx_channel_creator!(2);
1058 impl_rx_channel_creator!(3);
1059
1060 super::chip_specific::impl_tx_channel!(RMT_SIG_0, 0);
1061 super::chip_specific::impl_tx_channel!(RMT_SIG_1, 1);
1062 super::chip_specific::impl_tx_channel!(RMT_SIG_2, 2);
1063 super::chip_specific::impl_tx_channel!(RMT_SIG_3, 3);
1064
1065 super::chip_specific::impl_rx_channel!(RMT_SIG_0, 0);
1066 super::chip_specific::impl_rx_channel!(RMT_SIG_1, 1);
1067 super::chip_specific::impl_rx_channel!(RMT_SIG_2, 2);
1068 super::chip_specific::impl_rx_channel!(RMT_SIG_3, 3);
1069}
1070
1071#[cfg(esp32s3)]
1072mod impl_for_chip {
1073 use core::marker::PhantomData;
1074
1075 use crate::{
1076 peripheral::{Peripheral, PeripheralRef},
1077 peripherals::RMT,
1078 system::GenericPeripheralGuard,
1079 };
1080
1081 pub struct Rmt<'d, Dm>
1083 where
1084 Dm: crate::DriverMode,
1085 {
1086 pub(super) peripheral: PeripheralRef<'d, RMT>,
1087 pub channel0: ChannelCreator<Dm, 0>,
1089 pub channel1: ChannelCreator<Dm, 1>,
1091 pub channel2: ChannelCreator<Dm, 2>,
1093 pub channel3: ChannelCreator<Dm, 3>,
1095 pub channel4: ChannelCreator<Dm, 4>,
1097 pub channel5: ChannelCreator<Dm, 5>,
1099 pub channel6: ChannelCreator<Dm, 6>,
1101 pub channel7: ChannelCreator<Dm, 7>,
1103 phantom: PhantomData<Dm>,
1104 }
1105
1106 impl<'d, Dm> Rmt<'d, Dm>
1107 where
1108 Dm: crate::DriverMode,
1109 {
1110 pub(super) fn create(peripheral: impl Peripheral<P = RMT> + 'd) -> Self {
1111 crate::into_ref!(peripheral);
1112
1113 Self {
1114 peripheral,
1115 channel0: ChannelCreator {
1116 phantom: PhantomData,
1117 _guard: GenericPeripheralGuard::new(),
1118 },
1119 channel1: ChannelCreator {
1120 phantom: PhantomData,
1121 _guard: GenericPeripheralGuard::new(),
1122 },
1123 channel2: ChannelCreator {
1124 phantom: PhantomData,
1125 _guard: GenericPeripheralGuard::new(),
1126 },
1127 channel3: ChannelCreator {
1128 phantom: PhantomData,
1129 _guard: GenericPeripheralGuard::new(),
1130 },
1131 channel4: ChannelCreator {
1132 phantom: PhantomData,
1133 _guard: GenericPeripheralGuard::new(),
1134 },
1135 channel5: ChannelCreator {
1136 phantom: PhantomData,
1137 _guard: GenericPeripheralGuard::new(),
1138 },
1139 channel6: ChannelCreator {
1140 phantom: PhantomData,
1141 _guard: GenericPeripheralGuard::new(),
1142 },
1143 channel7: ChannelCreator {
1144 phantom: PhantomData,
1145 _guard: GenericPeripheralGuard::new(),
1146 },
1147 phantom: PhantomData,
1148 }
1149 }
1150 }
1151
1152 pub struct ChannelCreator<Dm, const CHANNEL: u8>
1154 where
1155 Dm: crate::DriverMode,
1156 {
1157 phantom: PhantomData<Dm>,
1158 _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Rmt as u8 }>,
1159 }
1160
1161 impl_tx_channel_creator!(0);
1162 impl_tx_channel_creator!(1);
1163 impl_tx_channel_creator!(2);
1164 impl_tx_channel_creator!(3);
1165
1166 impl_rx_channel_creator!(4);
1167 impl_rx_channel_creator!(5);
1168 impl_rx_channel_creator!(6);
1169 impl_rx_channel_creator!(7);
1170
1171 super::chip_specific::impl_tx_channel!(RMT_SIG_0, 0);
1172 super::chip_specific::impl_tx_channel!(RMT_SIG_1, 1);
1173 super::chip_specific::impl_tx_channel!(RMT_SIG_2, 2);
1174 super::chip_specific::impl_tx_channel!(RMT_SIG_3, 3);
1175
1176 super::chip_specific::impl_rx_channel!(RMT_SIG_0, 4, 0);
1177 super::chip_specific::impl_rx_channel!(RMT_SIG_1, 5, 1);
1178 super::chip_specific::impl_rx_channel!(RMT_SIG_2, 6, 2);
1179 super::chip_specific::impl_rx_channel!(RMT_SIG_3, 7, 3);
1180}
1181
1182#[derive(Debug)]
1184#[non_exhaustive]
1185pub struct Channel<Dm, const CHANNEL: u8>
1186where
1187 Dm: crate::DriverMode,
1188{
1189 phantom: PhantomData<Dm>,
1190 _guard: GenericPeripheralGuard<{ system::Peripheral::Rmt as u8 }>,
1191}
1192
1193pub trait TxChannel: TxChannelInternal {
1195 fn transmit(self, data: &[u32]) -> Result<SingleShotTxTransaction<'_, Self>, Error>
1200 where
1201 Self: Sized,
1202 {
1203 let index = Self::send_raw(data, false, 0)?;
1204 Ok(SingleShotTxTransaction {
1205 channel: self,
1206 index,
1207 data,
1208 })
1209 }
1210
1211 fn transmit_continuously(self, data: &[u32]) -> Result<ContinuousTxTransaction<Self>, Error>
1216 where
1217 Self: Sized,
1218 {
1219 self.transmit_continuously_with_loopcount(0, data)
1220 }
1221
1222 fn transmit_continuously_with_loopcount(
1226 self,
1227 loopcount: u16,
1228 data: &[u32],
1229 ) -> Result<ContinuousTxTransaction<Self>, Error>
1230 where
1231 Self: Sized,
1232 {
1233 if data.len() > constants::RMT_CHANNEL_RAM_SIZE {
1234 return Err(Error::Overflow);
1235 }
1236
1237 let _index = Self::send_raw(data, true, loopcount)?;
1238 Ok(ContinuousTxTransaction { channel: self })
1239 }
1240}
1241
1242pub struct RxTransaction<'a, C>
1244where
1245 C: RxChannel,
1246{
1247 channel: C,
1248 data: &'a mut [u32],
1249}
1250
1251impl<C> RxTransaction<'_, C>
1252where
1253 C: RxChannel,
1254{
1255 pub fn wait(self) -> Result<C, (Error, C)> {
1257 loop {
1258 if <C as RxChannelInternal>::is_error() {
1259 return Err((Error::TransmissionError, self.channel));
1260 }
1261
1262 if <C as RxChannelInternal>::is_done() {
1263 break;
1264 }
1265 }
1266
1267 <C as RxChannelInternal>::stop();
1268 <C as RxChannelInternal>::clear_interrupts();
1269 <C as RxChannelInternal>::update();
1270
1271 let ptr = (constants::RMT_RAM_START
1272 + C::CHANNEL as usize * constants::RMT_CHANNEL_RAM_SIZE * 4)
1273 as *mut u32;
1274 let len = self.data.len();
1275 for (idx, entry) in self.data.iter_mut().take(len).enumerate() {
1276 *entry = unsafe { ptr.add(idx).read_volatile() };
1277 }
1278
1279 Ok(self.channel)
1280 }
1281}
1282
1283pub trait RxChannel: RxChannelInternal {
1285 fn receive(self, data: &mut [u32]) -> Result<RxTransaction<'_, Self>, Error>
1290 where
1291 Self: Sized,
1292 {
1293 if data.len() > constants::RMT_CHANNEL_RAM_SIZE {
1294 return Err(Error::InvalidArgument);
1295 }
1296
1297 Self::start_receive_raw();
1298
1299 Ok(RxTransaction {
1300 channel: self,
1301 data,
1302 })
1303 }
1304}
1305
1306#[cfg(any(esp32, esp32s3))]
1307const NUM_CHANNELS: usize = 8;
1308#[cfg(not(any(esp32, esp32s3)))]
1309const NUM_CHANNELS: usize = 4;
1310
1311static WAKER: [AtomicWaker; NUM_CHANNELS] = [const { AtomicWaker::new() }; NUM_CHANNELS];
1312
1313#[must_use = "futures do nothing unless you `.await` or poll them"]
1314pub(crate) struct RmtTxFuture<T>
1315where
1316 T: TxChannelAsync,
1317{
1318 _phantom: PhantomData<T>,
1319}
1320
1321impl<T> RmtTxFuture<T>
1322where
1323 T: TxChannelAsync,
1324{
1325 pub fn new(_instance: &T) -> Self {
1326 Self {
1327 _phantom: PhantomData,
1328 }
1329 }
1330}
1331
1332impl<T> core::future::Future for RmtTxFuture<T>
1333where
1334 T: TxChannelAsync,
1335{
1336 type Output = ();
1337
1338 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
1339 WAKER[T::CHANNEL as usize].register(ctx.waker());
1340
1341 if T::is_error() || T::is_done() {
1342 Poll::Ready(())
1343 } else {
1344 Poll::Pending
1345 }
1346 }
1347}
1348
1349pub trait TxChannelAsync: TxChannelInternal {
1351 async fn transmit(&mut self, data: &[u32]) -> Result<(), Error>
1355 where
1356 Self: Sized,
1357 {
1358 if data.len() > constants::RMT_CHANNEL_RAM_SIZE {
1359 return Err(Error::InvalidArgument);
1360 }
1361
1362 Self::clear_interrupts();
1363 Self::listen_interrupt(Event::End | Event::Error);
1364 Self::send_raw(data, false, 0)?;
1365
1366 RmtTxFuture::new(self).await;
1367
1368 if Self::is_error() {
1369 Err(Error::TransmissionError)
1370 } else {
1371 Ok(())
1372 }
1373 }
1374}
1375
1376#[must_use = "futures do nothing unless you `.await` or poll them"]
1377pub(crate) struct RmtRxFuture<T>
1378where
1379 T: RxChannelAsync,
1380{
1381 _phantom: PhantomData<T>,
1382}
1383
1384impl<T> RmtRxFuture<T>
1385where
1386 T: RxChannelAsync,
1387{
1388 pub fn new(_instance: &T) -> Self {
1389 Self {
1390 _phantom: PhantomData,
1391 }
1392 }
1393}
1394
1395impl<T> core::future::Future for RmtRxFuture<T>
1396where
1397 T: RxChannelAsync,
1398{
1399 type Output = ();
1400
1401 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
1402 WAKER[T::CHANNEL as usize].register(ctx.waker());
1403 if T::is_error() || T::is_done() {
1404 Poll::Ready(())
1405 } else {
1406 Poll::Pending
1407 }
1408 }
1409}
1410
1411pub trait RxChannelAsync: RxChannelInternal {
1413 async fn receive<T: From<u32> + Copy>(&mut self, data: &mut [T]) -> Result<(), Error>
1417 where
1418 Self: Sized,
1419 {
1420 if data.len() > constants::RMT_CHANNEL_RAM_SIZE {
1421 return Err(Error::InvalidArgument);
1422 }
1423
1424 Self::clear_interrupts();
1425 Self::listen_interrupt(Event::End | Event::Error);
1426 Self::start_receive_raw();
1427
1428 RmtRxFuture::new(self).await;
1429
1430 if Self::is_error() {
1431 Err(Error::TransmissionError)
1432 } else {
1433 Self::stop();
1434 Self::clear_interrupts();
1435 Self::update();
1436
1437 let ptr = (constants::RMT_RAM_START
1438 + Self::CHANNEL as usize * constants::RMT_CHANNEL_RAM_SIZE * 4)
1439 as *mut u32;
1440 let len = data.len();
1441 for (idx, entry) in data.iter_mut().take(len).enumerate() {
1442 *entry = unsafe { ptr.add(idx).read_volatile().into() };
1443 }
1444
1445 Ok(())
1446 }
1447 }
1448}
1449
1450#[cfg(not(any(esp32, esp32s2)))]
1451#[handler]
1452fn async_interrupt_handler() {
1453 let Some(channel) = chip_specific::pending_interrupt_for_channel() else {
1454 return;
1455 };
1456 match channel {
1457 0 => Channel::<Async, 0>::unlisten_interrupt(Event::End | Event::Error),
1458 1 => Channel::<Async, 1>::unlisten_interrupt(Event::End | Event::Error),
1459 2 => Channel::<Async, 2>::unlisten_interrupt(Event::End | Event::Error),
1460 3 => Channel::<Async, 3>::unlisten_interrupt(Event::End | Event::Error),
1461
1462 #[cfg(any(esp32, esp32s3))]
1463 4 => Channel::<Async, 4>::unlisten_interrupt(Event::End | Event::Error),
1464 #[cfg(any(esp32, esp32s3))]
1465 5 => Channel::<Async, 5>::unlisten_interrupt(Event::End | Event::Error),
1466 #[cfg(any(esp32, esp32s3))]
1467 6 => Channel::<Async, 6>::unlisten_interrupt(Event::End | Event::Error),
1468 #[cfg(any(esp32, esp32s3))]
1469 7 => Channel::<Async, 7>::unlisten_interrupt(Event::End | Event::Error),
1470
1471 _ => unreachable!(),
1472 }
1473
1474 WAKER[channel].wake();
1475}
1476
1477#[cfg(any(esp32, esp32s2))]
1478#[handler]
1479fn async_interrupt_handler() {
1480 let Some(channel) = chip_specific::pending_interrupt_for_channel() else {
1481 return;
1482 };
1483 match channel {
1484 0 => {
1485 <Channel<Async, 0> as TxChannelInternal>::unlisten_interrupt(Event::End | Event::Error);
1486 <Channel<Async, 0> as RxChannelInternal>::unlisten_interrupt(Event::End | Event::Error);
1487 }
1488 1 => {
1489 <Channel<Async, 1> as TxChannelInternal>::unlisten_interrupt(Event::End | Event::Error);
1490 <Channel<Async, 1> as RxChannelInternal>::unlisten_interrupt(Event::End | Event::Error);
1491 }
1492 2 => {
1493 <Channel<Async, 2> as TxChannelInternal>::unlisten_interrupt(Event::End | Event::Error);
1494 <Channel<Async, 2> as RxChannelInternal>::unlisten_interrupt(Event::End | Event::Error);
1495 }
1496 3 => {
1497 <Channel<Async, 3> as TxChannelInternal>::unlisten_interrupt(Event::End | Event::Error);
1498 <Channel<Async, 3> as RxChannelInternal>::unlisten_interrupt(Event::End | Event::Error);
1499 }
1500 #[cfg(esp32)]
1501 4 => {
1502 <Channel<Async, 4> as TxChannelInternal>::unlisten_interrupt(Event::End | Event::Error);
1503 <Channel<Async, 4> as RxChannelInternal>::unlisten_interrupt(Event::End | Event::Error);
1504 }
1505 #[cfg(any(esp32, esp32s3))]
1506 5 => {
1507 <Channel<Async, 5> as TxChannelInternal>::unlisten_interrupt(Event::End | Event::Error);
1508 <Channel<Async, 5> as RxChannelInternal>::unlisten_interrupt(Event::End | Event::Error);
1509 }
1510 #[cfg(any(esp32, esp32s3))]
1511 6 => {
1512 <Channel<Async, 6> as TxChannelInternal>::unlisten_interrupt(Event::End | Event::Error);
1513 <Channel<Async, 6> as RxChannelInternal>::unlisten_interrupt(Event::End | Event::Error);
1514 }
1515 #[cfg(any(esp32, esp32s3))]
1516 7 => {
1517 <Channel<Async, 7> as TxChannelInternal>::unlisten_interrupt(Event::End | Event::Error);
1518 <Channel<Async, 7> as RxChannelInternal>::unlisten_interrupt(Event::End | Event::Error);
1519 }
1520
1521 _ => unreachable!(),
1522 }
1523
1524 WAKER[channel].wake();
1525}
1526
1527#[derive(Debug, EnumSetType)]
1528#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1529#[doc(hidden)]
1530pub enum Event {
1531 Error,
1532 Threshold,
1533 End,
1534}
1535
1536#[doc(hidden)]
1537pub trait TxChannelInternal {
1538 const CHANNEL: u8;
1539
1540 fn new() -> Self;
1541
1542 fn output_signal() -> crate::gpio::OutputSignal;
1543
1544 fn set_divider(divider: u8);
1545
1546 fn update();
1547
1548 fn set_generate_repeat_interrupt(repeats: u16);
1549
1550 fn clear_interrupts();
1551
1552 fn set_continuous(continuous: bool);
1553
1554 fn set_wrap_mode(wrap: bool);
1555
1556 fn set_carrier(carrier: bool, high: u16, low: u16, level: Level);
1557
1558 fn set_idle_output(enable: bool, level: Level);
1559
1560 fn set_memsize(memsize: u8);
1561
1562 fn start_tx();
1563
1564 fn is_done() -> bool;
1565
1566 fn is_error() -> bool;
1567
1568 fn is_threshold_set() -> bool;
1569
1570 fn reset_threshold_set();
1571
1572 fn set_threshold(threshold: u8);
1573
1574 fn is_loopcount_interrupt_set() -> bool;
1575
1576 fn send_raw(data: &[u32], continuous: bool, repeat: u16) -> Result<usize, Error> {
1577 Self::clear_interrupts();
1578
1579 if let Some(last) = data.last() {
1580 if !continuous && last.length2() != 0 && last.length1() != 0 {
1581 return Err(Error::EndMarkerMissing);
1582 }
1583 } else {
1584 return Err(Error::InvalidArgument);
1585 }
1586
1587 let ptr = (constants::RMT_RAM_START
1588 + Self::CHANNEL as usize * constants::RMT_CHANNEL_RAM_SIZE * 4)
1589 as *mut u32;
1590 for (idx, entry) in data
1591 .iter()
1592 .take(constants::RMT_CHANNEL_RAM_SIZE)
1593 .enumerate()
1594 {
1595 unsafe {
1596 ptr.add(idx).write_volatile(*entry);
1597 }
1598 }
1599
1600 Self::set_threshold((constants::RMT_CHANNEL_RAM_SIZE / 2) as u8);
1601 Self::set_continuous(continuous);
1602 Self::set_generate_repeat_interrupt(repeat);
1603 Self::set_wrap_mode(true);
1604 Self::set_memsize(1);
1605 Self::update();
1606 Self::start_tx();
1607 Self::update();
1608
1609 if data.len() >= constants::RMT_CHANNEL_RAM_SIZE {
1610 Ok(constants::RMT_CHANNEL_RAM_SIZE)
1611 } else {
1612 Ok(data.len())
1613 }
1614 }
1615
1616 fn stop();
1617
1618 fn enable_listen_interrupt(event: EnumSet<Event>, enable: bool);
1619
1620 fn listen_interrupt(event: impl Into<EnumSet<Event>>) {
1621 Self::enable_listen_interrupt(event.into(), true);
1622 }
1623
1624 fn unlisten_interrupt(event: impl Into<EnumSet<Event>>) {
1625 Self::enable_listen_interrupt(event.into(), false);
1626 }
1627}
1628
1629#[doc(hidden)]
1630pub trait RxChannelInternal {
1631 const CHANNEL: u8;
1632
1633 fn new() -> Self;
1634
1635 fn input_signal() -> crate::gpio::InputSignal;
1636
1637 fn set_divider(divider: u8);
1638
1639 fn update();
1640
1641 fn clear_interrupts();
1642
1643 fn set_wrap_mode(wrap: bool);
1644
1645 fn set_carrier(carrier: bool, high: u16, low: u16, level: Level);
1646
1647 fn set_memsize(memsize: u8);
1648
1649 fn start_rx();
1650
1651 fn is_done() -> bool;
1652
1653 fn is_error() -> bool;
1654
1655 fn start_receive_raw() {
1656 Self::clear_interrupts();
1657 Self::set_wrap_mode(false);
1658 Self::set_memsize(1);
1659 Self::start_rx();
1660 Self::update();
1661 }
1662
1663 fn stop();
1664
1665 fn set_filter_threshold(value: u8);
1666
1667 fn set_idle_threshold(value: u16);
1668
1669 fn enable_listen_interrupt(event: EnumSet<Event>, enable: bool);
1670
1671 fn listen_interrupt(event: impl Into<EnumSet<Event>>) {
1672 Self::enable_listen_interrupt(event.into(), true);
1673 }
1674
1675 fn unlisten_interrupt(event: impl Into<EnumSet<Event>>) {
1676 Self::enable_listen_interrupt(event.into(), false);
1677 }
1678}
1679
1680#[cfg(not(any(esp32, esp32s2)))]
1681mod chip_specific {
1682 use crate::peripherals::RMT;
1683
1684 pub fn configure_clock(div: u32) {
1685 #[cfg(not(pcr))]
1686 {
1687 RMT::regs().sys_conf().modify(|_, w| unsafe {
1688 w.clk_en().clear_bit();
1689 w.sclk_sel().bits(crate::soc::constants::RMT_CLOCK_SRC);
1690 w.sclk_div_num().bits(div as u8);
1691 w.sclk_div_a().bits(0);
1692 w.sclk_div_b().bits(0);
1693 w.apb_fifo_mask().set_bit()
1694 });
1695 }
1696
1697 #[cfg(pcr)]
1698 {
1699 use crate::peripherals::PCR;
1700 PCR::regs().rmt_sclk_conf().modify(|_, w| unsafe {
1701 w.sclk_div_num().bits(div as u8);
1702 w.sclk_div_a().bits(0);
1703 w.sclk_div_b().bits(0)
1704 });
1705
1706 #[cfg(esp32c6)]
1707 PCR::regs()
1708 .rmt_sclk_conf()
1709 .modify(|_, w| unsafe { w.sclk_sel().bits(crate::soc::constants::RMT_CLOCK_SRC) });
1710 #[cfg(not(esp32c6))]
1711 PCR::regs()
1712 .rmt_sclk_conf()
1713 .modify(|_, w| w.sclk_sel().bit(crate::soc::constants::RMT_CLOCK_SRC));
1714
1715 RMT::regs()
1716 .sys_conf()
1717 .modify(|_, w| w.apb_fifo_mask().set_bit());
1718 }
1719 }
1720
1721 #[allow(unused)]
1722 #[cfg(not(esp32s3))]
1723 pub fn pending_interrupt_for_channel() -> Option<usize> {
1724 let st = RMT::regs().int_st().read();
1725
1726 if st.ch0_tx_end().bit() || st.ch0_tx_err().bit() {
1727 Some(0)
1728 } else if st.ch1_tx_end().bit() || st.ch1_tx_err().bit() {
1729 Some(1)
1730 } else if st.ch2_rx_end().bit() || st.ch2_rx_err().bit() {
1731 Some(2)
1732 } else if st.ch3_rx_end().bit() || st.ch3_rx_err().bit() {
1733 Some(3)
1734 } else {
1735 None
1736 }
1737 }
1738
1739 #[allow(unused)]
1740 #[cfg(esp32s3)]
1741 pub fn pending_interrupt_for_channel() -> Option<usize> {
1742 let st = RMT::regs().int_st().read();
1743
1744 if st.ch0_tx_end().bit() || st.ch0_tx_err().bit() {
1745 Some(0)
1746 } else if st.ch1_tx_end().bit() || st.ch1_tx_err().bit() {
1747 Some(1)
1748 } else if st.ch2_tx_end().bit() || st.ch2_tx_err().bit() {
1749 Some(2)
1750 } else if st.ch3_tx_end().bit() || st.ch3_tx_err().bit() {
1751 Some(3)
1752 } else if st.ch4_rx_end().bit() || st.ch4_rx_err().bit() {
1753 Some(4)
1754 } else if st.ch5_rx_end().bit() || st.ch5_rx_err().bit() {
1755 Some(5)
1756 } else if st.ch6_rx_end().bit() || st.ch6_rx_err().bit() {
1757 Some(6)
1758 } else if st.ch7_rx_end().bit() || st.ch7_rx_err().bit() {
1759 Some(7)
1760 } else {
1761 None
1762 }
1763 }
1764
1765 macro_rules! impl_tx_channel {
1766 ($signal:ident, $ch_num:literal) => {
1767 impl<Dm> $crate::rmt::TxChannelInternal for $crate::rmt::Channel<Dm, $ch_num>
1768 where
1769 Dm: $crate::DriverMode,
1770 {
1771 const CHANNEL: u8 = $ch_num;
1772
1773 fn new() -> Self {
1774 let guard = GenericPeripheralGuard::new();
1775 Self {
1776 phantom: core::marker::PhantomData,
1777 _guard: guard,
1778 }
1779 }
1780
1781 fn output_signal() -> crate::gpio::OutputSignal {
1782 crate::gpio::OutputSignal::$signal
1783 }
1784
1785 fn set_divider(divider: u8) {
1786 let rmt = crate::peripherals::RMT::regs();
1787 rmt.ch_tx_conf0($ch_num)
1788 .modify(|_, w| unsafe { w.div_cnt().bits(divider) });
1789 }
1790
1791 fn update() {
1792 let rmt = crate::peripherals::RMT::regs();
1793 rmt.ch_tx_conf0($ch_num)
1794 .modify(|_, w| w.conf_update().set_bit());
1795 }
1796
1797 fn set_generate_repeat_interrupt(repeats: u16) {
1798 let rmt = crate::peripherals::RMT::regs();
1799 if repeats > 1 {
1800 rmt.ch_tx_lim($ch_num).modify(|_, w| unsafe {
1801 w.loop_count_reset().set_bit();
1802 w.tx_loop_cnt_en().set_bit();
1803 w.tx_loop_num().bits(repeats)
1804 });
1805 } else {
1806 rmt.ch_tx_lim($ch_num).modify(|_, w| unsafe {
1807 w.loop_count_reset().set_bit();
1808 w.tx_loop_cnt_en().clear_bit();
1809 w.tx_loop_num().bits(0)
1810 });
1811 }
1812
1813 rmt.ch_tx_lim($ch_num)
1814 .modify(|_, w| w.loop_count_reset().clear_bit());
1815 }
1816
1817 fn clear_interrupts() {
1818 let rmt = crate::peripherals::RMT::regs();
1819
1820 rmt.int_clr().write(|w| {
1821 w.ch_tx_end($ch_num).set_bit();
1822 w.ch_tx_err($ch_num).set_bit();
1823 w.ch_tx_loop($ch_num).set_bit();
1824 w.ch_tx_thr_event($ch_num).set_bit()
1825 });
1826 }
1827
1828 fn set_continuous(continuous: bool) {
1829 let rmt = crate::peripherals::RMT::regs();
1830
1831 rmt.ch_tx_conf0($ch_num)
1832 .modify(|_, w| w.tx_conti_mode().bit(continuous));
1833 }
1834
1835 fn set_wrap_mode(wrap: bool) {
1836 let rmt = crate::peripherals::RMT::regs();
1837
1838 rmt.ch_tx_conf0($ch_num)
1839 .modify(|_, w| w.mem_tx_wrap_en().bit(wrap));
1840 }
1841
1842 fn set_carrier(carrier: bool, high: u16, low: u16, level: $crate::gpio::Level) {
1843 let rmt = crate::peripherals::RMT::regs();
1844
1845 rmt.chcarrier_duty($ch_num)
1846 .write(|w| unsafe { w.carrier_high().bits(high).carrier_low().bits(low) });
1847
1848 rmt.ch_tx_conf0($ch_num).modify(|_, w| {
1849 w.carrier_en().bit(carrier);
1850 w.carrier_eff_en().set_bit();
1851 w.carrier_out_lv().bit(level.into())
1852 });
1853 }
1854
1855 fn set_idle_output(enable: bool, level: $crate::gpio::Level) {
1856 let rmt = crate::peripherals::RMT::regs();
1857 rmt.ch_tx_conf0($ch_num)
1858 .modify(|_, w| w.idle_out_en().bit(enable).idle_out_lv().bit(level.into()));
1859 }
1860
1861 fn set_memsize(memsize: u8) {
1862 let rmt = crate::peripherals::RMT::regs();
1863
1864 rmt.ch_tx_conf0($ch_num)
1865 .modify(|_, w| unsafe { w.mem_size().bits(memsize) });
1866 }
1867
1868 fn start_tx() {
1869 let rmt = crate::peripherals::RMT::regs();
1870
1871 rmt.ref_cnt_rst().write(|w| unsafe { w.bits(1 << $ch_num) });
1872 Self::update();
1873
1874 rmt.ch_tx_conf0($ch_num).modify(|_, w| {
1875 w.mem_rd_rst().set_bit();
1876 w.apb_mem_rst().set_bit();
1877 w.tx_start().set_bit()
1878 });
1879 Self::update();
1880 }
1881
1882 fn is_done() -> bool {
1883 let rmt = crate::peripherals::RMT::regs();
1884 rmt.int_raw().read().ch_tx_end($ch_num).bit()
1885 }
1886
1887 fn is_error() -> bool {
1888 let rmt = crate::peripherals::RMT::regs();
1889 rmt.int_raw().read().ch_tx_err($ch_num).bit()
1890 }
1891
1892 fn is_threshold_set() -> bool {
1893 let rmt = crate::peripherals::RMT::regs();
1894 rmt.int_raw().read().ch_tx_thr_event($ch_num).bit()
1895 }
1896
1897 fn reset_threshold_set() {
1898 let rmt = crate::peripherals::RMT::regs();
1899 rmt.int_clr()
1900 .write(|w| w.ch_tx_thr_event($ch_num).set_bit());
1901 }
1902
1903 fn set_threshold(threshold: u8) {
1904 let rmt = crate::peripherals::RMT::regs();
1905 rmt.ch_tx_lim($ch_num)
1906 .modify(|_, w| unsafe { w.tx_lim().bits(threshold as u16) });
1907 }
1908
1909 fn is_loopcount_interrupt_set() -> bool {
1910 let rmt = crate::peripherals::RMT::regs();
1911 rmt.int_raw().read().ch_tx_loop($ch_num).bit()
1912 }
1913
1914 fn stop() {
1915 let rmt = crate::peripherals::RMT::regs();
1916 rmt.ch_tx_conf0($ch_num)
1917 .modify(|_, w| w.tx_stop().set_bit());
1918 Self::update();
1919 }
1920
1921 fn enable_listen_interrupt(
1922 events: enumset::EnumSet<$crate::rmt::Event>,
1923 enable: bool,
1924 ) {
1925 let rmt = crate::peripherals::RMT::regs();
1926 rmt.int_ena().modify(|_, w| {
1927 if events.contains($crate::rmt::Event::Error) {
1928 w.ch_tx_err($ch_num).bit(enable);
1929 }
1930 if events.contains($crate::rmt::Event::End) {
1931 w.ch_tx_end($ch_num).bit(enable);
1932 }
1933 if events.contains($crate::rmt::Event::Threshold) {
1934 w.ch_tx_thr_event($ch_num).bit(enable);
1935 }
1936 w
1937 });
1938 }
1939 }
1940 };
1941 }
1942
1943 macro_rules! impl_rx_channel {
1944 ($signal:ident, $ch_num:literal, $ch_index:literal) => {
1945 impl<Dm> $crate::rmt::RxChannelInternal for $crate::rmt::Channel<Dm, $ch_num>
1946 where
1947 Dm: $crate::DriverMode,
1948 {
1949 const CHANNEL: u8 = $ch_num;
1950
1951 fn new() -> Self {
1952 let guard = GenericPeripheralGuard::new();
1953 Self {
1954 phantom: core::marker::PhantomData,
1955 _guard: guard,
1956 }
1957 }
1958
1959 fn input_signal() -> crate::gpio::InputSignal {
1960 crate::gpio::InputSignal::$signal
1961 }
1962
1963 fn set_divider(divider: u8) {
1964 let rmt = crate::peripherals::RMT::regs();
1965 rmt.ch_rx_conf0($ch_index)
1966 .modify(|_, w| unsafe { w.div_cnt().bits(divider) });
1967 }
1968
1969 fn update() {
1970 let rmt = crate::peripherals::RMT::regs();
1971 rmt.ch_rx_conf1($ch_index)
1972 .modify(|_, w| w.conf_update().set_bit());
1973 }
1974
1975 fn clear_interrupts() {
1976 let rmt = crate::peripherals::RMT::regs();
1977
1978 rmt.int_clr().write(|w| {
1979 w.ch_rx_end($ch_index).set_bit();
1980 w.ch_rx_err($ch_index).set_bit();
1981 w.ch_rx_thr_event($ch_index).set_bit()
1982 });
1983 }
1984
1985 fn set_wrap_mode(wrap: bool) {
1986 let rmt = crate::peripherals::RMT::regs();
1987 rmt.ch_rx_conf1($ch_index)
1988 .modify(|_, w| w.mem_rx_wrap_en().bit(wrap));
1989 }
1990
1991 fn set_carrier(carrier: bool, high: u16, low: u16, level: $crate::gpio::Level) {
1992 let rmt = crate::peripherals::RMT::regs();
1993
1994 rmt.ch_rx_carrier_rm($ch_index).write(|w| unsafe {
1995 w.carrier_high_thres().bits(high);
1996 w.carrier_low_thres().bits(low)
1997 });
1998
1999 rmt.ch_rx_conf0($ch_index).modify(|_, w| {
2000 w.carrier_en()
2001 .bit(carrier)
2002 .carrier_out_lv()
2003 .bit(level.into())
2004 });
2005 }
2006
2007 fn set_memsize(memsize: u8) {
2008 let rmt = crate::peripherals::RMT::regs();
2009 rmt.ch_rx_conf0($ch_index)
2010 .modify(|_, w| unsafe { w.mem_size().bits(memsize) });
2011 }
2012
2013 fn start_rx() {
2014 let rmt = crate::peripherals::RMT::regs();
2015 rmt.ch_rx_conf1($ch_index).modify(|_, w| {
2016 w.mem_wr_rst().set_bit();
2017 w.apb_mem_rst().set_bit();
2018 w.mem_owner().set_bit();
2019 w.rx_en().set_bit()
2020 });
2021 }
2022
2023 fn is_done() -> bool {
2024 let rmt = crate::peripherals::RMT::regs();
2025 rmt.int_raw().read().ch_rx_end($ch_index).bit()
2026 }
2027
2028 fn is_error() -> bool {
2029 let rmt = crate::peripherals::RMT::regs();
2030 rmt.int_raw().read().ch_rx_err($ch_index).bit()
2031 }
2032
2033 fn stop() {
2034 let rmt = crate::peripherals::RMT::regs();
2035 rmt.ch_rx_conf1($ch_index)
2036 .modify(|_, w| w.rx_en().clear_bit());
2037 }
2038
2039 fn set_filter_threshold(value: u8) {
2040 let rmt = crate::peripherals::RMT::regs();
2041
2042 rmt.ch_rx_conf1($ch_index).modify(|_, w| unsafe {
2043 w.rx_filter_en().bit(value > 0);
2044 w.rx_filter_thres().bits(value)
2045 });
2046 }
2047
2048 fn set_idle_threshold(value: u16) {
2049 let rmt = crate::peripherals::RMT::regs();
2050
2051 rmt.ch_rx_conf0($ch_index)
2052 .modify(|_, w| unsafe { w.idle_thres().bits(value) });
2053 }
2054
2055 fn enable_listen_interrupt(
2056 events: enumset::EnumSet<$crate::rmt::Event>,
2057 enable: bool,
2058 ) {
2059 let rmt = crate::peripherals::RMT::regs();
2060 rmt.int_ena().modify(|_, w| {
2061 if events.contains($crate::rmt::Event::Error) {
2062 w.ch_rx_err($ch_index).bit(enable);
2063 }
2064 if events.contains($crate::rmt::Event::End) {
2065 w.ch_rx_end($ch_index).bit(enable);
2066 }
2067 if events.contains($crate::rmt::Event::Threshold) {
2068 w.ch_rx_thr_event($ch_index).bit(enable);
2069 }
2070 w
2071 });
2072 }
2073 }
2074 };
2075 }
2076
2077 pub(crate) use impl_rx_channel;
2078 pub(crate) use impl_tx_channel;
2079}
2080
2081#[cfg(any(esp32, esp32s2))]
2082mod chip_specific {
2083 use crate::peripherals::RMT;
2084
2085 pub fn configure_clock() {
2086 let rmt = RMT::regs();
2087
2088 rmt.ch0conf1().modify(|_, w| w.ref_always_on().set_bit());
2089 rmt.ch1conf1().modify(|_, w| w.ref_always_on().set_bit());
2090 rmt.ch2conf1().modify(|_, w| w.ref_always_on().set_bit());
2091 rmt.ch3conf1().modify(|_, w| w.ref_always_on().set_bit());
2092 #[cfg(esp32)]
2093 {
2094 rmt.ch4conf1().modify(|_, w| w.ref_always_on().set_bit());
2095 rmt.ch5conf1().modify(|_, w| w.ref_always_on().set_bit());
2096 rmt.ch6conf1().modify(|_, w| w.ref_always_on().set_bit());
2097 rmt.ch7conf1().modify(|_, w| w.ref_always_on().set_bit());
2098 }
2099
2100 rmt.apb_conf().modify(|_, w| w.apb_fifo_mask().set_bit());
2101
2102 #[cfg(not(esp32))]
2103 rmt.apb_conf().modify(|_, w| w.clk_en().set_bit());
2104 }
2105
2106 #[allow(unused)]
2107 #[cfg(esp32)]
2108 pub fn pending_interrupt_for_channel() -> Option<usize> {
2109 let rmt = RMT::regs();
2110 let st = rmt.int_st().read();
2111
2112 if st.ch0_rx_end().bit() || st.ch0_tx_end().bit() || st.ch0_err().bit() {
2113 Some(0)
2114 } else if st.ch1_rx_end().bit() || st.ch1_tx_end().bit() || st.ch1_err().bit() {
2115 Some(1)
2116 } else if st.ch2_rx_end().bit() || st.ch2_tx_end().bit() || st.ch2_err().bit() {
2117 Some(2)
2118 } else if st.ch3_rx_end().bit() || st.ch3_tx_end().bit() || st.ch3_err().bit() {
2119 Some(3)
2120 } else if st.ch4_rx_end().bit() || st.ch4_tx_end().bit() || st.ch4_err().bit() {
2121 Some(4)
2122 } else if st.ch5_rx_end().bit() || st.ch5_tx_end().bit() || st.ch5_err().bit() {
2123 Some(5)
2124 } else if st.ch6_rx_end().bit() || st.ch6_tx_end().bit() || st.ch6_err().bit() {
2125 Some(6)
2126 } else if st.ch7_rx_end().bit() || st.ch7_tx_end().bit() || st.ch7_err().bit() {
2127 Some(7)
2128 } else {
2129 None
2130 }
2131 }
2132
2133 #[allow(unused)]
2134 #[cfg(esp32s2)]
2135 pub fn pending_interrupt_for_channel() -> Option<usize> {
2136 let rmt = RMT::regs();
2137 let st = rmt.int_st().read();
2138
2139 if st.ch0_rx_end().bit() || st.ch0_tx_end().bit() || st.ch0_err().bit() {
2140 Some(0)
2141 } else if st.ch1_rx_end().bit() || st.ch1_tx_end().bit() || st.ch1_err().bit() {
2142 Some(1)
2143 } else if st.ch2_rx_end().bit() || st.ch2_tx_end().bit() || st.ch2_err().bit() {
2144 Some(2)
2145 } else if st.ch3_rx_end().bit() || st.ch3_tx_end().bit() || st.ch3_err().bit() {
2146 Some(3)
2147 } else {
2148 None
2149 }
2150 }
2151
2152 macro_rules! impl_tx_channel {
2153 ($signal:ident, $ch_num:literal) => {
2154 impl<Dm> super::TxChannelInternal for $crate::rmt::Channel<Dm, $ch_num>
2155 where
2156 Dm: $crate::DriverMode,
2157 {
2158 const CHANNEL: u8 = $ch_num;
2159
2160 fn new() -> Self {
2161 let guard = GenericPeripheralGuard::new();
2162 Self {
2163 phantom: core::marker::PhantomData,
2164 _guard: guard,
2165 }
2166 }
2167
2168 fn output_signal() -> crate::gpio::OutputSignal {
2169 crate::gpio::OutputSignal::$signal
2170 }
2171
2172 fn set_divider(divider: u8) {
2173 let rmt = crate::peripherals::RMT::regs();
2174 rmt.chconf0($ch_num)
2175 .modify(|_, w| unsafe { w.div_cnt().bits(divider) });
2176 }
2177
2178 fn update() {
2179 }
2181
2182 #[cfg(not(esp32))]
2183 fn set_generate_repeat_interrupt(repeats: u16) {
2184 let rmt = crate::peripherals::RMT::regs();
2185 if repeats > 1 {
2186 rmt.ch_tx_lim($ch_num)
2187 .modify(|_, w| unsafe { w.tx_loop_num().bits(repeats) });
2188 } else {
2189 rmt.ch_tx_lim($ch_num)
2190 .modify(|_, w| unsafe { w.tx_loop_num().bits(0) });
2191 }
2192 }
2193
2194 #[cfg(esp32)]
2195 fn set_generate_repeat_interrupt(_repeats: u16) {
2196 }
2198
2199 fn clear_interrupts() {
2200 let rmt = crate::peripherals::RMT::regs();
2201
2202 rmt.int_clr().write(|w| {
2203 w.ch_err($ch_num).set_bit();
2204 w.ch_tx_end($ch_num).set_bit();
2205 w.ch_tx_thr_event($ch_num).set_bit()
2206 });
2207 }
2208
2209 fn set_continuous(continuous: bool) {
2210 let rmt = crate::peripherals::RMT::regs();
2211
2212 rmt.chconf1($ch_num)
2213 .modify(|_, w| w.tx_conti_mode().bit(continuous));
2214 }
2215
2216 fn set_wrap_mode(wrap: bool) {
2217 let rmt = crate::peripherals::RMT::regs();
2218 rmt.apb_conf().modify(|_, w| w.mem_tx_wrap_en().bit(wrap));
2220 }
2221
2222 fn set_carrier(carrier: bool, high: u16, low: u16, level: $crate::gpio::Level) {
2223 let rmt = crate::peripherals::RMT::regs();
2224
2225 rmt.chcarrier_duty($ch_num)
2226 .write(|w| unsafe { w.carrier_high().bits(high).carrier_low().bits(low) });
2227
2228 rmt.chconf0($ch_num).modify(|_, w| {
2229 w.carrier_en()
2230 .bit(carrier)
2231 .carrier_out_lv()
2232 .bit(level.into())
2233 });
2234 }
2235
2236 fn set_idle_output(enable: bool, level: $crate::gpio::Level) {
2237 let rmt = crate::peripherals::RMT::regs();
2238 rmt.chconf1($ch_num)
2239 .modify(|_, w| w.idle_out_en().bit(enable).idle_out_lv().bit(level.into()));
2240 }
2241
2242 fn set_memsize(memsize: u8) {
2243 let rmt = crate::peripherals::RMT::regs();
2244
2245 rmt.chconf0($ch_num)
2246 .modify(|_, w| unsafe { w.mem_size().bits(memsize) });
2247 }
2248
2249 fn start_tx() {
2250 let rmt = crate::peripherals::RMT::regs();
2251
2252 rmt.chconf1($ch_num).modify(|_, w| {
2253 w.mem_rd_rst().set_bit();
2254 w.apb_mem_rst().set_bit();
2255 w.tx_start().set_bit()
2256 });
2257 }
2258
2259 fn is_done() -> bool {
2260 let rmt = crate::peripherals::RMT::regs();
2261 rmt.int_raw().read().ch_tx_end($ch_num).bit()
2262 }
2263
2264 fn is_error() -> bool {
2265 let rmt = crate::peripherals::RMT::regs();
2266 rmt.int_raw().read().ch_err($ch_num).bit()
2267 }
2268
2269 fn is_threshold_set() -> bool {
2270 let rmt = crate::peripherals::RMT::regs();
2271 rmt.int_raw().read().ch_tx_thr_event($ch_num).bit()
2272 }
2273
2274 fn reset_threshold_set() {
2275 let rmt = crate::peripherals::RMT::regs();
2276 rmt.int_clr()
2277 .write(|w| w.ch_tx_thr_event($ch_num).set_bit());
2278 }
2279
2280 fn set_threshold(threshold: u8) {
2281 let rmt = crate::peripherals::RMT::regs();
2282 rmt.ch_tx_lim($ch_num)
2283 .modify(|_, w| unsafe { w.tx_lim().bits(threshold as u16) });
2284 }
2285
2286 fn is_loopcount_interrupt_set() -> bool {
2287 false
2289 }
2290
2291 fn stop() {
2292 #[cfg(esp32s2)]
2293 {
2294 let rmt = crate::peripherals::RMT::regs();
2295 rmt.chconf1($ch_num).modify(|_, w| w.tx_stop().set_bit());
2296 }
2297 }
2298
2299 fn enable_listen_interrupt(
2300 events: enumset::EnumSet<$crate::rmt::Event>,
2301 enable: bool,
2302 ) {
2303 let rmt = crate::peripherals::RMT::regs();
2304 rmt.int_ena().modify(|_, w| {
2305 if events.contains($crate::rmt::Event::Error) {
2306 w.ch_err($ch_num).bit(enable);
2307 }
2308 if events.contains($crate::rmt::Event::End) {
2309 w.ch_tx_end($ch_num).bit(enable);
2310 }
2311 if events.contains($crate::rmt::Event::Threshold) {
2312 w.ch_tx_thr_event($ch_num).bit(enable);
2313 }
2314 w
2315 });
2316 }
2317 }
2318 };
2319 }
2320
2321 macro_rules! impl_rx_channel {
2322 ($signal:ident, $ch_num:literal) => {
2323 impl<Dm> super::RxChannelInternal for $crate::rmt::Channel<Dm, $ch_num>
2324 where
2325 Dm: $crate::DriverMode,
2326 {
2327 const CHANNEL: u8 = $ch_num;
2328
2329 fn new() -> Self {
2330 let guard = GenericPeripheralGuard::new();
2331 Self {
2332 phantom: core::marker::PhantomData,
2333 _guard: guard,
2334 }
2335 }
2336
2337 fn input_signal() -> crate::gpio::InputSignal {
2338 crate::gpio::InputSignal::$signal
2339 }
2340
2341 fn set_divider(divider: u8) {
2342 let rmt = crate::peripherals::RMT::regs();
2343 rmt.chconf0($ch_num)
2344 .modify(|_, w| unsafe { w.div_cnt().bits(divider) });
2345 }
2346
2347 fn update() {
2348 }
2350
2351 fn clear_interrupts() {
2352 let rmt = crate::peripherals::RMT::regs();
2353
2354 rmt.chconf1($ch_num).modify(|_, w| {
2355 w.mem_wr_rst().set_bit();
2356 w.apb_mem_rst().set_bit();
2357 w.mem_owner().set_bit();
2358 w.rx_en().clear_bit()
2359 });
2360 Self::update();
2361
2362 rmt.int_clr().write(|w| {
2363 w.ch_rx_end($ch_num).set_bit();
2364 w.ch_err($ch_num).set_bit();
2365 w.ch_tx_thr_event($ch_num).set_bit()
2366 });
2367 }
2368
2369 fn set_wrap_mode(_wrap: bool) {
2370 }
2372
2373 fn set_carrier(carrier: bool, high: u16, low: u16, level: $crate::gpio::Level) {
2374 let rmt = crate::peripherals::RMT::regs();
2375
2376 rmt.chcarrier_duty($ch_num)
2377 .write(|w| unsafe { w.carrier_high().bits(high).carrier_low().bits(low) });
2378
2379 rmt.chconf0($ch_num).modify(|_, w| {
2380 w.carrier_en()
2381 .bit(carrier)
2382 .carrier_out_lv()
2383 .bit(level.into())
2384 });
2385 }
2386
2387 fn set_memsize(memsize: u8) {
2388 let rmt = crate::peripherals::RMT::regs();
2389
2390 rmt.chconf0($ch_num)
2391 .modify(|_, w| unsafe { w.mem_size().bits(memsize) });
2392 }
2393
2394 fn start_rx() {
2395 let rmt = crate::peripherals::RMT::regs();
2396
2397 rmt.chconf1($ch_num).modify(|_, w| {
2398 w.mem_wr_rst().set_bit();
2399 w.apb_mem_rst().set_bit();
2400 w.mem_owner().set_bit();
2401 w.rx_en().set_bit()
2402 });
2403 }
2404
2405 fn is_done() -> bool {
2406 let rmt = crate::peripherals::RMT::regs();
2407 rmt.int_raw().read().ch_rx_end($ch_num).bit()
2408 }
2409
2410 fn is_error() -> bool {
2411 let rmt = crate::peripherals::RMT::regs();
2412 rmt.int_raw().read().ch_err($ch_num).bit()
2413 }
2414
2415 fn stop() {
2416 let rmt = crate::peripherals::RMT::regs();
2417 rmt.chconf1($ch_num).modify(|_, w| w.rx_en().clear_bit());
2418 }
2419
2420 fn set_filter_threshold(value: u8) {
2421 let rmt = crate::peripherals::RMT::regs();
2422 rmt.chconf1($ch_num).modify(|_, w| unsafe {
2423 w.rx_filter_en().bit(value > 0);
2424 w.rx_filter_thres().bits(value)
2425 });
2426 }
2427
2428 fn set_idle_threshold(value: u16) {
2429 let rmt = crate::peripherals::RMT::regs();
2430 rmt.chconf0($ch_num)
2431 .modify(|_, w| unsafe { w.idle_thres().bits(value) });
2432 }
2433
2434 fn enable_listen_interrupt(
2435 events: enumset::EnumSet<$crate::rmt::Event>,
2436 enable: bool,
2437 ) {
2438 let rmt = crate::peripherals::RMT::regs();
2439 rmt.int_ena().modify(|_, w| {
2440 if events.contains($crate::rmt::Event::Error) {
2441 w.ch_err($ch_num).bit(enable);
2442 }
2443 if events.contains($crate::rmt::Event::End) {
2444 w.ch_rx_end($ch_num).bit(enable);
2445 }
2446 if events.contains($crate::rmt::Event::Threshold) {
2447 w.ch_tx_thr_event($ch_num).bit(enable);
2448 }
2449 w
2450 });
2451 }
2452 }
2453 };
2454 }
2455
2456 pub(crate) use impl_rx_channel;
2457 pub(crate) use impl_tx_channel;
2458}