esp_hal/i2s/
master.rs

1//! # Inter-IC Sound (I2S)
2//!
3//! ## Overview
4//!
5//! I2S (Inter-IC Sound) is a synchronous serial communication protocol usually
6//! used for transmitting audio data between two digital audio devices.
7//! Espressif devices may contain more than one I2S peripheral(s). These
8//! peripherals can be configured to input and output sample data via the I2S
9//! driver.
10//!
11//! ## Configuration
12//!
13//! I2S supports different data formats, including varying data and channel
14//! widths, different standards, such as the Philips standard and configurable
15//! pin mappings for I2S clock (BCLK), word select (WS), and data input/output
16//! (DOUT/DIN).
17//!
18//! The driver uses DMA (Direct Memory Access) for efficient data transfer and
19//! supports various configurations, such as different data formats, standards
20//! (e.g., Philips) and pin configurations. It relies on other peripheral
21//! modules, such as
22//!   - `GPIO`
23//!   - `DMA`
24//!   - `system` (to configure and enable the I2S peripheral)
25//!
26//! ## Examples
27//!
28//! ### I2S Read
29//!
30//! ```rust, no_run
31#![doc = crate::before_snippet!()]
32//! # use esp_hal::i2s::master::{I2s, Standard, DataFormat};
33//! # use esp_hal::dma_buffers;
34#![cfg_attr(any(esp32, esp32s2), doc = "let dma_channel = peripherals.DMA_I2S0;")]
35#![cfg_attr(
36    not(any(esp32, esp32s2)),
37    doc = "let dma_channel = peripherals.DMA_CH0;"
38)]
39//! let (mut rx_buffer, rx_descriptors, _, tx_descriptors) =
40//! dma_buffers!(0, 4 * 4092);
41//!
42//! let i2s = I2s::new(
43//!     peripherals.I2S0,
44//!     Standard::Philips,
45//!     DataFormat::Data16Channel16,
46//!     Rate::from_hz(44100),
47//!     dma_channel,
48//!     rx_descriptors,
49//!     tx_descriptors,
50//! );
51#![cfg_attr(not(esp32), doc = "let i2s = i2s.with_mclk(peripherals.GPIO0);")]
52//! let mut i2s_rx = i2s.i2s_rx
53//!     .with_bclk(peripherals.GPIO1)
54//!     .with_ws(peripherals.GPIO2)
55//!     .with_din(peripherals.GPIO5)
56//!     .build();
57//!
58//! let mut transfer = i2s_rx.read_dma_circular(&mut rx_buffer)?;
59//!
60//! loop {
61//!     let avail = transfer.available()?;
62//!
63//!     if avail > 0 {
64//!         let mut rcv = [0u8; 5000];
65//!         transfer.pop(&mut rcv[..avail])?;
66//!     }
67//! }
68//! # }
69//! ```
70//! 
71//! ## Implementation State
72//!
73//! - Only TDM Philips standard is supported.
74
75use enumset::{EnumSet, EnumSetType};
76use private::*;
77
78use crate::{
79    dma::{
80        dma_private::{DmaSupport, DmaSupportRx, DmaSupportTx},
81        Channel,
82        ChannelRx,
83        ChannelTx,
84        DescriptorChain,
85        DmaChannelFor,
86        DmaDescriptor,
87        DmaEligible,
88        DmaError,
89        DmaTransferRx,
90        DmaTransferRxCircular,
91        DmaTransferTx,
92        DmaTransferTxCircular,
93        PeripheralRxChannel,
94        PeripheralTxChannel,
95        ReadBuffer,
96        Rx,
97        Tx,
98        WriteBuffer,
99    },
100    gpio::interconnect::PeripheralOutput,
101    interrupt::{InterruptConfigurable, InterruptHandler},
102    peripheral::{Peripheral, PeripheralRef},
103    system::PeripheralGuard,
104    time::Rate,
105    Async,
106    Blocking,
107    DriverMode,
108};
109
110#[derive(Debug, EnumSetType)]
111#[cfg_attr(feature = "defmt", derive(defmt::Format))]
112/// Represents the various interrupt types for the I2S peripheral.
113pub enum I2sInterrupt {
114    /// Receive buffer hung, indicating a stall in data reception.
115    RxHung,
116    /// Transmit buffer hung, indicating a stall in data transmission.
117    TxHung,
118    #[cfg(not(any(esp32, esp32s2)))]
119    /// Reception of data is complete.
120    RxDone,
121    #[cfg(not(any(esp32, esp32s2)))]
122    /// Transmission of data is complete.
123    TxDone,
124}
125
126#[cfg(any(esp32, esp32s2, esp32s3))]
127pub(crate) const I2S_LL_MCLK_DIVIDER_BIT_WIDTH: usize = 6;
128
129#[cfg(any(esp32c3, esp32c6, esp32h2))]
130pub(crate) const I2S_LL_MCLK_DIVIDER_BIT_WIDTH: usize = 9;
131
132pub(crate) const I2S_LL_MCLK_DIVIDER_MAX: usize = (1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1;
133
134/// Data types that the I2S peripheral can work with.
135pub trait AcceptedWord: crate::private::Sealed {}
136impl AcceptedWord for u8 {}
137impl AcceptedWord for u16 {}
138impl AcceptedWord for u32 {}
139impl AcceptedWord for i8 {}
140impl AcceptedWord for i16 {}
141impl AcceptedWord for i32 {}
142
143/// I2S Error
144#[derive(Debug, Clone, Copy, PartialEq)]
145#[cfg_attr(feature = "defmt", derive(defmt::Format))]
146#[allow(clippy::enum_variant_names, reason = "peripheral is unstable")]
147pub enum Error {
148    /// An unspecified or unknown error occurred during an I2S operation.
149    Unknown,
150    /// A DMA-related error occurred during I2S operations.
151    DmaError(DmaError),
152    /// An illegal or invalid argument was passed to an I2S function or method.
153    IllegalArgument,
154}
155
156impl From<DmaError> for Error {
157    fn from(value: DmaError) -> Self {
158        Error::DmaError(value)
159    }
160}
161
162/// Supported standards.
163#[derive(Debug, Clone, Copy, PartialEq)]
164#[cfg_attr(feature = "defmt", derive(defmt::Format))]
165pub enum Standard {
166    /// The Philips I2S standard.
167    Philips,
168    // Tdm,
169    // Pdm,
170}
171
172/// Supported data formats
173#[derive(Debug, Clone, Copy, PartialEq)]
174#[cfg_attr(feature = "defmt", derive(defmt::Format))]
175#[cfg(not(any(esp32, esp32s2)))]
176pub enum DataFormat {
177    /// 32-bit data width and 32-bit channel width.
178    Data32Channel32,
179    /// 32-bit data width and 24-bit channel width.
180    Data32Channel24,
181    /// 32-bit data width and 16-bit channel width.
182    Data32Channel16,
183    /// 32-bit data width and 8-bit channel width.
184    Data32Channel8,
185    /// 16-bit data width and 16-bit channel width.
186    Data16Channel16,
187    /// 16-bit data width and 8-bit channel width.
188    Data16Channel8,
189    /// 8-bit data width and 8-bit channel width.
190    Data8Channel8,
191}
192
193/// Supported data formats
194#[derive(Debug, Clone, Copy, PartialEq)]
195#[cfg_attr(feature = "defmt", derive(defmt::Format))]
196#[cfg(any(esp32, esp32s2))]
197pub enum DataFormat {
198    /// 32-bit data width and 32-bit channel width.
199    Data32Channel32,
200    /// 16-bit data width and 16-bit channel width.
201    Data16Channel16,
202}
203
204#[cfg(not(any(esp32, esp32s2)))]
205impl DataFormat {
206    /// Returns the number of data bits for the selected data format.
207    pub fn data_bits(&self) -> u8 {
208        match self {
209            DataFormat::Data32Channel32 => 32,
210            DataFormat::Data32Channel24 => 32,
211            DataFormat::Data32Channel16 => 32,
212            DataFormat::Data32Channel8 => 32,
213            DataFormat::Data16Channel16 => 16,
214            DataFormat::Data16Channel8 => 16,
215            DataFormat::Data8Channel8 => 8,
216        }
217    }
218
219    /// Returns the number of channel bits for the selected data format.
220    pub fn channel_bits(&self) -> u8 {
221        match self {
222            DataFormat::Data32Channel32 => 32,
223            DataFormat::Data32Channel24 => 24,
224            DataFormat::Data32Channel16 => 16,
225            DataFormat::Data32Channel8 => 8,
226            DataFormat::Data16Channel16 => 16,
227            DataFormat::Data16Channel8 => 8,
228            DataFormat::Data8Channel8 => 8,
229        }
230    }
231}
232
233#[cfg(any(esp32, esp32s2))]
234impl DataFormat {
235    /// Returns the number of data bits for the selected data format.
236    pub fn data_bits(&self) -> u8 {
237        match self {
238            DataFormat::Data32Channel32 => 32,
239            DataFormat::Data16Channel16 => 16,
240        }
241    }
242
243    /// Returns the number of channel bits for the selected data format.
244    pub fn channel_bits(&self) -> u8 {
245        match self {
246            DataFormat::Data32Channel32 => 32,
247            DataFormat::Data16Channel16 => 16,
248        }
249    }
250}
251
252/// Instance of the I2S peripheral driver
253#[non_exhaustive]
254pub struct I2s<'d, Dm>
255where
256    Dm: DriverMode,
257{
258    /// Handles the reception (RX) side of the I2S peripheral.
259    pub i2s_rx: RxCreator<'d, Dm>,
260    /// Handles the transmission (TX) side of the I2S peripheral.
261    pub i2s_tx: TxCreator<'d, Dm>,
262}
263
264impl<Dm> I2s<'_, Dm>
265where
266    Dm: DriverMode,
267{
268    #[cfg_attr(
269        not(multi_core),
270        doc = "Registers an interrupt handler for the peripheral."
271    )]
272    #[cfg_attr(
273        multi_core,
274        doc = "Registers an interrupt handler for the peripheral on the current core."
275    )]
276    #[doc = ""]
277    /// Note that this will replace any previously registered interrupt
278    /// handlers.
279    ///
280    /// You can restore the default/unhandled interrupt handler by using
281    /// [crate::interrupt::DEFAULT_INTERRUPT_HANDLER]
282    #[instability::unstable]
283    pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
284        // tx.i2s and rx.i2s is the same, we could use either one
285        self.i2s_tx.i2s.set_interrupt_handler(handler);
286    }
287
288    /// Listen for the given interrupts
289    #[instability::unstable]
290    pub fn listen(&mut self, interrupts: impl Into<EnumSet<I2sInterrupt>>) {
291        // tx.i2s and rx.i2s is the same, we could use either one
292        self.i2s_tx.i2s.enable_listen(interrupts.into(), true);
293    }
294
295    /// Unlisten the given interrupts
296    #[instability::unstable]
297    pub fn unlisten(&mut self, interrupts: impl Into<EnumSet<I2sInterrupt>>) {
298        // tx.i2s and rx.i2s is the same, we could use either one
299        self.i2s_tx.i2s.enable_listen(interrupts.into(), false);
300    }
301
302    /// Gets asserted interrupts
303    #[instability::unstable]
304    pub fn interrupts(&mut self) -> EnumSet<I2sInterrupt> {
305        // tx.i2s and rx.i2s is the same, we could use either one
306        self.i2s_tx.i2s.interrupts()
307    }
308
309    /// Resets asserted interrupts
310    #[instability::unstable]
311    pub fn clear_interrupts(&mut self, interrupts: impl Into<EnumSet<I2sInterrupt>>) {
312        // tx.i2s and rx.i2s is the same, we could use either one
313        self.i2s_tx.i2s.clear_interrupts(interrupts.into());
314    }
315}
316
317impl<Dm> crate::private::Sealed for I2s<'_, Dm> where Dm: DriverMode {}
318
319impl<Dm> InterruptConfigurable for I2s<'_, Dm>
320where
321    Dm: DriverMode,
322{
323    fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
324        I2s::set_interrupt_handler(self, handler);
325    }
326}
327
328impl<'d> I2s<'d, Blocking> {
329    /// Construct a new I2S peripheral driver instance for the first I2S
330    /// peripheral
331    #[allow(clippy::too_many_arguments)]
332    pub fn new<CH>(
333        i2s: impl Peripheral<P = impl RegisterAccess> + 'd,
334        standard: Standard,
335        data_format: DataFormat,
336        sample_rate: Rate,
337        channel: impl Peripheral<P = CH> + 'd,
338        rx_descriptors: &'static mut [DmaDescriptor],
339        tx_descriptors: &'static mut [DmaDescriptor],
340    ) -> Self
341    where
342        CH: DmaChannelFor<AnyI2s>,
343    {
344        crate::into_ref!(i2s);
345
346        let channel = Channel::new(channel.map(|ch| ch.degrade()));
347        channel.runtime_ensure_compatible(&i2s);
348
349        // on ESP32-C3 / ESP32-S3 and later RX and TX are independent and
350        // could be configured totally independently but for now handle all
351        // the targets the same and force same configuration for both, TX and RX
352
353        // make sure the peripheral is enabled before configuring it
354        let peripheral = i2s.peripheral();
355        let rx_guard = PeripheralGuard::new(peripheral);
356        let tx_guard = PeripheralGuard::new(peripheral);
357
358        i2s.set_clock(calculate_clock(sample_rate, 2, data_format.channel_bits()));
359        i2s.configure(&standard, &data_format);
360        i2s.set_master();
361        i2s.update();
362
363        let i2s = i2s.map_into();
364
365        Self {
366            i2s_rx: RxCreator {
367                i2s: unsafe { i2s.clone_unchecked() },
368                rx_channel: channel.rx,
369                descriptors: rx_descriptors,
370                guard: rx_guard,
371            },
372            i2s_tx: TxCreator {
373                i2s,
374                tx_channel: channel.tx,
375                descriptors: tx_descriptors,
376                guard: tx_guard,
377            },
378        }
379    }
380
381    /// Converts the I2S instance into async mode.
382    pub fn into_async(self) -> I2s<'d, Async> {
383        I2s {
384            i2s_rx: RxCreator {
385                i2s: self.i2s_rx.i2s,
386                rx_channel: self.i2s_rx.rx_channel.into_async(),
387                descriptors: self.i2s_rx.descriptors,
388                guard: self.i2s_rx.guard,
389            },
390            i2s_tx: TxCreator {
391                i2s: self.i2s_tx.i2s,
392                tx_channel: self.i2s_tx.tx_channel.into_async(),
393                descriptors: self.i2s_tx.descriptors,
394                guard: self.i2s_tx.guard,
395            },
396        }
397    }
398}
399
400impl<'d, Dm> I2s<'d, Dm>
401where
402    Dm: DriverMode,
403{
404    /// Configures the I2S peripheral to use a master clock (MCLK) output pin.
405    pub fn with_mclk<P: PeripheralOutput>(self, pin: impl Peripheral<P = P> + 'd) -> Self {
406        crate::into_mapped_ref!(pin);
407        pin.set_to_push_pull_output();
408        self.i2s_tx.i2s.mclk_signal().connect_to(pin);
409
410        self
411    }
412}
413
414/// I2S TX channel
415pub struct I2sTx<'d, Dm>
416where
417    Dm: DriverMode,
418{
419    i2s: PeripheralRef<'d, AnyI2s>,
420    tx_channel: ChannelTx<'d, Dm, PeripheralTxChannel<AnyI2s>>,
421    tx_chain: DescriptorChain,
422    _guard: PeripheralGuard,
423}
424
425impl<Dm> core::fmt::Debug for I2sTx<'_, Dm>
426where
427    Dm: DriverMode,
428{
429    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
430        f.debug_struct("I2sTx").finish()
431    }
432}
433
434impl<Dm> DmaSupport for I2sTx<'_, Dm>
435where
436    Dm: DriverMode,
437{
438    fn peripheral_wait_dma(&mut self, _is_rx: bool, _is_tx: bool) {
439        self.i2s.wait_for_tx_done();
440    }
441
442    fn peripheral_dma_stop(&mut self) {
443        self.i2s.tx_stop();
444    }
445}
446
447impl<'d, Dm> DmaSupportTx for I2sTx<'d, Dm>
448where
449    Dm: DriverMode,
450{
451    type TX = ChannelTx<'d, Dm, PeripheralTxChannel<AnyI2s>>;
452
453    fn tx(&mut self) -> &mut Self::TX {
454        &mut self.tx_channel
455    }
456
457    fn chain(&mut self) -> &mut DescriptorChain {
458        &mut self.tx_chain
459    }
460}
461
462impl<Dm> I2sTx<'_, Dm>
463where
464    Dm: DriverMode,
465{
466    fn write(&mut self, data: &[u8]) -> Result<(), Error> {
467        self.start_tx_transfer(&data, false)?;
468
469        // wait until I2S_TX_IDLE is 1
470        self.i2s.wait_for_tx_done();
471
472        Ok(())
473    }
474
475    fn start_tx_transfer<'t, TXBUF>(
476        &'t mut self,
477        words: &'t TXBUF,
478        circular: bool,
479    ) -> Result<(), Error>
480    where
481        TXBUF: ReadBuffer,
482        Dm: DriverMode,
483    {
484        let (ptr, len) = unsafe { words.read_buffer() };
485
486        // Reset TX unit and TX FIFO
487        self.i2s.reset_tx();
488
489        // Enable corresponding interrupts if needed
490
491        // configure DMA outlink
492        unsafe {
493            self.tx_chain.fill_for_tx(circular, ptr, len)?;
494            self.tx_channel
495                .prepare_transfer_without_start(self.i2s.dma_peripheral(), &self.tx_chain)
496                .and_then(|_| self.tx_channel.start_transfer())?;
497        }
498
499        // set I2S_TX_STOP_EN if needed
500
501        // start: set I2S_TX_START
502        self.i2s.tx_start();
503
504        Ok(())
505    }
506
507    /// Writes a slice of data to the I2S peripheral.
508    pub fn write_words(&mut self, words: &[impl AcceptedWord]) -> Result<(), Error> {
509        self.write(unsafe {
510            core::slice::from_raw_parts(words.as_ptr().cast::<u8>(), core::mem::size_of_val(words))
511        })
512    }
513
514    /// Write I2S.
515    /// Returns [DmaTransferTx] which represents the in-progress DMA
516    /// transfer
517    pub fn write_dma<'t>(
518        &'t mut self,
519        words: &'t impl ReadBuffer,
520    ) -> Result<DmaTransferTx<'t, Self>, Error>
521    where
522        Self: DmaSupportTx,
523    {
524        self.start_tx_transfer(words, false)?;
525        Ok(DmaTransferTx::new(self))
526    }
527
528    /// Continuously write to I2S. Returns [DmaTransferTxCircular] which
529    /// represents the in-progress DMA transfer
530    pub fn write_dma_circular<'t>(
531        &'t mut self,
532        words: &'t impl ReadBuffer,
533    ) -> Result<DmaTransferTxCircular<'t, Self>, Error>
534    where
535        Self: DmaSupportTx,
536    {
537        self.start_tx_transfer(words, true)?;
538        Ok(DmaTransferTxCircular::new(self))
539    }
540}
541
542/// I2S RX channel
543pub struct I2sRx<'d, Dm>
544where
545    Dm: DriverMode,
546{
547    i2s: PeripheralRef<'d, AnyI2s>,
548    rx_channel: ChannelRx<'d, Dm, PeripheralRxChannel<AnyI2s>>,
549    rx_chain: DescriptorChain,
550    _guard: PeripheralGuard,
551}
552
553impl<Dm> core::fmt::Debug for I2sRx<'_, Dm>
554where
555    Dm: DriverMode,
556{
557    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
558        f.debug_struct("I2sRx").finish()
559    }
560}
561
562impl<Dm> DmaSupport for I2sRx<'_, Dm>
563where
564    Dm: DriverMode,
565{
566    fn peripheral_wait_dma(&mut self, _is_rx: bool, _is_tx: bool) {
567        self.i2s.wait_for_rx_done();
568    }
569
570    fn peripheral_dma_stop(&mut self) {
571        self.i2s.reset_rx();
572    }
573}
574
575impl<'d, Dm> DmaSupportRx for I2sRx<'d, Dm>
576where
577    Dm: DriverMode,
578{
579    type RX = ChannelRx<'d, Dm, PeripheralRxChannel<AnyI2s>>;
580
581    fn rx(&mut self) -> &mut Self::RX {
582        &mut self.rx_channel
583    }
584
585    fn chain(&mut self) -> &mut DescriptorChain {
586        &mut self.rx_chain
587    }
588}
589
590impl<Dm> I2sRx<'_, Dm>
591where
592    Dm: DriverMode,
593{
594    fn read(&mut self, mut data: &mut [u8]) -> Result<(), Error> {
595        self.start_rx_transfer(&mut data, false)?;
596
597        // wait until I2S_RX_IDLE is 1
598        self.i2s.wait_for_rx_done();
599
600        Ok(())
601    }
602
603    fn start_rx_transfer<'t, RXBUF>(
604        &'t mut self,
605        words: &'t mut RXBUF,
606        circular: bool,
607    ) -> Result<(), Error>
608    where
609        RXBUF: WriteBuffer,
610    {
611        let (ptr, len) = unsafe { words.write_buffer() };
612
613        if len % 4 != 0 {
614            return Err(Error::IllegalArgument);
615        }
616
617        // Reset RX unit and RX FIFO
618        self.i2s.reset_rx();
619
620        // Enable corresponding interrupts if needed
621
622        // configure DMA inlink
623        unsafe {
624            self.rx_chain.fill_for_rx(circular, ptr, len)?;
625            self.rx_channel
626                .prepare_transfer_without_start(self.i2s.dma_peripheral(), &self.rx_chain)
627                .and_then(|_| self.rx_channel.start_transfer())?;
628        }
629
630        // start: set I2S_RX_START
631        self.i2s.rx_start(len);
632        Ok(())
633    }
634
635    /// Reads a slice of data from the I2S peripheral and stores it in the
636    /// provided buffer.
637    pub fn read_words(&mut self, words: &mut [impl AcceptedWord]) -> Result<(), Error> {
638        if core::mem::size_of_val(words) > 4096 || words.is_empty() {
639            return Err(Error::IllegalArgument);
640        }
641
642        self.read(unsafe {
643            core::slice::from_raw_parts_mut(
644                words.as_mut_ptr().cast::<u8>(),
645                core::mem::size_of_val(words),
646            )
647        })
648    }
649
650    /// Read I2S.
651    /// Returns [DmaTransferRx] which represents the in-progress DMA
652    /// transfer
653    pub fn read_dma<'t>(
654        &'t mut self,
655        words: &'t mut impl WriteBuffer,
656    ) -> Result<DmaTransferRx<'t, Self>, Error>
657    where
658        Self: DmaSupportRx,
659    {
660        self.start_rx_transfer(words, false)?;
661        Ok(DmaTransferRx::new(self))
662    }
663
664    /// Continuously read from I2S.
665    /// Returns [DmaTransferRxCircular] which represents the in-progress DMA
666    /// transfer
667    pub fn read_dma_circular<'t>(
668        &'t mut self,
669        words: &'t mut impl WriteBuffer,
670    ) -> Result<DmaTransferRxCircular<'t, Self>, Error>
671    where
672        Self: DmaSupportRx,
673    {
674        self.start_rx_transfer(words, true)?;
675        Ok(DmaTransferRxCircular::new(self))
676    }
677}
678
679/// Provides an abstraction for accessing the I2S peripheral registers.
680pub trait RegisterAccess: RegisterAccessPrivate {}
681impl<T> RegisterAccess for T where T: RegisterAccessPrivate {}
682
683mod private {
684    use enumset::EnumSet;
685
686    use super::*;
687    #[cfg(not(i2s1))]
688    use crate::pac::i2s0::RegisterBlock;
689    use crate::{
690        dma::{ChannelRx, ChannelTx, DescriptorChain, DmaDescriptor, DmaEligible},
691        gpio::{
692            interconnect::{PeripheralInput, PeripheralOutput},
693            InputSignal,
694            OutputSignal,
695        },
696        interrupt::InterruptHandler,
697        peripheral::{Peripheral, PeripheralRef},
698        peripherals::{Interrupt, I2S0},
699        DriverMode,
700    };
701    // on ESP32-S3 I2S1 doesn't support all features - use that to avoid using those features
702    // by accident
703    #[cfg(i2s1)]
704    use crate::{pac::i2s1::RegisterBlock, peripherals::I2S1};
705
706    pub struct TxCreator<'d, Dm>
707    where
708        Dm: DriverMode,
709    {
710        pub i2s: PeripheralRef<'d, AnyI2s>,
711        pub tx_channel: ChannelTx<'d, Dm, PeripheralTxChannel<AnyI2s>>,
712        pub descriptors: &'static mut [DmaDescriptor],
713        pub(crate) guard: PeripheralGuard,
714    }
715
716    impl<'d, Dm> TxCreator<'d, Dm>
717    where
718        Dm: DriverMode,
719    {
720        pub fn build(self) -> I2sTx<'d, Dm> {
721            let peripheral = self.i2s.peripheral();
722            I2sTx {
723                i2s: self.i2s,
724                tx_channel: self.tx_channel,
725                tx_chain: DescriptorChain::new(self.descriptors),
726                _guard: PeripheralGuard::new(peripheral),
727            }
728        }
729
730        pub fn with_bclk<P>(self, pin: impl Peripheral<P = P> + 'd) -> Self
731        where
732            P: PeripheralOutput,
733        {
734            crate::into_mapped_ref!(pin);
735            pin.set_to_push_pull_output();
736            self.i2s.bclk_signal().connect_to(pin);
737
738            self
739        }
740
741        pub fn with_ws<P>(self, pin: impl Peripheral<P = P> + 'd) -> Self
742        where
743            P: PeripheralOutput,
744        {
745            crate::into_mapped_ref!(pin);
746            pin.set_to_push_pull_output();
747            self.i2s.ws_signal().connect_to(pin);
748
749            self
750        }
751
752        pub fn with_dout<P>(self, pin: impl Peripheral<P = P> + 'd) -> Self
753        where
754            P: PeripheralOutput,
755        {
756            crate::into_mapped_ref!(pin);
757            pin.set_to_push_pull_output();
758            self.i2s.dout_signal().connect_to(pin);
759
760            self
761        }
762    }
763
764    pub struct RxCreator<'d, Dm>
765    where
766        Dm: DriverMode,
767    {
768        pub i2s: PeripheralRef<'d, AnyI2s>,
769        pub rx_channel: ChannelRx<'d, Dm, PeripheralRxChannel<AnyI2s>>,
770        pub descriptors: &'static mut [DmaDescriptor],
771        pub(crate) guard: PeripheralGuard,
772    }
773
774    impl<'d, Dm> RxCreator<'d, Dm>
775    where
776        Dm: DriverMode,
777    {
778        pub fn build(self) -> I2sRx<'d, Dm> {
779            let peripheral = self.i2s.peripheral();
780            I2sRx {
781                i2s: self.i2s,
782                rx_channel: self.rx_channel,
783                rx_chain: DescriptorChain::new(self.descriptors),
784                _guard: PeripheralGuard::new(peripheral),
785            }
786        }
787
788        pub fn with_bclk<P>(self, pin: impl Peripheral<P = P> + 'd) -> Self
789        where
790            P: PeripheralOutput,
791        {
792            crate::into_mapped_ref!(pin);
793            pin.set_to_push_pull_output();
794            self.i2s.bclk_rx_signal().connect_to(pin);
795
796            self
797        }
798
799        pub fn with_ws<P>(self, pin: impl Peripheral<P = P> + 'd) -> Self
800        where
801            P: PeripheralOutput,
802        {
803            crate::into_mapped_ref!(pin);
804            pin.set_to_push_pull_output();
805            self.i2s.ws_rx_signal().connect_to(pin);
806
807            self
808        }
809
810        pub fn with_din<P>(self, pin: impl Peripheral<P = P> + 'd) -> Self
811        where
812            P: PeripheralInput,
813        {
814            crate::into_mapped_ref!(pin);
815            pin.init_input(crate::gpio::Pull::None);
816            self.i2s.din_signal().connect_to(pin);
817
818            self
819        }
820    }
821
822    pub trait RegBlock: Peripheral<P = Self> + DmaEligible + Into<super::AnyI2s> + 'static {
823        fn regs(&self) -> &RegisterBlock;
824        fn peripheral(&self) -> crate::system::Peripheral;
825    }
826
827    pub trait Signals: RegBlock {
828        fn mclk_signal(&self) -> OutputSignal;
829        fn bclk_signal(&self) -> OutputSignal;
830        fn ws_signal(&self) -> OutputSignal;
831        fn dout_signal(&self) -> OutputSignal;
832        fn bclk_rx_signal(&self) -> OutputSignal;
833        fn ws_rx_signal(&self) -> OutputSignal;
834        fn din_signal(&self) -> InputSignal;
835    }
836
837    #[cfg(any(esp32, esp32s2))]
838    pub trait RegisterAccessPrivate: Signals + RegBlock {
839        fn set_interrupt_handler(&self, handler: InterruptHandler);
840
841        fn enable_listen(&self, interrupts: EnumSet<I2sInterrupt>, enable: bool) {
842            self.regs().int_ena().modify(|_, w| {
843                for interrupt in interrupts {
844                    match interrupt {
845                        I2sInterrupt::RxHung => w.rx_hung().bit(enable),
846                        I2sInterrupt::TxHung => w.tx_hung().bit(enable),
847                    };
848                }
849                w
850            });
851        }
852
853        fn interrupts(&self) -> EnumSet<I2sInterrupt> {
854            let mut res = EnumSet::new();
855            let ints = self.regs().int_st().read();
856
857            if ints.rx_hung().bit() {
858                res.insert(I2sInterrupt::RxHung);
859            }
860            if ints.tx_hung().bit() {
861                res.insert(I2sInterrupt::TxHung);
862            }
863
864            res
865        }
866
867        fn clear_interrupts(&self, interrupts: EnumSet<I2sInterrupt>) {
868            self.regs().int_clr().write(|w| {
869                for interrupt in interrupts {
870                    match interrupt {
871                        I2sInterrupt::RxHung => w.rx_hung().clear_bit_by_one(),
872                        I2sInterrupt::TxHung => w.tx_hung().clear_bit_by_one(),
873                    };
874                }
875                w
876            });
877        }
878
879        fn set_clock(&self, clock_settings: I2sClockDividers) {
880            self.regs().clkm_conf().modify(|r, w| unsafe {
881                // select PLL_160M
882                w.bits(r.bits() | (crate::soc::constants::I2S_DEFAULT_CLK_SRC << 21))
883            });
884
885            #[cfg(esp32)]
886            self.regs()
887                .clkm_conf()
888                .modify(|_, w| w.clka_ena().clear_bit());
889
890            self.regs().clkm_conf().modify(|_, w| unsafe {
891                w.clk_en().set_bit();
892                w.clkm_div_num().bits(clock_settings.mclk_divider as u8);
893                w.clkm_div_a().bits(clock_settings.denominator as u8);
894                w.clkm_div_b().bits(clock_settings.numerator as u8)
895            });
896
897            self.regs().sample_rate_conf().modify(|_, w| unsafe {
898                w.tx_bck_div_num().bits(clock_settings.bclk_divider as u8);
899                w.rx_bck_div_num().bits(clock_settings.bclk_divider as u8)
900            });
901        }
902
903        fn configure(&self, _standard: &Standard, data_format: &DataFormat) {
904            let fifo_mod = match data_format {
905                DataFormat::Data32Channel32 => 2,
906                DataFormat::Data16Channel16 => 0,
907            };
908
909            self.regs().sample_rate_conf().modify(|_, w| unsafe {
910                w.tx_bits_mod().bits(data_format.channel_bits());
911                w.rx_bits_mod().bits(data_format.channel_bits())
912            });
913
914            self.regs().conf().modify(|_, w| {
915                w.tx_slave_mod().clear_bit();
916                w.rx_slave_mod().clear_bit();
917                // If the I2S_RX_MSB_SHIFT bit and the I2S_TX_MSB_SHIFT bit of register
918                // I2S_CONF_REG are set to 1, respectively, the I2S module will use the Philips
919                // standard when receiving and transmitting data.
920                w.tx_msb_shift().set_bit();
921                w.rx_msb_shift().set_bit();
922                // Short frame synchronization
923                w.tx_short_sync().bit(false);
924                w.rx_short_sync().bit(false);
925                // Send MSB to the right channel to be consistent with ESP32-S3 et al.
926                w.tx_msb_right().set_bit();
927                w.rx_msb_right().set_bit();
928                // ESP32 generates two clock pulses first. If the WS is low, those first clock
929                // pulses are indistinguishable from real data, which corrupts the first few
930                // samples. So we send the right channel first (which means WS is high during
931                // the first sample) to prevent this issue.
932                w.tx_right_first().set_bit();
933                w.rx_right_first().set_bit();
934                w.tx_mono().clear_bit();
935                w.rx_mono().clear_bit();
936                w.sig_loopback().clear_bit()
937            });
938
939            self.regs().fifo_conf().modify(|_, w| unsafe {
940                w.tx_fifo_mod().bits(fifo_mod);
941                w.tx_fifo_mod_force_en().set_bit();
942                w.dscr_en().set_bit();
943                w.rx_fifo_mod().bits(fifo_mod);
944                w.rx_fifo_mod_force_en().set_bit()
945            });
946
947            self.regs().conf_chan().modify(|_, w| unsafe {
948                // for now only stereo
949                w.tx_chan_mod().bits(0);
950                w.rx_chan_mod().bits(0)
951            });
952
953            self.regs().conf1().modify(|_, w| {
954                w.tx_pcm_bypass().set_bit();
955                w.rx_pcm_bypass().set_bit()
956            });
957
958            self.regs().pd_conf().modify(|_, w| {
959                w.fifo_force_pu().set_bit();
960                w.fifo_force_pd().clear_bit()
961            });
962
963            self.regs().conf2().modify(|_, w| {
964                w.camera_en().clear_bit();
965                w.lcd_en().clear_bit()
966            });
967        }
968
969        fn set_master(&self) {
970            self.regs().conf().modify(|_, w| {
971                w.rx_slave_mod().clear_bit();
972                w.tx_slave_mod().clear_bit()
973            });
974        }
975
976        fn update(&self) {
977            // nothing to do
978        }
979
980        fn reset_tx(&self) {
981            self.regs().conf().modify(|_, w| {
982                w.tx_reset().set_bit();
983                w.tx_fifo_reset().set_bit()
984            });
985            self.regs().conf().modify(|_, w| {
986                w.tx_reset().clear_bit();
987                w.tx_fifo_reset().clear_bit()
988            });
989
990            self.regs().lc_conf().modify(|_, w| w.out_rst().set_bit());
991            self.regs().lc_conf().modify(|_, w| w.out_rst().clear_bit());
992
993            self.regs().int_clr().write(|w| {
994                w.out_done().clear_bit_by_one();
995                w.out_total_eof().clear_bit_by_one()
996            });
997        }
998
999        fn tx_start(&self) {
1000            self.regs().conf().modify(|_, w| w.tx_start().set_bit());
1001
1002            while self.regs().state().read().tx_idle().bit_is_set() {
1003                // wait
1004            }
1005        }
1006
1007        fn tx_stop(&self) {
1008            self.regs().conf().modify(|_, w| w.tx_start().clear_bit());
1009        }
1010
1011        fn wait_for_tx_done(&self) {
1012            while self.regs().state().read().tx_idle().bit_is_clear() {
1013                // wait
1014            }
1015
1016            self.regs().conf().modify(|_, w| w.tx_start().clear_bit());
1017        }
1018
1019        fn reset_rx(&self) {
1020            self.regs().conf().modify(|_, w| {
1021                w.rx_reset().set_bit();
1022                w.rx_fifo_reset().set_bit()
1023            });
1024            self.regs().conf().modify(|_, w| {
1025                w.rx_reset().clear_bit();
1026                w.rx_fifo_reset().clear_bit()
1027            });
1028
1029            self.regs().lc_conf().modify(|_, w| w.in_rst().set_bit());
1030            self.regs().lc_conf().modify(|_, w| w.in_rst().clear_bit());
1031
1032            self.regs().int_clr().write(|w| {
1033                w.in_done().clear_bit_by_one();
1034                w.in_suc_eof().clear_bit_by_one()
1035            });
1036        }
1037
1038        fn rx_start(&self, len: usize) {
1039            self.regs()
1040                .int_clr()
1041                .write(|w| w.in_suc_eof().clear_bit_by_one());
1042
1043            cfg_if::cfg_if! {
1044                if #[cfg(esp32)] {
1045                    // On ESP32, the eof_num count in words.
1046                    let eof_num = len / 4;
1047                } else {
1048                    let eof_num = len - 1;
1049                }
1050            }
1051
1052            self.regs()
1053                .rxeof_num()
1054                .modify(|_, w| unsafe { w.rx_eof_num().bits(eof_num as u32) });
1055
1056            self.regs().conf().modify(|_, w| w.rx_start().set_bit());
1057        }
1058
1059        fn wait_for_rx_done(&self) {
1060            while self.regs().int_raw().read().in_suc_eof().bit_is_clear() {
1061                // wait
1062            }
1063
1064            self.regs()
1065                .int_clr()
1066                .write(|w| w.in_suc_eof().clear_bit_by_one());
1067        }
1068    }
1069
1070    #[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))]
1071    pub trait RegisterAccessPrivate: Signals + RegBlock {
1072        fn set_interrupt_handler(&self, handler: InterruptHandler);
1073
1074        fn enable_listen(&self, interrupts: EnumSet<I2sInterrupt>, enable: bool) {
1075            self.regs().int_ena().modify(|_, w| {
1076                for interrupt in interrupts {
1077                    match interrupt {
1078                        I2sInterrupt::RxHung => w.rx_hung().bit(enable),
1079                        I2sInterrupt::TxHung => w.tx_hung().bit(enable),
1080                        I2sInterrupt::RxDone => w.rx_done().bit(enable),
1081                        I2sInterrupt::TxDone => w.tx_done().bit(enable),
1082                    };
1083                }
1084                w
1085            });
1086        }
1087
1088        fn listen(&self, interrupts: impl Into<EnumSet<I2sInterrupt>>) {
1089            self.enable_listen(interrupts.into(), true);
1090        }
1091
1092        fn unlisten(&self, interrupts: impl Into<EnumSet<I2sInterrupt>>) {
1093            self.enable_listen(interrupts.into(), false);
1094        }
1095
1096        fn interrupts(&self) -> EnumSet<I2sInterrupt> {
1097            let mut res = EnumSet::new();
1098            let ints = self.regs().int_st().read();
1099
1100            if ints.rx_hung().bit() {
1101                res.insert(I2sInterrupt::RxHung);
1102            }
1103            if ints.tx_hung().bit() {
1104                res.insert(I2sInterrupt::TxHung);
1105            }
1106            if ints.rx_done().bit() {
1107                res.insert(I2sInterrupt::RxDone);
1108            }
1109            if ints.tx_done().bit() {
1110                res.insert(I2sInterrupt::TxDone);
1111            }
1112
1113            res
1114        }
1115
1116        fn clear_interrupts(&self, interrupts: EnumSet<I2sInterrupt>) {
1117            self.regs().int_clr().write(|w| {
1118                for interrupt in interrupts {
1119                    match interrupt {
1120                        I2sInterrupt::RxHung => w.rx_hung().clear_bit_by_one(),
1121                        I2sInterrupt::TxHung => w.tx_hung().clear_bit_by_one(),
1122                        I2sInterrupt::RxDone => w.rx_done().clear_bit_by_one(),
1123                        I2sInterrupt::TxDone => w.tx_done().clear_bit_by_one(),
1124                    };
1125                }
1126                w
1127            });
1128        }
1129
1130        #[cfg(any(esp32c3, esp32s3))]
1131        fn set_clock(&self, clock_settings: I2sClockDividers) {
1132            let clkm_div_x: u32;
1133            let clkm_div_y: u32;
1134            let clkm_div_z: u32;
1135            let clkm_div_yn1: u32;
1136
1137            if clock_settings.denominator == 0 || clock_settings.numerator == 0 {
1138                clkm_div_x = 0;
1139                clkm_div_y = 0;
1140                clkm_div_z = 0;
1141                clkm_div_yn1 = 1;
1142            } else if clock_settings.numerator > clock_settings.denominator / 2 {
1143                clkm_div_x = clock_settings
1144                    .denominator
1145                    .overflowing_div(
1146                        clock_settings
1147                            .denominator
1148                            .overflowing_sub(clock_settings.numerator)
1149                            .0,
1150                    )
1151                    .0
1152                    .overflowing_sub(1)
1153                    .0;
1154                clkm_div_y = clock_settings.denominator
1155                    % (clock_settings
1156                        .denominator
1157                        .overflowing_sub(clock_settings.numerator)
1158                        .0);
1159                clkm_div_z = clock_settings
1160                    .denominator
1161                    .overflowing_sub(clock_settings.numerator)
1162                    .0;
1163                clkm_div_yn1 = 1;
1164            } else {
1165                clkm_div_x = clock_settings.denominator / clock_settings.numerator - 1;
1166                clkm_div_y = clock_settings.denominator % clock_settings.numerator;
1167                clkm_div_z = clock_settings.numerator;
1168                clkm_div_yn1 = 0;
1169            }
1170
1171            self.regs().tx_clkm_div_conf().modify(|_, w| unsafe {
1172                w.tx_clkm_div_x().bits(clkm_div_x as u16);
1173                w.tx_clkm_div_y().bits(clkm_div_y as u16);
1174                w.tx_clkm_div_yn1().bit(clkm_div_yn1 != 0);
1175                w.tx_clkm_div_z().bits(clkm_div_z as u16)
1176            });
1177
1178            self.regs().tx_clkm_conf().modify(|_, w| unsafe {
1179                w.clk_en().set_bit();
1180                w.tx_clk_active().set_bit();
1181                w.tx_clk_sel()
1182                    .bits(crate::soc::constants::I2S_DEFAULT_CLK_SRC) // for now fixed at 160MHz
1183                    ;
1184                w.tx_clkm_div_num().bits(clock_settings.mclk_divider as u8)
1185            });
1186
1187            self.regs().tx_conf1().modify(|_, w| unsafe {
1188                w.tx_bck_div_num()
1189                    .bits((clock_settings.bclk_divider - 1) as u8)
1190            });
1191
1192            self.regs().rx_clkm_div_conf().modify(|_, w| unsafe {
1193                w.rx_clkm_div_x().bits(clkm_div_x as u16);
1194                w.rx_clkm_div_y().bits(clkm_div_y as u16);
1195                w.rx_clkm_div_yn1().bit(clkm_div_yn1 != 0);
1196                w.rx_clkm_div_z().bits(clkm_div_z as u16)
1197            });
1198
1199            self.regs().rx_clkm_conf().modify(|_, w| unsafe {
1200                w.rx_clk_active().set_bit();
1201                // for now fixed at 160MHz
1202                w.rx_clk_sel()
1203                    .bits(crate::soc::constants::I2S_DEFAULT_CLK_SRC);
1204                w.rx_clkm_div_num().bits(clock_settings.mclk_divider as u8);
1205                w.mclk_sel().bit(true)
1206            });
1207
1208            self.regs().rx_conf1().modify(|_, w| unsafe {
1209                w.rx_bck_div_num()
1210                    .bits((clock_settings.bclk_divider - 1) as u8)
1211            });
1212        }
1213
1214        #[cfg(any(esp32c6, esp32h2))]
1215        fn set_clock(&self, clock_settings: I2sClockDividers) {
1216            // I2S clocks are configured via PCR
1217            use crate::peripherals::PCR;
1218
1219            let clkm_div_x: u32;
1220            let clkm_div_y: u32;
1221            let clkm_div_z: u32;
1222            let clkm_div_yn1: u32;
1223
1224            if clock_settings.denominator == 0 || clock_settings.numerator == 0 {
1225                clkm_div_x = 0;
1226                clkm_div_y = 0;
1227                clkm_div_z = 0;
1228                clkm_div_yn1 = 1;
1229            } else if clock_settings.numerator > clock_settings.denominator / 2 {
1230                clkm_div_x = clock_settings
1231                    .denominator
1232                    .overflowing_div(
1233                        clock_settings
1234                            .denominator
1235                            .overflowing_sub(clock_settings.numerator)
1236                            .0,
1237                    )
1238                    .0
1239                    .overflowing_sub(1)
1240                    .0;
1241                clkm_div_y = clock_settings.denominator
1242                    % (clock_settings
1243                        .denominator
1244                        .overflowing_sub(clock_settings.numerator)
1245                        .0);
1246                clkm_div_z = clock_settings
1247                    .denominator
1248                    .overflowing_sub(clock_settings.numerator)
1249                    .0;
1250                clkm_div_yn1 = 1;
1251            } else {
1252                clkm_div_x = clock_settings.denominator / clock_settings.numerator - 1;
1253                clkm_div_y = clock_settings.denominator % clock_settings.numerator;
1254                clkm_div_z = clock_settings.numerator;
1255                clkm_div_yn1 = 0;
1256            }
1257
1258            PCR::regs().i2s_tx_clkm_div_conf().modify(|_, w| unsafe {
1259                w.i2s_tx_clkm_div_x().bits(clkm_div_x as u16);
1260                w.i2s_tx_clkm_div_y().bits(clkm_div_y as u16);
1261                w.i2s_tx_clkm_div_yn1().bit(clkm_div_yn1 != 0);
1262                w.i2s_tx_clkm_div_z().bits(clkm_div_z as u16)
1263            });
1264
1265            PCR::regs().i2s_tx_clkm_conf().modify(|_, w| unsafe {
1266                w.i2s_tx_clkm_en().set_bit();
1267                // for now fixed at 160MHz for C6 and 96MHz for H2
1268                w.i2s_tx_clkm_sel()
1269                    .bits(crate::soc::constants::I2S_DEFAULT_CLK_SRC);
1270                w.i2s_tx_clkm_div_num()
1271                    .bits(clock_settings.mclk_divider as u8)
1272            });
1273
1274            #[cfg(not(esp32h2))]
1275            self.regs().tx_conf1().modify(|_, w| unsafe {
1276                w.tx_bck_div_num()
1277                    .bits((clock_settings.bclk_divider - 1) as u8)
1278            });
1279            #[cfg(esp32h2)]
1280            self.regs().tx_conf().modify(|_, w| unsafe {
1281                w.tx_bck_div_num()
1282                    .bits((clock_settings.bclk_divider - 1) as u8)
1283            });
1284
1285            PCR::regs().i2s_rx_clkm_div_conf().modify(|_, w| unsafe {
1286                w.i2s_rx_clkm_div_x().bits(clkm_div_x as u16);
1287                w.i2s_rx_clkm_div_y().bits(clkm_div_y as u16);
1288                w.i2s_rx_clkm_div_yn1().bit(clkm_div_yn1 != 0);
1289                w.i2s_rx_clkm_div_z().bits(clkm_div_z as u16)
1290            });
1291
1292            PCR::regs().i2s_rx_clkm_conf().modify(|_, w| unsafe {
1293                w.i2s_rx_clkm_en().set_bit();
1294                // for now fixed at 160MHz for C6 and 96MHz for H2
1295                w.i2s_rx_clkm_sel()
1296                    .bits(crate::soc::constants::I2S_DEFAULT_CLK_SRC);
1297                w.i2s_rx_clkm_div_num()
1298                    .bits(clock_settings.mclk_divider as u8);
1299                w.i2s_mclk_sel().bit(true)
1300            });
1301            #[cfg(not(esp32h2))]
1302            self.regs().rx_conf1().modify(|_, w| unsafe {
1303                w.rx_bck_div_num()
1304                    .bits((clock_settings.bclk_divider - 1) as u8)
1305            });
1306            #[cfg(esp32h2)]
1307            self.regs().rx_conf().modify(|_, w| unsafe {
1308                w.rx_bck_div_num()
1309                    .bits((clock_settings.bclk_divider - 1) as u8)
1310            });
1311        }
1312
1313        fn configure(&self, _standard: &Standard, data_format: &DataFormat) {
1314            #[allow(clippy::useless_conversion)]
1315            self.regs().tx_conf1().modify(|_, w| unsafe {
1316                w.tx_tdm_ws_width()
1317                    .bits((data_format.channel_bits() - 1).into());
1318                w.tx_bits_mod().bits(data_format.data_bits() - 1);
1319                w.tx_tdm_chan_bits().bits(data_format.channel_bits() - 1);
1320                w.tx_half_sample_bits().bits(data_format.channel_bits() - 1)
1321            });
1322            #[cfg(not(esp32h2))]
1323            self.regs()
1324                .tx_conf1()
1325                .modify(|_, w| w.tx_msb_shift().set_bit());
1326            #[cfg(esp32h2)]
1327            self.regs()
1328                .tx_conf()
1329                .modify(|_, w| w.tx_msb_shift().set_bit());
1330            self.regs().tx_conf().modify(|_, w| unsafe {
1331                w.tx_mono().clear_bit();
1332                w.tx_mono_fst_vld().set_bit();
1333                w.tx_stop_en().set_bit();
1334                w.tx_chan_equal().clear_bit();
1335                w.tx_tdm_en().set_bit();
1336                w.tx_pdm_en().clear_bit();
1337                w.tx_pcm_bypass().set_bit();
1338                w.tx_big_endian().clear_bit();
1339                w.tx_bit_order().clear_bit();
1340                w.tx_chan_mod().bits(0)
1341            });
1342
1343            self.regs().tx_tdm_ctrl().modify(|_, w| unsafe {
1344                w.tx_tdm_tot_chan_num().bits(1);
1345                w.tx_tdm_chan0_en().set_bit();
1346                w.tx_tdm_chan1_en().set_bit();
1347                w.tx_tdm_chan2_en().clear_bit();
1348                w.tx_tdm_chan3_en().clear_bit();
1349                w.tx_tdm_chan4_en().clear_bit();
1350                w.tx_tdm_chan5_en().clear_bit();
1351                w.tx_tdm_chan6_en().clear_bit();
1352                w.tx_tdm_chan7_en().clear_bit();
1353                w.tx_tdm_chan8_en().clear_bit();
1354                w.tx_tdm_chan9_en().clear_bit();
1355                w.tx_tdm_chan10_en().clear_bit();
1356                w.tx_tdm_chan11_en().clear_bit();
1357                w.tx_tdm_chan12_en().clear_bit();
1358                w.tx_tdm_chan13_en().clear_bit();
1359                w.tx_tdm_chan14_en().clear_bit();
1360                w.tx_tdm_chan15_en().clear_bit()
1361            });
1362
1363            #[allow(clippy::useless_conversion)]
1364            self.regs().rx_conf1().modify(|_, w| unsafe {
1365                w.rx_tdm_ws_width()
1366                    .bits((data_format.channel_bits() - 1).into());
1367                w.rx_bits_mod().bits(data_format.data_bits() - 1);
1368                w.rx_tdm_chan_bits().bits(data_format.channel_bits() - 1);
1369                w.rx_half_sample_bits().bits(data_format.channel_bits() - 1)
1370            });
1371            #[cfg(not(esp32h2))]
1372            self.regs()
1373                .rx_conf1()
1374                .modify(|_, w| w.rx_msb_shift().set_bit());
1375            #[cfg(esp32h2)]
1376            self.regs()
1377                .rx_conf()
1378                .modify(|_, w| w.rx_msb_shift().set_bit());
1379
1380            self.regs().rx_conf().modify(|_, w| unsafe {
1381                w.rx_mono().clear_bit();
1382                w.rx_mono_fst_vld().set_bit();
1383                w.rx_stop_mode().bits(2);
1384                w.rx_tdm_en().set_bit();
1385                w.rx_pdm_en().clear_bit();
1386                w.rx_pcm_bypass().set_bit();
1387                w.rx_big_endian().clear_bit();
1388                w.rx_bit_order().clear_bit()
1389            });
1390
1391            self.regs().rx_tdm_ctrl().modify(|_, w| unsafe {
1392                w.rx_tdm_tot_chan_num().bits(1);
1393                w.rx_tdm_pdm_chan0_en().set_bit();
1394                w.rx_tdm_pdm_chan1_en().set_bit();
1395                w.rx_tdm_pdm_chan2_en().clear_bit();
1396                w.rx_tdm_pdm_chan3_en().clear_bit();
1397                w.rx_tdm_pdm_chan4_en().clear_bit();
1398                w.rx_tdm_pdm_chan5_en().clear_bit();
1399                w.rx_tdm_pdm_chan6_en().clear_bit();
1400                w.rx_tdm_pdm_chan7_en().clear_bit();
1401                w.rx_tdm_chan8_en().clear_bit();
1402                w.rx_tdm_chan9_en().clear_bit();
1403                w.rx_tdm_chan10_en().clear_bit();
1404                w.rx_tdm_chan11_en().clear_bit();
1405                w.rx_tdm_chan12_en().clear_bit();
1406                w.rx_tdm_chan13_en().clear_bit();
1407                w.rx_tdm_chan14_en().clear_bit();
1408                w.rx_tdm_chan15_en().clear_bit()
1409            });
1410        }
1411
1412        fn set_master(&self) {
1413            self.regs()
1414                .tx_conf()
1415                .modify(|_, w| w.tx_slave_mod().clear_bit());
1416            self.regs()
1417                .rx_conf()
1418                .modify(|_, w| w.rx_slave_mod().clear_bit());
1419        }
1420
1421        fn update(&self) {
1422            self.regs()
1423                .tx_conf()
1424                .modify(|_, w| w.tx_update().clear_bit());
1425            self.regs().tx_conf().modify(|_, w| w.tx_update().set_bit());
1426
1427            self.regs()
1428                .rx_conf()
1429                .modify(|_, w| w.rx_update().clear_bit());
1430            self.regs().rx_conf().modify(|_, w| w.rx_update().set_bit());
1431        }
1432
1433        fn reset_tx(&self) {
1434            self.regs().tx_conf().modify(|_, w| {
1435                w.tx_reset().set_bit();
1436                w.tx_fifo_reset().set_bit()
1437            });
1438            self.regs().tx_conf().modify(|_, w| {
1439                w.tx_reset().clear_bit();
1440                w.tx_fifo_reset().clear_bit()
1441            });
1442
1443            self.regs().int_clr().write(|w| {
1444                w.tx_done().clear_bit_by_one();
1445                w.tx_hung().clear_bit_by_one()
1446            });
1447        }
1448
1449        fn tx_start(&self) {
1450            self.regs().tx_conf().modify(|_, w| w.tx_start().set_bit());
1451        }
1452
1453        fn tx_stop(&self) {
1454            self.regs()
1455                .tx_conf()
1456                .modify(|_, w| w.tx_start().clear_bit());
1457        }
1458
1459        fn wait_for_tx_done(&self) {
1460            while self.regs().state().read().tx_idle().bit_is_clear() {
1461                // wait
1462            }
1463
1464            self.regs()
1465                .tx_conf()
1466                .modify(|_, w| w.tx_start().clear_bit());
1467        }
1468
1469        fn reset_rx(&self) {
1470            self.regs()
1471                .rx_conf()
1472                .modify(|_, w| w.rx_start().clear_bit());
1473
1474            self.regs().rx_conf().modify(|_, w| {
1475                w.rx_reset().set_bit();
1476                w.rx_fifo_reset().set_bit()
1477            });
1478            self.regs().rx_conf().modify(|_, w| {
1479                w.rx_reset().clear_bit();
1480                w.rx_fifo_reset().clear_bit()
1481            });
1482
1483            self.regs().int_clr().write(|w| {
1484                w.rx_done().clear_bit_by_one();
1485                w.rx_hung().clear_bit_by_one()
1486            });
1487        }
1488
1489        fn rx_start(&self, len: usize) {
1490            let len = len - 1;
1491
1492            self.regs()
1493                .rxeof_num()
1494                .write(|w| unsafe { w.rx_eof_num().bits(len as u16) });
1495            self.regs().rx_conf().modify(|_, w| w.rx_start().set_bit());
1496        }
1497
1498        fn wait_for_rx_done(&self) {
1499            while self.regs().int_raw().read().rx_done().bit_is_clear() {
1500                // wait
1501            }
1502
1503            self.regs()
1504                .int_clr()
1505                .write(|w| w.rx_done().clear_bit_by_one());
1506        }
1507    }
1508
1509    impl RegBlock for I2S0 {
1510        fn regs(&self) -> &RegisterBlock {
1511            unsafe { &*I2S0::PTR.cast::<RegisterBlock>() }
1512        }
1513
1514        fn peripheral(&self) -> crate::system::Peripheral {
1515            crate::system::Peripheral::I2s0
1516        }
1517    }
1518
1519    impl RegisterAccessPrivate for I2S0 {
1520        fn set_interrupt_handler(&self, handler: InterruptHandler) {
1521            for core in crate::system::Cpu::other() {
1522                crate::interrupt::disable(core, Interrupt::I2S0);
1523            }
1524            unsafe { crate::peripherals::I2S0::steal() }.bind_i2s0_interrupt(handler.handler());
1525            unwrap!(crate::interrupt::enable(
1526                Interrupt::I2S0,
1527                handler.priority()
1528            ));
1529        }
1530    }
1531
1532    impl Signals for crate::peripherals::I2S0 {
1533        fn mclk_signal(&self) -> OutputSignal {
1534            cfg_if::cfg_if! {
1535                if #[cfg(esp32)] {
1536                    panic!("MCLK currently not supported on ESP32");
1537                } else if #[cfg(esp32s2)] {
1538                    OutputSignal::CLK_I2S
1539                } else if #[cfg(esp32s3)] {
1540                    OutputSignal::I2S0_MCLK
1541                } else {
1542                    OutputSignal::I2S_MCLK
1543                }
1544            }
1545        }
1546
1547        fn bclk_signal(&self) -> OutputSignal {
1548            cfg_if::cfg_if! {
1549                if #[cfg(any(esp32, esp32s2, esp32s3))] {
1550                    OutputSignal::I2S0O_BCK
1551                } else {
1552                    OutputSignal::I2SO_BCK
1553                }
1554            }
1555        }
1556
1557        fn ws_signal(&self) -> OutputSignal {
1558            cfg_if::cfg_if! {
1559                if #[cfg(any(esp32, esp32s2, esp32s3))] {
1560                    OutputSignal::I2S0O_WS
1561                } else {
1562                    OutputSignal::I2SO_WS
1563                }
1564            }
1565        }
1566
1567        fn dout_signal(&self) -> OutputSignal {
1568            cfg_if::cfg_if! {
1569                if #[cfg(esp32)] {
1570                    OutputSignal::I2S0O_DATA_23
1571                } else if #[cfg(esp32s2)] {
1572                    OutputSignal::I2S0O_DATA_OUT23
1573                } else if #[cfg(esp32s3)] {
1574                    OutputSignal::I2S0O_SD
1575                } else {
1576                    OutputSignal::I2SO_SD
1577                }
1578            }
1579        }
1580
1581        fn bclk_rx_signal(&self) -> OutputSignal {
1582            cfg_if::cfg_if! {
1583                if #[cfg(any(esp32, esp32s2, esp32s3))] {
1584                    OutputSignal::I2S0I_BCK
1585                } else {
1586                    OutputSignal::I2SI_BCK
1587                }
1588            }
1589        }
1590
1591        fn ws_rx_signal(&self) -> OutputSignal {
1592            cfg_if::cfg_if! {
1593                if #[cfg(any(esp32, esp32s2, esp32s3))] {
1594                    OutputSignal::I2S0I_WS
1595                } else {
1596                    OutputSignal::I2SI_WS
1597                }
1598            }
1599        }
1600
1601        fn din_signal(&self) -> InputSignal {
1602            cfg_if::cfg_if! {
1603                if #[cfg(esp32)] {
1604                    InputSignal::I2S0I_DATA_15
1605                } else if #[cfg(esp32s2)] {
1606                    InputSignal::I2S0I_DATA_IN15
1607                } else if #[cfg(esp32s3)] {
1608                    InputSignal::I2S0I_SD
1609                } else {
1610                    InputSignal::I2SI_SD
1611                }
1612            }
1613        }
1614    }
1615
1616    #[cfg(i2s1)]
1617    impl RegBlock for I2S1 {
1618        fn regs(&self) -> &RegisterBlock {
1619            unsafe { &*I2S1::PTR.cast::<RegisterBlock>() }
1620        }
1621
1622        fn peripheral(&self) -> crate::system::Peripheral {
1623            crate::system::Peripheral::I2s1
1624        }
1625    }
1626
1627    #[cfg(i2s1)]
1628    impl RegisterAccessPrivate for I2S1 {
1629        fn set_interrupt_handler(&self, handler: InterruptHandler) {
1630            for core in crate::system::Cpu::other() {
1631                crate::interrupt::disable(core, Interrupt::I2S1);
1632            }
1633            unsafe { crate::peripherals::I2S1::steal() }.bind_i2s1_interrupt(handler.handler());
1634            unwrap!(crate::interrupt::enable(
1635                Interrupt::I2S1,
1636                handler.priority()
1637            ));
1638        }
1639    }
1640
1641    #[cfg(i2s1)]
1642    impl Signals for crate::peripherals::I2S1 {
1643        fn mclk_signal(&self) -> OutputSignal {
1644            cfg_if::cfg_if! {
1645                if #[cfg(esp32)] {
1646                    panic!("MCLK currently not supported on ESP32");
1647                } else {
1648                    OutputSignal::I2S1_MCLK
1649                }
1650            }
1651        }
1652
1653        fn bclk_signal(&self) -> OutputSignal {
1654            OutputSignal::I2S1O_BCK
1655        }
1656
1657        fn ws_signal(&self) -> OutputSignal {
1658            OutputSignal::I2S1O_WS
1659        }
1660
1661        fn dout_signal(&self) -> OutputSignal {
1662            cfg_if::cfg_if! {
1663                if #[cfg(esp32)] {
1664                    OutputSignal::I2S1O_DATA_23
1665                } else {
1666                    OutputSignal::I2S1O_SD
1667                }
1668            }
1669        }
1670
1671        fn bclk_rx_signal(&self) -> OutputSignal {
1672            OutputSignal::I2S1I_BCK
1673        }
1674
1675        fn ws_rx_signal(&self) -> OutputSignal {
1676            OutputSignal::I2S1I_WS
1677        }
1678
1679        fn din_signal(&self) -> InputSignal {
1680            cfg_if::cfg_if! {
1681                if #[cfg(esp32)] {
1682                    InputSignal::I2S1I_DATA_15
1683                } else {
1684                    InputSignal::I2S1I_SD
1685                }
1686            }
1687        }
1688    }
1689
1690    impl RegBlock for super::AnyI2s {
1691        fn regs(&self) -> &RegisterBlock {
1692            match &self.0 {
1693                super::AnyI2sInner::I2s0(i2s) => RegBlock::regs(i2s),
1694                #[cfg(i2s1)]
1695                super::AnyI2sInner::I2s1(i2s) => RegBlock::regs(i2s),
1696            }
1697        }
1698
1699        delegate::delegate! {
1700            to match &self.0 {
1701                super::AnyI2sInner::I2s0(i2s) => i2s,
1702                #[cfg(i2s1)]
1703                super::AnyI2sInner::I2s1(i2s) => i2s,
1704            } {
1705                fn peripheral(&self) -> crate::system::Peripheral;
1706            }
1707        }
1708    }
1709
1710    impl RegisterAccessPrivate for super::AnyI2s {
1711        delegate::delegate! {
1712            to match &self.0 {
1713                super::AnyI2sInner::I2s0(i2s) => i2s,
1714                #[cfg(i2s1)]
1715                super::AnyI2sInner::I2s1(i2s) => i2s,
1716            } {
1717                fn set_interrupt_handler(&self, handler: InterruptHandler);
1718            }
1719        }
1720    }
1721
1722    impl Signals for super::AnyI2s {
1723        delegate::delegate! {
1724            to match &self.0 {
1725                super::AnyI2sInner::I2s0(i2s) => i2s,
1726                #[cfg(i2s1)]
1727                super::AnyI2sInner::I2s1(i2s) => i2s,
1728            } {
1729                fn mclk_signal(&self) -> OutputSignal;
1730                fn bclk_signal(&self) -> OutputSignal;
1731                fn ws_signal(&self) -> OutputSignal;
1732                fn dout_signal(&self) -> OutputSignal;
1733                fn bclk_rx_signal(&self) -> OutputSignal;
1734                fn ws_rx_signal(&self) -> OutputSignal;
1735                fn din_signal(&self) -> InputSignal;
1736            }
1737        }
1738    }
1739
1740    pub struct I2sClockDividers {
1741        mclk_divider: u32,
1742        bclk_divider: u32,
1743        denominator: u32,
1744        numerator: u32,
1745    }
1746
1747    pub fn calculate_clock(sample_rate: Rate, channels: u8, data_bits: u8) -> I2sClockDividers {
1748        // this loosely corresponds to `i2s_std_calculate_clock` and
1749        // `i2s_ll_tx_set_mclk` in esp-idf
1750        //
1751        // main difference is we are using fixed-point arithmetic here
1752
1753        // If data_bits is a power of two, use 256 as the mclk_multiple
1754        // If data_bits is 24, use 192 (24 * 8) as the mclk_multiple
1755        let mclk_multiple = if data_bits == 24 { 192 } else { 256 };
1756        let sclk = crate::soc::constants::I2S_SCLK; // for now it's fixed 160MHz and 96MHz (just H2)
1757
1758        let rate = sample_rate.as_hz();
1759
1760        let bclk = rate * channels as u32 * data_bits as u32;
1761        let mclk = rate * mclk_multiple;
1762        let bclk_divider = mclk / bclk;
1763        let mut mclk_divider = sclk / mclk;
1764
1765        let mut ma: u32;
1766        let mut mb: u32;
1767        let mut denominator: u32 = 0;
1768        let mut numerator: u32 = 0;
1769
1770        let freq_diff = sclk.abs_diff(mclk * mclk_divider);
1771
1772        if freq_diff != 0 {
1773            let decimal = freq_diff as u64 * 10000 / mclk as u64;
1774
1775            // Carry bit if the decimal is greater than 1.0 - 1.0 / (63.0 * 2) = 125.0 /
1776            // 126.0
1777            if decimal > 1250000 / 126 {
1778                mclk_divider += 1;
1779            } else {
1780                let mut min: u32 = !0;
1781
1782                for a in 2..=I2S_LL_MCLK_DIVIDER_MAX {
1783                    let b = (a as u64) * (freq_diff as u64 * 10000u64 / mclk as u64) + 5000;
1784                    ma = ((freq_diff as u64 * 10000u64 * a as u64) / 10000) as u32;
1785                    mb = (mclk as u64 * (b / 10000)) as u32;
1786
1787                    if ma == mb {
1788                        denominator = a as u32;
1789                        numerator = (b / 10000) as u32;
1790                        break;
1791                    }
1792
1793                    if mb.abs_diff(ma) < min {
1794                        denominator = a as u32;
1795                        numerator = b as u32;
1796                        min = mb.abs_diff(ma);
1797                    }
1798                }
1799            }
1800        }
1801
1802        I2sClockDividers {
1803            mclk_divider,
1804            bclk_divider,
1805            denominator,
1806            numerator,
1807        }
1808    }
1809}
1810
1811/// Async functionality
1812pub mod asynch {
1813    use super::{Error, I2sRx, I2sTx, RegisterAccessPrivate};
1814    use crate::{
1815        dma::{
1816            asynch::{DmaRxDoneChFuture, DmaRxFuture, DmaTxDoneChFuture, DmaTxFuture},
1817            DmaEligible,
1818            ReadBuffer,
1819            Rx,
1820            RxCircularState,
1821            Tx,
1822            TxCircularState,
1823            WriteBuffer,
1824        },
1825        Async,
1826    };
1827
1828    impl<'d> I2sTx<'d, Async> {
1829        /// One-shot write I2S.
1830        pub async fn write_dma_async(&mut self, words: &mut [u8]) -> Result<(), Error> {
1831            let (ptr, len) = (words.as_ptr(), words.len());
1832
1833            self.i2s.reset_tx();
1834
1835            let future = DmaTxFuture::new(&mut self.tx_channel);
1836
1837            unsafe {
1838                self.tx_chain.fill_for_tx(false, ptr, len)?;
1839                future
1840                    .tx
1841                    .prepare_transfer_without_start(self.i2s.dma_peripheral(), &self.tx_chain)
1842                    .and_then(|_| future.tx.start_transfer())?;
1843            }
1844
1845            self.i2s.tx_start();
1846            future.await?;
1847
1848            Ok(())
1849        }
1850
1851        /// Continuously write to I2S. Returns [I2sWriteDmaTransferAsync]
1852        pub fn write_dma_circular_async<TXBUF: ReadBuffer>(
1853            mut self,
1854            words: TXBUF,
1855        ) -> Result<I2sWriteDmaTransferAsync<'d, TXBUF>, Error> {
1856            let (ptr, len) = unsafe { words.read_buffer() };
1857
1858            // Reset TX unit and TX FIFO
1859            self.i2s.reset_tx();
1860
1861            // Enable corresponding interrupts if needed
1862
1863            // configure DMA outlink
1864            unsafe {
1865                self.tx_chain.fill_for_tx(true, ptr, len)?;
1866                self.tx_channel
1867                    .prepare_transfer_without_start(self.i2s.dma_peripheral(), &self.tx_chain)
1868                    .and_then(|_| self.tx_channel.start_transfer())?;
1869            }
1870
1871            // set I2S_TX_STOP_EN if needed
1872
1873            // start: set I2S_TX_START
1874            self.i2s.tx_start();
1875
1876            let state = TxCircularState::new(&mut self.tx_chain);
1877            Ok(I2sWriteDmaTransferAsync {
1878                i2s_tx: self,
1879                state,
1880                _buffer: words,
1881            })
1882        }
1883    }
1884
1885    /// An in-progress async circular DMA write transfer.
1886    pub struct I2sWriteDmaTransferAsync<'d, BUFFER> {
1887        i2s_tx: I2sTx<'d, Async>,
1888        state: TxCircularState,
1889        _buffer: BUFFER,
1890    }
1891
1892    impl<BUFFER> I2sWriteDmaTransferAsync<'_, BUFFER> {
1893        /// How many bytes can be pushed into the DMA transaction.
1894        /// Will wait for more than 0 bytes available.
1895        pub async fn available(&mut self) -> Result<usize, Error> {
1896            loop {
1897                self.state.update(&self.i2s_tx.tx_channel)?;
1898                let res = self.state.available;
1899
1900                if res != 0 {
1901                    break Ok(res);
1902                }
1903
1904                DmaTxDoneChFuture::new(&mut self.i2s_tx.tx_channel).await?
1905            }
1906        }
1907
1908        /// Push bytes into the DMA transaction.
1909        pub async fn push(&mut self, data: &[u8]) -> Result<usize, Error> {
1910            let avail = self.available().await?;
1911            let to_send = usize::min(avail, data.len());
1912            Ok(self.state.push(&data[..to_send])?)
1913        }
1914
1915        /// Push bytes into the DMA buffer via the given closure.
1916        /// The closure *must* return the actual number of bytes written.
1917        /// The closure *might* get called with a slice which is smaller than
1918        /// the total available buffer. Only useful for circular DMA
1919        /// transfers
1920        pub async fn push_with(
1921            &mut self,
1922            f: impl FnOnce(&mut [u8]) -> usize,
1923        ) -> Result<usize, Error> {
1924            let _avail = self.available().await;
1925            Ok(self.state.push_with(f)?)
1926        }
1927    }
1928
1929    impl<'d> I2sRx<'d, Async> {
1930        /// One-shot read I2S.
1931        pub async fn read_dma_async(&mut self, words: &mut [u8]) -> Result<(), Error> {
1932            let (ptr, len) = (words.as_mut_ptr(), words.len());
1933
1934            if len % 4 != 0 {
1935                return Err(Error::IllegalArgument);
1936            }
1937
1938            // Reset RX unit and RX FIFO
1939            self.i2s.reset_rx();
1940
1941            let future = DmaRxFuture::new(&mut self.rx_channel);
1942
1943            // configure DMA inlink
1944            unsafe {
1945                self.rx_chain.fill_for_rx(false, ptr, len)?;
1946                future
1947                    .rx
1948                    .prepare_transfer_without_start(self.i2s.dma_peripheral(), &self.rx_chain)
1949                    .and_then(|_| future.rx.start_transfer())?;
1950            }
1951
1952            // start: set I2S_RX_START
1953            self.i2s.rx_start(len);
1954
1955            future.await?;
1956
1957            Ok(())
1958        }
1959
1960        /// Continuously read from I2S. Returns [I2sReadDmaTransferAsync]
1961        pub fn read_dma_circular_async<RXBUF>(
1962            mut self,
1963            mut words: RXBUF,
1964        ) -> Result<I2sReadDmaTransferAsync<'d, RXBUF>, Error>
1965        where
1966            RXBUF: WriteBuffer,
1967        {
1968            let (ptr, len) = unsafe { words.write_buffer() };
1969
1970            if len % 4 != 0 {
1971                return Err(Error::IllegalArgument);
1972            }
1973
1974            // Reset RX unit and RX FIFO
1975            self.i2s.reset_rx();
1976
1977            // Enable corresponding interrupts if needed
1978
1979            // configure DMA inlink
1980            unsafe {
1981                self.rx_chain.fill_for_rx(true, ptr, len)?;
1982                self.rx_channel
1983                    .prepare_transfer_without_start(self.i2s.dma_peripheral(), &self.rx_chain)
1984                    .and_then(|_| self.rx_channel.start_transfer())?;
1985            }
1986
1987            // start: set I2S_RX_START
1988            self.i2s.rx_start(len);
1989
1990            let state = RxCircularState::new(&mut self.rx_chain);
1991            Ok(I2sReadDmaTransferAsync {
1992                i2s_rx: self,
1993                state,
1994                _buffer: words,
1995            })
1996        }
1997    }
1998
1999    /// An in-progress async circular DMA read transfer.
2000    pub struct I2sReadDmaTransferAsync<'d, BUFFER> {
2001        i2s_rx: I2sRx<'d, Async>,
2002        state: RxCircularState,
2003        _buffer: BUFFER,
2004    }
2005
2006    impl<BUFFER> I2sReadDmaTransferAsync<'_, BUFFER> {
2007        /// How many bytes can be popped from the DMA transaction.
2008        /// Will wait for more than 0 bytes available.
2009        pub async fn available(&mut self) -> Result<usize, Error> {
2010            loop {
2011                self.state.update()?;
2012
2013                let res = self.state.available;
2014
2015                if res != 0 {
2016                    break Ok(res);
2017                }
2018
2019                DmaRxDoneChFuture::new(&mut self.i2s_rx.rx_channel).await?;
2020            }
2021        }
2022
2023        /// Pop bytes from the DMA transaction.
2024        pub async fn pop(&mut self, data: &mut [u8]) -> Result<usize, Error> {
2025            let avail = self.available().await?;
2026            let to_rcv = usize::min(avail, data.len());
2027            Ok(self.state.pop(&mut data[..to_rcv])?)
2028        }
2029    }
2030}
2031
2032crate::any_peripheral! {
2033    /// Any SPI peripheral.
2034    pub peripheral AnyI2s {
2035        #[cfg(i2s0)]
2036        I2s0(crate::peripherals::I2S0),
2037        #[cfg(i2s1)]
2038        I2s1(crate::peripherals::I2S1),
2039    }
2040}
2041
2042impl DmaEligible for AnyI2s {
2043    #[cfg(gdma)]
2044    type Dma = crate::dma::AnyGdmaChannel;
2045    #[cfg(pdma)]
2046    type Dma = crate::dma::AnyI2sDmaChannel;
2047
2048    fn dma_peripheral(&self) -> crate::dma::DmaPeripheral {
2049        match &self.0 {
2050            AnyI2sInner::I2s0(_) => crate::dma::DmaPeripheral::I2s0,
2051            #[cfg(i2s1)]
2052            AnyI2sInner::I2s1(_) => crate::dma::DmaPeripheral::I2s1,
2053        }
2054    }
2055}