esp_hal/
rmt.rs

1//! # Remote Control Peripheral (RMT)
2//!
3//! ## Overview
4//! The RMT (Remote Control) module is designed to send and receive infrared
5//! remote control signals. A variety of remote control protocols can be
6//! encoded/decoded via software based on the RMT module. The RMT module
7//! converts pulse codes stored in the module’s built-in RAM into output
8//! signals, or converts input signals into pulse codes and stores them in RAM.
9//! In addition, the RMT module optionally modulates its output signals with a
10//! carrier wave, or optionally demodulates and filters its input signals.
11//!
12//! Typically, the RMT peripheral can be used in the following scenarios:
13//! - Transmit or receive infrared signals, with any IR protocols, e.g., NEC
14//! - General-purpose sequence generator
15//! - Transmit signals in a hardware-controlled loop, with a finite or infinite
16//!   number of times
17//! - Modulate the carrier to the output signal or demodulate the carrier from
18//!   the input signal
19//!
20//! ### Channels
21//!
22//! There are
23#![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//! For more information, please refer to the
41#![doc = concat!("[ESP-IDF documentation](https://docs.espressif.com/projects/esp-idf/en/latest/", crate::soc::chip!(), "/api-reference/peripherals/rmt.html)")]
42//! ## Configuration
43//! Each TX/RX channel has the same functionality controlled by a dedicated set
44//! of registers and is able to independently transmit or receive data. TX
45//! channels are indicated by n which is used as a placeholder for the channel
46//! number, and by m for RX channels.
47//!
48//! ## Examples
49//!
50//! ### Initialization
51//!
52//! ```rust, no_run
53#![doc = crate::before_snippet!()]
54//! # use esp_hal::gpio::Level;
55//! # use esp_hal::peripherals::Peripherals;
56//! # use esp_hal::rmt::TxChannelConfig;
57//! # use esp_hal::rmt::Rmt;
58//! # use crate::esp_hal::rmt::TxChannelCreator;
59#![cfg_attr(esp32h2, doc = "let freq = Rate::from_mhz(32);")]
60#![cfg_attr(not(esp32h2), doc = "let freq = Rate::from_mhz(80);")]
61//! let rmt = Rmt::new(peripherals.RMT, freq)?;
62//! let mut channel = rmt
63//!     .channel0
64//!     .configure(
65//!         peripherals.GPIO1,
66//!         TxChannelConfig::default()
67//!             .with_clk_divider(1)
68//!             .with_idle_output_level(Level::Low)
69//!             .with_idle_output(false)
70//!             .with_carrier_modulation(false)
71//!             .with_carrier_high(1)
72//!             .with_carrier_low(1)
73//!             .with_carrier_level(Level::Low),
74//!     )?;
75//! # Ok(())
76//! # }
77//! ```
78//! 
79//! ### TX operation
80//! ```rust, no_run
81#![doc = crate::before_snippet!()]
82//! # use esp_hal::delay::Delay;
83//! # use esp_hal::gpio::Level;
84//! # use esp_hal::rmt::{PulseCode, Rmt, TxChannel, TxChannelConfig, TxChannelCreator};
85//!
86//! // Configure frequency based on chip type
87#![cfg_attr(esp32h2, doc = "let freq = Rate::from_mhz(32);")]
88#![cfg_attr(not(esp32h2), doc = "let freq = Rate::from_mhz(80);")]
89//! let rmt = Rmt::new(peripherals.RMT, freq)?;
90//!
91//! let tx_config = TxChannelConfig::default().with_clk_divider(255);
92//!
93//! let mut channel = rmt
94//!     .channel0
95//!     .configure(peripherals.GPIO4, tx_config)?;
96//!
97//! let delay = Delay::new();
98//!
99//! let mut data = [PulseCode::new(Level::High, 200, Level::Low, 50); 20];
100//! data[data.len() - 2] = PulseCode::new(Level::High, 3000, Level::Low, 500);
101//! data[data.len() - 1] = PulseCode::empty();
102//!
103//! loop {
104//!     let transaction = channel.transmit(&data)?;
105//!     channel = transaction.wait()?;
106//!     delay.delay_millis(500);
107//! }
108//! # }
109//! ```
110//! 
111//! ### RX operation
112//! ```rust, no_run
113#![doc = crate::before_snippet!()]
114//! # use esp_hal::rmt::{PulseCode, Rmt, RxChannel, RxChannelConfig, RxChannelCreator};
115//! # use esp_hal::delay::Delay;
116//! # use esp_hal::gpio::{Level, Output, OutputConfig};
117//!
118//! const WIDTH: usize = 80;
119//!
120//! let mut out = Output::new(
121//!     peripherals.GPIO5,
122//!     Level::Low,
123//!     OutputConfig::default(),
124//! );
125//!
126//! // Configure frequency based on chip type
127#![cfg_attr(esp32h2, doc = "let freq = Rate::from_mhz(32);")]
128#![cfg_attr(not(esp32h2), doc = "let freq = Rate::from_mhz(80);")]
129//! let rmt = Rmt::new(peripherals.RMT, freq)?;
130//!
131//! let rx_config = RxChannelConfig::default()
132//!     .with_clk_divider(1)
133//!     .with_idle_threshold(10000);
134#![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)]
146//! let delay = Delay::new();
147//! let mut data: [u32; 48] = [PulseCode::empty(); 48];
148//!
149//! loop {
150//!     for x in data.iter_mut() {
151//!         x.reset()
152//!     }
153//!
154//!     let transaction = channel.receive(&mut data)?;
155//!
156//!     // Simulate input
157//!     for i in 0u32..5u32 {
158//!         out.set_high();
159//!         delay.delay_micros(i * 10 + 20);
160//!         out.set_low();
161//!         delay.delay_micros(i * 20 + 20);
162//!     }
163//!
164//!     match transaction.wait() {
165//!         Ok(channel_res) => {
166//!             channel = channel_res;
167//!             let mut total = 0usize;
168//!             for entry in &data[..data.len()] {
169//!                 if entry.length1() == 0 {
170//!                     break;
171//!                 }
172//!                 total += entry.length1() as usize;
173//!
174//!                 if entry.length2() == 0 {
175//!                     break;
176//!                 }
177//!                 total += entry.length2() as usize;
178//!             }
179//!
180//!             for entry in &data[..data.len()] {
181//!                 if entry.length1() == 0 {
182//!                     break;
183//!                 }
184//!
185//!                 let count = WIDTH / (total / entry.length1() as usize);
186//!                 let c = match entry.level1() {
187//!                     Level::High => '-',
188//!                     Level::Low => '_',
189//!                 };
190//!                 for _ in 0..count + 1 {
191//!                     print!("{}", c);
192//!                 }
193//!
194//!                 if entry.length2() == 0 {
195//!                     break;
196//!                 }
197//!
198//!                 let count = WIDTH / (total / entry.length2() as usize);
199//!                 let c = match entry.level2() {
200//!                     Level::High => '-',
201//!                     Level::Low => '_',
202//!                 };
203//!                 for _ in 0..count + 1 {
204//!                     print!("{}", c);
205//!                 }
206//!             }
207//!
208//!             println!();
209//!         }
210//!         Err((_err, channel_res)) => {
211//!             channel = channel_res;
212//!         }
213//!     }
214//!
215//!     delay.delay_millis(1500);
216//! }
217//! # }
218//! ```
219//! 
220//! > Note: on ESP32 and ESP32-S2 you cannot specify a base frequency other than 80 MHz
221
222use 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/// Errors
248#[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    /// The desired frequency is impossible to reach
253    UnreachableTargetFrequency,
254    /// The amount of pulses exceeds the size of the FIFO
255    Overflow,
256    /// An argument is invalid
257    InvalidArgument,
258    /// An error occurred during transmission
259    TransmissionError,
260    /// No transmission end marker found
261    EndMarkerMissing,
262}
263
264///  Convenience trait to work with pulse codes.
265pub trait PulseCode: crate::private::Sealed {
266    /// Create a new instance
267    fn new(level1: Level, length1: u16, level2: Level, length2: u16) -> Self;
268
269    /// Create a new empty instance
270    fn empty() -> Self;
271
272    /// Set all levels and lengths to 0
273    fn reset(&mut self);
274
275    /// Logical output level in the first pulse code interval
276    fn level1(&self) -> Level;
277
278    /// Length of the first pulse code interval (in clock cycles)
279    fn length1(&self) -> u16;
280
281    /// Logical output level in the second pulse code interval
282    fn level2(&self) -> Level;
283
284    /// Length of the second pulse code interval (in clock cycles)
285    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/// Channel configuration for TX channels
321#[derive(Debug, Copy, Clone, procmacros::BuilderLite)]
322#[cfg_attr(feature = "defmt", derive(defmt::Format))]
323pub struct TxChannelConfig {
324    /// Channel's clock divider
325    clk_divider: u8,
326    /// Set the idle output level to low/high
327    idle_output_level: Level,
328    /// Enable idle output
329    idle_output: bool,
330    /// Enable carrier modulation
331    carrier_modulation: bool,
332    /// Carrier high phase in ticks
333    carrier_high: u16,
334    /// Carrier low phase in ticks
335    carrier_low: u16,
336    /// Level of the carrier
337    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/// Channel configuration for RX channels
355#[derive(Debug, Copy, Clone, procmacros::BuilderLite)]
356#[cfg_attr(feature = "defmt", derive(defmt::Format))]
357pub struct RxChannelConfig {
358    /// Channel's clock divider
359    clk_divider: u8,
360    /// Enable carrier demodulation
361    carrier_modulation: bool,
362    /// Carrier high phase in ticks
363    carrier_high: u16,
364    /// Carrier low phase in ticks
365    carrier_low: u16,
366    /// Level of the carrier
367    carrier_level: Level,
368    /// Filter threshold in ticks
369    filter_threshold: u8,
370    /// Idle threshold in ticks
371    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    /// Create a new RMT instance
436    pub fn new(peripheral: impl Peripheral<P = RMT> + 'd, frequency: Rate) -> Result<Self, Error> {
437        Self::new_internal(peripheral, frequency)
438    }
439
440    /// Reconfigures the driver for asynchronous operation.
441    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    /// Registers an interrupt handler for the RMT peripheral.
447    ///
448    /// Note that this will replace any previously registered interrupt
449    /// handlers.
450    #[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
526/// Creates a TX channel
527pub trait TxChannelCreator<'d, T, P>
528where
529    P: PeripheralOutput,
530    T: TxChannel,
531{
532    /// Configure the TX channel
533    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
545/// Creates a TX channel in async mode
546pub trait TxChannelCreatorAsync<'d, T, P>
547where
548    P: PeripheralOutput,
549    T: TxChannelAsync,
550{
551    /// Configure the TX channel
552    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
564/// Creates a RX channel
565pub trait RxChannelCreator<'d, T, P>
566where
567    P: PeripheralInput,
568    T: RxChannel,
569{
570    /// Configure the RX channel
571    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
583/// Creates a RX channel in async mode
584pub trait RxChannelCreatorAsync<'d, T, P>
585where
586    P: PeripheralInput,
587    T: RxChannelAsync,
588{
589    /// Configure the RX channel
590    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
602/// An in-progress transaction for a single shot TX transaction.
603pub 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    /// Wait for the transaction to complete
617    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            // wait for TX-THR
628            while !<C as TxChannelInternal>::is_threshold_set() {}
629            <C as TxChannelInternal>::reset_threshold_set();
630
631            // re-fill TX RAM
632            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
667/// An in-progress continuous TX transaction
668pub struct ContinuousTxTransaction<C>
669where
670    C: TxChannel,
671{
672    channel: C,
673}
674
675impl<C> ContinuousTxTransaction<C>
676where
677    C: TxChannel,
678{
679    /// Stop transaction when the current iteration ends.
680    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    /// Stop transaction as soon as possible.
698    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    /// Check if the `loopcount` interrupt bit is set
725    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    /// RMT Instance
788    pub struct Rmt<'d, Dm>
789    where
790        Dm: crate::DriverMode,
791    {
792        pub(super) peripheral: PeripheralRef<'d, crate::peripherals::RMT>,
793        /// RMT Channel 0.
794        pub channel0: ChannelCreator<Dm, 0>,
795        /// RMT Channel 1.
796        pub channel1: ChannelCreator<Dm, 1>,
797        /// RMT Channel 2.
798        pub channel2: ChannelCreator<Dm, 2>,
799        /// RMT Channel 3.
800        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    /// RMT Channel Creator
837    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    /// RMT Instance
869    pub struct Rmt<'d, Dm>
870    where
871        Dm: crate::DriverMode,
872    {
873        pub(super) peripheral: PeripheralRef<'d, RMT>,
874        /// RMT Channel 0.
875        pub channel0: ChannelCreator<Dm, 0>,
876        /// RMT Channel 1.
877        pub channel1: ChannelCreator<Dm, 1>,
878        /// RMT Channel 2.
879        pub channel2: ChannelCreator<Dm, 2>,
880        /// RMT Channel 3.
881        pub channel3: ChannelCreator<Dm, 3>,
882        /// RMT Channel 4.
883        pub channel4: ChannelCreator<Dm, 4>,
884        /// RMT Channel 5.
885        pub channel5: ChannelCreator<Dm, 5>,
886        /// RMT Channel 6.
887        pub channel6: ChannelCreator<Dm, 6>,
888        /// RMT Channel 7.
889        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    /// RMT Channel Creator
939    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    /// RMT Instance
995    pub struct Rmt<'d, Dm>
996    where
997        Dm: crate::DriverMode,
998    {
999        pub(super) peripheral: PeripheralRef<'d, RMT>,
1000        /// RMT Channel 0.
1001        pub channel0: ChannelCreator<Dm, 0>,
1002        /// RMT Channel 1.
1003        pub channel1: ChannelCreator<Dm, 1>,
1004        /// RMT Channel 2.
1005        pub channel2: ChannelCreator<Dm, 2>,
1006        /// RMT Channel 3.
1007        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    /// RMT Channel Creator
1042    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    /// RMT Instance
1082    pub struct Rmt<'d, Dm>
1083    where
1084        Dm: crate::DriverMode,
1085    {
1086        pub(super) peripheral: PeripheralRef<'d, RMT>,
1087        /// RMT Channel 0.
1088        pub channel0: ChannelCreator<Dm, 0>,
1089        /// RMT Channel 1.
1090        pub channel1: ChannelCreator<Dm, 1>,
1091        /// RMT Channel 2.
1092        pub channel2: ChannelCreator<Dm, 2>,
1093        /// RMT Channel 3.
1094        pub channel3: ChannelCreator<Dm, 3>,
1095        /// RMT Channel 4.
1096        pub channel4: ChannelCreator<Dm, 4>,
1097        /// RMT Channel 5.
1098        pub channel5: ChannelCreator<Dm, 5>,
1099        /// RMT Channel 6.
1100        pub channel6: ChannelCreator<Dm, 6>,
1101        /// RMT Channel 7.
1102        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    /// RMT Channel Creator
1153    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/// RMT Channel
1183#[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
1193/// Channel in TX mode
1194pub trait TxChannel: TxChannelInternal {
1195    /// Start transmitting the given pulse code sequence.
1196    /// This returns a [`SingleShotTxTransaction`] which can be used to wait for
1197    /// the transaction to complete and get back the channel for further
1198    /// use.
1199    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    /// Start transmitting the given pulse code continuously.
1212    /// This returns a [`ContinuousTxTransaction`] which can be used to stop the
1213    /// ongoing transmission and get back the channel for further use.
1214    /// The length of sequence cannot exceed the size of the allocated RMT RAM.
1215    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    /// Like [`Self::transmit_continuously`] but also sets a loop count.
1223    /// [`ContinuousTxTransaction`] can be used to check if the loop count is
1224    /// reached.
1225    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
1242/// RX transaction instance
1243pub 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    /// Wait for the transaction to complete
1256    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
1283/// Channel is RX mode
1284pub trait RxChannel: RxChannelInternal {
1285    /// Start receiving pulse codes into the given buffer.
1286    /// This returns a [RxTransaction] which can be used to wait for receive to
1287    /// complete and get back the channel for further use.
1288    /// The length of the received data cannot exceed the allocated RMT RAM.
1289    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
1349/// TX channel in async mode
1350pub trait TxChannelAsync: TxChannelInternal {
1351    /// Start transmitting the given pulse code sequence.
1352    /// The length of sequence cannot exceed the size of the allocated RMT
1353    /// RAM.
1354    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
1411/// RX channel in async mode
1412pub trait RxChannelAsync: RxChannelInternal {
1413    /// Start receiving a pulse code sequence.
1414    /// The length of sequence cannot exceed the size of the allocated RMT
1415    /// RAM.
1416    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                    // no-op
2180                }
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                    // unsupported
2197                }
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                    // this is "okay", because we use all TX channels always in wrap mode
2219                    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                    // no-op
2288                    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                    // no-op
2349                }
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                    // no-op
2371                }
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}