diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 8277ac941..1ce6bf348 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed +- The `i2s::{I2sWrite, I2sWriteDma, I2sRead, I2sReadDma, I2sWriteDmaAsync, I2sReadDmaAsync}` traits have been removed. (#2316) + ## [0.21.1] ### Fixed diff --git a/esp-hal/MIGRATING-0.21.md b/esp-hal/MIGRATING-0.21.md index ecd058d4a..2421b6b95 100644 --- a/esp-hal/MIGRATING-0.21.md +++ b/esp-hal/MIGRATING-0.21.md @@ -1 +1,24 @@ # Migration Guide from 0.21.x to v0.22.x + +## Removed `i2s` traits + +The following traits have been removed: + +- `I2sWrite` +- `I2sWriteDma` +- `I2sRead` +- `I2sReadDma` +- `I2sWriteDmaAsync` +- `I2sReadDmaAsync` + +You no longer have to import these to access their respective APIs. If you used these traits +in your functions as generic parameters, you can use the `I2s` type directly instead. + +For example: + +```diff +-fn foo(i2s: &mut impl I2sWrite) { ++fn foo(i2s: &mut I2s<'_, I2S0, Blocking>) { + // ... + } +``` diff --git a/esp-hal/src/i2s.rs b/esp-hal/src/i2s.rs index 6b9d9035f..7ca4da148 100644 --- a/esp-hal/src/i2s.rs +++ b/esp-hal/src/i2s.rs @@ -32,7 +32,6 @@ //! # use esp_hal::i2s::I2s; //! # use esp_hal::i2s::Standard; //! # use esp_hal::i2s::DataFormat; -//! # use esp_hal::i2s::I2sReadDma; //! # use esp_hal::gpio::Io; //! # use esp_hal::dma_buffers; //! # use esp_hal::dma::{Dma, DmaPriority}; @@ -106,7 +105,7 @@ use crate::{ gpio::PeripheralOutput, interrupt::InterruptHandler, into_ref, - peripheral::Peripheral, + peripheral::{Peripheral, PeripheralRef}, system::PeripheralClockControl, InterruptConfigurable, Mode, @@ -135,7 +134,8 @@ const I2S_LL_MCLK_DIVIDER_BIT_WIDTH: usize = 9; const I2S_LL_MCLK_DIVIDER_MAX: usize = (1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1; -trait AcceptedWord {} +/// Data types that the I2S peripheral can work with. +pub trait AcceptedWord: crate::private::Sealed {} impl AcceptedWord for u8 {} impl AcceptedWord for u16 {} impl AcceptedWord for u32 {} @@ -251,89 +251,27 @@ impl DataFormat { } } -/// Blocking I2s Write -pub trait I2sWrite { - /// Writes a slice of data to the I2S peripheral. - fn write(&mut self, words: &[W]) -> Result<(), Error>; -} - -/// Initiate a DMA tx transfer -pub trait I2sWriteDma<'d, T, TXBUF, DmaMode> -where - T: RegisterAccess, - DmaMode: Mode, - Self: DmaSupportTx + Sized, -{ - /// Write I2S. - /// Returns [DmaTransferTx] which represents the in-progress DMA - /// transfer - fn write_dma<'t>(&'t mut self, words: &'t TXBUF) -> Result, Error> - where - TXBUF: ReadBuffer; - - /// Continuously write to I2S. Returns [DmaTransferTxCircular] which - /// represents the in-progress DMA transfer - fn write_dma_circular<'t>( - &'t mut self, - words: &'t TXBUF, - ) -> Result, Error> - where - TXBUF: ReadBuffer; -} - -/// Blocking I2S Read -pub trait I2sRead { - /// Reads a slice of data from the I2S peripheral and stores it in the - /// provided buffer. - fn read(&mut self, words: &mut [W]) -> Result<(), Error>; -} - -/// Initiate a DMA rx transfer -pub trait I2sReadDma<'d, T, RXBUF, DmaMode> -where - T: RegisterAccess, - DmaMode: Mode, - Self: DmaSupportRx + Sized, -{ - /// Read I2S. - /// Returns [DmaTransferRx] which represents the in-progress DMA - /// transfer - fn read_dma<'t>(&'t mut self, words: &'t mut RXBUF) -> Result, Error> - where - RXBUF: WriteBuffer; - - /// Continuously read from I2S. - /// Returns [DmaTransferRxCircular] which represents the in-progress DMA - /// transfer - fn read_dma_circular<'t>( - &'t mut self, - words: &'t mut RXBUF, - ) -> Result, Error> - where - RXBUF: WriteBuffer; -} - /// Instance of the I2S peripheral driver -pub struct I2s<'d, I, DmaMode> +pub struct I2s<'d, T, DmaMode> where - I: RegisterAccess, + T: RegisterAccess, DmaMode: Mode, { /// Handles the reception (RX) side of the I2S peripheral. - pub i2s_rx: RxCreator<'d, I, DmaMode>, + pub i2s_rx: RxCreator<'d, T, DmaMode>, /// Handles the transmission (TX) side of the I2S peripheral. - pub i2s_tx: TxCreator<'d, I, DmaMode>, + pub i2s_tx: TxCreator<'d, T, DmaMode>, phantom: PhantomData, } -impl<'d, I, DmaMode> I2s<'d, I, DmaMode> +impl<'d, T, DmaMode> I2s<'d, T, DmaMode> where - I: RegisterAccess, + T: RegisterAccess, DmaMode: Mode, { #[allow(clippy::too_many_arguments)] fn new_internal( - i2s: impl Peripheral

+ 'd, + i2s: impl Peripheral

+ 'd, standard: Standard, data_format: DataFormat, sample_rate: impl Into, @@ -342,7 +280,7 @@ where tx_descriptors: &'static mut [DmaDescriptor], ) -> Self where - CH: DmaChannelConvert, + CH: DmaChannelConvert, { crate::into_ref!(i2s); channel.runtime_ensure_compatible(&i2s); @@ -350,23 +288,23 @@ where // could be configured totally independently but for now handle all // the targets the same and force same configuration for both, TX and RX - PeripheralClockControl::reset(I::get_peripheral()); - PeripheralClockControl::enable(I::get_peripheral()); - I::set_clock(calculate_clock(sample_rate, 2, data_format.channel_bits())); - I::configure(&standard, &data_format); - I::set_master(); - I::update(); + PeripheralClockControl::reset(i2s.peripheral()); + PeripheralClockControl::enable(i2s.peripheral()); + i2s.set_clock(calculate_clock(sample_rate, 2, data_format.channel_bits())); + i2s.configure(&standard, &data_format); + i2s.set_master(); + i2s.update(); let channel = channel.degrade(); Self { i2s_rx: RxCreator { - register_access: PhantomData, + i2s: unsafe { i2s.clone_unchecked() }, rx_channel: channel.rx, descriptors: rx_descriptors, phantom: PhantomData, }, i2s_tx: TxCreator { - register_access: PhantomData, + i2s, tx_channel: channel.tx, descriptors: tx_descriptors, phantom: PhantomData, @@ -376,36 +314,41 @@ where } } -impl<'d, I, DmaMode> I2s<'d, I, DmaMode> +impl<'d, T, DmaMode> I2s<'d, T, DmaMode> where - I: RegisterAccess, + T: RegisterAccess, DmaMode: Mode, { /// Sets the interrupt handler /// /// Interrupts are not enabled at the peripheral level here. pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) { - I::set_interrupt_handler(handler); + // tx.i2s and rx.i2s is the same, we could use either one + self.i2s_tx.i2s.set_interrupt_handler(handler); } /// Listen for the given interrupts pub fn listen(&mut self, interrupts: EnumSet) { - I::listen(interrupts); + // tx.i2s and rx.i2s is the same, we could use either one + self.i2s_tx.i2s.listen(interrupts); } /// Unlisten the given interrupts pub fn unlisten(&mut self, interrupts: EnumSet) { - I::unlisten(interrupts); + // tx.i2s and rx.i2s is the same, we could use either one + self.i2s_tx.i2s.unlisten(interrupts); } /// Gets asserted interrupts pub fn interrupts(&mut self) -> EnumSet { - I::interrupts() + // tx.i2s and rx.i2s is the same, we could use either one + self.i2s_tx.i2s.interrupts() } /// Resets asserted interrupts pub fn clear_interrupts(&mut self, interrupts: EnumSet) { - I::clear_interrupts(interrupts); + // tx.i2s and rx.i2s is the same, we could use either one + self.i2s_tx.i2s.clear_interrupts(interrupts); } } @@ -426,16 +369,16 @@ where } } -impl<'d, I, DmaMode> I2s<'d, I, DmaMode> +impl<'d, T, DmaMode> I2s<'d, T, DmaMode> where - I: RegisterAccess, + T: RegisterAccess, DmaMode: Mode, { /// Construct a new I2S peripheral driver instance for the first I2S /// peripheral #[allow(clippy::too_many_arguments)] pub fn new( - i2s: impl Peripheral

+ 'd, + i2s: impl Peripheral

+ 'd, standard: Standard, data_format: DataFormat, sample_rate: impl Into, @@ -444,7 +387,7 @@ where tx_descriptors: &'static mut [DmaDescriptor], ) -> Self where - CH: DmaChannelConvert, + CH: DmaChannelConvert, DmaMode: Mode, { Self::new_internal( @@ -462,7 +405,7 @@ where pub fn with_mclk(self, pin: impl Peripheral

+ 'd) -> Self { into_ref!(pin); pin.set_to_push_pull_output(crate::private::Internal); - pin.connect_peripheral_to_output(I::mclk_signal(), crate::private::Internal); + pin.connect_peripheral_to_output(self.i2s_tx.i2s.mclk_signal(), crate::private::Internal); self } @@ -473,7 +416,7 @@ pub struct I2sTx<'d, T, DmaMode> where T: RegisterAccess, { - register_access: PhantomData, + i2s: PeripheralRef<'d, T>, tx_channel: ChannelTx<'d, T::Dma>, tx_chain: DescriptorChain, phantom: PhantomData, @@ -495,11 +438,11 @@ where DmaMode: Mode, { fn peripheral_wait_dma(&mut self, _is_rx: bool, _is_tx: bool) { - T::wait_for_tx_done(); + self.i2s.wait_for_tx_done(); } fn peripheral_dma_stop(&mut self) { - T::tx_stop(); + self.i2s.tx_stop(); } } @@ -524,38 +467,11 @@ where T: RegisterAccess, DmaMode: Mode, { - fn new(tx_channel: ChannelTx<'d, T::Dma>, descriptors: &'static mut [DmaDescriptor]) -> Self { - Self { - register_access: PhantomData, - tx_channel, - tx_chain: DescriptorChain::new(descriptors), - phantom: PhantomData, - } - } - fn write_bytes(&mut self, data: &[u8]) -> Result<(), Error> { - let ptr = data.as_ptr(); - - // Reset TX unit and TX FIFO - T::reset_tx(); - - // Enable corresponding interrupts if needed - - // configure DMA outlink - unsafe { - self.tx_chain.fill_for_tx(false, ptr, data.len())?; - self.tx_channel - .prepare_transfer_without_start(T::get_dma_peripheral(), &self.tx_chain) - .and_then(|_| self.tx_channel.start_transfer())?; - } - - // set I2S_TX_STOP_EN if needed - - // start: set I2S_TX_START - T::tx_start(); + self.start_tx_transfer(&data, false)?; // wait until I2S_TX_IDLE is 1 - T::wait_for_tx_done(); + self.i2s.wait_for_tx_done(); Ok(()) } @@ -572,7 +488,7 @@ where let (ptr, len) = unsafe { words.read_buffer() }; // Reset TX unit and TX FIFO - T::reset_tx(); + self.i2s.reset_tx(); // Enable corresponding interrupts if needed @@ -580,51 +496,47 @@ where unsafe { self.tx_chain.fill_for_tx(circular, ptr, len)?; self.tx_channel - .prepare_transfer_without_start(T::get_dma_peripheral(), &self.tx_chain) + .prepare_transfer_without_start(self.i2s.dma_peripheral(), &self.tx_chain) .and_then(|_| self.tx_channel.start_transfer())?; } // set I2S_TX_STOP_EN if needed // start: set I2S_TX_START - T::tx_start(); + self.i2s.tx_start(); Ok(()) } -} -impl<'d, T, W, DmaMode> I2sWrite for I2sTx<'d, T, DmaMode> -where - T: RegisterAccess, - W: AcceptedWord, - DmaMode: Mode, -{ - fn write(&mut self, words: &[W]) -> Result<(), Error> { + /// Writes a slice of data to the I2S peripheral. + pub fn write(&mut self, words: &[impl AcceptedWord]) -> Result<(), Error> { self.write_bytes(unsafe { core::slice::from_raw_parts(words.as_ptr().cast::(), core::mem::size_of_val(words)) }) } -} -impl<'d, T, TXBUF, DmaMode> I2sWriteDma<'d, T, TXBUF, DmaMode> for I2sTx<'d, T, DmaMode> -where - T: RegisterAccess, - DmaMode: Mode, -{ - fn write_dma<'t>(&'t mut self, words: &'t TXBUF) -> Result, Error> + /// Write I2S. + /// Returns [DmaTransferTx] which represents the in-progress DMA + /// transfer + pub fn write_dma<'t>( + &'t mut self, + words: &'t impl ReadBuffer, + ) -> Result, Error> where - TXBUF: ReadBuffer, + Self: DmaSupportTx, { self.start_tx_transfer(words, false)?; Ok(DmaTransferTx::new(self)) } - fn write_dma_circular<'t>( + /// Continuously write to I2S. Returns [DmaTransferTxCircular] which + /// represents the in-progress DMA transfer + pub fn write_dma_circular<'t>( &'t mut self, - words: &'t TXBUF, + words: &'t impl ReadBuffer, ) -> Result, Error> where - TXBUF: ReadBuffer, + Self: DmaSupportTx, { self.start_tx_transfer(words, true)?; Ok(DmaTransferTxCircular::new(self)) @@ -637,7 +549,7 @@ where T: RegisterAccess, DmaMode: Mode, { - register_access: PhantomData, + i2s: PeripheralRef<'d, T>, rx_channel: ChannelRx<'d, T::Dma>, rx_chain: DescriptorChain, phantom: PhantomData, @@ -659,11 +571,11 @@ where DmaMode: Mode, { fn peripheral_wait_dma(&mut self, _is_rx: bool, _is_tx: bool) { - T::wait_for_rx_done(); + self.i2s.wait_for_rx_done(); } fn peripheral_dma_stop(&mut self) { - T::reset_rx(); + self.i2s.reset_rx(); } } @@ -688,36 +600,11 @@ where T: RegisterAccess, DmaMode: Mode, { - fn new(rx_channel: ChannelRx<'d, T::Dma>, descriptors: &'static mut [DmaDescriptor]) -> Self { - Self { - register_access: PhantomData, - rx_channel, - rx_chain: DescriptorChain::new(descriptors), - phantom: PhantomData, - } - } - - fn read_bytes(&mut self, data: &mut [u8]) -> Result<(), Error> { - let ptr = data.as_mut_ptr(); - - // Reset RX unit and RX FIFO - T::reset_rx(); - - // Enable corresponding interrupts if needed - - // configure DMA inlink - unsafe { - self.rx_chain.fill_for_rx(false, ptr, data.len())?; - self.rx_channel - .prepare_transfer_without_start(T::get_dma_peripheral(), &self.rx_chain) - .and_then(|_| self.rx_channel.start_transfer())?; - } - - // start: set I2S_RX_START - T::rx_start(data.len()); + fn read_bytes(&mut self, mut data: &mut [u8]) -> Result<(), Error> { + self.start_rx_transfer(&mut data, false)?; // wait until I2S_RX_IDLE is 1 - T::wait_for_rx_done(); + self.i2s.wait_for_rx_done(); Ok(()) } @@ -737,7 +624,7 @@ where } // Reset RX unit and RX FIFO - T::reset_rx(); + self.i2s.reset_rx(); // Enable corresponding interrupts if needed @@ -745,23 +632,18 @@ where unsafe { self.rx_chain.fill_for_rx(circular, ptr, len)?; self.rx_channel - .prepare_transfer_without_start(T::get_dma_peripheral(), &self.rx_chain) + .prepare_transfer_without_start(self.i2s.dma_peripheral(), &self.rx_chain) .and_then(|_| self.rx_channel.start_transfer())?; } // start: set I2S_RX_START - T::rx_start(len); + self.i2s.rx_start(len); Ok(()) } -} -impl<'d, W, T, DmaMode> I2sRead for I2sRx<'d, T, DmaMode> -where - T: RegisterAccess, - W: AcceptedWord, - DmaMode: Mode, -{ - fn read(&mut self, words: &mut [W]) -> Result<(), Error> { + /// Reads a slice of data from the I2S peripheral and stores it in the + /// provided buffer. + pub fn read(&mut self, words: &mut [impl AcceptedWord]) -> Result<(), Error> { if core::mem::size_of_val(words) > 4096 || words.is_empty() { return Err(Error::IllegalArgument); } @@ -773,28 +655,30 @@ where ) }) } -} -impl<'d, T, RXBUF, DmaMode> I2sReadDma<'d, T, RXBUF, DmaMode> for I2sRx<'d, T, DmaMode> -where - T: RegisterAccess, - DmaMode: Mode, - Self: DmaSupportRx + Sized, -{ - fn read_dma<'t>(&'t mut self, words: &'t mut RXBUF) -> Result, Error> + /// Read I2S. + /// Returns [DmaTransferRx] which represents the in-progress DMA + /// transfer + pub fn read_dma<'t>( + &'t mut self, + words: &'t mut impl WriteBuffer, + ) -> Result, Error> where - RXBUF: WriteBuffer, + Self: DmaSupportRx, { self.start_rx_transfer(words, false)?; Ok(DmaTransferRx::new(self)) } - fn read_dma_circular<'t>( + /// Continuously read from I2S. + /// Returns [DmaTransferRxCircular] which represents the in-progress DMA + /// transfer + pub fn read_dma_circular<'t>( &'t mut self, - words: &'t mut RXBUF, + words: &'t mut impl WriteBuffer, ) -> Result, Error> where - RXBUF: WriteBuffer, + Self: DmaSupportRx, { self.start_rx_transfer(words, true)?; Ok(DmaTransferRxCircular::new(self)) @@ -820,20 +704,27 @@ mod private { Standard, I2S_LL_MCLK_DIVIDER_MAX, }; - #[cfg(not(any(esp32, esp32s3)))] + #[cfg(not(i2s1))] use crate::peripherals::i2s0::RegisterBlock; // on ESP32-S3 I2S1 doesn't support all features - use that to avoid using those features // by accident - #[cfg(any(esp32, esp32s3))] + #[cfg(i2s1)] use crate::peripherals::{i2s1::RegisterBlock, I2S1}; use crate::{ - dma::{ChannelRx, ChannelTx, DmaDescriptor, DmaEligible, DmaPeripheral, PeripheralMarker}, + dma::{ + ChannelRx, + ChannelTx, + DescriptorChain, + DmaDescriptor, + DmaEligible, + PeripheralMarker, + }, gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput}, interrupt::InterruptHandler, into_ref, + peripheral::PeripheralRef, peripherals::I2S0, private, - system::Peripheral, Mode, }; @@ -842,7 +733,7 @@ mod private { T: RegisterAccess, DmaMode: Mode, { - pub register_access: PhantomData, + pub i2s: PeripheralRef<'d, T>, pub tx_channel: ChannelTx<'d, T::Dma>, pub descriptors: &'static mut [DmaDescriptor], pub(crate) phantom: PhantomData, @@ -854,7 +745,12 @@ mod private { DmaMode: Mode, { pub fn build(self) -> I2sTx<'d, T, DmaMode> { - I2sTx::new(self.tx_channel, self.descriptors) + I2sTx { + i2s: self.i2s, + tx_channel: self.tx_channel, + tx_chain: DescriptorChain::new(self.descriptors), + phantom: PhantomData, + } } pub fn with_bclk

(self, pin: impl crate::peripheral::Peripheral

+ 'd) -> Self @@ -863,7 +759,7 @@ mod private { { into_ref!(pin); pin.set_to_push_pull_output(private::Internal); - pin.connect_peripheral_to_output(T::bclk_signal(), private::Internal); + pin.connect_peripheral_to_output(self.i2s.bclk_signal(), private::Internal); self } @@ -874,7 +770,7 @@ mod private { { into_ref!(pin); pin.set_to_push_pull_output(private::Internal); - pin.connect_peripheral_to_output(T::ws_signal(), private::Internal); + pin.connect_peripheral_to_output(self.i2s.ws_signal(), private::Internal); self } @@ -885,7 +781,7 @@ mod private { { into_ref!(pin); pin.set_to_push_pull_output(private::Internal); - pin.connect_peripheral_to_output(T::dout_signal(), private::Internal); + pin.connect_peripheral_to_output(self.i2s.dout_signal(), private::Internal); self } @@ -896,7 +792,7 @@ mod private { T: RegisterAccess, DmaMode: Mode, { - pub register_access: PhantomData, + pub i2s: PeripheralRef<'d, T>, pub rx_channel: ChannelRx<'d, T::Dma>, pub descriptors: &'static mut [DmaDescriptor], pub(crate) phantom: PhantomData, @@ -908,7 +804,12 @@ mod private { DmaMode: Mode, { pub fn build(self) -> I2sRx<'d, T, DmaMode> { - I2sRx::new(self.rx_channel, self.descriptors) + I2sRx { + i2s: self.i2s, + rx_channel: self.rx_channel, + rx_chain: DescriptorChain::new(self.descriptors), + phantom: PhantomData, + } } pub fn with_bclk

(self, pin: impl crate::peripheral::Peripheral

+ 'd) -> Self @@ -917,7 +818,7 @@ mod private { { into_ref!(pin); pin.set_to_push_pull_output(private::Internal); - pin.connect_peripheral_to_output(T::bclk_rx_signal(), private::Internal); + pin.connect_peripheral_to_output(self.i2s.bclk_rx_signal(), private::Internal); self } @@ -928,7 +829,7 @@ mod private { { into_ref!(pin); pin.set_to_push_pull_output(private::Internal); - pin.connect_peripheral_to_output(T::ws_rx_signal(), private::Internal); + pin.connect_peripheral_to_output(self.i2s.ws_rx_signal(), private::Internal); self } @@ -939,42 +840,34 @@ mod private { { into_ref!(pin); pin.init_input(crate::gpio::Pull::None, private::Internal); - pin.connect_input_to_peripheral(T::din_signal(), private::Internal); + pin.connect_input_to_peripheral(self.i2s.din_signal(), private::Internal); self } } - pub trait Signals { - fn get_peripheral() -> Peripheral; - - fn get_dma_peripheral() -> DmaPeripheral; - - fn mclk_signal() -> OutputSignal; - - fn bclk_signal() -> OutputSignal; - - fn ws_signal() -> OutputSignal; - - fn dout_signal() -> OutputSignal; - - fn bclk_rx_signal() -> OutputSignal; - - fn ws_rx_signal() -> OutputSignal; - - fn din_signal() -> InputSignal; + pub trait RegBlock: + crate::peripheral::Peripheral

+ PeripheralMarker + DmaEligible + { + fn register_block(&self) -> &RegisterBlock; } - pub trait RegBlock: PeripheralMarker + DmaEligible { - fn register_block() -> &'static RegisterBlock; + pub trait Signals: RegBlock { + fn mclk_signal(&self) -> OutputSignal; + fn bclk_signal(&self) -> OutputSignal; + fn ws_signal(&self) -> OutputSignal; + fn dout_signal(&self) -> OutputSignal; + fn bclk_rx_signal(&self) -> OutputSignal; + fn ws_rx_signal(&self) -> OutputSignal; + fn din_signal(&self) -> InputSignal; } #[cfg(any(esp32, esp32s2))] pub trait RegisterAccessPrivate: Signals + RegBlock { - fn set_interrupt_handler(handler: InterruptHandler); + fn set_interrupt_handler(&self, handler: InterruptHandler); - fn enable_listen(interrupts: EnumSet, enable: bool) { - let reg_block = Self::register_block(); + fn enable_listen(&self, interrupts: EnumSet, enable: bool) { + let reg_block = self.register_block(); reg_block.int_ena().modify(|_, w| { for interrupt in interrupts { @@ -987,17 +880,17 @@ mod private { }); } - fn listen(interrupts: impl Into>) { - Self::enable_listen(interrupts.into(), true); + fn listen(&self, interrupts: impl Into>) { + self.enable_listen(interrupts.into(), true); } - fn unlisten(interrupts: impl Into>) { - Self::enable_listen(interrupts.into(), false); + fn unlisten(&self, interrupts: impl Into>) { + self.enable_listen(interrupts.into(), false); } - fn interrupts() -> EnumSet { + fn interrupts(&self) -> EnumSet { let mut res = EnumSet::new(); - let reg_block = Self::register_block(); + let reg_block = self.register_block(); let ints = reg_block.int_st().read(); if ints.rx_hung().bit() { @@ -1010,23 +903,22 @@ mod private { res } - fn clear_interrupts(interrupts: EnumSet) { - let reg_block = Self::register_block(); + fn clear_interrupts(&self, interrupts: EnumSet) { + let reg_block = self.register_block(); - for interrupt in interrupts { - match interrupt { - I2sInterrupt::RxHung => reg_block - .int_clr() - .write(|w| w.rx_hung().clear_bit_by_one()), - I2sInterrupt::TxHung => reg_block - .int_clr() - .write(|w| w.tx_hung().clear_bit_by_one()), + reg_block.int_clr().write(|w| { + for interrupt in interrupts { + match interrupt { + I2sInterrupt::RxHung => w.rx_hung().clear_bit_by_one(), + I2sInterrupt::TxHung => w.tx_hung().clear_bit_by_one(), + }; } - } + w + }); } - fn set_clock(clock_settings: I2sClockDividers) { - let i2s = Self::register_block(); + fn set_clock(&self, clock_settings: I2sClockDividers) { + let i2s = self.register_block(); i2s.clkm_conf().modify(|r, w| unsafe { w.bits(r.bits() | (crate::soc::constants::I2S_DEFAULT_CLK_SRC << 21)) @@ -1052,8 +944,8 @@ mod private { }); } - fn configure(_standard: &Standard, data_format: &DataFormat) { - let i2s = Self::register_block(); + fn configure(&self, _standard: &Standard, data_format: &DataFormat) { + let i2s = self.register_block(); let fifo_mod = match data_format { DataFormat::Data32Channel32 => 2, @@ -1120,18 +1012,18 @@ mod private { }); } - fn set_master() { - let i2s = Self::register_block(); + fn set_master(&self) { + let i2s = self.register_block(); i2s.conf() .modify(|_, w| w.rx_slave_mod().clear_bit().tx_slave_mod().clear_bit()); } - fn update() { + fn update(&self) { // nothing to do } - fn reset_tx() { - let i2s = Self::register_block(); + fn reset_tx(&self) { + let i2s = self.register_block(); i2s.conf().modify(|_, w| { w.tx_reset().set_bit(); w.tx_fifo_reset().set_bit() @@ -1150,8 +1042,8 @@ mod private { }); } - fn tx_start() { - let i2s = Self::register_block(); + fn tx_start(&self) { + let i2s = self.register_block(); i2s.conf().modify(|_, w| w.tx_start().set_bit()); while i2s.state().read().tx_idle().bit_is_set() { @@ -1159,13 +1051,13 @@ mod private { } } - fn tx_stop() { - let i2s = Self::register_block(); + fn tx_stop(&self) { + let i2s = self.register_block(); i2s.conf().modify(|_, w| w.tx_start().clear_bit()); } - fn wait_for_tx_done() { - let i2s = Self::register_block(); + fn wait_for_tx_done(&self) { + let i2s = self.register_block(); while i2s.state().read().tx_idle().bit_is_clear() { // wait } @@ -1173,8 +1065,8 @@ mod private { i2s.conf().modify(|_, w| w.tx_start().clear_bit()); } - fn reset_rx() { - let i2s = Self::register_block(); + fn reset_rx(&self) { + let i2s = self.register_block(); i2s.conf().modify(|_, w| { w.rx_reset().set_bit(); w.rx_fifo_reset().set_bit() @@ -1193,8 +1085,8 @@ mod private { }); } - fn rx_start(len: usize) { - let i2s = Self::register_block(); + fn rx_start(&self, len: usize) { + let i2s = self.register_block(); i2s.int_clr().write(|w| w.in_suc_eof().clear_bit_by_one()); @@ -1213,8 +1105,8 @@ mod private { i2s.conf().modify(|_, w| w.rx_start().set_bit()); } - fn wait_for_rx_done() { - let i2s = Self::register_block(); + fn wait_for_rx_done(&self) { + let i2s = self.register_block(); while i2s.int_raw().read().in_suc_eof().bit_is_clear() { // wait } @@ -1225,10 +1117,10 @@ mod private { #[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))] pub trait RegisterAccessPrivate: Signals + RegBlock { - fn set_interrupt_handler(handler: InterruptHandler); + fn set_interrupt_handler(&self, handler: InterruptHandler); - fn enable_listen(interrupts: EnumSet, enable: bool) { - let reg_block = Self::register_block(); + fn enable_listen(&self, interrupts: EnumSet, enable: bool) { + let reg_block = self.register_block(); reg_block.int_ena().modify(|_, w| { for interrupt in interrupts { @@ -1243,17 +1135,17 @@ mod private { }); } - fn listen(interrupts: impl Into>) { - Self::enable_listen(interrupts.into(), true); + fn listen(&self, interrupts: impl Into>) { + self.enable_listen(interrupts.into(), true); } - fn unlisten(interrupts: impl Into>) { - Self::enable_listen(interrupts.into(), false); + fn unlisten(&self, interrupts: impl Into>) { + self.enable_listen(interrupts.into(), false); } - fn interrupts() -> EnumSet { + fn interrupts(&self) -> EnumSet { let mut res = EnumSet::new(); - let reg_block = Self::register_block(); + let reg_block = self.register_block(); let ints = reg_block.int_st().read(); if ints.rx_hung().bit() { @@ -1272,8 +1164,8 @@ mod private { res } - fn clear_interrupts(interrupts: EnumSet) { - let reg_block = Self::register_block(); + fn clear_interrupts(&self, interrupts: EnumSet) { + let reg_block = self.register_block(); reg_block.int_clr().write(|w| { for interrupt in interrupts { @@ -1289,8 +1181,8 @@ mod private { } #[cfg(any(esp32c3, esp32s3))] - fn set_clock(clock_settings: I2sClockDividers) { - let i2s = Self::register_block(); + fn set_clock(&self, clock_settings: I2sClockDividers) { + let i2s = self.register_block(); let clkm_div_x: u32; let clkm_div_y: u32; @@ -1339,14 +1231,12 @@ mod private { }); i2s.tx_clkm_conf().modify(|_, w| unsafe { - w.clk_en() - .set_bit() - .tx_clk_active() - .set_bit() - .tx_clk_sel() + w.clk_en().set_bit(); + w.tx_clk_active().set_bit(); + w.tx_clk_sel() .bits(crate::soc::constants::I2S_DEFAULT_CLK_SRC) // for now fixed at 160MHz - .tx_clkm_div_num() - .bits(clock_settings.mclk_divider as u8) + ; + w.tx_clkm_div_num().bits(clock_settings.mclk_divider as u8) }); i2s.tx_conf1().modify(|_, w| unsafe { @@ -1377,8 +1267,8 @@ mod private { } #[cfg(any(esp32c6, esp32h2))] - fn set_clock(clock_settings: I2sClockDividers) { - let i2s = Self::register_block(); + fn set_clock(&self, clock_settings: I2sClockDividers) { + let i2s = self.register_block(); let pcr = unsafe { &*crate::peripherals::PCR::PTR }; // I2S clocks are configured via PCR let clkm_div_x: u32; @@ -1475,8 +1365,8 @@ mod private { }); } - fn configure(_standard: &Standard, data_format: &DataFormat) { - let i2s = Self::register_block(); + fn configure(&self, _standard: &Standard, data_format: &DataFormat) { + let i2s = self.register_block(); #[allow(clippy::useless_conversion)] i2s.tx_conf1().modify(|_, w| unsafe { @@ -1568,14 +1458,14 @@ mod private { }); } - fn set_master() { - let i2s = Self::register_block(); + fn set_master(&self) { + let i2s = self.register_block(); i2s.tx_conf().modify(|_, w| w.tx_slave_mod().clear_bit()); i2s.rx_conf().modify(|_, w| w.rx_slave_mod().clear_bit()); } - fn update() { - let i2s = Self::register_block(); + fn update(&self) { + let i2s = self.register_block(); i2s.tx_conf().modify(|_, w| w.tx_update().clear_bit()); i2s.tx_conf().modify(|_, w| w.tx_update().set_bit()); @@ -1583,8 +1473,8 @@ mod private { i2s.rx_conf().modify(|_, w| w.rx_update().set_bit()); } - fn reset_tx() { - let i2s = Self::register_block(); + fn reset_tx(&self) { + let i2s = self.register_block(); i2s.tx_conf().modify(|_, w| { w.tx_reset().set_bit(); w.tx_fifo_reset().set_bit() @@ -1600,18 +1490,18 @@ mod private { }); } - fn tx_start() { - let i2s = Self::register_block(); + fn tx_start(&self) { + let i2s = self.register_block(); i2s.tx_conf().modify(|_, w| w.tx_start().set_bit()); } - fn tx_stop() { - let i2s = Self::register_block(); + fn tx_stop(&self) { + let i2s = self.register_block(); i2s.tx_conf().modify(|_, w| w.tx_start().clear_bit()); } - fn wait_for_tx_done() { - let i2s = Self::register_block(); + fn wait_for_tx_done(&self) { + let i2s = self.register_block(); while i2s.state().read().tx_idle().bit_is_clear() { // wait } @@ -1619,8 +1509,8 @@ mod private { i2s.tx_conf().modify(|_, w| w.tx_start().clear_bit()); } - fn reset_rx() { - let i2s = Self::register_block(); + fn reset_rx(&self) { + let i2s = self.register_block(); i2s.rx_conf().modify(|_, w| { w.rx_reset().set_bit(); w.rx_fifo_reset().set_bit() @@ -1636,17 +1526,17 @@ mod private { }); } - fn rx_start(len: usize) { + fn rx_start(&self, len: usize) { let len = len - 1; - let i2s = Self::register_block(); + let i2s = self.register_block(); i2s.rxeof_num() .write(|w| unsafe { w.rx_eof_num().bits(len as u16) }); i2s.rx_conf().modify(|_, w| w.rx_start().set_bit()); } - fn wait_for_rx_done() { - let i2s = Self::register_block(); + fn wait_for_rx_done(&self) { + let i2s = self.register_block(); while i2s.int_raw().read().rx_done().bit_is_clear() { // wait } @@ -1655,246 +1545,111 @@ mod private { } } - #[cfg(any(esp32c3, esp32c6, esp32h2))] - impl Signals for crate::peripherals::I2S0 { - fn get_peripheral() -> Peripheral { - Peripheral::I2s0 - } - - fn get_dma_peripheral() -> DmaPeripheral { - DmaPeripheral::I2s0 - } - - fn mclk_signal() -> OutputSignal { - OutputSignal::I2S_MCLK - } - - fn bclk_signal() -> OutputSignal { - OutputSignal::I2SO_BCK - } - - fn ws_signal() -> OutputSignal { - OutputSignal::I2SO_WS - } - - fn dout_signal() -> OutputSignal { - OutputSignal::I2SO_SD - } - - fn bclk_rx_signal() -> OutputSignal { - OutputSignal::I2SI_BCK - } - - fn ws_rx_signal() -> OutputSignal { - OutputSignal::I2SI_WS - } - - fn din_signal() -> InputSignal { - InputSignal::I2SI_SD - } - } - - #[cfg(esp32s3)] - impl Signals for crate::peripherals::I2S0 { - fn get_peripheral() -> Peripheral { - Peripheral::I2s0 - } - - fn get_dma_peripheral() -> DmaPeripheral { - DmaPeripheral::I2s0 - } - - fn mclk_signal() -> OutputSignal { - OutputSignal::I2S0_MCLK - } - - fn bclk_signal() -> OutputSignal { - OutputSignal::I2S0O_BCK - } - - fn ws_signal() -> OutputSignal { - OutputSignal::I2S0O_WS - } - - fn dout_signal() -> OutputSignal { - OutputSignal::I2S0O_SD - } - - fn bclk_rx_signal() -> OutputSignal { - OutputSignal::I2S0I_BCK - } - - fn ws_rx_signal() -> OutputSignal { - OutputSignal::I2S0I_WS - } - - fn din_signal() -> InputSignal { - InputSignal::I2S0I_SD - } - } - - #[cfg(esp32s3)] - impl Signals for crate::peripherals::I2S1 { - fn get_peripheral() -> Peripheral { - Peripheral::I2s1 - } - - fn get_dma_peripheral() -> DmaPeripheral { - DmaPeripheral::I2s1 - } - - fn mclk_signal() -> OutputSignal { - OutputSignal::I2S1_MCLK - } - - fn bclk_signal() -> OutputSignal { - OutputSignal::I2S1O_BCK - } - - fn ws_signal() -> OutputSignal { - OutputSignal::I2S1O_WS - } - - fn dout_signal() -> OutputSignal { - OutputSignal::I2S1O_SD - } - - fn bclk_rx_signal() -> OutputSignal { - OutputSignal::I2S1I_BCK - } - - fn ws_rx_signal() -> OutputSignal { - OutputSignal::I2S1I_WS - } - - fn din_signal() -> InputSignal { - InputSignal::I2S1I_SD - } - } - - #[cfg(esp32)] - impl Signals for crate::peripherals::I2S0 { - fn get_peripheral() -> Peripheral { - Peripheral::I2s0 - } - - fn get_dma_peripheral() -> DmaPeripheral { - DmaPeripheral::I2s0 - } - - fn mclk_signal() -> OutputSignal { - panic!("MCLK currently not supported on ESP32"); - } - - fn bclk_signal() -> OutputSignal { - OutputSignal::I2S0O_BCK - } - - fn ws_signal() -> OutputSignal { - OutputSignal::I2S0O_WS - } - - fn dout_signal() -> OutputSignal { - OutputSignal::I2S0O_DATA_23 - } - - fn bclk_rx_signal() -> OutputSignal { - OutputSignal::I2S0I_BCK - } - - fn ws_rx_signal() -> OutputSignal { - OutputSignal::I2S0I_WS - } - - fn din_signal() -> InputSignal { - InputSignal::I2S0I_DATA_15 - } - } - - #[cfg(esp32)] - impl Signals for crate::peripherals::I2S1 { - fn get_peripheral() -> Peripheral { - Peripheral::I2s1 - } - - fn get_dma_peripheral() -> DmaPeripheral { - DmaPeripheral::I2s1 - } - - fn mclk_signal() -> OutputSignal { - panic!("MCLK currently not supported on ESP32"); - } - - fn bclk_signal() -> OutputSignal { - OutputSignal::I2S1O_BCK - } - - fn ws_signal() -> OutputSignal { - OutputSignal::I2S1O_WS - } - - fn dout_signal() -> OutputSignal { - OutputSignal::I2S1O_DATA_23 - } - - fn bclk_rx_signal() -> OutputSignal { - OutputSignal::I2S1I_BCK - } - - fn ws_rx_signal() -> OutputSignal { - OutputSignal::I2S1I_WS - } - - fn din_signal() -> InputSignal { - InputSignal::I2S1I_DATA_15 - } - } - - #[cfg(esp32s2)] - impl Signals for crate::peripherals::I2S0 { - fn get_peripheral() -> Peripheral { - Peripheral::I2s0 - } - - fn get_dma_peripheral() -> DmaPeripheral { - DmaPeripheral::I2s0 - } - - fn mclk_signal() -> OutputSignal { - OutputSignal::CLK_I2S - } - - fn bclk_signal() -> OutputSignal { - OutputSignal::I2S0O_BCK - } - - fn ws_signal() -> OutputSignal { - OutputSignal::I2S0O_WS - } - - fn dout_signal() -> OutputSignal { - OutputSignal::I2S0O_DATA_OUT23 - } - - fn bclk_rx_signal() -> OutputSignal { - OutputSignal::I2S0I_BCK - } - - fn ws_rx_signal() -> OutputSignal { - OutputSignal::I2S0I_WS - } - - fn din_signal() -> InputSignal { - InputSignal::I2S0I_DATA_IN15 - } - } - impl PeripheralMarker for I2S0 { fn peripheral(&self) -> crate::system::Peripheral { crate::system::Peripheral::I2s0 } } + impl RegBlock for I2S0 { + fn register_block(&self) -> &RegisterBlock { + unsafe { &*I2S0::PTR.cast::() } + } + } + + impl RegisterAccessPrivate for I2S0 { + fn set_interrupt_handler(&self, handler: InterruptHandler) { + unsafe { crate::peripherals::I2S0::steal() }.bind_i2s0_interrupt(handler.handler()); + crate::interrupt::enable(crate::peripherals::Interrupt::I2S0, handler.priority()) + .unwrap(); + } + } + + #[cfg(i2s0)] + impl Signals for crate::peripherals::I2S0 { + fn mclk_signal(&self) -> OutputSignal { + cfg_if::cfg_if! { + if #[cfg(esp32)] { + panic!("MCLK currently not supported on ESP32"); + } else if #[cfg(esp32s2)] { + OutputSignal::CLK_I2S + } else if #[cfg(esp32s3)] { + OutputSignal::I2S0_MCLK + } else { + OutputSignal::I2S_MCLK + } + } + } + + fn bclk_signal(&self) -> OutputSignal { + cfg_if::cfg_if! { + if #[cfg(any(esp32, esp32s2, esp32s3))] { + OutputSignal::I2S0O_BCK + } else { + OutputSignal::I2SO_BCK + } + } + } + + fn ws_signal(&self) -> OutputSignal { + cfg_if::cfg_if! { + if #[cfg(any(esp32, esp32s2, esp32s3))] { + OutputSignal::I2S0O_WS + } else { + OutputSignal::I2SO_WS + } + } + } + + fn dout_signal(&self) -> OutputSignal { + cfg_if::cfg_if! { + if #[cfg(esp32)] { + OutputSignal::I2S0O_DATA_23 + } else if #[cfg(esp32s2)] { + OutputSignal::I2S0O_DATA_OUT23 + } else if #[cfg(esp32s3)] { + OutputSignal::I2S0O_SD + } else { + OutputSignal::I2SO_SD + } + } + } + + fn bclk_rx_signal(&self) -> OutputSignal { + cfg_if::cfg_if! { + if #[cfg(any(esp32, esp32s2, esp32s3))] { + OutputSignal::I2S0I_BCK + } else { + OutputSignal::I2SI_BCK + } + } + } + + fn ws_rx_signal(&self) -> OutputSignal { + cfg_if::cfg_if! { + if #[cfg(any(esp32, esp32s2, esp32s3))] { + OutputSignal::I2S0I_WS + } else { + OutputSignal::I2SI_WS + } + } + } + + fn din_signal(&self) -> InputSignal { + cfg_if::cfg_if! { + if #[cfg(esp32)] { + InputSignal::I2S0I_DATA_15 + } else if #[cfg(esp32s2)] { + InputSignal::I2S0I_DATA_IN15 + } else if #[cfg(esp32s3)] { + InputSignal::I2S0I_SD + } else { + InputSignal::I2SI_SD + } + } + } + } + #[cfg(i2s1)] impl PeripheralMarker for I2S1 { fn peripheral(&self) -> crate::system::Peripheral { @@ -1902,36 +1657,71 @@ mod private { } } - impl RegBlock for I2S0 { - fn register_block() -> &'static RegisterBlock { - unsafe { &*I2S0::PTR.cast::() } - } - } - #[cfg(i2s1)] impl RegBlock for I2S1 { - fn register_block() -> &'static RegisterBlock { + fn register_block(&self) -> &RegisterBlock { unsafe { &*I2S1::PTR.cast::() } } } - impl RegisterAccessPrivate for I2S0 { - fn set_interrupt_handler(handler: InterruptHandler) { - unsafe { crate::peripherals::I2S0::steal() }.bind_i2s0_interrupt(handler.handler()); - crate::interrupt::enable(crate::peripherals::Interrupt::I2S0, handler.priority()) - .unwrap(); - } - } - #[cfg(i2s1)] impl RegisterAccessPrivate for I2S1 { - fn set_interrupt_handler(handler: InterruptHandler) { + fn set_interrupt_handler(&self, handler: InterruptHandler) { unsafe { crate::peripherals::I2S1::steal() }.bind_i2s1_interrupt(handler.handler()); crate::interrupt::enable(crate::peripherals::Interrupt::I2S1, handler.priority()) .unwrap(); } } + #[cfg(i2s1)] + impl Signals for crate::peripherals::I2S1 { + fn mclk_signal(&self) -> OutputSignal { + cfg_if::cfg_if! { + if #[cfg(esp32)] { + panic!("MCLK currently not supported on ESP32"); + } else { + OutputSignal::I2S1_MCLK + } + } + } + + fn bclk_signal(&self) -> OutputSignal { + OutputSignal::I2S1O_BCK + } + + fn ws_signal(&self) -> OutputSignal { + OutputSignal::I2S1O_WS + } + + fn dout_signal(&self) -> OutputSignal { + cfg_if::cfg_if! { + if #[cfg(esp32)] { + OutputSignal::I2S1O_DATA_23 + } else { + OutputSignal::I2S1O_SD + } + } + } + + fn bclk_rx_signal(&self) -> OutputSignal { + OutputSignal::I2S1I_BCK + } + + fn ws_rx_signal(&self) -> OutputSignal { + OutputSignal::I2S1I_WS + } + + fn din_signal(&self) -> InputSignal { + cfg_if::cfg_if! { + if #[cfg(esp32)] { + InputSignal::I2S1I_DATA_15 + } else { + InputSignal::I2S1I_SD + } + } + } + } + pub struct I2sClockDividers { mclk_divider: u32, bclk_divider: u32, @@ -2024,31 +1814,15 @@ pub mod asynch { Async, }; - /// Initiate an async DMA tx transfer - pub trait I2sWriteDmaAsync<'d, T> + impl<'d, T> I2sTx<'d, T, Async> where T: RegisterAccess, { /// One-shot write I2S. - async fn write_dma_async(&mut self, words: &mut [u8]) -> Result<(), Error>; - - /// Continuously write to I2S. Returns [I2sWriteDmaTransferAsync] - fn write_dma_circular_async( - self, - words: TXBUF, - ) -> Result, Error> - where - TXBUF: ReadBuffer; - } - - impl<'d, T> I2sWriteDmaAsync<'d, T> for super::I2sTx<'d, T, Async> - where - T: RegisterAccess, - { - async fn write_dma_async(&mut self, words: &mut [u8]) -> Result<(), Error> { + pub async fn write_dma_async(&mut self, words: &mut [u8]) -> Result<(), Error> { let (ptr, len) = (words.as_ptr(), words.len()); - T::reset_tx(); + self.i2s.reset_tx(); let future = DmaTxFuture::new(&mut self.tx_channel); @@ -2056,27 +1830,25 @@ pub mod asynch { self.tx_chain.fill_for_tx(false, ptr, len)?; future .tx - .prepare_transfer_without_start(T::get_dma_peripheral(), &self.tx_chain) + .prepare_transfer_without_start(self.i2s.dma_peripheral(), &self.tx_chain) .and_then(|_| future.tx.start_transfer())?; } - T::tx_start(); + self.i2s.tx_start(); future.await?; Ok(()) } - fn write_dma_circular_async( + /// Continuously write to I2S. Returns [I2sWriteDmaTransferAsync] + pub fn write_dma_circular_async( mut self, words: TXBUF, - ) -> Result, Error> - where - TXBUF: ReadBuffer, - { + ) -> Result, Error> { let (ptr, len) = unsafe { words.read_buffer() }; // Reset TX unit and TX FIFO - T::reset_tx(); + self.i2s.reset_tx(); // Enable corresponding interrupts if needed @@ -2084,14 +1856,14 @@ pub mod asynch { unsafe { self.tx_chain.fill_for_tx(true, ptr, len)?; self.tx_channel - .prepare_transfer_without_start(T::get_dma_peripheral(), &self.tx_chain) + .prepare_transfer_without_start(self.i2s.dma_peripheral(), &self.tx_chain) .and_then(|_| self.tx_channel.start_transfer())?; } // set I2S_TX_STOP_EN if needed // start: set I2S_TX_START - T::tx_start(); + self.i2s.tx_start(); let state = TxCircularState::new(&mut self.tx_chain); Ok(I2sWriteDmaTransferAsync { @@ -2152,28 +1924,12 @@ pub mod asynch { } } - /// Initiate an async DMA rx transfer - pub trait I2sReadDmaAsync<'d, T> + impl<'d, T> I2sRx<'d, T, Async> where T: RegisterAccess, { /// One-shot read I2S. - async fn read_dma_async(&mut self, words: &mut [u8]) -> Result<(), Error>; - - /// Continuously read from I2S. Returns [I2sReadDmaTransferAsync] - fn read_dma_circular_async( - self, - words: RXBUF, - ) -> Result, Error> - where - RXBUF: WriteBuffer; - } - - impl<'d, T> I2sReadDmaAsync<'d, T> for super::I2sRx<'d, T, Async> - where - T: RegisterAccess, - { - async fn read_dma_async(&mut self, words: &mut [u8]) -> Result<(), Error> { + pub async fn read_dma_async(&mut self, words: &mut [u8]) -> Result<(), Error> { let (ptr, len) = (words.as_mut_ptr(), words.len()); if len % 4 != 0 { @@ -2181,7 +1937,7 @@ pub mod asynch { } // Reset RX unit and RX FIFO - T::reset_rx(); + self.i2s.reset_rx(); let future = DmaRxFuture::new(&mut self.rx_channel); @@ -2190,19 +1946,20 @@ pub mod asynch { self.rx_chain.fill_for_rx(false, ptr, len)?; future .rx - .prepare_transfer_without_start(T::get_dma_peripheral(), &self.rx_chain) + .prepare_transfer_without_start(self.i2s.dma_peripheral(), &self.rx_chain) .and_then(|_| future.rx.start_transfer())?; } // start: set I2S_RX_START - T::rx_start(len); + self.i2s.rx_start(len); future.await?; Ok(()) } - fn read_dma_circular_async( + /// Continuously read from I2S. Returns [I2sReadDmaTransferAsync] + pub fn read_dma_circular_async( mut self, mut words: RXBUF, ) -> Result, Error> @@ -2216,7 +1973,7 @@ pub mod asynch { } // Reset RX unit and RX FIFO - T::reset_rx(); + self.i2s.reset_rx(); // Enable corresponding interrupts if needed @@ -2224,12 +1981,12 @@ pub mod asynch { unsafe { self.rx_chain.fill_for_rx(true, ptr, len)?; self.rx_channel - .prepare_transfer_without_start(T::get_dma_peripheral(), &self.rx_chain) + .prepare_transfer_without_start(self.i2s.dma_peripheral(), &self.rx_chain) .and_then(|_| self.rx_channel.start_transfer())?; } // start: set I2S_RX_START - T::rx_start(len); + self.i2s.rx_start(len); let state = RxCircularState::new(&mut self.rx_chain); Ok(I2sReadDmaTransferAsync { diff --git a/examples/src/bin/embassy_i2s_read.rs b/examples/src/bin/embassy_i2s_read.rs index 8c1949a75..17c48383c 100644 --- a/examples/src/bin/embassy_i2s_read.rs +++ b/examples/src/bin/embassy_i2s_read.rs @@ -23,7 +23,7 @@ use esp_hal::{ dma::{Dma, DmaPriority}, dma_buffers, gpio::Io, - i2s::{asynch::*, DataFormat, I2s, Standard}, + i2s::{DataFormat, I2s, Standard}, prelude::*, timer::timg::TimerGroup, }; diff --git a/examples/src/bin/embassy_i2s_sound.rs b/examples/src/bin/embassy_i2s_sound.rs index cbea6965f..50660d818 100644 --- a/examples/src/bin/embassy_i2s_sound.rs +++ b/examples/src/bin/embassy_i2s_sound.rs @@ -37,7 +37,7 @@ use esp_hal::{ dma::{Dma, DmaPriority}, dma_buffers, gpio::Io, - i2s::{asynch::*, DataFormat, I2s, Standard}, + i2s::{DataFormat, I2s, Standard}, prelude::*, timer::timg::TimerGroup, }; diff --git a/examples/src/bin/i2s_read.rs b/examples/src/bin/i2s_read.rs index 0ad0f0619..30f453612 100644 --- a/examples/src/bin/i2s_read.rs +++ b/examples/src/bin/i2s_read.rs @@ -21,7 +21,7 @@ use esp_hal::{ dma::{Dma, DmaPriority}, dma_buffers, gpio::Io, - i2s::{DataFormat, I2s, I2sReadDma, Standard}, + i2s::{DataFormat, I2s, Standard}, prelude::*, }; use esp_println::println; diff --git a/examples/src/bin/i2s_sound.rs b/examples/src/bin/i2s_sound.rs index 060bbdc63..e998928b7 100644 --- a/examples/src/bin/i2s_sound.rs +++ b/examples/src/bin/i2s_sound.rs @@ -35,7 +35,7 @@ use esp_hal::{ dma::{Dma, DmaPriority}, dma_buffers, gpio::Io, - i2s::{DataFormat, I2s, I2sWriteDma, Standard}, + i2s::{DataFormat, I2s, Standard}, prelude::*, }; diff --git a/hil-test/tests/i2s.rs b/hil-test/tests/i2s.rs index a9351bd51..1146da5dc 100644 --- a/hil-test/tests/i2s.rs +++ b/hil-test/tests/i2s.rs @@ -14,7 +14,7 @@ use esp_hal::{ dma::{Dma, DmaPriority}, dma_buffers, gpio::{Io, NoPin}, - i2s::{asynch::*, DataFormat, I2s, I2sReadDma, I2sTx, I2sWriteDma, Standard}, + i2s::{DataFormat, I2s, I2sTx, Standard}, peripherals::I2S0, prelude::*, Async,