diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 902605877dd..3c8429e7fdc 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial ESP32-P4 (chip revision v3.0+) support (#5400) - P4: Initial peripheral support for GPIO, UART, I2C, SPI, DMA, USB Serial/JTAG, eFuse, SYSTIMER (#5400) - P4: AP-HEX PSRAM driver stub with configurable HP L2MEM cache/RAM split via `ESP_HAL_CONFIG_L2_CACHE_SIZE` (#5400) +- C5 and C61: I2S support (#5483) ### Changed diff --git a/esp-hal/README.md b/esp-hal/README.md index d5c79d30d34..95a0427e617 100644 --- a/esp-hal/README.md +++ b/esp-hal/README.md @@ -80,7 +80,7 @@ For help getting started with this HAL, please refer to [The Rust on ESP Book] a | HMAC | | | ⚒️ | [❌][5166] [^1] | ⚒️ | | ⚒️ | ❌ | ⚒️ | ⚒️ | | I2C master | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ⚒️ | ✔️ | ✔️ | | I2C slave | [❌][1909] [^1] | | [❌][1909] [^1] | [❌][1909] [^1] | [❌][1909] [^1] | [❌][1909] [^1] | [❌][1909] [^1] | ❌ | [❌][1909] [^1] | [❌][1909] [^1] | -| I2S | ⚒️ | | ⚒️ | [❌][5172] [^1] | ⚒️ | [❌][5415] [^1] | ⚒️ | ❌ | ⚒️ | ⚒️ | +| I2S | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ❌ | ⚒️ | ⚒️ | | IEEE 802.15.4 | | | | ⚒️ | ⚒️ | | ⚒️ | | | | | Interrupts | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | IOMUX | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | @@ -141,8 +141,6 @@ For help getting started with this HAL, please refer to [The Rust on ESP Book] a [5169]: https://github.com/esp-rs/esp-hal/issues/5169 [5170]: https://github.com/esp-rs/esp-hal/issues/5170 [5171]: https://github.com/esp-rs/esp-hal/issues/5171 -[5172]: https://github.com/esp-rs/esp-hal/issues/5172 -[5415]: https://github.com/esp-rs/esp-hal/issues/5415 [5417]: https://github.com/esp-rs/esp-hal/issues/5417 [5418]: https://github.com/esp-rs/esp-hal/issues/5418 [5419]: https://github.com/esp-rs/esp-hal/issues/5419 diff --git a/esp-hal/src/dma/mod.rs b/esp-hal/src/dma/mod.rs index 01b6fd705d7..95b8603b344 100644 --- a/esp-hal/src/dma/mod.rs +++ b/esp-hal/src/dma/mod.rs @@ -2825,7 +2825,7 @@ pub(crate) mod asynch { const FAILURE_INTERRUPTS: EnumSet = enum_set!(DmaTxInterrupt::DescriptorError); - #[cfg_attr(any(esp32c2, esp32c61), expect(dead_code))] + #[cfg_attr(esp32c2, expect(dead_code))] pub fn new(tx: &'a mut ChannelTx) -> Self { Self { tx } } diff --git a/esp-hal/src/i2s/master.rs b/esp-hal/src/i2s/master.rs index c9b2bcea47c..2e8ac6d1402 100644 --- a/esp-hal/src/i2s/master.rs +++ b/esp-hal/src/i2s/master.rs @@ -1,7 +1,7 @@ #![cfg_attr(docsrs, procmacros::doc_replace( "dma_channel" => { - cfg(any(esp32, esp32s2)) => "DMA_I2S0", - cfg(not(any(esp32, esp32s2))) => "DMA_CH0" + cfg(dma_kind = "pdma") => "DMA_I2S0", + cfg(dma_kind = "gdma") => "DMA_CH0" }, "mclk" => { cfg(not(esp32)) => "let i2s = i2s.with_mclk(peripherals.GPIO0);", @@ -153,19 +153,15 @@ pub enum I2sInterrupt { RxHung, /// Transmit buffer hung, indicating a stall in data transmission. TxHung, - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] /// Reception of data is complete. RxDone, - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] /// Transmission of data is complete. TxDone, } -#[cfg(any(esp32, esp32s2, esp32s3))] -pub(crate) const I2S_LL_MCLK_DIVIDER_BIT_WIDTH: usize = 6; - -#[cfg(any(esp32c3, esp32c6, esp32h2))] -pub(crate) const I2S_LL_MCLK_DIVIDER_BIT_WIDTH: usize = 9; +pub(crate) const I2S_LL_MCLK_DIVIDER_BIT_WIDTH: usize = property!("i2s.mclk_divider_bit_width"); pub(crate) const I2S_LL_MCLK_DIVIDER_MAX: usize = (1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1; @@ -200,7 +196,7 @@ impl From for Error { /// Supported data formats #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[cfg(not(any(esp32, esp32s2)))] +#[cfg(not(i2s_version = "1"))] pub enum DataFormat { /// 32-bit data width and 32-bit channel width. Data32Channel32, @@ -244,7 +240,7 @@ pub enum DataFormat { Data16Channel16, } -#[cfg(not(any(esp32, esp32s2)))] +#[cfg(not(i2s_version = "1"))] impl DataFormat { /// Returns the number of data bits for the selected data format. pub fn data_bits(&self) -> u8 { @@ -346,12 +342,12 @@ pub enum WsWidth { HalfFrame, /// Word select signal will be kept active for the length of the first channel (PCM long frame /// standard) - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] OneChannel, /// Word select signal will be kept active for a single BCLK cycle (PCM short frame standard) Bit, /// Word select signal will be kept active for the specified amount of bits(BCLK cycles) - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] Bits(u16), } @@ -412,7 +408,7 @@ impl Channels { /// let channels = Channels::new(6, 0b_001_001, None); /// # {after_snippet} /// ``` - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] pub const fn new(count: u8, mask: u16, fill: Option) -> Self { Self::new_impl(count, mask, fill) } @@ -423,7 +419,7 @@ impl Channels { Self { count, mask, fill } } - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] fn active_count(&self) -> u8 { self.mask.count_ones() as u8 } @@ -445,11 +441,11 @@ pub struct Config { signal_loopback: bool, /// The target sample rate - #[cfg(any(esp32, esp32s2))] + #[cfg(i2s_version = "1")] sample_rate: Rate, /// Format of the data - #[cfg(any(esp32, esp32s2))] + #[cfg(i2s_version = "1")] data_format: DataFormat, } @@ -482,7 +478,7 @@ impl Config { } /// TDM PCM long frame standard configuration with two 16-bit active channels - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] pub fn new_tdm_pcm_long() -> Self { Self { rx_config: UnitConfig::new_tdm_pcm_long(), @@ -493,7 +489,7 @@ impl Config { /// Assign the given value to the `sample_rate` field in both units. #[must_use] - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] pub fn with_sample_rate(mut self, sample_rate: Rate) -> Self { self.rx_config.sample_rate = sample_rate; self.tx_config.sample_rate = sample_rate; @@ -510,7 +506,7 @@ impl Config { /// Assign the given value to the `data_format` field in both units. #[must_use] - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] pub fn with_data_format(mut self, data_format: DataFormat) -> Self { self.rx_config.data_format = data_format; self.tx_config.data_format = data_format; @@ -551,7 +547,7 @@ impl Config { } /// Assign the given value to the `bit_order` field in both units. - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] #[must_use] pub fn with_bit_order(mut self, bit_order: BitOrder) -> Self { self.rx_config.bit_order = bit_order; @@ -559,7 +555,7 @@ impl Config { self } - #[cfg(any(esp32, esp32s2))] + #[cfg(i2s_version = "1")] fn calculate_clock(&self) -> I2sClockDividers { I2sClockDividers::new(self.sample_rate, 2, self.data_format.data_bits()) } @@ -578,9 +574,9 @@ impl Default for Config { rx_config: UnitConfig::new_tdm_philips(), tx_config: UnitConfig::new_tdm_philips(), signal_loopback: false, - #[cfg(any(esp32, esp32s2))] + #[cfg(i2s_version = "1")] sample_rate: Rate::from_hz(44100), - #[cfg(any(esp32, esp32s2))] + #[cfg(i2s_version = "1")] data_format: DataFormat::Data16Channel16, } } @@ -592,14 +588,14 @@ impl Default for Config { #[non_exhaustive] pub struct UnitConfig { /// The target sample rate - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] sample_rate: Rate, /// I2S channels configuration channels: Channels, /// Format of the data - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] data_format: DataFormat, /// Duration for which WS signal is kept active @@ -616,7 +612,7 @@ pub struct UnitConfig { endianness: Endianness, /// Bit order of the data - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] bit_order: BitOrder, } @@ -624,17 +620,17 @@ impl UnitConfig { /// TDM Philips standard configuration with two 16-bit active channels pub fn new_tdm_philips() -> Self { Self { - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] sample_rate: Rate::from_hz(44100), channels: Channels::STEREO, - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] data_format: DataFormat::Data16Channel16, ws_width: WsWidth::HalfFrame, ws_polarity: Polarity::ActiveLow, msb_shift: true, #[cfg(not(esp32))] endianness: Endianness::LittleEndian, - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] bit_order: BitOrder::MsbFirst, } } @@ -652,7 +648,7 @@ impl UnitConfig { } /// TDM PCM long frame standard configuration with two 16-bit active channels - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] pub fn new_tdm_pcm_long() -> Self { Self::new_tdm_philips() .with_ws_width(WsWidth::OneChannel) @@ -660,7 +656,7 @@ impl UnitConfig { } fn validate(&self) -> Result<(), ConfigError> { - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] if self.channels.active_count() == 0 || self.channels.count > 16 { return Err(ConfigError::ChannelsOutOfRange); } @@ -668,7 +664,7 @@ impl UnitConfig { Ok(()) } - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] fn calculate_ws_width(&self) -> Result { let ws_width = match self.ws_width { WsWidth::HalfFrame => { @@ -679,10 +675,7 @@ impl UnitConfig { WsWidth::Bits(bits) => bits, }; - #[cfg(not(esp32h2))] - const MAX_WS_WIDTH: u16 = 128; - #[cfg(esp32h2)] - const MAX_WS_WIDTH: u16 = 512; + const MAX_WS_WIDTH: u16 = property!("i2s.max_ws_width"); if !(1..=MAX_WS_WIDTH).contains(&ws_width) || ws_width > self.data_format.data_bits() as u16 * self.channels.count as u16 @@ -693,7 +686,7 @@ impl UnitConfig { Ok(ws_width) } - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] fn calculate_clock(&self) -> I2sClockDividers { I2sClockDividers::new( self.sample_rate, @@ -715,10 +708,10 @@ impl Default for UnitConfig { #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum ConfigError { /// Provided [Channels] configuration has no active channels or has over 16 total channels - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] ChannelsOutOfRange, /// Requested WS signal width is out of range - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] WsWidthOutOfRange, } @@ -728,14 +721,14 @@ impl core::fmt::Display for ConfigError { #[allow(unused_variables)] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match *self { - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] ConfigError::ChannelsOutOfRange => { write!( f, "Provided channels configuration has no active channels or has over 16 total channels" ) } - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(i2s_version = "1"))] ConfigError::WsWidthOutOfRange => { write!( f, @@ -852,14 +845,14 @@ impl<'d> I2s<'d, Blocking> { i2s: unsafe { i2s.clone_unchecked() }, rx_channel: channel.rx, guard: rx_guard, - #[cfg(any(esp32, esp32s2))] + #[cfg(i2s_version = "1")] data_format: config.data_format, }, i2s_tx: TxCreator { i2s, tx_channel: channel.tx, guard: tx_guard, - #[cfg(any(esp32, esp32s2))] + #[cfg(i2s_version = "1")] data_format: config.data_format, }, }) @@ -872,14 +865,14 @@ impl<'d> I2s<'d, Blocking> { i2s: self.i2s_rx.i2s, rx_channel: self.i2s_rx.rx_channel.into_async(), guard: self.i2s_rx.guard, - #[cfg(any(esp32, esp32s2))] + #[cfg(i2s_version = "1")] data_format: self.i2s_rx.data_format, }, i2s_tx: TxCreator { i2s: self.i2s_tx.i2s, tx_channel: self.i2s_tx.tx_channel.into_async(), guard: self.i2s_tx.guard, - #[cfg(any(esp32, esp32s2))] + #[cfg(i2s_version = "1")] data_format: self.i2s_tx.data_format, }, } @@ -988,7 +981,7 @@ where tx_channel: ChannelTx>>, tx_chain: DescriptorChain, _guard: PeripheralGuard, - #[cfg(any(esp32, esp32s2))] + #[cfg(i2s_version = "1")] data_format: DataFormat, } @@ -1079,7 +1072,7 @@ where /// Change the I2S Tx unit configuration. pub fn apply_config(&mut self, tx_config: &UnitConfig) -> Result<(), ConfigError> { cfg_if::cfg_if! { - if #[cfg(any(esp32, esp32s2))] { + if #[cfg(i2s_version = "1")] { self.i2s.configure_tx(tx_config, self.data_format) } else { self.i2s.configure_tx(tx_config) @@ -1131,7 +1124,7 @@ where rx_channel: ChannelRx>>, rx_chain: DescriptorChain, _guard: PeripheralGuard, - #[cfg(any(esp32, esp32s2))] + #[cfg(i2s_version = "1")] data_format: DataFormat, } @@ -1223,7 +1216,7 @@ where /// Change the I2S Rx unit configuration. pub fn apply_config(&mut self, rx_config: &UnitConfig) -> Result<(), ConfigError> { cfg_if::cfg_if! { - if #[cfg(any(esp32, esp32s2))] { + if #[cfg(i2s_version = "1")] { self.i2s.configure_rx(rx_config, self.data_format) } else { self.i2s.configure_rx(rx_config) @@ -1315,7 +1308,7 @@ mod private { pub i2s: AnyI2s<'d>, pub tx_channel: ChannelTx>>, pub(crate) guard: PeripheralGuard, - #[cfg(any(esp32, esp32s2))] + #[cfg(i2s_version = "1")] pub(crate) data_format: DataFormat, } @@ -1330,7 +1323,7 @@ mod private { tx_channel: self.tx_channel, tx_chain: DescriptorChain::new(descriptors), _guard: PeripheralGuard::new(peripheral), - #[cfg(any(esp32, esp32s2))] + #[cfg(i2s_version = "1")] data_format: self.data_format, } } @@ -1376,7 +1369,7 @@ mod private { pub i2s: AnyI2s<'d>, pub rx_channel: ChannelRx>>, pub(crate) guard: PeripheralGuard, - #[cfg(any(esp32, esp32s2))] + #[cfg(i2s_version = "1")] pub(crate) data_format: DataFormat, } @@ -1391,7 +1384,7 @@ mod private { rx_channel: self.rx_channel, rx_chain: DescriptorChain::new(descriptors), _guard: PeripheralGuard::new(peripheral), - #[cfg(any(esp32, esp32s2))] + #[cfg(i2s_version = "1")] data_format: self.data_format, } } @@ -1447,7 +1440,7 @@ mod private { fn din_signal(&self) -> InputSignal; } - #[cfg(any(esp32, esp32s2))] + #[cfg(i2s_version = "1")] pub trait RegisterAccessPrivate: Signals + RegBlock { fn enable_listen(&self, interrupts: EnumSet, enable: bool) { self.regs().int_ena().modify(|_, w| { @@ -1490,7 +1483,7 @@ mod private { fn set_clock(&self, clock_settings: I2sClockDividers) { self.regs().clkm_conf().modify(|r, w| unsafe { // select PLL_160M - w.bits(r.bits() | (crate::soc::constants::I2S_DEFAULT_CLK_SRC << 21)) + w.bits(r.bits() | (property!("i2s.default_clock_source") << 21)) }); #[cfg(esp32)] @@ -1758,7 +1751,7 @@ mod private { } } - #[cfg(any(esp32c3, esp32s3, esp32c6, esp32h2))] + #[cfg(not(i2s_version = "1"))] pub trait RegisterAccessPrivate: Signals + RegBlock { fn enable_listen(&self, interrupts: EnumSet, enable: bool) { self.regs().int_ena().modify(|_, w| { @@ -1816,7 +1809,7 @@ mod private { }); } - #[cfg(any(esp32c3, esp32s3))] + #[cfg(not(i2s_clock_configured_by_pcr))] fn set_tx_clock(&self, clock_settings: I2sClockDividers) { let clkm_div = clock_settings.mclk_dividers(); @@ -1831,18 +1824,23 @@ mod private { w.clk_en().set_bit(); w.tx_clk_active().set_bit(); // for now fixed at 160MHz - w.tx_clk_sel() - .bits(crate::soc::constants::I2S_DEFAULT_CLK_SRC); + w.tx_clk_sel().bits(property!("i2s.default_clock_source")); w.tx_clkm_div_num().bits(clock_settings.mclk_divider as u8) }); + #[cfg(i2s_version = "2")] self.regs().tx_conf1().modify(|_, w| unsafe { w.tx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) }); + #[cfg(i2s_version = "3")] + self.regs().tx_conf().modify(|_, w| unsafe { + w.tx_bck_div_num() + .bits((clock_settings.bclk_divider - 1) as u8) + }); } - #[cfg(any(esp32c3, esp32s3))] + #[cfg(not(i2s_clock_configured_by_pcr))] fn set_rx_clock(&self, clock_settings: I2sClockDividers) { let clkm_div = clock_settings.mclk_dividers(); @@ -1856,19 +1854,24 @@ mod private { self.regs().rx_clkm_conf().modify(|_, w| unsafe { w.rx_clk_active().set_bit(); // for now fixed at 160MHz - w.rx_clk_sel() - .bits(crate::soc::constants::I2S_DEFAULT_CLK_SRC); + w.rx_clk_sel().bits(property!("i2s.default_clock_source")); w.rx_clkm_div_num().bits(clock_settings.mclk_divider as u8); w.mclk_sel().bit(true) }); + #[cfg(i2s_version = "2")] self.regs().rx_conf1().modify(|_, w| unsafe { w.rx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) }); + #[cfg(i2s_version = "3")] + self.regs().rx_conf().modify(|_, w| unsafe { + w.rx_bck_div_num() + .bits((clock_settings.bclk_divider - 1) as u8) + }); } - #[cfg(any(esp32c6, esp32h2))] + #[cfg(i2s_clock_configured_by_pcr)] fn set_tx_clock(&self, clock_settings: I2sClockDividers) { // I2S clocks are configured via PCR use crate::peripherals::PCR; @@ -1886,24 +1889,25 @@ mod private { w.i2s_tx_clkm_en().set_bit(); // for now fixed at 160MHz for C6 and 96MHz for H2 w.i2s_tx_clkm_sel() - .bits(crate::soc::constants::I2S_DEFAULT_CLK_SRC); + .bits(property!("i2s.default_clock_source")); w.i2s_tx_clkm_div_num() .bits(clock_settings.mclk_divider as u8) }); - #[cfg(not(esp32h2))] + #[cfg(i2s_version = "2")] self.regs().tx_conf1().modify(|_, w| unsafe { w.tx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) }); - #[cfg(esp32h2)] + + #[cfg(i2s_version = "3")] self.regs().tx_conf().modify(|_, w| unsafe { w.tx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) }); } - #[cfg(any(esp32c6, esp32h2))] + #[cfg(i2s_clock_configured_by_pcr)] fn set_rx_clock(&self, clock_settings: I2sClockDividers) { // I2S clocks are configured via PCR use crate::peripherals::PCR; @@ -1921,17 +1925,19 @@ mod private { w.i2s_rx_clkm_en().set_bit(); // for now fixed at 160MHz for C6 and 96MHz for H2 w.i2s_rx_clkm_sel() - .bits(crate::soc::constants::I2S_DEFAULT_CLK_SRC); + .bits(property!("i2s.default_clock_source")); w.i2s_rx_clkm_div_num() .bits(clock_settings.mclk_divider as u8); w.i2s_mclk_sel().bit(true) }); - #[cfg(not(esp32h2))] + + #[cfg(i2s_version = "2")] self.regs().rx_conf1().modify(|_, w| unsafe { w.rx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) }); - #[cfg(esp32h2)] + + #[cfg(i2s_version = "3")] self.regs().rx_conf().modify(|_, w| unsafe { w.rx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) @@ -1963,7 +1969,7 @@ mod private { self.set_tx_clock(config.calculate_clock()); self.regs().tx_conf1().modify(|_, w| unsafe { - #[cfg(not(esp32h2))] + #[cfg(i2s_version = "2")] w.tx_msb_shift().bit(config.msb_shift); #[allow(clippy::useless_conversion)] w.tx_tdm_ws_width().bits((ws_width - 1).try_into().unwrap()); @@ -1982,7 +1988,7 @@ mod private { w.tx_tdm_en().set_bit(); w.tx_pdm_en().clear_bit(); w.tx_pcm_bypass().set_bit(); - #[cfg(esp32h2)] + #[cfg(i2s_version = "3")] w.tx_msb_shift().bit(config.msb_shift); w.tx_big_endian() .bit(config.endianness == Endianness::BigEndian); @@ -2029,7 +2035,7 @@ mod private { self.set_rx_clock(config.calculate_clock()); self.regs().rx_conf1().modify(|_, w| unsafe { - #[cfg(not(esp32h2))] + #[cfg(i2s_version = "2")] w.rx_msb_shift().bit(config.msb_shift); #[allow(clippy::useless_conversion)] w.rx_tdm_ws_width().bits((ws_width - 1).try_into().unwrap()); @@ -2047,7 +2053,7 @@ mod private { w.rx_tdm_en().set_bit(); w.rx_pdm_en().clear_bit(); w.rx_pcm_bypass().set_bit(); - #[cfg(esp32h2)] + #[cfg(i2s_version = "3")] w.rx_msb_shift().bit(config.msb_shift); w.rx_big_endian() .bit(config.endianness == Endianness::BigEndian); @@ -2193,7 +2199,7 @@ mod private { fn bclk_signal(&self) -> OutputSignal { cfg_if::cfg_if! { - if #[cfg(any(esp32, esp32s2, esp32s3))] { + if #[cfg(any(i2s_version = "1", esp32s3))] { OutputSignal::I2S0O_BCK } else { OutputSignal::I2SO_BCK @@ -2203,7 +2209,7 @@ mod private { fn ws_signal(&self) -> OutputSignal { cfg_if::cfg_if! { - if #[cfg(any(esp32, esp32s2, esp32s3))] { + if #[cfg(any(i2s_version = "1", esp32s3))] { OutputSignal::I2S0O_WS } else { OutputSignal::I2SO_WS @@ -2227,7 +2233,7 @@ mod private { fn bclk_rx_signal(&self) -> OutputSignal { cfg_if::cfg_if! { - if #[cfg(any(esp32, esp32s2, esp32s3))] { + if #[cfg(any(i2s_version = "1", esp32s3))] { OutputSignal::I2S0I_BCK } else { OutputSignal::I2SI_BCK @@ -2237,7 +2243,7 @@ mod private { fn ws_rx_signal(&self) -> OutputSignal { cfg_if::cfg_if! { - if #[cfg(any(esp32, esp32s2, esp32s3))] { + if #[cfg(any(i2s_version = "1", esp32s3))] { OutputSignal::I2S0I_WS } else { OutputSignal::I2SI_WS @@ -2388,7 +2394,7 @@ mod private { numerator: u32, } - #[cfg(any(esp32c3, esp32s3, esp32c6, esp32h2))] + #[cfg(not(i2s_version = "1"))] pub struct I2sMclkDividers { x: u32, y: u32, @@ -2406,7 +2412,7 @@ mod private { // If data_bits is a power of two, use 256 as the mclk_multiple // If data_bits is 24, use 192 (24 * 8) as the mclk_multiple let mclk_multiple = if data_bits == 24 { 192 } else { 256 }; - let sclk = crate::soc::constants::I2S_SCLK; // for now it's fixed 160MHz and 96MHz (just H2) + let sclk = crate::soc::i2s_sclk_frequency(); let rate = sample_rate.as_hz(); @@ -2460,7 +2466,7 @@ mod private { } } - #[cfg(any(esp32c3, esp32s3, esp32c6, esp32h2))] + #[cfg(not(i2s_version = "1"))] fn mclk_dividers(&self) -> I2sMclkDividers { let x; let y; diff --git a/esp-hal/src/i2s/parallel.rs b/esp-hal/src/i2s/parallel.rs index eeaf28babe2..d4a19aebb34 100644 --- a/esp-hal/src/i2s/parallel.rs +++ b/esp-hal/src/i2s/parallel.rs @@ -436,7 +436,7 @@ fn calculate_clock(sample_rate: Rate, data_bits: u8) -> I2sClockDividers { // main difference is we are using fixed-point arithmetic here // plus adjusted for parallel interface clocking - let sclk = crate::soc::constants::I2S_SCLK; // for now it's fixed 160MHz and 96MHz (just H2) + let sclk = crate::soc::i2s_sclk_frequency(); let rate = sample_rate.as_hz(); @@ -573,7 +573,7 @@ pub trait PrivateInstance: DmaEligible { fn set_clock(&self, clock_settings: I2sClockDividers) { self.regs().clkm_conf().modify(|r, w| unsafe { - w.bits(r.bits() | (crate::soc::constants::I2S_DEFAULT_CLK_SRC << 21)) + w.bits(r.bits() | (property!("i2s.default_clock_source") << 21)) // select PLL_160M }); diff --git a/esp-hal/src/soc/esp32/mod.rs b/esp-hal/src/soc/esp32/mod.rs index a839c2bb881..8478fc3de6c 100644 --- a/esp-hal/src/soc/esp32/mod.rs +++ b/esp-hal/src/soc/esp32/mod.rs @@ -16,12 +16,10 @@ pub(crate) mod regi2c; pub(crate) use esp32 as pac; +#[cfg(i2s_driver_supported)] #[cfg_attr(not(feature = "unstable"), allow(unused))] -pub(crate) mod constants { - /// The base clock frequency for the I2S peripheral (Hertz). - pub const I2S_SCLK: u32 = 160_000_000; - /// The default clock source for I2S operations. - pub const I2S_DEFAULT_CLK_SRC: u32 = 2; +pub(crate) fn i2s_sclk_frequency() -> u32 { + clocks::pll_f160m_clk_frequency() } pub(crate) unsafe fn configure_cpu_caches() {} diff --git a/esp-hal/src/soc/esp32c3/mod.rs b/esp-hal/src/soc/esp32c3/mod.rs index ebee53e0f2a..f6726077ba8 100644 --- a/esp-hal/src/soc/esp32c3/mod.rs +++ b/esp-hal/src/soc/esp32c3/mod.rs @@ -4,10 +4,6 @@ //! //! The `SOC` module provides access, functions and structures that are useful //! for interacting with various system-related peripherals on `ESP32-C3` chip. -//! -//! Also few constants are defined in this module for `ESP32-C3` chip: -//! * I2S_SCLK: 160_000_000 - I2S clock frequency -//! * I2S_DEFAULT_CLK_SRC: 2 - I2S clock source crate::unstable_module! { pub mod clocks; @@ -18,12 +14,10 @@ pub(crate) mod regi2c; pub(crate) use esp32c3 as pac; +#[cfg(i2s_driver_supported)] #[cfg_attr(not(feature = "unstable"), allow(unused))] -pub(crate) mod constants { - /// The base clock frequency for the I2S peripheral (Hertz). - pub const I2S_SCLK: u32 = 160_000_000; - /// The default clock source for I2S operations. - pub const I2S_DEFAULT_CLK_SRC: u8 = 2; +pub(crate) fn i2s_sclk_frequency() -> u32 { + clocks::pll_160m_frequency() } pub(crate) fn pre_init() {} diff --git a/esp-hal/src/soc/esp32c5/mod.rs b/esp-hal/src/soc/esp32c5/mod.rs index ec3098c93a3..5ff39510b07 100644 --- a/esp-hal/src/soc/esp32c5/mod.rs +++ b/esp-hal/src/soc/esp32c5/mod.rs @@ -4,8 +4,6 @@ //! //! The `SOC` module provides access, functions and structures that are useful //! for interacting with various system-related peripherals on `ESP32-C5` chip. -//! -//! Also few constants are defined in this module for `ESP32-C5` chip: crate::unstable_module! { pub mod clocks; @@ -15,8 +13,11 @@ pub(crate) mod regi2c; pub(crate) use esp32c5 as pac; +#[cfg(i2s_driver_supported)] #[cfg_attr(not(feature = "unstable"), allow(unused))] -pub(crate) mod constants {} +pub(crate) fn i2s_sclk_frequency() -> u32 { + clocks::pll_f160m_frequency() +} pub(crate) fn pre_init() { // Reset TEE security modes. This allows unrestricted access to TEE masters, including DMA. @@ -58,7 +59,7 @@ pub unsafe fn cache_invalidate_addr(addr: u32, size: u32) { #[unsafe(link_section = ".rwtext")] pub unsafe fn cache_get_dcache_line_size() -> u32 { unsafe extern "C" { - fn Cache_Get_DCache_Line_Size() -> u32; + fn Cache_Get_Line_Size() -> u32; } - unsafe { Cache_Get_DCache_Line_Size() } + unsafe { Cache_Get_Line_Size() } } diff --git a/esp-hal/src/soc/esp32c6/mod.rs b/esp-hal/src/soc/esp32c6/mod.rs index 227ce96342c..83f94b343f5 100644 --- a/esp-hal/src/soc/esp32c6/mod.rs +++ b/esp-hal/src/soc/esp32c6/mod.rs @@ -7,8 +7,6 @@ //! //! Also few constants are defined in this module for `ESP32-C6` chip: //! * TIMG_DEFAULT_CLK_SRC: 1 - Timer clock source -//! * I2S_DEFAULT_CLK_SRC: 2 - I2S clock source -//! * I2S_SCLK: 160_000_000 - I2S clock frequency crate::unstable_module! { pub mod clocks; @@ -20,12 +18,10 @@ pub(crate) mod regi2c; pub(crate) use esp32c6 as pac; +#[cfg(i2s_driver_supported)] #[cfg_attr(not(feature = "unstable"), allow(unused))] -pub(crate) mod constants { - /// The clock frequency for the I2S peripheral in Hertz. - pub const I2S_SCLK: u32 = 160_000_000; - /// The default clock source for the I2S peripheral. - pub const I2S_DEFAULT_CLK_SRC: u8 = 2; +pub(crate) fn i2s_sclk_frequency() -> u32 { + clocks::pll_f160m_frequency() } pub(crate) fn pre_init() { diff --git a/esp-hal/src/soc/esp32c61/mod.rs b/esp-hal/src/soc/esp32c61/mod.rs index a58f81ab087..18374d1694c 100644 --- a/esp-hal/src/soc/esp32c61/mod.rs +++ b/esp-hal/src/soc/esp32c61/mod.rs @@ -4,8 +4,6 @@ //! //! The `SOC` module provides access, functions and structures that are useful //! for interacting with various system-related peripherals on `ESP32-C61` chip. -//! -//! Also few constants are defined in this module for `ESP32-C61` chip: crate::unstable_module! { pub mod clocks; @@ -15,6 +13,12 @@ pub(crate) mod regi2c; pub(crate) use esp32c61 as pac; +#[cfg(i2s_driver_supported)] +#[cfg_attr(not(feature = "unstable"), allow(unused))] +pub(crate) fn i2s_sclk_frequency() -> u32 { + clocks::pll_f160m_frequency() +} + pub(crate) fn pre_init() { // Reset TEE security modes. This allows unrestricted access to TEE masters, including DMA. // FIXME: this is a temporary workaround until we have a proper solution for TEE security modes. diff --git a/esp-hal/src/soc/esp32h2/mod.rs b/esp-hal/src/soc/esp32h2/mod.rs index 82d7c190cb4..42a3628d1df 100644 --- a/esp-hal/src/soc/esp32h2/mod.rs +++ b/esp-hal/src/soc/esp32h2/mod.rs @@ -7,8 +7,6 @@ //! //! Also few constants are defined in this module for `ESP32-H2` chip: //! * TIMG_DEFAULT_CLK_SRC: 2 - Timer clock source -//! * I2S_DEFAULT_CLK_SRC: 1 - I2S clock source -//! * I2S_SCLK: 96_000_000 - I2S clock frequency crate::unstable_module! { pub mod clocks; @@ -19,12 +17,10 @@ pub(crate) mod regi2c; pub(crate) use esp32h2 as pac; +#[cfg(i2s_driver_supported)] #[cfg_attr(not(feature = "unstable"), allow(unused))] -pub(crate) mod constants { - /// Default clock source for the I2S peripheral. - pub const I2S_DEFAULT_CLK_SRC: u8 = 1; - /// Clock frequency for the I2S peripheral, in Hertz. - pub const I2S_SCLK: u32 = 96_000_000; +pub(crate) fn i2s_sclk_frequency() -> u32 { + clocks::pll_f96m_clk_frequency() } pub(crate) fn pre_init() { diff --git a/esp-hal/src/soc/esp32s2/mod.rs b/esp-hal/src/soc/esp32s2/mod.rs index 895adeea746..7c94610e2b4 100644 --- a/esp-hal/src/soc/esp32s2/mod.rs +++ b/esp-hal/src/soc/esp32s2/mod.rs @@ -4,10 +4,6 @@ //! //! The `SOC` module provides access, functions and structures that are useful //! for interacting with various system-related peripherals on `ESP32-S2` chip. -//! -//! Also few constants are defined in this module for `ESP32-S2` chip: -//! * I2S_SCLK: 160_000_000 - I2S clock frequency -//! * I2S_DEFAULT_CLK_SRC: 2 - I2S clock source crate::unstable_module! { pub mod clocks; @@ -19,12 +15,15 @@ pub(crate) mod regi2c; pub(crate) use esp32s2 as pac; +#[cfg(i2s_driver_supported)] #[cfg_attr(not(feature = "unstable"), allow(unused))] -pub(crate) mod constants { - /// System clock frequency for the I2S peripheral, in Hertz. - pub const I2S_SCLK: u32 = 160_000_000; - /// Default clock source for the I2S peripheral. - pub const I2S_DEFAULT_CLK_SRC: u32 = 2; +pub(crate) fn i2s_sclk_frequency() -> u32 { + // I2S uses the 160 MHz PLL tap, derived from either supported PLL frequency. + match clocks::pll_clk_frequency() { + 320_000_000 => 320_000_000 / 2, + 480_000_000 => 480_000_000 / 3, + _ => unreachable!(), + } } /// Write back a specific range of data in the cache. diff --git a/esp-hal/src/soc/esp32s3/mod.rs b/esp-hal/src/soc/esp32s3/mod.rs index b02f3b84bc2..9c24391db4e 100644 --- a/esp-hal/src/soc/esp32s3/mod.rs +++ b/esp-hal/src/soc/esp32s3/mod.rs @@ -4,10 +4,6 @@ //! //! The `SOC` module provides access, functions and structures that are useful //! for interacting with various system-related peripherals on `ESP32-S3` chip. -//! -//! Also few constants are defined in this module for `ESP32-S3` chip: -//! * I2S_SCLK: 160_000_000 - I2S clock frequency -//! * I2S_DEFAULT_CLK_SRC: 2 - I2S clock source crate::unstable_module! { pub mod clocks; @@ -21,12 +17,10 @@ pub(crate) mod regi2c; pub use esp32s3 as pac; +#[cfg(i2s_driver_supported)] #[cfg_attr(not(feature = "unstable"), allow(unused))] -pub(crate) mod constants { - /// The base clock frequency for the I2S peripheral (Hertz). - pub const I2S_SCLK: u32 = 160_000_000; - /// The default clock source for I2S operations. - pub const I2S_DEFAULT_CLK_SRC: u8 = 2; +pub(crate) fn i2s_sclk_frequency() -> u32 { + clocks::pll_160m_frequency() } #[unsafe(link_section = ".rwtext")] diff --git a/esp-metadata-generated/src/_build_script_utils.rs b/esp-metadata-generated/src/_build_script_utils.rs index a8e09dc239d..fa9b17d7c0b 100644 --- a/esp-metadata-generated/src/_build_script_utils.rs +++ b/esp-metadata-generated/src/_build_script_utils.rs @@ -337,6 +337,14 @@ impl Chip { "i2c_master_max_bus_timeout=\"1048575\"", "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", + "i2s_version=\"1\"", + "i2s_version_is_set", + "i2s_default_clock_source=\"2\"", + "i2s_default_clock_source_is_set", + "i2s_mclk_divider_bit_width=\"6\"", + "i2s_mclk_divider_bit_width_is_set", + "i2s_max_ws_width=\"128\"", + "i2s_max_ws_width_is_set", "interrupts_status_registers=\"3\"", "interrupt_controller=\"xtensa\"", "phy_combo_module", @@ -537,6 +545,14 @@ impl Chip { "cargo:rustc-cfg=i2c_master_max_bus_timeout=\"1048575\"", "cargo:rustc-cfg=i2c_master_ll_intr_mask=\"262143\"", "cargo:rustc-cfg=i2c_master_fifo_size=\"32\"", + "cargo:rustc-cfg=i2s_version=\"1\"", + "cargo:rustc-cfg=i2s_version_is_set", + "cargo:rustc-cfg=i2s_default_clock_source=\"2\"", + "cargo:rustc-cfg=i2s_default_clock_source_is_set", + "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"6\"", + "cargo:rustc-cfg=i2s_mclk_divider_bit_width_is_set", + "cargo:rustc-cfg=i2s_max_ws_width=\"128\"", + "cargo:rustc-cfg=i2s_max_ws_width_is_set", "cargo:rustc-cfg=interrupts_status_registers=\"3\"", "cargo:rustc-cfg=interrupt_controller=\"xtensa\"", "cargo:rustc-cfg=phy_combo_module", @@ -1321,6 +1337,14 @@ impl Chip { "i2c_master_max_bus_timeout=\"31\"", "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", + "i2s_version=\"2\"", + "i2s_version_is_set", + "i2s_default_clock_source=\"2\"", + "i2s_default_clock_source_is_set", + "i2s_mclk_divider_bit_width=\"9\"", + "i2s_mclk_divider_bit_width_is_set", + "i2s_max_ws_width=\"128\"", + "i2s_max_ws_width_is_set", "interrupts_status_registers=\"2\"", "interrupt_controller=\"riscv_basic\"", "phy_combo_module", @@ -1526,6 +1550,14 @@ impl Chip { "cargo:rustc-cfg=i2c_master_max_bus_timeout=\"31\"", "cargo:rustc-cfg=i2c_master_ll_intr_mask=\"262143\"", "cargo:rustc-cfg=i2c_master_fifo_size=\"32\"", + "cargo:rustc-cfg=i2s_version=\"2\"", + "cargo:rustc-cfg=i2s_version_is_set", + "cargo:rustc-cfg=i2s_default_clock_source=\"2\"", + "cargo:rustc-cfg=i2s_default_clock_source_is_set", + "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"9\"", + "cargo:rustc-cfg=i2s_mclk_divider_bit_width_is_set", + "cargo:rustc-cfg=i2s_max_ws_width=\"128\"", + "cargo:rustc-cfg=i2s_max_ws_width_is_set", "cargo:rustc-cfg=interrupts_status_registers=\"2\"", "cargo:rustc-cfg=interrupt_controller=\"riscv_basic\"", "cargo:rustc-cfg=phy_combo_module", @@ -1804,6 +1836,7 @@ impl Chip { "ecc_driver_supported", "gpio_driver_supported", "i2c_master_driver_supported", + "i2s_driver_supported", "ieee802154_driver_supported", "interrupts_driver_supported", "io_mux_driver_supported", @@ -1879,6 +1912,15 @@ impl Chip { "i2c_master_max_bus_timeout=\"31\"", "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", + "i2s_version=\"3\"", + "i2s_version_is_set", + "i2s_default_clock_source=\"2\"", + "i2s_default_clock_source_is_set", + "i2s_mclk_divider_bit_width=\"9\"", + "i2s_mclk_divider_bit_width_is_set", + "i2s_max_ws_width=\"512\"", + "i2s_max_ws_width_is_set", + "i2s_clock_configured_by_pcr", "interrupts_status_registers=\"3\"", "interrupt_controller=\"clic\"", "lp_i2c_master_fifo_size=\"16\"", @@ -2054,6 +2096,7 @@ impl Chip { "cargo:rustc-cfg=ecc_driver_supported", "cargo:rustc-cfg=gpio_driver_supported", "cargo:rustc-cfg=i2c_master_driver_supported", + "cargo:rustc-cfg=i2s_driver_supported", "cargo:rustc-cfg=ieee802154_driver_supported", "cargo:rustc-cfg=interrupts_driver_supported", "cargo:rustc-cfg=io_mux_driver_supported", @@ -2129,6 +2172,15 @@ impl Chip { "cargo:rustc-cfg=i2c_master_max_bus_timeout=\"31\"", "cargo:rustc-cfg=i2c_master_ll_intr_mask=\"262143\"", "cargo:rustc-cfg=i2c_master_fifo_size=\"32\"", + "cargo:rustc-cfg=i2s_version=\"3\"", + "cargo:rustc-cfg=i2s_version_is_set", + "cargo:rustc-cfg=i2s_default_clock_source=\"2\"", + "cargo:rustc-cfg=i2s_default_clock_source_is_set", + "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"9\"", + "cargo:rustc-cfg=i2s_mclk_divider_bit_width_is_set", + "cargo:rustc-cfg=i2s_max_ws_width=\"512\"", + "cargo:rustc-cfg=i2s_max_ws_width_is_set", + "cargo:rustc-cfg=i2s_clock_configured_by_pcr", "cargo:rustc-cfg=interrupts_status_registers=\"3\"", "cargo:rustc-cfg=interrupt_controller=\"clic\"", "cargo:rustc-cfg=lp_i2c_master_fifo_size=\"16\"", @@ -2536,6 +2588,15 @@ impl Chip { "i2c_master_max_bus_timeout=\"31\"", "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", + "i2s_version=\"2\"", + "i2s_version_is_set", + "i2s_default_clock_source=\"2\"", + "i2s_default_clock_source_is_set", + "i2s_mclk_divider_bit_width=\"9\"", + "i2s_mclk_divider_bit_width_is_set", + "i2s_max_ws_width=\"128\"", + "i2s_max_ws_width_is_set", + "i2s_clock_configured_by_pcr", "interrupts_status_registers=\"3\"", "interrupt_controller=\"plic\"", "lp_i2c_master_fifo_size=\"16\"", @@ -2812,6 +2873,15 @@ impl Chip { "cargo:rustc-cfg=i2c_master_max_bus_timeout=\"31\"", "cargo:rustc-cfg=i2c_master_ll_intr_mask=\"262143\"", "cargo:rustc-cfg=i2c_master_fifo_size=\"32\"", + "cargo:rustc-cfg=i2s_version=\"2\"", + "cargo:rustc-cfg=i2s_version_is_set", + "cargo:rustc-cfg=i2s_default_clock_source=\"2\"", + "cargo:rustc-cfg=i2s_default_clock_source_is_set", + "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"9\"", + "cargo:rustc-cfg=i2s_mclk_divider_bit_width_is_set", + "cargo:rustc-cfg=i2s_max_ws_width=\"128\"", + "cargo:rustc-cfg=i2s_max_ws_width_is_set", + "cargo:rustc-cfg=i2s_clock_configured_by_pcr", "cargo:rustc-cfg=interrupts_status_registers=\"3\"", "cargo:rustc-cfg=interrupt_controller=\"plic\"", "cargo:rustc-cfg=lp_i2c_master_fifo_size=\"16\"", @@ -3124,6 +3194,7 @@ impl Chip { "ecc_driver_supported", "gpio_driver_supported", "i2c_master_driver_supported", + "i2s_driver_supported", "interrupts_driver_supported", "io_mux_driver_supported", "phy_driver_supported", @@ -3182,6 +3253,15 @@ impl Chip { "i2c_master_max_bus_timeout=\"31\"", "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", + "i2s_version=\"3\"", + "i2s_version_is_set", + "i2s_default_clock_source=\"2\"", + "i2s_default_clock_source_is_set", + "i2s_mclk_divider_bit_width=\"9\"", + "i2s_mclk_divider_bit_width_is_set", + "i2s_max_ws_width=\"512\"", + "i2s_max_ws_width_is_set", + "i2s_clock_configured_by_pcr", "interrupts_status_registers=\"3\"", "interrupt_controller=\"clic\"", "phy_combo_module", @@ -3314,6 +3394,7 @@ impl Chip { "cargo:rustc-cfg=ecc_driver_supported", "cargo:rustc-cfg=gpio_driver_supported", "cargo:rustc-cfg=i2c_master_driver_supported", + "cargo:rustc-cfg=i2s_driver_supported", "cargo:rustc-cfg=interrupts_driver_supported", "cargo:rustc-cfg=io_mux_driver_supported", "cargo:rustc-cfg=phy_driver_supported", @@ -3372,6 +3453,15 @@ impl Chip { "cargo:rustc-cfg=i2c_master_max_bus_timeout=\"31\"", "cargo:rustc-cfg=i2c_master_ll_intr_mask=\"262143\"", "cargo:rustc-cfg=i2c_master_fifo_size=\"32\"", + "cargo:rustc-cfg=i2s_version=\"3\"", + "cargo:rustc-cfg=i2s_version_is_set", + "cargo:rustc-cfg=i2s_default_clock_source=\"2\"", + "cargo:rustc-cfg=i2s_default_clock_source_is_set", + "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"9\"", + "cargo:rustc-cfg=i2s_mclk_divider_bit_width_is_set", + "cargo:rustc-cfg=i2s_max_ws_width=\"512\"", + "cargo:rustc-cfg=i2s_max_ws_width_is_set", + "cargo:rustc-cfg=i2s_clock_configured_by_pcr", "cargo:rustc-cfg=interrupts_status_registers=\"3\"", "cargo:rustc-cfg=interrupt_controller=\"clic\"", "cargo:rustc-cfg=phy_combo_module", @@ -3737,6 +3827,15 @@ impl Chip { "i2c_master_max_bus_timeout=\"31\"", "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", + "i2s_version=\"3\"", + "i2s_version_is_set", + "i2s_default_clock_source=\"1\"", + "i2s_default_clock_source_is_set", + "i2s_mclk_divider_bit_width=\"9\"", + "i2s_mclk_divider_bit_width_is_set", + "i2s_max_ws_width=\"512\"", + "i2s_max_ws_width_is_set", + "i2s_clock_configured_by_pcr", "interrupts_status_registers=\"2\"", "interrupt_controller=\"plic\"", "parl_io_version=\"2\"", @@ -3977,6 +4076,15 @@ impl Chip { "cargo:rustc-cfg=i2c_master_max_bus_timeout=\"31\"", "cargo:rustc-cfg=i2c_master_ll_intr_mask=\"262143\"", "cargo:rustc-cfg=i2c_master_fifo_size=\"32\"", + "cargo:rustc-cfg=i2s_version=\"3\"", + "cargo:rustc-cfg=i2s_version_is_set", + "cargo:rustc-cfg=i2s_default_clock_source=\"1\"", + "cargo:rustc-cfg=i2s_default_clock_source_is_set", + "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"9\"", + "cargo:rustc-cfg=i2s_mclk_divider_bit_width_is_set", + "cargo:rustc-cfg=i2s_max_ws_width=\"512\"", + "cargo:rustc-cfg=i2s_max_ws_width_is_set", + "cargo:rustc-cfg=i2s_clock_configured_by_pcr", "cargo:rustc-cfg=interrupts_status_registers=\"2\"", "cargo:rustc-cfg=interrupt_controller=\"plic\"", "cargo:rustc-cfg=parl_io_version=\"2\"", @@ -4836,6 +4944,14 @@ impl Chip { "i2c_master_max_bus_timeout=\"16777215\"", "i2c_master_ll_intr_mask=\"131071\"", "i2c_master_fifo_size=\"32\"", + "i2s_version=\"1\"", + "i2s_version_is_set", + "i2s_default_clock_source=\"2\"", + "i2s_default_clock_source_is_set", + "i2s_mclk_divider_bit_width=\"6\"", + "i2s_mclk_divider_bit_width_is_set", + "i2s_max_ws_width=\"128\"", + "i2s_max_ws_width_is_set", "interrupts_status_registers=\"3\"", "interrupt_controller=\"xtensa\"", "psram_extmem_origin=\"1062207488\"", @@ -5050,6 +5166,14 @@ impl Chip { "cargo:rustc-cfg=i2c_master_max_bus_timeout=\"16777215\"", "cargo:rustc-cfg=i2c_master_ll_intr_mask=\"131071\"", "cargo:rustc-cfg=i2c_master_fifo_size=\"32\"", + "cargo:rustc-cfg=i2s_version=\"1\"", + "cargo:rustc-cfg=i2s_version_is_set", + "cargo:rustc-cfg=i2s_default_clock_source=\"2\"", + "cargo:rustc-cfg=i2s_default_clock_source_is_set", + "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"6\"", + "cargo:rustc-cfg=i2s_mclk_divider_bit_width_is_set", + "cargo:rustc-cfg=i2s_max_ws_width=\"128\"", + "cargo:rustc-cfg=i2s_max_ws_width_is_set", "cargo:rustc-cfg=interrupts_status_registers=\"3\"", "cargo:rustc-cfg=interrupt_controller=\"xtensa\"", "cargo:rustc-cfg=psram_extmem_origin=\"1062207488\"", @@ -5483,6 +5607,14 @@ impl Chip { "i2c_master_max_bus_timeout=\"31\"", "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", + "i2s_version=\"2\"", + "i2s_version_is_set", + "i2s_default_clock_source=\"2\"", + "i2s_default_clock_source_is_set", + "i2s_mclk_divider_bit_width=\"6\"", + "i2s_mclk_divider_bit_width_is_set", + "i2s_max_ws_width=\"128\"", + "i2s_max_ws_width_is_set", "interrupts_status_registers=\"4\"", "interrupt_controller=\"xtensa\"", "phy_combo_module", @@ -5734,6 +5866,14 @@ impl Chip { "cargo:rustc-cfg=i2c_master_max_bus_timeout=\"31\"", "cargo:rustc-cfg=i2c_master_ll_intr_mask=\"262143\"", "cargo:rustc-cfg=i2c_master_fifo_size=\"32\"", + "cargo:rustc-cfg=i2s_version=\"2\"", + "cargo:rustc-cfg=i2s_version_is_set", + "cargo:rustc-cfg=i2s_default_clock_source=\"2\"", + "cargo:rustc-cfg=i2s_default_clock_source_is_set", + "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"6\"", + "cargo:rustc-cfg=i2s_mclk_divider_bit_width_is_set", + "cargo:rustc-cfg=i2s_max_ws_width=\"128\"", + "cargo:rustc-cfg=i2s_max_ws_width_is_set", "cargo:rustc-cfg=interrupts_status_registers=\"4\"", "cargo:rustc-cfg=interrupt_controller=\"xtensa\"", "cargo:rustc-cfg=phy_combo_module", @@ -6194,6 +6334,10 @@ pub fn emit_check_cfg_directives() { println!("cargo:rustc-check-cfg=cfg(gpio_remap_iomux_pin_registers)"); println!("cargo:rustc-check-cfg=cfg(i2c_master_separate_filter_config_registers)"); println!("cargo:rustc-check-cfg=cfg(i2c_master_i2c0_data_register_ahb_address_is_set)"); + println!("cargo:rustc-check-cfg=cfg(i2s_version_is_set)"); + println!("cargo:rustc-check-cfg=cfg(i2s_default_clock_source_is_set)"); + println!("cargo:rustc-check-cfg=cfg(i2s_mclk_divider_bit_width_is_set)"); + println!("cargo:rustc-check-cfg=cfg(i2s_max_ws_width_is_set)"); println!("cargo:rustc-check-cfg=cfg(phy_combo_module)"); println!("cargo:rustc-check-cfg=cfg(rmt_has_per_channel_clock)"); println!("cargo:rustc-check-cfg=cfg(rmt_supports_reftick_clock)"); @@ -6388,6 +6532,7 @@ pub fn emit_check_cfg_directives() { println!("cargo:rustc-check-cfg=cfg(ecc_has_curve_p384)"); println!("cargo:rustc-check-cfg=cfg(i2c_master_can_estimate_nack_reason)"); println!("cargo:rustc-check-cfg=cfg(i2c_master_has_reliable_fsm_reset)"); + println!("cargo:rustc-check-cfg=cfg(i2s_clock_configured_by_pcr)"); println!("cargo:rustc-check-cfg=cfg(rmt_has_tx_loop_auto_stop)"); println!("cargo:rustc-check-cfg=cfg(rmt_supports_pll80mhz_clock)"); println!("cargo:rustc-check-cfg=cfg(soc_cpu_has_branch_predictor)"); @@ -6524,6 +6669,10 @@ pub fn emit_check_cfg_directives() { ); println!("cargo:rustc-check-cfg=cfg(i2c_master_ll_intr_mask, values(\"262143\",\"131071\"))"); println!("cargo:rustc-check-cfg=cfg(i2c_master_fifo_size, values(\"32\",\"16\"))"); + println!("cargo:rustc-check-cfg=cfg(i2s_version, values(\"1\",\"2\",\"3\"))"); + println!("cargo:rustc-check-cfg=cfg(i2s_default_clock_source, values(\"2\",\"1\"))"); + println!("cargo:rustc-check-cfg=cfg(i2s_mclk_divider_bit_width, values(\"6\",\"9\"))"); + println!("cargo:rustc-check-cfg=cfg(i2s_max_ws_width, values(\"128\",\"512\"))"); println!("cargo:rustc-check-cfg=cfg(interrupts_status_registers, values(\"3\",\"2\",\"4\"))"); println!( "cargo:rustc-check-cfg=cfg(interrupt_controller, \ diff --git a/esp-metadata-generated/src/_generated_esp32.rs b/esp-metadata-generated/src/_generated_esp32.rs index 9a7daa1a579..06600409ed4 100644 --- a/esp-metadata-generated/src/_generated_esp32.rs +++ b/esp-metadata-generated/src/_generated_esp32.rs @@ -175,6 +175,33 @@ macro_rules! property { ("i2c_master.fifo_size", str) => { stringify!(32) }; + ("i2s.version") => { + 1 + }; + ("i2s.version", str) => { + stringify!(1) + }; + ("i2s.default_clock_source") => { + 2 + }; + ("i2s.default_clock_source", str) => { + stringify!(2) + }; + ("i2s.mclk_divider_bit_width") => { + 6 + }; + ("i2s.mclk_divider_bit_width", str) => { + stringify!(6) + }; + ("i2s.max_ws_width") => { + 128 + }; + ("i2s.max_ws_width", str) => { + stringify!(128) + }; + ("i2s.clock_configured_by_pcr") => { + false + }; ("interrupts.status_registers") => { 3 }; diff --git a/esp-metadata-generated/src/_generated_esp32c3.rs b/esp-metadata-generated/src/_generated_esp32c3.rs index 72f53b73874..34577278e3a 100644 --- a/esp-metadata-generated/src/_generated_esp32c3.rs +++ b/esp-metadata-generated/src/_generated_esp32c3.rs @@ -196,6 +196,33 @@ macro_rules! property { ("i2c_master.fifo_size", str) => { stringify!(32) }; + ("i2s.version") => { + 2 + }; + ("i2s.version", str) => { + stringify!(2) + }; + ("i2s.default_clock_source") => { + 2 + }; + ("i2s.default_clock_source", str) => { + stringify!(2) + }; + ("i2s.mclk_divider_bit_width") => { + 9 + }; + ("i2s.mclk_divider_bit_width", str) => { + stringify!(9) + }; + ("i2s.max_ws_width") => { + 128 + }; + ("i2s.max_ws_width", str) => { + stringify!(128) + }; + ("i2s.clock_configured_by_pcr") => { + false + }; ("interrupts.status_registers") => { 2 }; diff --git a/esp-metadata-generated/src/_generated_esp32c5.rs b/esp-metadata-generated/src/_generated_esp32c5.rs index f631830423b..4890dab7e7c 100644 --- a/esp-metadata-generated/src/_generated_esp32c5.rs +++ b/esp-metadata-generated/src/_generated_esp32c5.rs @@ -211,6 +211,33 @@ macro_rules! property { ("i2c_master.fifo_size", str) => { stringify!(32) }; + ("i2s.version") => { + 3 + }; + ("i2s.version", str) => { + stringify!(3) + }; + ("i2s.default_clock_source") => { + 2 + }; + ("i2s.default_clock_source", str) => { + stringify!(2) + }; + ("i2s.mclk_divider_bit_width") => { + 9 + }; + ("i2s.mclk_divider_bit_width", str) => { + stringify!(9) + }; + ("i2s.max_ws_width") => { + 512 + }; + ("i2s.max_ws_width", str) => { + stringify!(512) + }; + ("i2s.clock_configured_by_pcr") => { + true + }; ("interrupts.status_registers") => { 3 }; @@ -3202,6 +3229,8 @@ macro_rules! implement_peripheral_clocks { Ecc, /// I2C_EXT0 peripheral clock signal I2cExt0, + /// I2S0 peripheral clock signal + I2s0, /// PARL_IO peripheral clock signal ParlIo, /// PCNT peripheral clock signal @@ -3244,6 +3273,7 @@ macro_rules! implement_peripheral_clocks { Self::Dma, Self::Ecc, Self::I2cExt0, + Self::I2s0, Self::ParlIo, Self::Pcnt, Self::Rmt, @@ -3286,6 +3316,11 @@ macro_rules! implement_peripheral_clocks { .i2c0_conf() .modify(|_, w| w.i2c0_clk_en().bit(enable)); } + Peripheral::I2s0 => { + crate::peripherals::SYSTEM::regs() + .i2s_conf() + .modify(|_, w| w.i2s_clk_en().bit(enable)); + } Peripheral::ParlIo => { crate::peripherals::SYSTEM::regs() .parl_io_conf() @@ -3384,6 +3419,11 @@ macro_rules! implement_peripheral_clocks { .i2c0_conf() .modify(|_, w| w.i2c0_rst_en().bit(reset)); } + Peripheral::I2s0 => { + crate::peripherals::SYSTEM::regs() + .i2s_conf() + .modify(|_, w| w.i2s_rst_en().bit(reset)); + } Peripheral::ParlIo => { crate::peripherals::SYSTEM::regs() .parl_io_conf() diff --git a/esp-metadata-generated/src/_generated_esp32c6.rs b/esp-metadata-generated/src/_generated_esp32c6.rs index ac5d5772442..94565ff35ca 100644 --- a/esp-metadata-generated/src/_generated_esp32c6.rs +++ b/esp-metadata-generated/src/_generated_esp32c6.rs @@ -211,6 +211,33 @@ macro_rules! property { ("i2c_master.fifo_size", str) => { stringify!(32) }; + ("i2s.version") => { + 2 + }; + ("i2s.version", str) => { + stringify!(2) + }; + ("i2s.default_clock_source") => { + 2 + }; + ("i2s.default_clock_source", str) => { + stringify!(2) + }; + ("i2s.mclk_divider_bit_width") => { + 9 + }; + ("i2s.mclk_divider_bit_width", str) => { + stringify!(9) + }; + ("i2s.max_ws_width") => { + 128 + }; + ("i2s.max_ws_width", str) => { + stringify!(128) + }; + ("i2s.clock_configured_by_pcr") => { + true + }; ("interrupts.status_registers") => { 3 }; diff --git a/esp-metadata-generated/src/_generated_esp32c61.rs b/esp-metadata-generated/src/_generated_esp32c61.rs index 3485ebad068..9c122ade67d 100644 --- a/esp-metadata-generated/src/_generated_esp32c61.rs +++ b/esp-metadata-generated/src/_generated_esp32c61.rs @@ -202,6 +202,33 @@ macro_rules! property { ("i2c_master.fifo_size", str) => { stringify!(32) }; + ("i2s.version") => { + 3 + }; + ("i2s.version", str) => { + stringify!(3) + }; + ("i2s.default_clock_source") => { + 2 + }; + ("i2s.default_clock_source", str) => { + stringify!(2) + }; + ("i2s.mclk_divider_bit_width") => { + 9 + }; + ("i2s.mclk_divider_bit_width", str) => { + stringify!(9) + }; + ("i2s.max_ws_width") => { + 512 + }; + ("i2s.max_ws_width", str) => { + stringify!(512) + }; + ("i2s.clock_configured_by_pcr") => { + true + }; ("interrupts.status_registers") => { 3 }; @@ -2305,6 +2332,8 @@ macro_rules! implement_peripheral_clocks { Ecc, /// I2C_EXT0 peripheral clock signal I2cExt0, + /// I2S0 peripheral clock signal + I2s0, /// SHA peripheral clock signal Sha, /// SPI2 peripheral clock signal @@ -2330,6 +2359,7 @@ macro_rules! implement_peripheral_clocks { Self::Dma, Self::Ecc, Self::I2cExt0, + Self::I2s0, Self::Sha, Self::Spi2, Self::Systimer, @@ -2357,6 +2387,11 @@ macro_rules! implement_peripheral_clocks { .i2c0_conf() .modify(|_, w| w.i2c0_clk_en().bit(enable)); } + Peripheral::I2s0 => { + crate::peripherals::SYSTEM::regs() + .i2s_conf() + .modify(|_, w| w.i2s_clk_en().bit(enable)); + } Peripheral::Sha => { crate::peripherals::SYSTEM::regs() .sha_conf() @@ -2420,6 +2455,11 @@ macro_rules! implement_peripheral_clocks { .i2c0_conf() .modify(|_, w| w.i2c0_rst_en().bit(reset)); } + Peripheral::I2s0 => { + crate::peripherals::SYSTEM::regs() + .i2s_conf() + .modify(|_, w| w.i2s_rst_en().bit(reset)); + } Peripheral::Sha => { crate::peripherals::SYSTEM::regs() .sha_conf() diff --git a/esp-metadata-generated/src/_generated_esp32h2.rs b/esp-metadata-generated/src/_generated_esp32h2.rs index 2a1d6dbb749..39e8fda19dd 100644 --- a/esp-metadata-generated/src/_generated_esp32h2.rs +++ b/esp-metadata-generated/src/_generated_esp32h2.rs @@ -211,6 +211,33 @@ macro_rules! property { ("i2c_master.fifo_size", str) => { stringify!(32) }; + ("i2s.version") => { + 3 + }; + ("i2s.version", str) => { + stringify!(3) + }; + ("i2s.default_clock_source") => { + 1 + }; + ("i2s.default_clock_source", str) => { + stringify!(1) + }; + ("i2s.mclk_divider_bit_width") => { + 9 + }; + ("i2s.mclk_divider_bit_width", str) => { + stringify!(9) + }; + ("i2s.max_ws_width") => { + 512 + }; + ("i2s.max_ws_width", str) => { + stringify!(512) + }; + ("i2s.clock_configured_by_pcr") => { + true + }; ("interrupts.status_registers") => { 2 }; diff --git a/esp-metadata-generated/src/_generated_esp32p4.rs b/esp-metadata-generated/src/_generated_esp32p4.rs index 669df1e3d22..0b302397b04 100644 --- a/esp-metadata-generated/src/_generated_esp32p4.rs +++ b/esp-metadata-generated/src/_generated_esp32p4.rs @@ -199,6 +199,9 @@ macro_rules! property { ("i2c_master.fifo_size", str) => { stringify!(32) }; + ("i2s.clock_configured_by_pcr") => { + false + }; ("interrupts.status_registers") => { 3 }; diff --git a/esp-metadata-generated/src/_generated_esp32s2.rs b/esp-metadata-generated/src/_generated_esp32s2.rs index d1aebcb4940..43b7da9f6e1 100644 --- a/esp-metadata-generated/src/_generated_esp32s2.rs +++ b/esp-metadata-generated/src/_generated_esp32s2.rs @@ -181,6 +181,33 @@ macro_rules! property { ("i2c_master.fifo_size", str) => { stringify!(32) }; + ("i2s.version") => { + 1 + }; + ("i2s.version", str) => { + stringify!(1) + }; + ("i2s.default_clock_source") => { + 2 + }; + ("i2s.default_clock_source", str) => { + stringify!(2) + }; + ("i2s.mclk_divider_bit_width") => { + 6 + }; + ("i2s.mclk_divider_bit_width", str) => { + stringify!(6) + }; + ("i2s.max_ws_width") => { + 128 + }; + ("i2s.max_ws_width", str) => { + stringify!(128) + }; + ("i2s.clock_configured_by_pcr") => { + false + }; ("interrupts.status_registers") => { 3 }; diff --git a/esp-metadata-generated/src/_generated_esp32s3.rs b/esp-metadata-generated/src/_generated_esp32s3.rs index 452e19bf81d..98bae5a4253 100644 --- a/esp-metadata-generated/src/_generated_esp32s3.rs +++ b/esp-metadata-generated/src/_generated_esp32s3.rs @@ -196,6 +196,33 @@ macro_rules! property { ("i2c_master.fifo_size", str) => { stringify!(32) }; + ("i2s.version") => { + 2 + }; + ("i2s.version", str) => { + stringify!(2) + }; + ("i2s.default_clock_source") => { + 2 + }; + ("i2s.default_clock_source", str) => { + stringify!(2) + }; + ("i2s.mclk_divider_bit_width") => { + 6 + }; + ("i2s.mclk_divider_bit_width", str) => { + stringify!(6) + }; + ("i2s.max_ws_width") => { + 128 + }; + ("i2s.max_ws_width", str) => { + stringify!(128) + }; + ("i2s.clock_configured_by_pcr") => { + false + }; ("interrupts.status_registers") => { 4 }; diff --git a/esp-metadata/CHANGELOG.md b/esp-metadata/CHANGELOG.md index 490833fef81..06de5ce842c 100644 --- a/esp-metadata/CHANGELOG.md +++ b/esp-metadata/CHANGELOG.md @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - C5 and C61: Enable RTC timekeeping (#5449) - ESP32-P4: emit `rom_crc_le`, `rom_crc_be`, `rom_md5_bsd` cfg flags (#5400) - ESP32-P4: emit `pm_support_ext1_wakeup` and `pm_support_touch_sensor_wakeup` (#5400) +- C5 and C61: I2S support (#5483) +- More I2S flags for HW unification (#5483) ### Changed diff --git a/esp-metadata/devices/esp32.toml b/esp-metadata/devices/esp32.toml index 823865e3020..c8af0337a13 100644 --- a/esp-metadata/devices/esp32.toml +++ b/esp-metadata/devices/esp32.toml @@ -879,6 +879,11 @@ deep_sleep = true ## Interfaces [device.i2s] +version = 1 +default_clock_source = 2 +mclk_divider_bit_width = 6 +max_ws_width = 128 + [device.ledc] [device.mcpwm] [device.pcnt] diff --git a/esp-metadata/devices/esp32c3.toml b/esp-metadata/devices/esp32c3.toml index 307c2df5b1e..344edcda7bb 100644 --- a/esp-metadata/devices/esp32c3.toml +++ b/esp-metadata/devices/esp32c3.toml @@ -537,6 +537,11 @@ deep_sleep = true ## Interfaces [device.i2s] +version = 2 +default_clock_source = 2 +mclk_divider_bit_width = 9 +max_ws_width = 128 + [device.ledc] [device.twai] [device.usb_serial_jtag] diff --git a/esp-metadata/devices/esp32c5.toml b/esp-metadata/devices/esp32c5.toml index b9f68ef00fb..bfed39d12b9 100644 --- a/esp-metadata/devices/esp32c5.toml +++ b/esp-metadata/devices/esp32c5.toml @@ -265,6 +265,7 @@ clocks = { system_clocks = { clock_tree = [ { name = "Timg0", template_params = { conf_register = "timergroup(0).conf", clk_en_field = "clk_en", rst_field = "rst_en" }, keep_enabled = true }, { name = "Timg1", template_params = { conf_register = "timergroup(1).conf", clk_en_field = "clk_en", rst_field = "rst_en" } }, { name = "I2cExt0", template_params = { peripheral = "i2c0" } }, + { name = "I2s0", template_params = { peripheral = "i2s" } }, { name = "Pcnt" }, { name = "Rmt" }, { name = "Systimer", keep_enabled = true }, # can be clocked from XTAL_CLK or RC_FAST_CLK, the latter has no divider? @@ -709,7 +710,11 @@ support_status = { status = "not_supported", issue = 5166 } support_status = { status = "not_supported", issue = 5444 } [device.i2s] -support_status = { status = "not_supported", issue = 5172 } +version = 3 +default_clock_source = 2 +mclk_divider_bit_width = 9 +max_ws_width = 512 +clock_configured_by_pcr = true [device.io_mux] diff --git a/esp-metadata/devices/esp32c6.toml b/esp-metadata/devices/esp32c6.toml index ebf04019699..7f24dd0eb79 100644 --- a/esp-metadata/devices/esp32c6.toml +++ b/esp-metadata/devices/esp32c6.toml @@ -752,6 +752,12 @@ version = 1 ## Interfaces [device.i2s] +version = 2 +default_clock_source = 2 +mclk_divider_bit_width = 9 +max_ws_width = 128 +clock_configured_by_pcr = true + [device.ledc] [device.mcpwm] diff --git a/esp-metadata/devices/esp32c61.toml b/esp-metadata/devices/esp32c61.toml index 68de710c36e..3ea3bc71a3e 100644 --- a/esp-metadata/devices/esp32c61.toml +++ b/esp-metadata/devices/esp32c61.toml @@ -206,6 +206,7 @@ clocks = { system_clocks = { clock_tree = [ { name = "Timg1", template_params = { conf_register = "timergroup(1).conf", clk_en_field = "clk_en", rst_field = "rst_en" } }, { name = "I2cExt0", template_params = { peripheral = "i2c0" }}, { name = "Dma", template_params = { peripheral = "gdma" } }, + { name = "I2s0", template_params = { peripheral = "i2s" } }, { name = "Spi2" }, { name = "Sha" }, @@ -489,7 +490,11 @@ support_status = { status = "not_supported", issue = 5423 } [device.io_mux] [device.i2s] -support_status = { status = "not_supported", issue = 5415 } +version = 3 +default_clock_source = 2 +mclk_divider_bit_width = 9 +max_ws_width = 512 +clock_configured_by_pcr = true [device.sd_slave] support_status = { status = "not_supported", issue = 5417 } diff --git a/esp-metadata/devices/esp32h2.toml b/esp-metadata/devices/esp32h2.toml index 9b1d8a24e3a..885f435255d 100644 --- a/esp-metadata/devices/esp32h2.toml +++ b/esp-metadata/devices/esp32h2.toml @@ -650,6 +650,12 @@ deep_sleep = true ## Interfaces [device.i2s] +version = 3 +default_clock_source = 1 +mclk_divider_bit_width = 9 +max_ws_width = 512 +clock_configured_by_pcr = true + [device.ledc] [device.mcpwm] [device.pcnt] diff --git a/esp-metadata/devices/esp32s2.toml b/esp-metadata/devices/esp32s2.toml index 75c31523b5c..fc07ca79996 100644 --- a/esp-metadata/devices/esp32s2.toml +++ b/esp-metadata/devices/esp32s2.toml @@ -672,6 +672,11 @@ deep_sleep = true ## Interfaces [device.i2s] +version = 1 +default_clock_source = 2 +mclk_divider_bit_width = 6 +max_ws_width = 128 + [device.ledc] [device.pcnt] [device.twai] diff --git a/esp-metadata/devices/esp32s3.toml b/esp-metadata/devices/esp32s3.toml index 40be59290f0..5f55cbacbcb 100644 --- a/esp-metadata/devices/esp32s3.toml +++ b/esp-metadata/devices/esp32s3.toml @@ -866,6 +866,11 @@ deep_sleep = true ## Interfaces [device.i2s] +version = 2 +default_clock_source = 2 +mclk_divider_bit_width = 6 +max_ws_width = 128 + [device.camera] [device.rgb_display] [device.ledc] diff --git a/esp-metadata/src/cfg.rs b/esp-metadata/src/cfg.rs index 5ced4eeb509..f8ce6950bc8 100644 --- a/esp-metadata/src/cfg.rs +++ b/esp-metadata/src/cfg.rs @@ -452,7 +452,19 @@ driver_configs![ I2sProperties { driver: i2s, name: "I2S", - properties: {} + properties: { + /// Register-layout generation derived from the chip SVD. + version: Option, + /// Default clock source selector written to the I2S clock source register. + default_clock_source: Option, + /// Width of the MCLK divider field in the I2S clock register. + mclk_divider_bit_width: Option, + /// Largest WS divider value supported by the peripheral. + max_ws_width: Option, + #[serde(default)] + /// Whether I2S clock/reset control is performed via PCR. + clock_configured_by_pcr: bool, + } }, IeeeProperties { driver: ieee802154, diff --git a/hil-test/src/bin/i2s.rs b/hil-test/src/bin/i2s.rs index f2c5bccb5b8..e9a072300cf 100644 --- a/hil-test/src/bin/i2s.rs +++ b/hil-test/src/bin/i2s.rs @@ -3,7 +3,7 @@ //! This test uses I2S TX to transmit known data to I2S RX (forced to slave mode //! with loopback mode enabled). -//% CHIPS: esp32 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3 +//% CHIPS: esp32 esp32c3 esp32c5 esp32c6 esp32c61 esp32h2 esp32s2 esp32s3 //% FEATURES: unstable // FIXME: re-enable on ESP32 when it no longer fails spuriously diff --git a/qa-test/src/bin/embassy_i2s_read.rs b/qa-test/src/bin/embassy_i2s_read.rs index f3884f7f6c6..9e11a703c4e 100644 --- a/qa-test/src/bin/embassy_i2s_read.rs +++ b/qa-test/src/bin/embassy_i2s_read.rs @@ -11,7 +11,7 @@ //! - WS => GPIO4 //! - DIN => GPIO5 -//% CHIPS: esp32 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3 +//% CHIPS: esp32 esp32c3 esp32c5 esp32c6 esp32c61 esp32h2 esp32s2 esp32s3 #![no_std] #![no_main] diff --git a/qa-test/src/bin/embassy_i2s_sound.rs b/qa-test/src/bin/embassy_i2s_sound.rs index 762e3770b2e..87f8defa279 100644 --- a/qa-test/src/bin/embassy_i2s_sound.rs +++ b/qa-test/src/bin/embassy_i2s_sound.rs @@ -25,7 +25,7 @@ //! | DEMP | Gnd | //! | XSMT | +3V3 | -//% CHIPS: esp32 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3 +//% CHIPS: esp32 esp32c3 esp32c5 esp32c6 esp32c61 esp32h2 esp32s2 esp32s3 #![no_std] #![no_main]