Skip to main content

esp_hal/peripherals/
overlay_rmt.rs

1//! Register-block overlay for ESP32-P4 and ESP32-S31 RMT.
2//!
3//! The peripheral matches ESP32-S3. The PAC uses different SVD names, so this
4//! overlay presents the ESP32-S3 register API. RMT must be `virtual` for this
5//! to work.
6
7use core::ops::Deref;
8
9use super::*;
10use crate::soc::pac::rmt;
11
12impl RMT<'_> {
13    /// Return a reference to the register block.
14    #[inline(always)]
15    #[instability::unstable]
16    pub const fn regs<'a>() -> &'a RmtRegisterBlock {
17        &RmtRegisterBlock
18    }
19
20    /// Return a reference to the register block.
21    #[inline(always)]
22    #[instability::unstable]
23    pub fn register_block(&self) -> &RmtRegisterBlock {
24        &RmtRegisterBlock
25    }
26}
27
28/// Register block overlay for the RMT peripheral.
29#[instability::unstable]
30pub struct RmtRegisterBlock;
31
32impl Deref for RmtRegisterBlock {
33    type Target = rmt::RegisterBlock;
34
35    fn deref(&self) -> &Self::Target {
36        unsafe { &*pac::RMT::ptr() }
37    }
38}
39
40impl RmtRegisterBlock {
41    /// Channel n TX configure register 0.
42    #[inline]
43    pub fn ch_tx_conf0(&self, n: usize) -> TxConf0<'_> {
44        TxConf0(self.chconf0(n))
45    }
46
47    /// Channel n RX configure register 0.
48    #[inline]
49    pub fn ch_rx_conf0(&self, n: usize) -> ChRxConf0 {
50        assert!(n < 4);
51        ChRxConf0 {
52            ptr: unsafe {
53                core::ptr::from_ref(Deref::deref(self))
54                    .cast::<u8>()
55                    .add(0x30)
56                    .add(8 * n)
57                    .cast::<u32>()
58                    .cast_mut()
59            },
60        }
61    }
62
63    /// Channel n RX configure register 1.
64    #[inline]
65    pub fn ch_rx_conf1(&self, n: usize) -> RxConf1<'_> {
66        RxConf1(self.chconf1(n))
67    }
68
69    /// Channel n TX status register.
70    #[inline]
71    pub fn ch_tx_status(&self, n: usize) -> ChStatus<'_> {
72        ChStatus(self.chstatus(n))
73    }
74
75    /// Channel n RX status register.
76    #[inline]
77    pub fn ch_rx_status(&self, n: usize) -> ChStatus<'_> {
78        cfg_select! {
79            esp32s31 => ChStatus(match n {
80                0 => self.ch4status(),
81                1 => self.ch5status(),
82                2 => self.ch6status(),
83                3 => self.ch7status(),
84                _ => panic!("RMT RX status index must be 0..=3"),
85            }),
86            esp32p4 => {
87                assert!(n < 4);
88                ChStatus(unsafe {
89                    &*core::ptr::from_ref(Deref::deref(self))
90                        .cast::<u8>()
91                        .add(0x60)
92                        .add(4 * n)
93                        .cast()
94                })
95            }
96        }
97    }
98
99    /// Channel n TX event configuration register.
100    #[inline]
101    pub fn ch_tx_lim(&self, n: usize) -> TxLim<'_> {
102        TxLim(Deref::deref(self).ch_tx_lim(n))
103    }
104
105    /// Channel n RX event configuration register.
106    #[inline]
107    pub fn ch_rx_lim(&self, n: usize) -> RxLim<'_> {
108        RxLim(Deref::deref(self).ch_rx_lim(n))
109    }
110
111    /// Channel n carrier duty register.
112    #[inline]
113    pub fn chcarrier_duty(&self, n: usize) -> CarrierDuty<'_> {
114        CarrierDuty(Deref::deref(self).chcarrier_duty(n))
115    }
116
117    /// Channel n RX carrier remove register.
118    #[inline]
119    pub fn ch_rx_carrier_rm(&self, n: usize) -> RxCarrierRm<'_> {
120        RxCarrierRm(Deref::deref(self).ch_rx_carrier_rm(n))
121    }
122
123    /// Masked interrupt status.
124    #[inline]
125    pub fn int_st(&self) -> IntSt<'_> {
126        IntSt(Deref::deref(self).int_st())
127    }
128
129    /// Raw interrupt status.
130    #[inline]
131    pub fn int_raw(&self) -> IntRaw<'_> {
132        IntRaw(Deref::deref(self).int_raw())
133    }
134
135    /// Interrupt enable bits.
136    #[inline]
137    pub fn int_ena(&self) -> IntEna<'_> {
138        IntEna(Deref::deref(self).int_ena())
139    }
140
141    /// Interrupt clear bits.
142    #[inline]
143    pub fn int_clr(&self) -> IntClr<'_> {
144        IntClr(Deref::deref(self).int_clr())
145    }
146}
147
148/// Bit flag reader with a PAC-like [`bit`](BitFlag::bit) method.
149pub struct BitFlag(bool);
150
151impl BitFlag {
152    #[inline]
153    pub fn bit(self) -> bool {
154        self.0
155    }
156}
157
158/// Field reader with a PAC-like [`bits`](FieldVal::bits) method.
159pub struct FieldVal<T>(T);
160
161impl<T> FieldVal<T> {
162    #[inline]
163    pub fn bits(self) -> T {
164        self.0
165    }
166}
167
168/// Bit field writer with PAC-like `bit` / `set_bit` / `clear_bit` methods.
169pub struct BitProxy<'a, W>(&'a mut W, fn(&mut W, bool));
170
171impl<'a, W> BitProxy<'a, W> {
172    #[inline]
173    pub fn bit(self, val: bool) -> &'a mut W {
174        (self.1)(self.0, val);
175        self.0
176    }
177
178    #[inline]
179    pub fn set_bit(self) -> &'a mut W {
180        self.bit(true)
181    }
182
183    #[inline]
184    pub fn clear_bit(self) -> &'a mut W {
185        self.bit(false)
186    }
187}
188
189/// Multi-bit field writer with a PAC-like `bits` method.
190pub struct FieldProxy<'a, W, T>(&'a mut W, fn(&mut W, T));
191
192impl<'a, W, T> FieldProxy<'a, W, T> {
193    #[inline]
194    pub unsafe fn bits(self, val: T) -> &'a mut W {
195        (self.1)(self.0, val);
196        self.0
197    }
198}
199
200fn overlay_w<P, O>(w: &mut P) -> &mut O {
201    unsafe { &mut *core::ptr::from_mut(w).cast() }
202}
203
204macro_rules! bit_proxy {
205    ($self:ident, $s31:ident, $p4:ident) => {
206        BitProxy($self, |w, val| {
207            #[cfg(esp32s31)]
208            {
209                w.0.$s31().bit(val);
210            }
211            #[cfg(esp32p4)]
212            {
213                w.0.$p4().bit(val);
214            }
215        })
216    };
217}
218
219macro_rules! field_proxy {
220    ($self:ident, $s31:ident, $p4:ident) => {
221        FieldProxy($self, |w, val| {
222            #[cfg(esp32s31)]
223            {
224                let _ = unsafe { w.0.$s31().bits(val) };
225            }
226            #[cfg(esp32p4)]
227            {
228                let _ = unsafe { w.0.$p4().bits(val) };
229            }
230        })
231    };
232}
233
234/// Channel TX configure register 0.
235pub struct TxConf0<'a>(&'a rmt::CHCONF0);
236
237/// Reader for [`TxConf0`].
238pub struct TxConf0R(u32);
239
240/// Writer for [`TxConf0`].
241#[repr(transparent)]
242pub struct TxConf0W(rmt::chconf0::W);
243
244impl TxConf0<'_> {
245    /// Read the register.
246    #[inline]
247    pub fn read(&self) -> TxConf0R {
248        TxConf0R(self.0.read().bits())
249    }
250
251    /// Modify the register.
252    #[inline]
253    pub fn modify<F>(&self, f: F)
254    where
255        F: for<'a> FnOnce(&TxConf0R, &'a mut TxConf0W) -> &'a mut TxConf0W,
256    {
257        self.0.modify(|r, w| {
258            let overlay_r = TxConf0R(r.bits());
259            let _ = f(&overlay_r, overlay_w(w));
260            w
261        });
262    }
263}
264
265impl TxConf0R {
266    #[inline]
267    pub fn mem_size(&self) -> FieldVal<u8> {
268        FieldVal(((self.0 >> 16) & 0x0f) as u8)
269    }
270
271    #[inline]
272    pub fn idle_out_en(&self) -> BitFlag {
273        BitFlag((self.0 >> 6) & 1 != 0)
274    }
275
276    #[inline]
277    pub fn idle_out_lv(&self) -> BitFlag {
278        BitFlag((self.0 >> 5) & 1 != 0)
279    }
280}
281
282impl TxConf0W {
283    #[inline]
284    pub fn conf_update(&mut self) -> BitProxy<'_, Self> {
285        bit_proxy!(self, conf_update_ch, conf_update_ch0)
286    }
287
288    #[inline]
289    pub fn div_cnt(&mut self) -> FieldProxy<'_, Self, u8> {
290        field_proxy!(self, div_cnt_ch, div_cnt_ch0)
291    }
292
293    #[inline]
294    pub fn mem_size(&mut self) -> FieldProxy<'_, Self, u8> {
295        field_proxy!(self, mem_size_ch, mem_size_ch0)
296    }
297
298    #[inline]
299    pub fn tx_conti_mode(&mut self) -> BitProxy<'_, Self> {
300        bit_proxy!(self, tx_conti_mode_ch, tx_conti_mode_ch0)
301    }
302
303    #[inline]
304    pub fn mem_tx_wrap_en(&mut self) -> BitProxy<'_, Self> {
305        bit_proxy!(self, mem_tx_wrap_en_ch, mem_tx_wrap_en_ch0)
306    }
307
308    #[inline]
309    pub fn carrier_en(&mut self) -> BitProxy<'_, Self> {
310        bit_proxy!(self, carrier_en_ch, carrier_en_ch0)
311    }
312
313    #[inline]
314    pub fn carrier_eff_en(&mut self) -> BitProxy<'_, Self> {
315        bit_proxy!(self, carrier_eff_en_ch, carrier_eff_en_ch0)
316    }
317
318    #[inline]
319    pub fn carrier_out_lv(&mut self) -> BitProxy<'_, Self> {
320        bit_proxy!(self, carrier_out_lv_ch, carrier_out_lv_ch0)
321    }
322
323    #[inline]
324    pub fn idle_out_en(&mut self) -> BitProxy<'_, Self> {
325        bit_proxy!(self, idle_out_en_ch, idle_out_en_ch0)
326    }
327
328    #[inline]
329    pub fn idle_out_lv(&mut self) -> BitProxy<'_, Self> {
330        bit_proxy!(self, idle_out_lv_ch, idle_out_lv_ch0)
331    }
332
333    #[inline]
334    pub fn mem_rd_rst(&mut self) -> BitProxy<'_, Self> {
335        bit_proxy!(self, mem_rd_rst_ch, mem_rd_rst_ch0)
336    }
337
338    #[inline]
339    pub fn apb_mem_rst(&mut self) -> BitProxy<'_, Self> {
340        bit_proxy!(self, apb_mem_rst_ch, apb_mem_rst_ch0)
341    }
342
343    #[inline]
344    pub fn tx_start(&mut self) -> BitProxy<'_, Self> {
345        bit_proxy!(self, tx_start_ch, tx_start_ch0)
346    }
347
348    #[inline]
349    pub fn tx_stop(&mut self) -> BitProxy<'_, Self> {
350        bit_proxy!(self, tx_stop_ch, tx_stop_ch0)
351    }
352}
353
354/// RX CONF0 layout (ESP32-S3 `CH_RX_CONF0`). The PAC aliases this register to TX CONF0.
355pub struct ChRxConf0 {
356    ptr: *mut u32,
357}
358
359/// Reader for [`ChRxConf0`].
360pub struct ChRxConf0R(u32);
361
362/// Writer for [`ChRxConf0`].
363pub struct ChRxConf0W(u32);
364
365/// Bit writer for [`ChRxConf0`].
366pub struct RxBit<'a> {
367    w: &'a mut ChRxConf0W,
368    bit: u8,
369}
370
371/// Field writer for [`ChRxConf0`].
372pub struct RxField<'a> {
373    w: &'a mut ChRxConf0W,
374    offset: u8,
375    width: u8,
376}
377
378impl ChRxConf0R {
379    #[inline]
380    pub fn mem_size(&self) -> FieldVal<u8> {
381        FieldVal(((self.0 >> 24) & 0x0f) as u8)
382    }
383}
384
385impl ChRxConf0W {
386    #[inline]
387    pub fn div_cnt(&mut self) -> RxField<'_> {
388        RxField {
389            w: self,
390            offset: 0,
391            width: 8,
392        }
393    }
394
395    #[inline]
396    pub fn idle_thres(&mut self) -> RxField<'_> {
397        RxField {
398            w: self,
399            offset: 8,
400            width: 15,
401        }
402    }
403
404    #[inline]
405    pub fn mem_size(&mut self) -> RxField<'_> {
406        RxField {
407            w: self,
408            offset: 24,
409            width: 4,
410        }
411    }
412
413    #[inline]
414    pub fn carrier_en(&mut self) -> RxBit<'_> {
415        RxBit { w: self, bit: 28 }
416    }
417
418    #[inline]
419    pub fn carrier_out_lv(&mut self) -> RxBit<'_> {
420        RxBit { w: self, bit: 29 }
421    }
422}
423
424impl<'a> RxBit<'a> {
425    #[inline]
426    pub fn bit(self, val: bool) -> &'a mut ChRxConf0W {
427        if val {
428            self.w.0 |= 1 << self.bit;
429        } else {
430            self.w.0 &= !(1 << self.bit);
431        }
432        self.w
433    }
434}
435
436impl<'a> RxField<'a> {
437    #[inline]
438    pub unsafe fn bits(self, val: impl Into<u16>) -> &'a mut ChRxConf0W {
439        let mask = (1u32 << self.width) - 1;
440        self.w.0 &= !(mask << self.offset);
441        self.w.0 |= (u32::from(val.into()) & mask) << self.offset;
442        self.w
443    }
444}
445
446impl ChRxConf0 {
447    #[inline]
448    pub fn read(&self) -> ChRxConf0R {
449        ChRxConf0R(unsafe { self.ptr.read_volatile() })
450    }
451
452    #[inline]
453    pub fn modify<F>(&self, f: F)
454    where
455        F: for<'a> FnOnce(&ChRxConf0R, &'a mut ChRxConf0W) -> &'a mut ChRxConf0W,
456    {
457        let bits = unsafe { self.ptr.read_volatile() };
458        let r = ChRxConf0R(bits);
459        let mut w = ChRxConf0W(bits);
460        let _ = f(&r, &mut w);
461        unsafe { self.ptr.write_volatile(w.0) };
462    }
463}
464
465/// Channel RX configure register 1.
466pub struct RxConf1<'a>(&'a rmt::CHCONF1);
467
468/// Writer for [`RxConf1`].
469#[repr(transparent)]
470pub struct RxConf1W(rmt::chconf1::W);
471
472impl RxConf1<'_> {
473    #[inline]
474    pub fn modify<F>(&self, f: F)
475    where
476        F: for<'a> FnOnce(&(), &'a mut RxConf1W) -> &'a mut RxConf1W,
477    {
478        self.0.modify(|_, w| {
479            let _ = f(&(), overlay_w(w));
480            w
481        });
482    }
483}
484
485impl RxConf1W {
486    #[inline]
487    pub fn conf_update(&mut self) -> BitProxy<'_, Self> {
488        bit_proxy!(self, conf_update_ch, conf_update_ch4)
489    }
490
491    #[inline]
492    pub fn mem_rx_wrap_en(&mut self) -> BitProxy<'_, Self> {
493        bit_proxy!(self, mem_rx_wrap_en_ch, mem_rx_wrap_en_ch4)
494    }
495
496    #[inline]
497    pub fn mem_owner(&mut self) -> BitProxy<'_, Self> {
498        bit_proxy!(self, mem_owner_ch, mem_owner_ch4)
499    }
500
501    #[inline]
502    pub fn mem_wr_rst(&mut self) -> BitProxy<'_, Self> {
503        bit_proxy!(self, mem_wr_rst_ch, mem_wr_rst_ch4)
504    }
505
506    #[inline]
507    pub fn apb_mem_rst(&mut self) -> BitProxy<'_, Self> {
508        bit_proxy!(self, apb_mem_rst_ch, apb_mem_rst_ch4)
509    }
510
511    #[inline]
512    pub fn rx_en(&mut self) -> BitProxy<'_, Self> {
513        bit_proxy!(self, rx_en_ch, rx_en_ch4)
514    }
515
516    #[inline]
517    pub fn rx_filter_en(&mut self) -> BitProxy<'_, Self> {
518        bit_proxy!(self, rx_filter_en_ch, rx_filter_en_ch4)
519    }
520
521    #[inline]
522    pub fn rx_filter_thres(&mut self) -> FieldProxy<'_, Self, u8> {
523        field_proxy!(self, rx_filter_thres_ch, rx_filter_thres_ch4)
524    }
525}
526
527/// Channel TX/RX status register.
528pub struct ChStatus<'a>(&'a rmt::CHSTATUS);
529
530/// Reader for [`ChStatus`].
531pub struct StatusR(u32);
532
533impl ChStatus<'_> {
534    #[inline]
535    pub fn read(&self) -> StatusR {
536        StatusR(self.0.read().bits())
537    }
538}
539
540impl StatusR {
541    #[inline]
542    pub fn mem_raddr_ex(&self) -> FieldVal<u16> {
543        FieldVal((self.0 & 0x03ff) as u16)
544    }
545
546    #[inline]
547    pub fn mem_waddr_ex(&self) -> FieldVal<u16> {
548        self.mem_raddr_ex()
549    }
550}
551
552/// Channel TX limit register.
553pub struct TxLim<'a>(&'a rmt::CH_TX_LIM);
554
555/// Writer for [`TxLim`].
556#[repr(transparent)]
557pub struct TxLimW(rmt::ch_tx_lim::W);
558
559impl TxLim<'_> {
560    #[inline]
561    pub fn modify<F>(&self, f: F)
562    where
563        F: for<'a> FnOnce(&(), &'a mut TxLimW) -> &'a mut TxLimW,
564    {
565        self.0.modify(|_, w| {
566            let _ = f(&(), overlay_w(w));
567            w
568        });
569    }
570}
571
572impl TxLimW {
573    #[inline]
574    pub fn loop_count_reset(&mut self) -> BitProxy<'_, Self> {
575        BitProxy(self, |w, val| {
576            w.0.loop_count_reset_ch().bit(val);
577        })
578    }
579
580    #[inline]
581    pub fn tx_loop_cnt_en(&mut self) -> BitProxy<'_, Self> {
582        BitProxy(self, |w, val| {
583            w.0.tx_loop_cnt_en_ch().bit(val);
584        })
585    }
586
587    #[inline]
588    pub fn tx_loop_num(&mut self) -> FieldProxy<'_, Self, u16> {
589        FieldProxy(self, |w, val| {
590            let _ = unsafe { w.0.tx_loop_num_ch().bits(val) };
591        })
592    }
593
594    #[inline]
595    pub fn loop_stop_en(&mut self) -> BitProxy<'_, Self> {
596        BitProxy(self, |w, val| {
597            w.0.loop_stop_en_ch().bit(val);
598        })
599    }
600
601    #[inline]
602    pub fn tx_lim(&mut self) -> FieldProxy<'_, Self, u16> {
603        FieldProxy(self, |w, val| {
604            let _ = unsafe { w.0.tx_lim_ch().bits(val) };
605        })
606    }
607}
608
609/// Channel RX limit register.
610pub struct RxLim<'a>(&'a rmt::CH_RX_LIM);
611
612/// Writer for [`RxLim`].
613#[repr(transparent)]
614pub struct RxLimW(rmt::ch_rx_lim::W);
615
616impl RxLim<'_> {
617    #[inline]
618    pub fn modify<F>(&self, f: F)
619    where
620        F: for<'a> FnOnce(&(), &'a mut RxLimW) -> &'a mut RxLimW,
621    {
622        self.0.modify(|_, w| {
623            let _ = f(&(), overlay_w(w));
624            w
625        });
626    }
627}
628
629impl RxLimW {
630    #[inline]
631    pub fn rx_lim(&mut self) -> FieldProxy<'_, Self, u16> {
632        field_proxy!(self, rx_lim_ch, rx_lim_ch4)
633    }
634}
635
636/// Channel carrier duty register.
637pub struct CarrierDuty<'a>(&'a rmt::CHCARRIER_DUTY);
638
639/// Writer for [`CarrierDuty`].
640#[repr(transparent)]
641pub struct CarrierDutyW(rmt::chcarrier_duty::W);
642
643impl CarrierDuty<'_> {
644    #[inline]
645    pub fn write<F>(&self, f: F)
646    where
647        F: for<'a> FnOnce(&'a mut CarrierDutyW) -> &'a mut CarrierDutyW,
648    {
649        self.0.write(|w| {
650            let _ = f(overlay_w(w));
651            w
652        });
653    }
654}
655
656impl CarrierDutyW {
657    #[inline]
658    pub fn carrier_high(&mut self) -> FieldProxy<'_, Self, u16> {
659        FieldProxy(self, |w, val| {
660            let _ = unsafe { w.0.carrier_high_ch().bits(val) };
661        })
662    }
663
664    #[inline]
665    pub fn carrier_low(&mut self) -> FieldProxy<'_, Self, u16> {
666        FieldProxy(self, |w, val| {
667            let _ = unsafe { w.0.carrier_low_ch().bits(val) };
668        })
669    }
670}
671
672/// Channel RX carrier remove register.
673pub struct RxCarrierRm<'a>(&'a rmt::CH_RX_CARRIER_RM);
674
675/// Writer for [`RxCarrierRm`].
676#[repr(transparent)]
677pub struct RxCarrierRmW(rmt::ch_rx_carrier_rm::W);
678
679impl RxCarrierRm<'_> {
680    #[inline]
681    pub fn write<F>(&self, f: F)
682    where
683        F: for<'a> FnOnce(&'a mut RxCarrierRmW) -> &'a mut RxCarrierRmW,
684    {
685        self.0.write(|w| {
686            let _ = f(overlay_w(w));
687            w
688        });
689    }
690}
691
692impl RxCarrierRmW {
693    #[inline]
694    pub fn carrier_high_thres(&mut self) -> FieldProxy<'_, Self, u16> {
695        FieldProxy(self, |w, val| {
696            let _ = unsafe { w.0.carrier_high_thres_ch().bits(val) };
697        })
698    }
699
700    #[inline]
701    pub fn carrier_low_thres(&mut self) -> FieldProxy<'_, Self, u16> {
702        FieldProxy(self, |w, val| {
703            let _ = unsafe { w.0.carrier_low_thres_ch().bits(val) };
704        })
705    }
706}
707
708/// Masked interrupt status.
709pub struct IntSt<'a>(&'a rmt::INT_ST);
710
711/// Raw interrupt status.
712pub struct IntRaw<'a>(&'a rmt::INT_RAW);
713
714/// Interrupt status reader.
715pub struct IntR(u32);
716
717impl IntSt<'_> {
718    #[inline]
719    pub fn read(&self) -> IntR {
720        IntR(self.0.read().bits())
721    }
722}
723
724impl IntRaw<'_> {
725    #[inline]
726    pub fn read(&self) -> IntR {
727        IntR(self.0.read().bits())
728    }
729}
730
731impl IntR {
732    #[inline]
733    pub fn ch_tx_end(&self, n: u8) -> BitFlag {
734        BitFlag((self.0 >> n) & 1 != 0)
735    }
736
737    #[inline]
738    pub fn ch_tx_err(&self, n: u8) -> BitFlag {
739        BitFlag((self.0 >> (n + 4)) & 1 != 0)
740    }
741
742    #[inline]
743    pub fn ch_tx_thr_event(&self, n: u8) -> BitFlag {
744        BitFlag((self.0 >> (n + 8)) & 1 != 0)
745    }
746
747    #[inline]
748    pub fn ch_tx_loop(&self, n: u8) -> BitFlag {
749        BitFlag((self.0 >> (n + 12)) & 1 != 0)
750    }
751
752    #[inline]
753    pub fn ch_rx_end(&self, n: u8) -> BitFlag {
754        BitFlag((self.0 >> (n + 16)) & 1 != 0)
755    }
756
757    #[inline]
758    pub fn ch_rx_err(&self, n: u8) -> BitFlag {
759        BitFlag((self.0 >> (n + 20)) & 1 != 0)
760    }
761
762    #[inline]
763    pub fn ch_rx_thr_event(&self, n: u8) -> BitFlag {
764        BitFlag((self.0 >> (n + 24)) & 1 != 0)
765    }
766}
767
768/// Interrupt enable register.
769pub struct IntEna<'a>(&'a rmt::INT_ENA);
770
771/// Writer for [`IntEna`].
772#[repr(transparent)]
773pub struct IntEnaW(rmt::int_ena::W);
774
775/// Interrupt clear register.
776pub struct IntClr<'a>(&'a rmt::INT_CLR);
777
778/// Writer for [`IntClr`].
779#[repr(transparent)]
780pub struct IntClrW(rmt::int_clr::W);
781
782/// Clustered interrupt bit writer.
783pub struct IntBitW<'a, W> {
784    w: &'a mut W,
785    n: u8,
786    set: fn(&mut W, u8, bool),
787}
788
789impl<'a, W> IntBitW<'a, W> {
790    #[inline]
791    pub fn bit(self, val: bool) -> &'a mut W {
792        (self.set)(self.w, self.n, val);
793        self.w
794    }
795}
796
797impl IntEna<'_> {
798    #[inline]
799    pub fn modify<F>(&self, f: F)
800    where
801        F: for<'a> FnOnce(&(), &'a mut IntEnaW) -> &'a mut IntEnaW,
802    {
803        self.0.modify(|_, w| {
804            let _ = f(&(), overlay_w(w));
805            w
806        });
807    }
808}
809
810impl IntClr<'_> {
811    #[inline]
812    pub fn write<F>(&self, f: F)
813    where
814        F: for<'a> FnOnce(&'a mut IntClrW) -> &'a mut IntClrW,
815    {
816        self.0.write(|w| {
817            let _ = f(overlay_w(w));
818            w
819        });
820    }
821}
822
823macro_rules! set_tx_int {
824    ($w:expr, $n:expr, $val:expr, $p4:ident, $s31:ident) => {
825        paste::paste! {
826            match $n {
827                0 => {
828                    #[cfg(esp32p4)]
829                    {
830                        $w.[<ch0_ $p4>]().bit($val);
831                    }
832                    #[cfg(esp32s31)]
833                    {
834                        $w.[<ch0_ $s31>]().bit($val);
835                    }
836                }
837                1 => {
838                    #[cfg(esp32p4)]
839                    {
840                        $w.[<ch1_ $p4>]().bit($val);
841                    }
842                    #[cfg(esp32s31)]
843                    {
844                        $w.[<ch1_ $s31>]().bit($val);
845                    }
846                }
847                2 => {
848                    #[cfg(esp32p4)]
849                    {
850                        $w.[<ch2_ $p4>]().bit($val);
851                    }
852                    #[cfg(esp32s31)]
853                    {
854                        $w.[<ch2_ $s31>]().bit($val);
855                    }
856                }
857                3 => {
858                    #[cfg(esp32p4)]
859                    {
860                        $w.[<ch3_ $p4>]().bit($val);
861                    }
862                    #[cfg(esp32s31)]
863                    {
864                        $w.[<ch3_ $s31>]().bit($val);
865                    }
866                }
867                _ => unreachable!(),
868            }
869        }
870    };
871}
872
873macro_rules! set_rx_int {
874    ($w:expr, $n:expr, $val:expr, $p4:ident, $s31:ident) => {
875        paste::paste! {
876            match $n {
877                0 => {
878                    #[cfg(esp32p4)]
879                    {
880                        $w.[<ch4_ $p4>]().bit($val);
881                    }
882                    #[cfg(esp32s31)]
883                    {
884                        $w.[<ch4_ $s31>]().bit($val);
885                    }
886                }
887                1 => {
888                    #[cfg(esp32p4)]
889                    {
890                        $w.[<ch5_ $p4>]().bit($val);
891                    }
892                    #[cfg(esp32s31)]
893                    {
894                        $w.[<ch5_ $s31>]().bit($val);
895                    }
896                }
897                2 => {
898                    #[cfg(esp32p4)]
899                    {
900                        $w.[<ch6_ $p4>]().bit($val);
901                    }
902                    #[cfg(esp32s31)]
903                    {
904                        $w.[<ch6_ $s31>]().bit($val);
905                    }
906                }
907                3 => {
908                    #[cfg(esp32p4)]
909                    {
910                        $w.[<ch7_ $p4>]().bit($val);
911                    }
912                    #[cfg(esp32s31)]
913                    {
914                        $w.[<ch7_ $s31>]().bit($val);
915                    }
916                }
917                _ => unreachable!(),
918            }
919        }
920    };
921}
922
923macro_rules! impl_int_w {
924    ($ty:ty, $tx_end_p4:ident, $tx_end_s31:ident, $tx_err_p4:ident, $tx_err_s31:ident, $tx_thr_p4:ident, $tx_thr_s31:ident, $tx_loop_p4:ident, $tx_loop_s31:ident, $rx_end_p4:ident, $rx_end_s31:ident, $rx_err_p4:ident, $rx_err_s31:ident, $rx_thr_p4:ident, $rx_thr_s31:ident) => {
925        impl $ty {
926            #[inline]
927            pub fn ch_tx_end(&mut self, n: u8) -> IntBitW<'_, Self> {
928                IntBitW {
929                    w: self,
930                    n,
931                    set: |w, n, val| set_tx_int!(w.0, n, val, $tx_end_p4, $tx_end_s31),
932                }
933            }
934
935            #[inline]
936            pub fn ch_tx_err(&mut self, n: u8) -> IntBitW<'_, Self> {
937                IntBitW {
938                    w: self,
939                    n,
940                    set: |w, n, val| set_tx_int!(w.0, n, val, $tx_err_p4, $tx_err_s31),
941                }
942            }
943
944            #[inline]
945            pub fn ch_tx_thr_event(&mut self, n: u8) -> IntBitW<'_, Self> {
946                IntBitW {
947                    w: self,
948                    n,
949                    set: |w, n, val| set_tx_int!(w.0, n, val, $tx_thr_p4, $tx_thr_s31),
950                }
951            }
952
953            #[inline]
954            pub fn ch_tx_loop(&mut self, n: u8) -> IntBitW<'_, Self> {
955                IntBitW {
956                    w: self,
957                    n,
958                    set: |w, n, val| set_tx_int!(w.0, n, val, $tx_loop_p4, $tx_loop_s31),
959                }
960            }
961
962            #[inline]
963            pub fn ch_rx_end(&mut self, n: u8) -> IntBitW<'_, Self> {
964                IntBitW {
965                    w: self,
966                    n,
967                    set: |w, n, val| set_rx_int!(w.0, n, val, $rx_end_p4, $rx_end_s31),
968                }
969            }
970
971            #[inline]
972            pub fn ch_rx_err(&mut self, n: u8) -> IntBitW<'_, Self> {
973                IntBitW {
974                    w: self,
975                    n,
976                    set: |w, n, val| set_rx_int!(w.0, n, val, $rx_err_p4, $rx_err_s31),
977                }
978            }
979
980            #[inline]
981            pub fn ch_rx_thr_event(&mut self, n: u8) -> IntBitW<'_, Self> {
982                IntBitW {
983                    w: self,
984                    n,
985                    set: |w, n, val| set_rx_int!(w.0, n, val, $rx_thr_p4, $rx_thr_s31),
986                }
987            }
988        }
989    };
990}
991
992impl_int_w!(
993    IntEnaW,
994    tx_end,
995    tx_end_int_ena,
996    err,
997    err_int_ena,
998    tx_thr_event,
999    tx_thr_event_int_ena,
1000    tx_loop,
1001    tx_loop_int_ena,
1002    rx_end,
1003    rx_end_int_ena,
1004    err,
1005    err_int_ena,
1006    rx_thr_event,
1007    rx_thr_event_int_ena
1008);
1009
1010impl_int_w!(
1011    IntClrW,
1012    tx_end,
1013    tx_end_int_clr,
1014    err,
1015    err_int_clr,
1016    tx_thr_event,
1017    tx_thr_event_int_clr,
1018    tx_loop,
1019    tx_loop_int_clr,
1020    rx_end,
1021    rx_end_int_clr,
1022    err,
1023    err_int_clr,
1024    rx_thr_event,
1025    rx_thr_event_int_clr
1026);