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