From e89af24eb9a5900401ec03bcef6c7d0dcaf358ae Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Thu, 30 Apr 2026 16:03:24 +0200 Subject: [PATCH 1/9] Unify I2S hardware with metadata, add C5 and C61 I2S support --- esp-hal/README.md | 2 - esp-hal/src/dma/mod.rs | 2 +- esp-hal/src/i2s/master.rs | 157 +++++++++--------- esp-hal/src/soc/esp32c5/mod.rs | 11 +- esp-hal/src/soc/esp32c61/mod.rs | 8 + .../src/_build_script_utils.rs | 78 +++++++++ .../src/_generated_esp32.rs | 27 +++ .../src/_generated_esp32c3.rs | 27 +++ .../src/_generated_esp32c5.rs | 40 +++++ .../src/_generated_esp32c6.rs | 27 +++ .../src/_generated_esp32c61.rs | 40 +++++ .../src/_generated_esp32h2.rs | 27 +++ .../src/_generated_esp32s2.rs | 27 +++ .../src/_generated_esp32s3.rs | 27 +++ esp-metadata/devices/esp32.toml | 4 + esp-metadata/devices/esp32c3.toml | 4 + esp-metadata/devices/esp32c5.toml | 8 +- esp-metadata/devices/esp32c6.toml | 5 + esp-metadata/devices/esp32c61.toml | 8 +- esp-metadata/devices/esp32h2.toml | 7 + esp-metadata/devices/esp32s2.toml | 4 + esp-metadata/devices/esp32s3.toml | 4 + esp-metadata/src/cfg.rs | 12 +- hil-test/src/bin/i2s.rs | 2 +- qa-test/src/bin/embassy_i2s_read.rs | 2 +- qa-test/src/bin/embassy_i2s_sound.rs | 2 +- qa-test/src/bin/embassy_wifi_i2s.rs | 2 +- 27 files changed, 477 insertions(+), 87 deletions(-) diff --git a/esp-hal/README.md b/esp-hal/README.md index d5c79d30d34..669e9f5b028 100644 --- a/esp-hal/README.md +++ b/esp-hal/README.md @@ -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..cb490d656e6 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(i2s_version = "1") => "DMA_I2S0", + cfg(not(i2s_version = "1")) => "DMA_CH0" }, "mclk" => { cfg(not(esp32)) => "let i2s = i2s.with_mclk(peripherals.GPIO0);", @@ -153,19 +153,16 @@ 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 +197,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 +241,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 +343,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 +409,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 +420,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 +442,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 +479,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 +490,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 +507,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 +548,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 +556,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 +575,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 +589,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 +613,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 +621,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 +649,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 +657,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 +665,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 +676,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") as u16; if !(1..=MAX_WS_WIDTH).contains(&ws_width) || ws_width > self.data_format.data_bits() as u16 * self.channels.count as u16 @@ -693,7 +687,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 +709,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 +722,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 +846,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 +866,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 +982,7 @@ where tx_channel: ChannelTx>>, tx_chain: DescriptorChain, _guard: PeripheralGuard, - #[cfg(any(esp32, esp32s2))] + #[cfg(i2s_version = "1")] data_format: DataFormat, } @@ -1079,7 +1073,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 +1125,7 @@ where rx_channel: ChannelRx>>, rx_chain: DescriptorChain, _guard: PeripheralGuard, - #[cfg(any(esp32, esp32s2))] + #[cfg(i2s_version = "1")] data_format: DataFormat, } @@ -1223,7 +1217,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 +1309,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 +1324,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 +1370,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 +1385,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 +1441,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| { @@ -1758,7 +1752,7 @@ mod private { } } - #[cfg(any(esp32c3, esp32s3, esp32c6, esp32h2))] + #[cfg(i2s_version = "2")] pub trait RegisterAccessPrivate: Signals + RegBlock { fn enable_listen(&self, interrupts: EnumSet, enable: bool) { self.regs().int_ena().modify(|_, w| { @@ -1816,7 +1810,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(); @@ -1836,13 +1830,19 @@ mod private { w.tx_clkm_div_num().bits(clock_settings.mclk_divider as u8) }); + #[cfg(not(i2s_bck_divider_in_conf))] self.regs().tx_conf1().modify(|_, w| unsafe { w.tx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) }); + #[cfg(i2s_bck_divider_in_conf)] + 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(); @@ -1862,13 +1862,19 @@ mod private { w.mclk_sel().bit(true) }); + #[cfg(not(i2s_bck_divider_in_conf))] self.regs().rx_conf1().modify(|_, w| unsafe { w.rx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) }); + #[cfg(i2s_bck_divider_in_conf)] + 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; @@ -1891,19 +1897,20 @@ mod private { .bits(clock_settings.mclk_divider as u8) }); - #[cfg(not(esp32h2))] + #[cfg(not(i2s_bck_divider_in_conf))] self.regs().tx_conf1().modify(|_, w| unsafe { w.tx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) }); - #[cfg(esp32h2)] + + #[cfg(i2s_bck_divider_in_conf)] 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; @@ -1926,12 +1933,14 @@ mod private { .bits(clock_settings.mclk_divider as u8); w.i2s_mclk_sel().bit(true) }); - #[cfg(not(esp32h2))] + + #[cfg(not(i2s_bck_divider_in_conf))] self.regs().rx_conf1().modify(|_, w| unsafe { w.rx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) }); - #[cfg(esp32h2)] + + #[cfg(i2s_bck_divider_in_conf)] self.regs().rx_conf().modify(|_, w| unsafe { w.rx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) @@ -1963,7 +1972,7 @@ mod private { self.set_tx_clock(config.calculate_clock()); self.regs().tx_conf1().modify(|_, w| unsafe { - #[cfg(not(esp32h2))] + #[cfg(not(i2s_msb_shift_in_conf))] 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 +1991,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_msb_shift_in_conf)] w.tx_msb_shift().bit(config.msb_shift); w.tx_big_endian() .bit(config.endianness == Endianness::BigEndian); @@ -2029,7 +2038,7 @@ mod private { self.set_rx_clock(config.calculate_clock()); self.regs().rx_conf1().modify(|_, w| unsafe { - #[cfg(not(esp32h2))] + #[cfg(not(i2s_msb_shift_in_conf))] 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 +2056,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_msb_shift_in_conf)] w.rx_msb_shift().bit(config.msb_shift); w.rx_big_endian() .bit(config.endianness == Endianness::BigEndian); @@ -2193,7 +2202,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 +2212,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 +2236,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 +2246,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 +2397,7 @@ mod private { numerator: u32, } - #[cfg(any(esp32c3, esp32s3, esp32c6, esp32h2))] + #[cfg(i2s_version = "2")] pub struct I2sMclkDividers { x: u32, y: u32, @@ -2460,7 +2469,7 @@ mod private { } } - #[cfg(any(esp32c3, esp32s3, esp32c6, esp32h2))] + #[cfg(i2s_version = "2")] fn mclk_dividers(&self) -> I2sMclkDividers { let x; let y; diff --git a/esp-hal/src/soc/esp32c5/mod.rs b/esp-hal/src/soc/esp32c5/mod.rs index ec3098c93a3..b62d5255ba9 100644 --- a/esp-hal/src/soc/esp32c5/mod.rs +++ b/esp-hal/src/soc/esp32c5/mod.rs @@ -16,7 +16,12 @@ pub(crate) mod regi2c; pub(crate) use esp32c5 as pac; #[cfg_attr(not(feature = "unstable"), allow(unused))] -pub(crate) mod constants {} +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 pre_init() { // Reset TEE security modes. This allows unrestricted access to TEE masters, including DMA. @@ -58,7 +63,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/esp32c61/mod.rs b/esp-hal/src/soc/esp32c61/mod.rs index a58f81ab087..a306512aecf 100644 --- a/esp-hal/src/soc/esp32c61/mod.rs +++ b/esp-hal/src/soc/esp32c61/mod.rs @@ -15,6 +15,14 @@ pub(crate) mod regi2c; pub(crate) use esp32c61 as pac; +#[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 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-metadata-generated/src/_build_script_utils.rs b/esp-metadata-generated/src/_build_script_utils.rs index a8e09dc239d..84c1b2ef6b8 100644 --- a/esp-metadata-generated/src/_build_script_utils.rs +++ b/esp-metadata-generated/src/_build_script_utils.rs @@ -337,6 +337,9 @@ impl Chip { "i2c_master_max_bus_timeout=\"1048575\"", "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", + "i2s_version=\"1\"", + "i2s_mclk_divider_bit_width=\"6\"", + "i2s_max_ws_width=\"128\"", "interrupts_status_registers=\"3\"", "interrupt_controller=\"xtensa\"", "phy_combo_module", @@ -537,6 +540,9 @@ 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_mclk_divider_bit_width=\"6\"", + "cargo:rustc-cfg=i2s_max_ws_width=\"128\"", "cargo:rustc-cfg=interrupts_status_registers=\"3\"", "cargo:rustc-cfg=interrupt_controller=\"xtensa\"", "cargo:rustc-cfg=phy_combo_module", @@ -1321,6 +1327,9 @@ impl Chip { "i2c_master_max_bus_timeout=\"31\"", "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", + "i2s_version=\"2\"", + "i2s_mclk_divider_bit_width=\"9\"", + "i2s_max_ws_width=\"128\"", "interrupts_status_registers=\"2\"", "interrupt_controller=\"riscv_basic\"", "phy_combo_module", @@ -1526,6 +1535,9 @@ 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_mclk_divider_bit_width=\"9\"", + "cargo:rustc-cfg=i2s_max_ws_width=\"128\"", "cargo:rustc-cfg=interrupts_status_registers=\"2\"", "cargo:rustc-cfg=interrupt_controller=\"riscv_basic\"", "cargo:rustc-cfg=phy_combo_module", @@ -1804,6 +1816,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 +1892,12 @@ impl Chip { "i2c_master_max_bus_timeout=\"31\"", "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", + "i2s_version=\"2\"", + "i2s_mclk_divider_bit_width=\"9\"", + "i2s_max_ws_width=\"512\"", + "i2s_clock_configured_by_pcr", + "i2s_bck_divider_in_conf", + "i2s_msb_shift_in_conf", "interrupts_status_registers=\"3\"", "interrupt_controller=\"clic\"", "lp_i2c_master_fifo_size=\"16\"", @@ -2054,6 +2073,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 +2149,12 @@ 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_mclk_divider_bit_width=\"9\"", + "cargo:rustc-cfg=i2s_max_ws_width=\"512\"", + "cargo:rustc-cfg=i2s_clock_configured_by_pcr", + "cargo:rustc-cfg=i2s_bck_divider_in_conf", + "cargo:rustc-cfg=i2s_msb_shift_in_conf", "cargo:rustc-cfg=interrupts_status_registers=\"3\"", "cargo:rustc-cfg=interrupt_controller=\"clic\"", "cargo:rustc-cfg=lp_i2c_master_fifo_size=\"16\"", @@ -2536,6 +2562,10 @@ impl Chip { "i2c_master_max_bus_timeout=\"31\"", "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", + "i2s_version=\"2\"", + "i2s_mclk_divider_bit_width=\"9\"", + "i2s_max_ws_width=\"128\"", + "i2s_clock_configured_by_pcr", "interrupts_status_registers=\"3\"", "interrupt_controller=\"plic\"", "lp_i2c_master_fifo_size=\"16\"", @@ -2812,6 +2842,10 @@ 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_mclk_divider_bit_width=\"9\"", + "cargo:rustc-cfg=i2s_max_ws_width=\"128\"", + "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 +3158,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 +3217,12 @@ impl Chip { "i2c_master_max_bus_timeout=\"31\"", "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", + "i2s_version=\"2\"", + "i2s_mclk_divider_bit_width=\"9\"", + "i2s_max_ws_width=\"512\"", + "i2s_clock_configured_by_pcr", + "i2s_bck_divider_in_conf", + "i2s_msb_shift_in_conf", "interrupts_status_registers=\"3\"", "interrupt_controller=\"clic\"", "phy_combo_module", @@ -3314,6 +3355,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 +3414,12 @@ 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_mclk_divider_bit_width=\"9\"", + "cargo:rustc-cfg=i2s_max_ws_width=\"512\"", + "cargo:rustc-cfg=i2s_clock_configured_by_pcr", + "cargo:rustc-cfg=i2s_bck_divider_in_conf", + "cargo:rustc-cfg=i2s_msb_shift_in_conf", "cargo:rustc-cfg=interrupts_status_registers=\"3\"", "cargo:rustc-cfg=interrupt_controller=\"clic\"", "cargo:rustc-cfg=phy_combo_module", @@ -3737,6 +3785,12 @@ impl Chip { "i2c_master_max_bus_timeout=\"31\"", "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", + "i2s_version=\"2\"", + "i2s_mclk_divider_bit_width=\"9\"", + "i2s_max_ws_width=\"512\"", + "i2s_clock_configured_by_pcr", + "i2s_bck_divider_in_conf", + "i2s_msb_shift_in_conf", "interrupts_status_registers=\"2\"", "interrupt_controller=\"plic\"", "parl_io_version=\"2\"", @@ -3977,6 +4031,12 @@ 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_mclk_divider_bit_width=\"9\"", + "cargo:rustc-cfg=i2s_max_ws_width=\"512\"", + "cargo:rustc-cfg=i2s_clock_configured_by_pcr", + "cargo:rustc-cfg=i2s_bck_divider_in_conf", + "cargo:rustc-cfg=i2s_msb_shift_in_conf", "cargo:rustc-cfg=interrupts_status_registers=\"2\"", "cargo:rustc-cfg=interrupt_controller=\"plic\"", "cargo:rustc-cfg=parl_io_version=\"2\"", @@ -4836,6 +4896,9 @@ impl Chip { "i2c_master_max_bus_timeout=\"16777215\"", "i2c_master_ll_intr_mask=\"131071\"", "i2c_master_fifo_size=\"32\"", + "i2s_version=\"1\"", + "i2s_mclk_divider_bit_width=\"6\"", + "i2s_max_ws_width=\"128\"", "interrupts_status_registers=\"3\"", "interrupt_controller=\"xtensa\"", "psram_extmem_origin=\"1062207488\"", @@ -5050,6 +5113,9 @@ 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_mclk_divider_bit_width=\"6\"", + "cargo:rustc-cfg=i2s_max_ws_width=\"128\"", "cargo:rustc-cfg=interrupts_status_registers=\"3\"", "cargo:rustc-cfg=interrupt_controller=\"xtensa\"", "cargo:rustc-cfg=psram_extmem_origin=\"1062207488\"", @@ -5483,6 +5549,9 @@ impl Chip { "i2c_master_max_bus_timeout=\"31\"", "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", + "i2s_version=\"2\"", + "i2s_mclk_divider_bit_width=\"6\"", + "i2s_max_ws_width=\"128\"", "interrupts_status_registers=\"4\"", "interrupt_controller=\"xtensa\"", "phy_combo_module", @@ -5734,6 +5803,9 @@ 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_mclk_divider_bit_width=\"6\"", + "cargo:rustc-cfg=i2s_max_ws_width=\"128\"", "cargo:rustc-cfg=interrupts_status_registers=\"4\"", "cargo:rustc-cfg=interrupt_controller=\"xtensa\"", "cargo:rustc-cfg=phy_combo_module", @@ -6388,6 +6460,9 @@ 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(i2s_bck_divider_in_conf)"); + println!("cargo:rustc-check-cfg=cfg(i2s_msb_shift_in_conf)"); 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 +6599,9 @@ 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\"))"); + 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..5381a90164a 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.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 + }; + ("i2s.bck_divider_in_conf") => { + false + }; + ("i2s.msb_shift_in_conf") => { + 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..6256abf1053 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.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 + }; + ("i2s.bck_divider_in_conf") => { + false + }; + ("i2s.msb_shift_in_conf") => { + 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..faf7d033dc5 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") => { + 2 + }; + ("i2s.version", 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 + }; + ("i2s.bck_divider_in_conf") => { + true + }; + ("i2s.msb_shift_in_conf") => { + 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..19d9a3e49b1 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.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 + }; + ("i2s.bck_divider_in_conf") => { + false + }; + ("i2s.msb_shift_in_conf") => { + false + }; ("interrupts.status_registers") => { 3 }; diff --git a/esp-metadata-generated/src/_generated_esp32c61.rs b/esp-metadata-generated/src/_generated_esp32c61.rs index 3485ebad068..aae8b0f8f7f 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") => { + 2 + }; + ("i2s.version", 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 + }; + ("i2s.bck_divider_in_conf") => { + true + }; + ("i2s.msb_shift_in_conf") => { + 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..5d8914f8227 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") => { + 2 + }; + ("i2s.version", 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 + }; + ("i2s.bck_divider_in_conf") => { + true + }; + ("i2s.msb_shift_in_conf") => { + true + }; ("interrupts.status_registers") => { 2 }; diff --git a/esp-metadata-generated/src/_generated_esp32s2.rs b/esp-metadata-generated/src/_generated_esp32s2.rs index d1aebcb4940..3e4c9090e24 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.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 + }; + ("i2s.bck_divider_in_conf") => { + false + }; + ("i2s.msb_shift_in_conf") => { + 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..56c819e957f 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.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 + }; + ("i2s.bck_divider_in_conf") => { + false + }; + ("i2s.msb_shift_in_conf") => { + false + }; ("interrupts.status_registers") => { 4 }; diff --git a/esp-metadata/devices/esp32.toml b/esp-metadata/devices/esp32.toml index 823865e3020..b6cc72ec6b0 100644 --- a/esp-metadata/devices/esp32.toml +++ b/esp-metadata/devices/esp32.toml @@ -879,6 +879,10 @@ deep_sleep = true ## Interfaces [device.i2s] +version = 1 +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..a9d85189535 100644 --- a/esp-metadata/devices/esp32c3.toml +++ b/esp-metadata/devices/esp32c3.toml @@ -537,6 +537,10 @@ deep_sleep = true ## Interfaces [device.i2s] +version = 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..2835fc1ef2e 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,12 @@ support_status = { status = "not_supported", issue = 5166 } support_status = { status = "not_supported", issue = 5444 } [device.i2s] -support_status = { status = "not_supported", issue = 5172 } +version = 2 +mclk_divider_bit_width = 9 +max_ws_width = 512 +clock_configured_by_pcr = true +bck_divider_in_conf = true +msb_shift_in_conf = true [device.io_mux] diff --git a/esp-metadata/devices/esp32c6.toml b/esp-metadata/devices/esp32c6.toml index ebf04019699..dcf158d0bc2 100644 --- a/esp-metadata/devices/esp32c6.toml +++ b/esp-metadata/devices/esp32c6.toml @@ -752,6 +752,11 @@ version = 1 ## Interfaces [device.i2s] +version = 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..02303717c3a 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,12 @@ support_status = { status = "not_supported", issue = 5423 } [device.io_mux] [device.i2s] -support_status = { status = "not_supported", issue = 5415 } +version = 2 +mclk_divider_bit_width = 9 +max_ws_width = 512 +clock_configured_by_pcr = true +bck_divider_in_conf = true +msb_shift_in_conf = 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..1fd7442bf9e 100644 --- a/esp-metadata/devices/esp32h2.toml +++ b/esp-metadata/devices/esp32h2.toml @@ -650,6 +650,13 @@ deep_sleep = true ## Interfaces [device.i2s] +version = 2 +mclk_divider_bit_width = 9 +max_ws_width = 512 +clock_configured_by_pcr = true +bck_divider_in_conf = true +msb_shift_in_conf = true + [device.ledc] [device.mcpwm] [device.pcnt] diff --git a/esp-metadata/devices/esp32s2.toml b/esp-metadata/devices/esp32s2.toml index 75c31523b5c..19e785e4bb3 100644 --- a/esp-metadata/devices/esp32s2.toml +++ b/esp-metadata/devices/esp32s2.toml @@ -672,6 +672,10 @@ deep_sleep = true ## Interfaces [device.i2s] +version = 1 +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..12401a78850 100644 --- a/esp-metadata/devices/esp32s3.toml +++ b/esp-metadata/devices/esp32s3.toml @@ -866,6 +866,10 @@ deep_sleep = true ## Interfaces [device.i2s] +version = 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..52bd2a0fc93 100644 --- a/esp-metadata/src/cfg.rs +++ b/esp-metadata/src/cfg.rs @@ -452,7 +452,17 @@ driver_configs![ I2sProperties { driver: i2s, name: "I2S", - properties: {} + properties: { + version: u32, + mclk_divider_bit_width: u32, + max_ws_width: u32, + #[serde(default)] + clock_configured_by_pcr: bool, + #[serde(default)] + bck_divider_in_conf: bool, + #[serde(default)] + msb_shift_in_conf: 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] diff --git a/qa-test/src/bin/embassy_wifi_i2s.rs b/qa-test/src/bin/embassy_wifi_i2s.rs index ca01f329bc2..95c867ec94c 100644 --- a/qa-test/src/bin/embassy_wifi_i2s.rs +++ b/qa-test/src/bin/embassy_wifi_i2s.rs @@ -1,5 +1,5 @@ //% FEATURES: esp-radio esp-radio/wifi esp-radio/unstable esp-hal/unstable -//% CHIPS: esp32 esp32s2 esp32s3 +//% CHIPS: esp32 esp32c5 esp32c61 esp32s2 esp32s3 #![no_std] #![no_main] From 9862c692318126f0445ffebf5cbd80dacce37f93 Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Thu, 30 Apr 2026 16:25:56 +0200 Subject: [PATCH 2/9] FMT + comment new I2S metadata flags --- esp-hal/src/i2s/master.rs | 3 +-- esp-metadata/src/cfg.rs | 8 ++++++++ qa-test/src/bin/embassy_wifi_i2s.rs | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/esp-hal/src/i2s/master.rs b/esp-hal/src/i2s/master.rs index cb490d656e6..39a960fb50a 100644 --- a/esp-hal/src/i2s/master.rs +++ b/esp-hal/src/i2s/master.rs @@ -161,8 +161,7 @@ pub enum I2sInterrupt { TxDone, } -pub(crate) const I2S_LL_MCLK_DIVIDER_BIT_WIDTH: usize = - property!("i2s.mclk_divider_bit_width"); +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; diff --git a/esp-metadata/src/cfg.rs b/esp-metadata/src/cfg.rs index 52bd2a0fc93..9f77430ac21 100644 --- a/esp-metadata/src/cfg.rs +++ b/esp-metadata/src/cfg.rs @@ -453,14 +453,22 @@ driver_configs![ driver: i2s, name: "I2S", properties: { + /// Register-layout generation derived from the chip SVD. version: u32, + /// Width of the MCLK divider field in the I2S clock register. mclk_divider_bit_width: u32, + /// Largest WS divider value supported by the peripheral. max_ws_width: u32, #[serde(default)] + /// Whether I2S clock/reset control is performed via PCR. clock_configured_by_pcr: bool, #[serde(default)] + /// Whether BCK divider fields live in the main TX/RX_CONF registers. + /// Another option is CONF1 registers. bck_divider_in_conf: bool, #[serde(default)] + /// Whether MSB shift fields live in the main TX/RX_CONF registers. + /// Another option is CONF1 registers. msb_shift_in_conf: bool, } }, diff --git a/qa-test/src/bin/embassy_wifi_i2s.rs b/qa-test/src/bin/embassy_wifi_i2s.rs index 95c867ec94c..ca01f329bc2 100644 --- a/qa-test/src/bin/embassy_wifi_i2s.rs +++ b/qa-test/src/bin/embassy_wifi_i2s.rs @@ -1,5 +1,5 @@ //% FEATURES: esp-radio esp-radio/wifi esp-radio/unstable esp-hal/unstable -//% CHIPS: esp32 esp32c5 esp32c61 esp32s2 esp32s3 +//% CHIPS: esp32 esp32s2 esp32s3 #![no_std] #![no_main] From 79469a41889464e23fb817ff619ca3dae5a7444a Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Thu, 30 Apr 2026 17:03:17 +0200 Subject: [PATCH 3/9] changlogs --- esp-hal/CHANGELOG.md | 1 + esp-metadata/CHANGELOG.md | 2 ++ 2 files changed, 3 insertions(+) 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-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 From 000e91989226a955d03b13fdc56a9f8401166549 Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Thu, 30 Apr 2026 17:04:33 +0200 Subject: [PATCH 4/9] lint --- esp-hal/src/i2s/master.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esp-hal/src/i2s/master.rs b/esp-hal/src/i2s/master.rs index 39a960fb50a..1fd821f8ee1 100644 --- a/esp-hal/src/i2s/master.rs +++ b/esp-hal/src/i2s/master.rs @@ -675,7 +675,7 @@ impl UnitConfig { WsWidth::Bits(bits) => bits, }; - const MAX_WS_WIDTH: u16 = property!("i2s.max_ws_width") as u16; + 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 From 8ab1050db4ce615f56e2fd7becb3f5181efca373 Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Mon, 4 May 2026 12:55:25 +0200 Subject: [PATCH 5/9] rename and unify two CONF1 related options --- esp-hal/src/i2s/master.rs | 24 +++++++++---------- .../src/_build_script_utils.rs | 21 ++++++---------- .../src/_generated_esp32.rs | 5 +--- .../src/_generated_esp32c3.rs | 5 +--- .../src/_generated_esp32c5.rs | 5 +--- .../src/_generated_esp32c6.rs | 5 +--- .../src/_generated_esp32c61.rs | 5 +--- .../src/_generated_esp32h2.rs | 5 +--- .../src/_generated_esp32s2.rs | 5 +--- .../src/_generated_esp32s3.rs | 5 +--- esp-metadata/devices/esp32c5.toml | 3 +-- esp-metadata/devices/esp32c61.toml | 3 +-- esp-metadata/devices/esp32h2.toml | 3 +-- esp-metadata/src/cfg.rs | 9 ++----- 14 files changed, 32 insertions(+), 71 deletions(-) diff --git a/esp-hal/src/i2s/master.rs b/esp-hal/src/i2s/master.rs index 1fd821f8ee1..c7f51ced549 100644 --- a/esp-hal/src/i2s/master.rs +++ b/esp-hal/src/i2s/master.rs @@ -1829,12 +1829,12 @@ mod private { w.tx_clkm_div_num().bits(clock_settings.mclk_divider as u8) }); - #[cfg(not(i2s_bck_divider_in_conf))] + #[cfg(not(i2s_conf1_fields_in_conf))] self.regs().tx_conf1().modify(|_, w| unsafe { w.tx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) }); - #[cfg(i2s_bck_divider_in_conf)] + #[cfg(i2s_conf1_fields_in_conf)] self.regs().tx_conf().modify(|_, w| unsafe { w.tx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) @@ -1861,12 +1861,12 @@ mod private { w.mclk_sel().bit(true) }); - #[cfg(not(i2s_bck_divider_in_conf))] + #[cfg(not(i2s_conf1_fields_in_conf))] self.regs().rx_conf1().modify(|_, w| unsafe { w.rx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) }); - #[cfg(i2s_bck_divider_in_conf)] + #[cfg(i2s_conf1_fields_in_conf)] self.regs().rx_conf().modify(|_, w| unsafe { w.rx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) @@ -1896,13 +1896,13 @@ mod private { .bits(clock_settings.mclk_divider as u8) }); - #[cfg(not(i2s_bck_divider_in_conf))] + #[cfg(not(i2s_conf1_fields_in_conf))] self.regs().tx_conf1().modify(|_, w| unsafe { w.tx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) }); - #[cfg(i2s_bck_divider_in_conf)] + #[cfg(i2s_conf1_fields_in_conf)] self.regs().tx_conf().modify(|_, w| unsafe { w.tx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) @@ -1933,13 +1933,13 @@ mod private { w.i2s_mclk_sel().bit(true) }); - #[cfg(not(i2s_bck_divider_in_conf))] + #[cfg(not(i2s_conf1_fields_in_conf))] self.regs().rx_conf1().modify(|_, w| unsafe { w.rx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) }); - #[cfg(i2s_bck_divider_in_conf)] + #[cfg(i2s_conf1_fields_in_conf)] self.regs().rx_conf().modify(|_, w| unsafe { w.rx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) @@ -1971,7 +1971,7 @@ mod private { self.set_tx_clock(config.calculate_clock()); self.regs().tx_conf1().modify(|_, w| unsafe { - #[cfg(not(i2s_msb_shift_in_conf))] + #[cfg(not(i2s_conf1_fields_in_conf))] w.tx_msb_shift().bit(config.msb_shift); #[allow(clippy::useless_conversion)] w.tx_tdm_ws_width().bits((ws_width - 1).try_into().unwrap()); @@ -1990,7 +1990,7 @@ mod private { w.tx_tdm_en().set_bit(); w.tx_pdm_en().clear_bit(); w.tx_pcm_bypass().set_bit(); - #[cfg(i2s_msb_shift_in_conf)] + #[cfg(i2s_conf1_fields_in_conf)] w.tx_msb_shift().bit(config.msb_shift); w.tx_big_endian() .bit(config.endianness == Endianness::BigEndian); @@ -2037,7 +2037,7 @@ mod private { self.set_rx_clock(config.calculate_clock()); self.regs().rx_conf1().modify(|_, w| unsafe { - #[cfg(not(i2s_msb_shift_in_conf))] + #[cfg(not(i2s_conf1_fields_in_conf))] w.rx_msb_shift().bit(config.msb_shift); #[allow(clippy::useless_conversion)] w.rx_tdm_ws_width().bits((ws_width - 1).try_into().unwrap()); @@ -2055,7 +2055,7 @@ mod private { w.rx_tdm_en().set_bit(); w.rx_pdm_en().clear_bit(); w.rx_pcm_bypass().set_bit(); - #[cfg(i2s_msb_shift_in_conf)] + #[cfg(i2s_conf1_fields_in_conf)] w.rx_msb_shift().bit(config.msb_shift); w.rx_big_endian() .bit(config.endianness == Endianness::BigEndian); diff --git a/esp-metadata-generated/src/_build_script_utils.rs b/esp-metadata-generated/src/_build_script_utils.rs index 84c1b2ef6b8..ea83690375c 100644 --- a/esp-metadata-generated/src/_build_script_utils.rs +++ b/esp-metadata-generated/src/_build_script_utils.rs @@ -1896,8 +1896,7 @@ impl Chip { "i2s_mclk_divider_bit_width=\"9\"", "i2s_max_ws_width=\"512\"", "i2s_clock_configured_by_pcr", - "i2s_bck_divider_in_conf", - "i2s_msb_shift_in_conf", + "i2s_conf1_fields_in_conf", "interrupts_status_registers=\"3\"", "interrupt_controller=\"clic\"", "lp_i2c_master_fifo_size=\"16\"", @@ -2153,8 +2152,7 @@ impl Chip { "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"9\"", "cargo:rustc-cfg=i2s_max_ws_width=\"512\"", "cargo:rustc-cfg=i2s_clock_configured_by_pcr", - "cargo:rustc-cfg=i2s_bck_divider_in_conf", - "cargo:rustc-cfg=i2s_msb_shift_in_conf", + "cargo:rustc-cfg=i2s_conf1_fields_in_conf", "cargo:rustc-cfg=interrupts_status_registers=\"3\"", "cargo:rustc-cfg=interrupt_controller=\"clic\"", "cargo:rustc-cfg=lp_i2c_master_fifo_size=\"16\"", @@ -3221,8 +3219,7 @@ impl Chip { "i2s_mclk_divider_bit_width=\"9\"", "i2s_max_ws_width=\"512\"", "i2s_clock_configured_by_pcr", - "i2s_bck_divider_in_conf", - "i2s_msb_shift_in_conf", + "i2s_conf1_fields_in_conf", "interrupts_status_registers=\"3\"", "interrupt_controller=\"clic\"", "phy_combo_module", @@ -3418,8 +3415,7 @@ impl Chip { "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"9\"", "cargo:rustc-cfg=i2s_max_ws_width=\"512\"", "cargo:rustc-cfg=i2s_clock_configured_by_pcr", - "cargo:rustc-cfg=i2s_bck_divider_in_conf", - "cargo:rustc-cfg=i2s_msb_shift_in_conf", + "cargo:rustc-cfg=i2s_conf1_fields_in_conf", "cargo:rustc-cfg=interrupts_status_registers=\"3\"", "cargo:rustc-cfg=interrupt_controller=\"clic\"", "cargo:rustc-cfg=phy_combo_module", @@ -3789,8 +3785,7 @@ impl Chip { "i2s_mclk_divider_bit_width=\"9\"", "i2s_max_ws_width=\"512\"", "i2s_clock_configured_by_pcr", - "i2s_bck_divider_in_conf", - "i2s_msb_shift_in_conf", + "i2s_conf1_fields_in_conf", "interrupts_status_registers=\"2\"", "interrupt_controller=\"plic\"", "parl_io_version=\"2\"", @@ -4035,8 +4030,7 @@ impl Chip { "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"9\"", "cargo:rustc-cfg=i2s_max_ws_width=\"512\"", "cargo:rustc-cfg=i2s_clock_configured_by_pcr", - "cargo:rustc-cfg=i2s_bck_divider_in_conf", - "cargo:rustc-cfg=i2s_msb_shift_in_conf", + "cargo:rustc-cfg=i2s_conf1_fields_in_conf", "cargo:rustc-cfg=interrupts_status_registers=\"2\"", "cargo:rustc-cfg=interrupt_controller=\"plic\"", "cargo:rustc-cfg=parl_io_version=\"2\"", @@ -6461,8 +6455,7 @@ pub fn emit_check_cfg_directives() { 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(i2s_bck_divider_in_conf)"); - println!("cargo:rustc-check-cfg=cfg(i2s_msb_shift_in_conf)"); + println!("cargo:rustc-check-cfg=cfg(i2s_conf1_fields_in_conf)"); 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)"); diff --git a/esp-metadata-generated/src/_generated_esp32.rs b/esp-metadata-generated/src/_generated_esp32.rs index 5381a90164a..89ef66d39d8 100644 --- a/esp-metadata-generated/src/_generated_esp32.rs +++ b/esp-metadata-generated/src/_generated_esp32.rs @@ -196,10 +196,7 @@ macro_rules! property { ("i2s.clock_configured_by_pcr") => { false }; - ("i2s.bck_divider_in_conf") => { - false - }; - ("i2s.msb_shift_in_conf") => { + ("i2s.conf1_fields_in_conf") => { false }; ("interrupts.status_registers") => { diff --git a/esp-metadata-generated/src/_generated_esp32c3.rs b/esp-metadata-generated/src/_generated_esp32c3.rs index 6256abf1053..cd20f15a3d8 100644 --- a/esp-metadata-generated/src/_generated_esp32c3.rs +++ b/esp-metadata-generated/src/_generated_esp32c3.rs @@ -217,10 +217,7 @@ macro_rules! property { ("i2s.clock_configured_by_pcr") => { false }; - ("i2s.bck_divider_in_conf") => { - false - }; - ("i2s.msb_shift_in_conf") => { + ("i2s.conf1_fields_in_conf") => { false }; ("interrupts.status_registers") => { diff --git a/esp-metadata-generated/src/_generated_esp32c5.rs b/esp-metadata-generated/src/_generated_esp32c5.rs index faf7d033dc5..4dc292894a2 100644 --- a/esp-metadata-generated/src/_generated_esp32c5.rs +++ b/esp-metadata-generated/src/_generated_esp32c5.rs @@ -232,10 +232,7 @@ macro_rules! property { ("i2s.clock_configured_by_pcr") => { true }; - ("i2s.bck_divider_in_conf") => { - true - }; - ("i2s.msb_shift_in_conf") => { + ("i2s.conf1_fields_in_conf") => { true }; ("interrupts.status_registers") => { diff --git a/esp-metadata-generated/src/_generated_esp32c6.rs b/esp-metadata-generated/src/_generated_esp32c6.rs index 19d9a3e49b1..a7b409f7920 100644 --- a/esp-metadata-generated/src/_generated_esp32c6.rs +++ b/esp-metadata-generated/src/_generated_esp32c6.rs @@ -232,10 +232,7 @@ macro_rules! property { ("i2s.clock_configured_by_pcr") => { true }; - ("i2s.bck_divider_in_conf") => { - false - }; - ("i2s.msb_shift_in_conf") => { + ("i2s.conf1_fields_in_conf") => { false }; ("interrupts.status_registers") => { diff --git a/esp-metadata-generated/src/_generated_esp32c61.rs b/esp-metadata-generated/src/_generated_esp32c61.rs index aae8b0f8f7f..d1f5079fa9f 100644 --- a/esp-metadata-generated/src/_generated_esp32c61.rs +++ b/esp-metadata-generated/src/_generated_esp32c61.rs @@ -223,10 +223,7 @@ macro_rules! property { ("i2s.clock_configured_by_pcr") => { true }; - ("i2s.bck_divider_in_conf") => { - true - }; - ("i2s.msb_shift_in_conf") => { + ("i2s.conf1_fields_in_conf") => { true }; ("interrupts.status_registers") => { diff --git a/esp-metadata-generated/src/_generated_esp32h2.rs b/esp-metadata-generated/src/_generated_esp32h2.rs index 5d8914f8227..0e1c1c5b0fd 100644 --- a/esp-metadata-generated/src/_generated_esp32h2.rs +++ b/esp-metadata-generated/src/_generated_esp32h2.rs @@ -232,10 +232,7 @@ macro_rules! property { ("i2s.clock_configured_by_pcr") => { true }; - ("i2s.bck_divider_in_conf") => { - true - }; - ("i2s.msb_shift_in_conf") => { + ("i2s.conf1_fields_in_conf") => { true }; ("interrupts.status_registers") => { diff --git a/esp-metadata-generated/src/_generated_esp32s2.rs b/esp-metadata-generated/src/_generated_esp32s2.rs index 3e4c9090e24..998ea37d617 100644 --- a/esp-metadata-generated/src/_generated_esp32s2.rs +++ b/esp-metadata-generated/src/_generated_esp32s2.rs @@ -202,10 +202,7 @@ macro_rules! property { ("i2s.clock_configured_by_pcr") => { false }; - ("i2s.bck_divider_in_conf") => { - false - }; - ("i2s.msb_shift_in_conf") => { + ("i2s.conf1_fields_in_conf") => { false }; ("interrupts.status_registers") => { diff --git a/esp-metadata-generated/src/_generated_esp32s3.rs b/esp-metadata-generated/src/_generated_esp32s3.rs index 56c819e957f..36709c019b9 100644 --- a/esp-metadata-generated/src/_generated_esp32s3.rs +++ b/esp-metadata-generated/src/_generated_esp32s3.rs @@ -217,10 +217,7 @@ macro_rules! property { ("i2s.clock_configured_by_pcr") => { false }; - ("i2s.bck_divider_in_conf") => { - false - }; - ("i2s.msb_shift_in_conf") => { + ("i2s.conf1_fields_in_conf") => { false }; ("interrupts.status_registers") => { diff --git a/esp-metadata/devices/esp32c5.toml b/esp-metadata/devices/esp32c5.toml index 2835fc1ef2e..f4016db64a9 100644 --- a/esp-metadata/devices/esp32c5.toml +++ b/esp-metadata/devices/esp32c5.toml @@ -714,8 +714,7 @@ version = 2 mclk_divider_bit_width = 9 max_ws_width = 512 clock_configured_by_pcr = true -bck_divider_in_conf = true -msb_shift_in_conf = true +conf1_fields_in_conf = true [device.io_mux] diff --git a/esp-metadata/devices/esp32c61.toml b/esp-metadata/devices/esp32c61.toml index 02303717c3a..46d8671b23a 100644 --- a/esp-metadata/devices/esp32c61.toml +++ b/esp-metadata/devices/esp32c61.toml @@ -494,8 +494,7 @@ version = 2 mclk_divider_bit_width = 9 max_ws_width = 512 clock_configured_by_pcr = true -bck_divider_in_conf = true -msb_shift_in_conf = true +conf1_fields_in_conf = 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 1fd7442bf9e..8541d6df1cb 100644 --- a/esp-metadata/devices/esp32h2.toml +++ b/esp-metadata/devices/esp32h2.toml @@ -654,8 +654,7 @@ version = 2 mclk_divider_bit_width = 9 max_ws_width = 512 clock_configured_by_pcr = true -bck_divider_in_conf = true -msb_shift_in_conf = true +conf1_fields_in_conf = true [device.ledc] [device.mcpwm] diff --git a/esp-metadata/src/cfg.rs b/esp-metadata/src/cfg.rs index 9f77430ac21..7327a657776 100644 --- a/esp-metadata/src/cfg.rs +++ b/esp-metadata/src/cfg.rs @@ -463,13 +463,8 @@ driver_configs![ /// Whether I2S clock/reset control is performed via PCR. clock_configured_by_pcr: bool, #[serde(default)] - /// Whether BCK divider fields live in the main TX/RX_CONF registers. - /// Another option is CONF1 registers. - bck_divider_in_conf: bool, - #[serde(default)] - /// Whether MSB shift fields live in the main TX/RX_CONF registers. - /// Another option is CONF1 registers. - msb_shift_in_conf: bool, + /// Whether CONF1 fields (BCK divider and MSB shift) live in TX/RX_CONF. + conf1_fields_in_conf: bool, } }, IeeeProperties { From 4e8de68c9b2d90aa43b02b7b07275b9d1a5ba163 Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Mon, 4 May 2026 14:31:50 +0200 Subject: [PATCH 6/9] Remove I2S-related constants, use clocks from metadata, clk_src to mdata --- esp-hal/src/i2s/master.rs | 14 ++++++-------- esp-hal/src/i2s/parallel.rs | 4 ++-- esp-hal/src/soc/esp32/mod.rs | 8 ++------ esp-hal/src/soc/esp32c3/mod.rs | 12 ++---------- esp-hal/src/soc/esp32c5/mod.rs | 10 ++-------- esp-hal/src/soc/esp32c6/mod.rs | 10 ++-------- esp-hal/src/soc/esp32c61/mod.rs | 10 ++-------- esp-hal/src/soc/esp32h2/mod.rs | 10 ++-------- esp-hal/src/soc/esp32s2/mod.rs | 17 +++++++---------- esp-hal/src/soc/esp32s3/mod.rs | 12 ++---------- .../src/_build_script_utils.rs | 17 +++++++++++++++++ esp-metadata-generated/src/_generated_esp32.rs | 6 ++++++ .../src/_generated_esp32c3.rs | 6 ++++++ .../src/_generated_esp32c5.rs | 6 ++++++ .../src/_generated_esp32c6.rs | 6 ++++++ .../src/_generated_esp32c61.rs | 6 ++++++ .../src/_generated_esp32h2.rs | 6 ++++++ .../src/_generated_esp32s2.rs | 6 ++++++ .../src/_generated_esp32s3.rs | 6 ++++++ esp-metadata/devices/esp32.toml | 1 + esp-metadata/devices/esp32c3.toml | 1 + esp-metadata/devices/esp32c5.toml | 1 + esp-metadata/devices/esp32c6.toml | 1 + esp-metadata/devices/esp32c61.toml | 1 + esp-metadata/devices/esp32h2.toml | 1 + esp-metadata/devices/esp32s2.toml | 1 + esp-metadata/devices/esp32s3.toml | 1 + esp-metadata/src/cfg.rs | 2 ++ 28 files changed, 104 insertions(+), 78 deletions(-) diff --git a/esp-hal/src/i2s/master.rs b/esp-hal/src/i2s/master.rs index c7f51ced549..4ee68937226 100644 --- a/esp-hal/src/i2s/master.rs +++ b/esp-hal/src/i2s/master.rs @@ -1483,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)] @@ -1824,8 +1824,7 @@ 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) }); @@ -1855,8 +1854,7 @@ 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) }); @@ -1891,7 +1889,7 @@ 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) }); @@ -1927,7 +1925,7 @@ 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) @@ -2414,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(); 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..9817a638ad2 100644 --- a/esp-hal/src/soc/esp32/mod.rs +++ b/esp-hal/src/soc/esp32/mod.rs @@ -16,12 +16,8 @@ pub(crate) mod regi2c; pub(crate) use esp32 as pac; -#[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..e3bedbc96cb 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,8 @@ pub(crate) mod regi2c; pub(crate) use esp32c3 as pac; -#[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 b62d5255ba9..1a1a632d4ac 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,12 +13,8 @@ pub(crate) mod regi2c; pub(crate) use esp32c5 as pac; -#[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/esp32c6/mod.rs b/esp-hal/src/soc/esp32c6/mod.rs index 227ce96342c..4735e1cc93c 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,8 @@ pub(crate) mod regi2c; pub(crate) use esp32c6 as pac; -#[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 a306512aecf..2b582411dfe 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,12 +13,8 @@ pub(crate) mod regi2c; pub(crate) use esp32c61 as pac; -#[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/esp32h2/mod.rs b/esp-hal/src/soc/esp32h2/mod.rs index 82d7c190cb4..5de747773f6 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,8 @@ pub(crate) mod regi2c; pub(crate) use esp32h2 as pac; -#[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..c5bd0367724 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,13 @@ pub(crate) mod regi2c; pub(crate) use esp32s2 as pac; -#[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..8f03bdf277b 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,8 @@ pub(crate) mod regi2c; pub use esp32s3 as pac; -#[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 ea83690375c..bdfab83bd45 100644 --- a/esp-metadata-generated/src/_build_script_utils.rs +++ b/esp-metadata-generated/src/_build_script_utils.rs @@ -338,6 +338,7 @@ impl Chip { "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", "i2s_version=\"1\"", + "i2s_default_clock_source=\"2\"", "i2s_mclk_divider_bit_width=\"6\"", "i2s_max_ws_width=\"128\"", "interrupts_status_registers=\"3\"", @@ -541,6 +542,7 @@ impl Chip { "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_default_clock_source=\"2\"", "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"6\"", "cargo:rustc-cfg=i2s_max_ws_width=\"128\"", "cargo:rustc-cfg=interrupts_status_registers=\"3\"", @@ -1328,6 +1330,7 @@ impl Chip { "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", "i2s_version=\"2\"", + "i2s_default_clock_source=\"2\"", "i2s_mclk_divider_bit_width=\"9\"", "i2s_max_ws_width=\"128\"", "interrupts_status_registers=\"2\"", @@ -1536,6 +1539,7 @@ impl Chip { "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_default_clock_source=\"2\"", "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"9\"", "cargo:rustc-cfg=i2s_max_ws_width=\"128\"", "cargo:rustc-cfg=interrupts_status_registers=\"2\"", @@ -1893,6 +1897,7 @@ impl Chip { "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", "i2s_version=\"2\"", + "i2s_default_clock_source=\"2\"", "i2s_mclk_divider_bit_width=\"9\"", "i2s_max_ws_width=\"512\"", "i2s_clock_configured_by_pcr", @@ -2149,6 +2154,7 @@ impl Chip { "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_default_clock_source=\"2\"", "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"9\"", "cargo:rustc-cfg=i2s_max_ws_width=\"512\"", "cargo:rustc-cfg=i2s_clock_configured_by_pcr", @@ -2561,6 +2567,7 @@ impl Chip { "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", "i2s_version=\"2\"", + "i2s_default_clock_source=\"2\"", "i2s_mclk_divider_bit_width=\"9\"", "i2s_max_ws_width=\"128\"", "i2s_clock_configured_by_pcr", @@ -2841,6 +2848,7 @@ impl Chip { "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_default_clock_source=\"2\"", "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"9\"", "cargo:rustc-cfg=i2s_max_ws_width=\"128\"", "cargo:rustc-cfg=i2s_clock_configured_by_pcr", @@ -3216,6 +3224,7 @@ impl Chip { "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", "i2s_version=\"2\"", + "i2s_default_clock_source=\"2\"", "i2s_mclk_divider_bit_width=\"9\"", "i2s_max_ws_width=\"512\"", "i2s_clock_configured_by_pcr", @@ -3412,6 +3421,7 @@ impl Chip { "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_default_clock_source=\"2\"", "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"9\"", "cargo:rustc-cfg=i2s_max_ws_width=\"512\"", "cargo:rustc-cfg=i2s_clock_configured_by_pcr", @@ -3782,6 +3792,7 @@ impl Chip { "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", "i2s_version=\"2\"", + "i2s_default_clock_source=\"1\"", "i2s_mclk_divider_bit_width=\"9\"", "i2s_max_ws_width=\"512\"", "i2s_clock_configured_by_pcr", @@ -4027,6 +4038,7 @@ impl Chip { "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_default_clock_source=\"1\"", "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"9\"", "cargo:rustc-cfg=i2s_max_ws_width=\"512\"", "cargo:rustc-cfg=i2s_clock_configured_by_pcr", @@ -4891,6 +4903,7 @@ impl Chip { "i2c_master_ll_intr_mask=\"131071\"", "i2c_master_fifo_size=\"32\"", "i2s_version=\"1\"", + "i2s_default_clock_source=\"2\"", "i2s_mclk_divider_bit_width=\"6\"", "i2s_max_ws_width=\"128\"", "interrupts_status_registers=\"3\"", @@ -5108,6 +5121,7 @@ impl Chip { "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_default_clock_source=\"2\"", "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"6\"", "cargo:rustc-cfg=i2s_max_ws_width=\"128\"", "cargo:rustc-cfg=interrupts_status_registers=\"3\"", @@ -5544,6 +5558,7 @@ impl Chip { "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", "i2s_version=\"2\"", + "i2s_default_clock_source=\"2\"", "i2s_mclk_divider_bit_width=\"6\"", "i2s_max_ws_width=\"128\"", "interrupts_status_registers=\"4\"", @@ -5798,6 +5813,7 @@ impl Chip { "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_default_clock_source=\"2\"", "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"6\"", "cargo:rustc-cfg=i2s_max_ws_width=\"128\"", "cargo:rustc-cfg=interrupts_status_registers=\"4\"", @@ -6593,6 +6609,7 @@ 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\"))"); + 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\"))"); diff --git a/esp-metadata-generated/src/_generated_esp32.rs b/esp-metadata-generated/src/_generated_esp32.rs index 89ef66d39d8..770fc6f22b6 100644 --- a/esp-metadata-generated/src/_generated_esp32.rs +++ b/esp-metadata-generated/src/_generated_esp32.rs @@ -181,6 +181,12 @@ macro_rules! property { ("i2s.version", str) => { stringify!(1) }; + ("i2s.default_clock_source") => { + 2 + }; + ("i2s.default_clock_source", str) => { + stringify!(2) + }; ("i2s.mclk_divider_bit_width") => { 6 }; diff --git a/esp-metadata-generated/src/_generated_esp32c3.rs b/esp-metadata-generated/src/_generated_esp32c3.rs index cd20f15a3d8..05a7cdcdec2 100644 --- a/esp-metadata-generated/src/_generated_esp32c3.rs +++ b/esp-metadata-generated/src/_generated_esp32c3.rs @@ -202,6 +202,12 @@ macro_rules! property { ("i2s.version", str) => { stringify!(2) }; + ("i2s.default_clock_source") => { + 2 + }; + ("i2s.default_clock_source", str) => { + stringify!(2) + }; ("i2s.mclk_divider_bit_width") => { 9 }; diff --git a/esp-metadata-generated/src/_generated_esp32c5.rs b/esp-metadata-generated/src/_generated_esp32c5.rs index 4dc292894a2..19977719880 100644 --- a/esp-metadata-generated/src/_generated_esp32c5.rs +++ b/esp-metadata-generated/src/_generated_esp32c5.rs @@ -217,6 +217,12 @@ macro_rules! property { ("i2s.version", str) => { stringify!(2) }; + ("i2s.default_clock_source") => { + 2 + }; + ("i2s.default_clock_source", str) => { + stringify!(2) + }; ("i2s.mclk_divider_bit_width") => { 9 }; diff --git a/esp-metadata-generated/src/_generated_esp32c6.rs b/esp-metadata-generated/src/_generated_esp32c6.rs index a7b409f7920..abc588d1ec3 100644 --- a/esp-metadata-generated/src/_generated_esp32c6.rs +++ b/esp-metadata-generated/src/_generated_esp32c6.rs @@ -217,6 +217,12 @@ macro_rules! property { ("i2s.version", str) => { stringify!(2) }; + ("i2s.default_clock_source") => { + 2 + }; + ("i2s.default_clock_source", str) => { + stringify!(2) + }; ("i2s.mclk_divider_bit_width") => { 9 }; diff --git a/esp-metadata-generated/src/_generated_esp32c61.rs b/esp-metadata-generated/src/_generated_esp32c61.rs index d1f5079fa9f..cb9d38f3ca0 100644 --- a/esp-metadata-generated/src/_generated_esp32c61.rs +++ b/esp-metadata-generated/src/_generated_esp32c61.rs @@ -208,6 +208,12 @@ macro_rules! property { ("i2s.version", str) => { stringify!(2) }; + ("i2s.default_clock_source") => { + 2 + }; + ("i2s.default_clock_source", str) => { + stringify!(2) + }; ("i2s.mclk_divider_bit_width") => { 9 }; diff --git a/esp-metadata-generated/src/_generated_esp32h2.rs b/esp-metadata-generated/src/_generated_esp32h2.rs index 0e1c1c5b0fd..702e8a54778 100644 --- a/esp-metadata-generated/src/_generated_esp32h2.rs +++ b/esp-metadata-generated/src/_generated_esp32h2.rs @@ -217,6 +217,12 @@ macro_rules! property { ("i2s.version", str) => { stringify!(2) }; + ("i2s.default_clock_source") => { + 1 + }; + ("i2s.default_clock_source", str) => { + stringify!(1) + }; ("i2s.mclk_divider_bit_width") => { 9 }; diff --git a/esp-metadata-generated/src/_generated_esp32s2.rs b/esp-metadata-generated/src/_generated_esp32s2.rs index 998ea37d617..7d1349ceff4 100644 --- a/esp-metadata-generated/src/_generated_esp32s2.rs +++ b/esp-metadata-generated/src/_generated_esp32s2.rs @@ -187,6 +187,12 @@ macro_rules! property { ("i2s.version", str) => { stringify!(1) }; + ("i2s.default_clock_source") => { + 2 + }; + ("i2s.default_clock_source", str) => { + stringify!(2) + }; ("i2s.mclk_divider_bit_width") => { 6 }; diff --git a/esp-metadata-generated/src/_generated_esp32s3.rs b/esp-metadata-generated/src/_generated_esp32s3.rs index 36709c019b9..84fddeb3c22 100644 --- a/esp-metadata-generated/src/_generated_esp32s3.rs +++ b/esp-metadata-generated/src/_generated_esp32s3.rs @@ -202,6 +202,12 @@ macro_rules! property { ("i2s.version", str) => { stringify!(2) }; + ("i2s.default_clock_source") => { + 2 + }; + ("i2s.default_clock_source", str) => { + stringify!(2) + }; ("i2s.mclk_divider_bit_width") => { 6 }; diff --git a/esp-metadata/devices/esp32.toml b/esp-metadata/devices/esp32.toml index b6cc72ec6b0..c8af0337a13 100644 --- a/esp-metadata/devices/esp32.toml +++ b/esp-metadata/devices/esp32.toml @@ -880,6 +880,7 @@ deep_sleep = true ## Interfaces [device.i2s] version = 1 +default_clock_source = 2 mclk_divider_bit_width = 6 max_ws_width = 128 diff --git a/esp-metadata/devices/esp32c3.toml b/esp-metadata/devices/esp32c3.toml index a9d85189535..344edcda7bb 100644 --- a/esp-metadata/devices/esp32c3.toml +++ b/esp-metadata/devices/esp32c3.toml @@ -538,6 +538,7 @@ deep_sleep = true ## Interfaces [device.i2s] version = 2 +default_clock_source = 2 mclk_divider_bit_width = 9 max_ws_width = 128 diff --git a/esp-metadata/devices/esp32c5.toml b/esp-metadata/devices/esp32c5.toml index f4016db64a9..3792814935e 100644 --- a/esp-metadata/devices/esp32c5.toml +++ b/esp-metadata/devices/esp32c5.toml @@ -711,6 +711,7 @@ support_status = { status = "not_supported", issue = 5444 } [device.i2s] version = 2 +default_clock_source = 2 mclk_divider_bit_width = 9 max_ws_width = 512 clock_configured_by_pcr = true diff --git a/esp-metadata/devices/esp32c6.toml b/esp-metadata/devices/esp32c6.toml index dcf158d0bc2..7f24dd0eb79 100644 --- a/esp-metadata/devices/esp32c6.toml +++ b/esp-metadata/devices/esp32c6.toml @@ -753,6 +753,7 @@ 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 diff --git a/esp-metadata/devices/esp32c61.toml b/esp-metadata/devices/esp32c61.toml index 46d8671b23a..d8e3560dfda 100644 --- a/esp-metadata/devices/esp32c61.toml +++ b/esp-metadata/devices/esp32c61.toml @@ -491,6 +491,7 @@ support_status = { status = "not_supported", issue = 5423 } [device.i2s] version = 2 +default_clock_source = 2 mclk_divider_bit_width = 9 max_ws_width = 512 clock_configured_by_pcr = true diff --git a/esp-metadata/devices/esp32h2.toml b/esp-metadata/devices/esp32h2.toml index 8541d6df1cb..13a3e7b853f 100644 --- a/esp-metadata/devices/esp32h2.toml +++ b/esp-metadata/devices/esp32h2.toml @@ -651,6 +651,7 @@ deep_sleep = true ## Interfaces [device.i2s] version = 2 +default_clock_source = 1 mclk_divider_bit_width = 9 max_ws_width = 512 clock_configured_by_pcr = true diff --git a/esp-metadata/devices/esp32s2.toml b/esp-metadata/devices/esp32s2.toml index 19e785e4bb3..fc07ca79996 100644 --- a/esp-metadata/devices/esp32s2.toml +++ b/esp-metadata/devices/esp32s2.toml @@ -673,6 +673,7 @@ deep_sleep = true ## Interfaces [device.i2s] version = 1 +default_clock_source = 2 mclk_divider_bit_width = 6 max_ws_width = 128 diff --git a/esp-metadata/devices/esp32s3.toml b/esp-metadata/devices/esp32s3.toml index 12401a78850..5f55cbacbcb 100644 --- a/esp-metadata/devices/esp32s3.toml +++ b/esp-metadata/devices/esp32s3.toml @@ -867,6 +867,7 @@ deep_sleep = true ## Interfaces [device.i2s] version = 2 +default_clock_source = 2 mclk_divider_bit_width = 6 max_ws_width = 128 diff --git a/esp-metadata/src/cfg.rs b/esp-metadata/src/cfg.rs index 7327a657776..e4fb9c19ba1 100644 --- a/esp-metadata/src/cfg.rs +++ b/esp-metadata/src/cfg.rs @@ -455,6 +455,8 @@ driver_configs![ properties: { /// Register-layout generation derived from the chip SVD. version: u32, + /// Default clock source selector written to the I2S clock source register. + default_clock_source: u32, /// Width of the MCLK divider field in the I2S clock register. mclk_divider_bit_width: u32, /// Largest WS divider value supported by the peripheral. From 680c9e295525a46aa1b54ca201877a381ba4d340 Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Mon, 4 May 2026 15:33:27 +0200 Subject: [PATCH 7/9] separate conf1-conf different chips into v3 --- esp-hal/src/i2s/master.rs | 30 +++++++++---------- .../src/_build_script_utils.rs | 21 +++++-------- .../src/_generated_esp32.rs | 3 -- .../src/_generated_esp32c3.rs | 3 -- .../src/_generated_esp32c5.rs | 7 ++--- .../src/_generated_esp32c6.rs | 3 -- .../src/_generated_esp32c61.rs | 7 ++--- .../src/_generated_esp32h2.rs | 7 ++--- .../src/_generated_esp32s2.rs | 3 -- .../src/_generated_esp32s3.rs | 3 -- esp-metadata/devices/esp32c5.toml | 3 +- esp-metadata/devices/esp32c61.toml | 3 +- esp-metadata/devices/esp32h2.toml | 3 +- esp-metadata/src/cfg.rs | 3 -- 14 files changed, 31 insertions(+), 68 deletions(-) diff --git a/esp-hal/src/i2s/master.rs b/esp-hal/src/i2s/master.rs index 4ee68937226..1a09b07a86a 100644 --- a/esp-hal/src/i2s/master.rs +++ b/esp-hal/src/i2s/master.rs @@ -1751,7 +1751,7 @@ mod private { } } - #[cfg(i2s_version = "2")] + #[cfg(not(i2s_version = "1"))] pub trait RegisterAccessPrivate: Signals + RegBlock { fn enable_listen(&self, interrupts: EnumSet, enable: bool) { self.regs().int_ena().modify(|_, w| { @@ -1828,12 +1828,12 @@ mod private { w.tx_clkm_div_num().bits(clock_settings.mclk_divider as u8) }); - #[cfg(not(i2s_conf1_fields_in_conf))] + #[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_conf1_fields_in_conf)] + #[cfg(i2s_version = "3")] self.regs().tx_conf().modify(|_, w| unsafe { w.tx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) @@ -1859,12 +1859,12 @@ mod private { w.mclk_sel().bit(true) }); - #[cfg(not(i2s_conf1_fields_in_conf))] + #[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_conf1_fields_in_conf)] + #[cfg(i2s_version = "3")] self.regs().rx_conf().modify(|_, w| unsafe { w.rx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) @@ -1894,13 +1894,13 @@ mod private { .bits(clock_settings.mclk_divider as u8) }); - #[cfg(not(i2s_conf1_fields_in_conf))] + #[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_conf1_fields_in_conf)] + #[cfg(i2s_version = "3")] self.regs().tx_conf().modify(|_, w| unsafe { w.tx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) @@ -1931,13 +1931,13 @@ mod private { w.i2s_mclk_sel().bit(true) }); - #[cfg(not(i2s_conf1_fields_in_conf))] + #[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_conf1_fields_in_conf)] + #[cfg(i2s_version = "3")] self.regs().rx_conf().modify(|_, w| unsafe { w.rx_bck_div_num() .bits((clock_settings.bclk_divider - 1) as u8) @@ -1969,7 +1969,7 @@ mod private { self.set_tx_clock(config.calculate_clock()); self.regs().tx_conf1().modify(|_, w| unsafe { - #[cfg(not(i2s_conf1_fields_in_conf))] + #[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()); @@ -1988,7 +1988,7 @@ mod private { w.tx_tdm_en().set_bit(); w.tx_pdm_en().clear_bit(); w.tx_pcm_bypass().set_bit(); - #[cfg(i2s_conf1_fields_in_conf)] + #[cfg(i2s_version = "3")] w.tx_msb_shift().bit(config.msb_shift); w.tx_big_endian() .bit(config.endianness == Endianness::BigEndian); @@ -2035,7 +2035,7 @@ mod private { self.set_rx_clock(config.calculate_clock()); self.regs().rx_conf1().modify(|_, w| unsafe { - #[cfg(not(i2s_conf1_fields_in_conf))] + #[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()); @@ -2053,7 +2053,7 @@ mod private { w.rx_tdm_en().set_bit(); w.rx_pdm_en().clear_bit(); w.rx_pcm_bypass().set_bit(); - #[cfg(i2s_conf1_fields_in_conf)] + #[cfg(i2s_version = "3")] w.rx_msb_shift().bit(config.msb_shift); w.rx_big_endian() .bit(config.endianness == Endianness::BigEndian); @@ -2394,7 +2394,7 @@ mod private { numerator: u32, } - #[cfg(i2s_version = "2")] + #[cfg(not(i2s_version = "1"))] pub struct I2sMclkDividers { x: u32, y: u32, @@ -2466,7 +2466,7 @@ mod private { } } - #[cfg(i2s_version = "2")] + #[cfg(not(i2s_version = "1"))] fn mclk_dividers(&self) -> I2sMclkDividers { let x; let y; diff --git a/esp-metadata-generated/src/_build_script_utils.rs b/esp-metadata-generated/src/_build_script_utils.rs index bdfab83bd45..07cb66b2f4f 100644 --- a/esp-metadata-generated/src/_build_script_utils.rs +++ b/esp-metadata-generated/src/_build_script_utils.rs @@ -1896,12 +1896,11 @@ impl Chip { "i2c_master_max_bus_timeout=\"31\"", "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", - "i2s_version=\"2\"", + "i2s_version=\"3\"", "i2s_default_clock_source=\"2\"", "i2s_mclk_divider_bit_width=\"9\"", "i2s_max_ws_width=\"512\"", "i2s_clock_configured_by_pcr", - "i2s_conf1_fields_in_conf", "interrupts_status_registers=\"3\"", "interrupt_controller=\"clic\"", "lp_i2c_master_fifo_size=\"16\"", @@ -2153,12 +2152,11 @@ 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=\"3\"", "cargo:rustc-cfg=i2s_default_clock_source=\"2\"", "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"9\"", "cargo:rustc-cfg=i2s_max_ws_width=\"512\"", "cargo:rustc-cfg=i2s_clock_configured_by_pcr", - "cargo:rustc-cfg=i2s_conf1_fields_in_conf", "cargo:rustc-cfg=interrupts_status_registers=\"3\"", "cargo:rustc-cfg=interrupt_controller=\"clic\"", "cargo:rustc-cfg=lp_i2c_master_fifo_size=\"16\"", @@ -3223,12 +3221,11 @@ impl Chip { "i2c_master_max_bus_timeout=\"31\"", "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", - "i2s_version=\"2\"", + "i2s_version=\"3\"", "i2s_default_clock_source=\"2\"", "i2s_mclk_divider_bit_width=\"9\"", "i2s_max_ws_width=\"512\"", "i2s_clock_configured_by_pcr", - "i2s_conf1_fields_in_conf", "interrupts_status_registers=\"3\"", "interrupt_controller=\"clic\"", "phy_combo_module", @@ -3420,12 +3417,11 @@ 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=\"3\"", "cargo:rustc-cfg=i2s_default_clock_source=\"2\"", "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"9\"", "cargo:rustc-cfg=i2s_max_ws_width=\"512\"", "cargo:rustc-cfg=i2s_clock_configured_by_pcr", - "cargo:rustc-cfg=i2s_conf1_fields_in_conf", "cargo:rustc-cfg=interrupts_status_registers=\"3\"", "cargo:rustc-cfg=interrupt_controller=\"clic\"", "cargo:rustc-cfg=phy_combo_module", @@ -3791,12 +3787,11 @@ impl Chip { "i2c_master_max_bus_timeout=\"31\"", "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", - "i2s_version=\"2\"", + "i2s_version=\"3\"", "i2s_default_clock_source=\"1\"", "i2s_mclk_divider_bit_width=\"9\"", "i2s_max_ws_width=\"512\"", "i2s_clock_configured_by_pcr", - "i2s_conf1_fields_in_conf", "interrupts_status_registers=\"2\"", "interrupt_controller=\"plic\"", "parl_io_version=\"2\"", @@ -4037,12 +4032,11 @@ 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=\"3\"", "cargo:rustc-cfg=i2s_default_clock_source=\"1\"", "cargo:rustc-cfg=i2s_mclk_divider_bit_width=\"9\"", "cargo:rustc-cfg=i2s_max_ws_width=\"512\"", "cargo:rustc-cfg=i2s_clock_configured_by_pcr", - "cargo:rustc-cfg=i2s_conf1_fields_in_conf", "cargo:rustc-cfg=interrupts_status_registers=\"2\"", "cargo:rustc-cfg=interrupt_controller=\"plic\"", "cargo:rustc-cfg=parl_io_version=\"2\"", @@ -6471,7 +6465,6 @@ pub fn emit_check_cfg_directives() { 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(i2s_conf1_fields_in_conf)"); 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)"); @@ -6608,7 +6601,7 @@ 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\"))"); + 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\"))"); diff --git a/esp-metadata-generated/src/_generated_esp32.rs b/esp-metadata-generated/src/_generated_esp32.rs index 770fc6f22b6..06600409ed4 100644 --- a/esp-metadata-generated/src/_generated_esp32.rs +++ b/esp-metadata-generated/src/_generated_esp32.rs @@ -202,9 +202,6 @@ macro_rules! property { ("i2s.clock_configured_by_pcr") => { false }; - ("i2s.conf1_fields_in_conf") => { - false - }; ("interrupts.status_registers") => { 3 }; diff --git a/esp-metadata-generated/src/_generated_esp32c3.rs b/esp-metadata-generated/src/_generated_esp32c3.rs index 05a7cdcdec2..34577278e3a 100644 --- a/esp-metadata-generated/src/_generated_esp32c3.rs +++ b/esp-metadata-generated/src/_generated_esp32c3.rs @@ -223,9 +223,6 @@ macro_rules! property { ("i2s.clock_configured_by_pcr") => { false }; - ("i2s.conf1_fields_in_conf") => { - false - }; ("interrupts.status_registers") => { 2 }; diff --git a/esp-metadata-generated/src/_generated_esp32c5.rs b/esp-metadata-generated/src/_generated_esp32c5.rs index 19977719880..4890dab7e7c 100644 --- a/esp-metadata-generated/src/_generated_esp32c5.rs +++ b/esp-metadata-generated/src/_generated_esp32c5.rs @@ -212,10 +212,10 @@ macro_rules! property { stringify!(32) }; ("i2s.version") => { - 2 + 3 }; ("i2s.version", str) => { - stringify!(2) + stringify!(3) }; ("i2s.default_clock_source") => { 2 @@ -238,9 +238,6 @@ macro_rules! property { ("i2s.clock_configured_by_pcr") => { true }; - ("i2s.conf1_fields_in_conf") => { - true - }; ("interrupts.status_registers") => { 3 }; diff --git a/esp-metadata-generated/src/_generated_esp32c6.rs b/esp-metadata-generated/src/_generated_esp32c6.rs index abc588d1ec3..94565ff35ca 100644 --- a/esp-metadata-generated/src/_generated_esp32c6.rs +++ b/esp-metadata-generated/src/_generated_esp32c6.rs @@ -238,9 +238,6 @@ macro_rules! property { ("i2s.clock_configured_by_pcr") => { true }; - ("i2s.conf1_fields_in_conf") => { - false - }; ("interrupts.status_registers") => { 3 }; diff --git a/esp-metadata-generated/src/_generated_esp32c61.rs b/esp-metadata-generated/src/_generated_esp32c61.rs index cb9d38f3ca0..9c122ade67d 100644 --- a/esp-metadata-generated/src/_generated_esp32c61.rs +++ b/esp-metadata-generated/src/_generated_esp32c61.rs @@ -203,10 +203,10 @@ macro_rules! property { stringify!(32) }; ("i2s.version") => { - 2 + 3 }; ("i2s.version", str) => { - stringify!(2) + stringify!(3) }; ("i2s.default_clock_source") => { 2 @@ -229,9 +229,6 @@ macro_rules! property { ("i2s.clock_configured_by_pcr") => { true }; - ("i2s.conf1_fields_in_conf") => { - true - }; ("interrupts.status_registers") => { 3 }; diff --git a/esp-metadata-generated/src/_generated_esp32h2.rs b/esp-metadata-generated/src/_generated_esp32h2.rs index 702e8a54778..39e8fda19dd 100644 --- a/esp-metadata-generated/src/_generated_esp32h2.rs +++ b/esp-metadata-generated/src/_generated_esp32h2.rs @@ -212,10 +212,10 @@ macro_rules! property { stringify!(32) }; ("i2s.version") => { - 2 + 3 }; ("i2s.version", str) => { - stringify!(2) + stringify!(3) }; ("i2s.default_clock_source") => { 1 @@ -238,9 +238,6 @@ macro_rules! property { ("i2s.clock_configured_by_pcr") => { true }; - ("i2s.conf1_fields_in_conf") => { - true - }; ("interrupts.status_registers") => { 2 }; diff --git a/esp-metadata-generated/src/_generated_esp32s2.rs b/esp-metadata-generated/src/_generated_esp32s2.rs index 7d1349ceff4..43b7da9f6e1 100644 --- a/esp-metadata-generated/src/_generated_esp32s2.rs +++ b/esp-metadata-generated/src/_generated_esp32s2.rs @@ -208,9 +208,6 @@ macro_rules! property { ("i2s.clock_configured_by_pcr") => { false }; - ("i2s.conf1_fields_in_conf") => { - false - }; ("interrupts.status_registers") => { 3 }; diff --git a/esp-metadata-generated/src/_generated_esp32s3.rs b/esp-metadata-generated/src/_generated_esp32s3.rs index 84fddeb3c22..98bae5a4253 100644 --- a/esp-metadata-generated/src/_generated_esp32s3.rs +++ b/esp-metadata-generated/src/_generated_esp32s3.rs @@ -223,9 +223,6 @@ macro_rules! property { ("i2s.clock_configured_by_pcr") => { false }; - ("i2s.conf1_fields_in_conf") => { - false - }; ("interrupts.status_registers") => { 4 }; diff --git a/esp-metadata/devices/esp32c5.toml b/esp-metadata/devices/esp32c5.toml index 3792814935e..bfed39d12b9 100644 --- a/esp-metadata/devices/esp32c5.toml +++ b/esp-metadata/devices/esp32c5.toml @@ -710,12 +710,11 @@ support_status = { status = "not_supported", issue = 5166 } support_status = { status = "not_supported", issue = 5444 } [device.i2s] -version = 2 +version = 3 default_clock_source = 2 mclk_divider_bit_width = 9 max_ws_width = 512 clock_configured_by_pcr = true -conf1_fields_in_conf = true [device.io_mux] diff --git a/esp-metadata/devices/esp32c61.toml b/esp-metadata/devices/esp32c61.toml index d8e3560dfda..3ea3bc71a3e 100644 --- a/esp-metadata/devices/esp32c61.toml +++ b/esp-metadata/devices/esp32c61.toml @@ -490,12 +490,11 @@ support_status = { status = "not_supported", issue = 5423 } [device.io_mux] [device.i2s] -version = 2 +version = 3 default_clock_source = 2 mclk_divider_bit_width = 9 max_ws_width = 512 clock_configured_by_pcr = true -conf1_fields_in_conf = 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 13a3e7b853f..885f435255d 100644 --- a/esp-metadata/devices/esp32h2.toml +++ b/esp-metadata/devices/esp32h2.toml @@ -650,12 +650,11 @@ deep_sleep = true ## Interfaces [device.i2s] -version = 2 +version = 3 default_clock_source = 1 mclk_divider_bit_width = 9 max_ws_width = 512 clock_configured_by_pcr = true -conf1_fields_in_conf = true [device.ledc] [device.mcpwm] diff --git a/esp-metadata/src/cfg.rs b/esp-metadata/src/cfg.rs index e4fb9c19ba1..21dd97f9670 100644 --- a/esp-metadata/src/cfg.rs +++ b/esp-metadata/src/cfg.rs @@ -464,9 +464,6 @@ driver_configs![ #[serde(default)] /// Whether I2S clock/reset control is performed via PCR. clock_configured_by_pcr: bool, - #[serde(default)] - /// Whether CONF1 fields (BCK divider and MSB shift) live in TX/RX_CONF. - conf1_fields_in_conf: bool, } }, IeeeProperties { From 89b2197ca41ca6b4ec292b6733c4711408a824eb Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Mon, 4 May 2026 17:00:02 +0200 Subject: [PATCH 8/9] remap DMA channel to be based on dma_kind --- esp-hal/src/i2s/master.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esp-hal/src/i2s/master.rs b/esp-hal/src/i2s/master.rs index 1a09b07a86a..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(i2s_version = "1") => "DMA_I2S0", - cfg(not(i2s_version = "1")) => "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);", From 1c199852f8974df017f62c67e5269c966116ee45 Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Tue, 5 May 2026 11:16:07 +0200 Subject: [PATCH 9/9] rebase, fix `unused` warnings --- esp-hal/README.md | 2 +- esp-hal/src/soc/esp32/mod.rs | 2 + esp-hal/src/soc/esp32c3/mod.rs | 2 + esp-hal/src/soc/esp32c5/mod.rs | 2 + esp-hal/src/soc/esp32c6/mod.rs | 2 + esp-hal/src/soc/esp32c61/mod.rs | 2 + esp-hal/src/soc/esp32h2/mod.rs | 2 + esp-hal/src/soc/esp32s2/mod.rs | 2 + esp-hal/src/soc/esp32s3/mod.rs | 2 + .../src/_build_script_utils.rs | 68 +++++++++++++++++++ .../src/_generated_esp32p4.rs | 3 + esp-metadata/src/cfg.rs | 8 +-- 12 files changed, 92 insertions(+), 5 deletions(-) diff --git a/esp-hal/README.md b/esp-hal/README.md index 669e9f5b028..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 | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | | ⚒️ | ⚒️ | diff --git a/esp-hal/src/soc/esp32/mod.rs b/esp-hal/src/soc/esp32/mod.rs index 9817a638ad2..8478fc3de6c 100644 --- a/esp-hal/src/soc/esp32/mod.rs +++ b/esp-hal/src/soc/esp32/mod.rs @@ -16,6 +16,8 @@ pub(crate) mod regi2c; pub(crate) use esp32 as pac; +#[cfg(i2s_driver_supported)] +#[cfg_attr(not(feature = "unstable"), allow(unused))] pub(crate) fn i2s_sclk_frequency() -> u32 { clocks::pll_f160m_clk_frequency() } diff --git a/esp-hal/src/soc/esp32c3/mod.rs b/esp-hal/src/soc/esp32c3/mod.rs index e3bedbc96cb..f6726077ba8 100644 --- a/esp-hal/src/soc/esp32c3/mod.rs +++ b/esp-hal/src/soc/esp32c3/mod.rs @@ -14,6 +14,8 @@ pub(crate) mod regi2c; pub(crate) use esp32c3 as pac; +#[cfg(i2s_driver_supported)] +#[cfg_attr(not(feature = "unstable"), allow(unused))] pub(crate) fn i2s_sclk_frequency() -> u32 { clocks::pll_160m_frequency() } diff --git a/esp-hal/src/soc/esp32c5/mod.rs b/esp-hal/src/soc/esp32c5/mod.rs index 1a1a632d4ac..5ff39510b07 100644 --- a/esp-hal/src/soc/esp32c5/mod.rs +++ b/esp-hal/src/soc/esp32c5/mod.rs @@ -13,6 +13,8 @@ pub(crate) mod regi2c; pub(crate) use esp32c5 as pac; +#[cfg(i2s_driver_supported)] +#[cfg_attr(not(feature = "unstable"), allow(unused))] pub(crate) fn i2s_sclk_frequency() -> u32 { clocks::pll_f160m_frequency() } diff --git a/esp-hal/src/soc/esp32c6/mod.rs b/esp-hal/src/soc/esp32c6/mod.rs index 4735e1cc93c..83f94b343f5 100644 --- a/esp-hal/src/soc/esp32c6/mod.rs +++ b/esp-hal/src/soc/esp32c6/mod.rs @@ -18,6 +18,8 @@ pub(crate) mod regi2c; pub(crate) use esp32c6 as pac; +#[cfg(i2s_driver_supported)] +#[cfg_attr(not(feature = "unstable"), allow(unused))] pub(crate) fn i2s_sclk_frequency() -> u32 { clocks::pll_f160m_frequency() } diff --git a/esp-hal/src/soc/esp32c61/mod.rs b/esp-hal/src/soc/esp32c61/mod.rs index 2b582411dfe..18374d1694c 100644 --- a/esp-hal/src/soc/esp32c61/mod.rs +++ b/esp-hal/src/soc/esp32c61/mod.rs @@ -13,6 +13,8 @@ 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() } diff --git a/esp-hal/src/soc/esp32h2/mod.rs b/esp-hal/src/soc/esp32h2/mod.rs index 5de747773f6..42a3628d1df 100644 --- a/esp-hal/src/soc/esp32h2/mod.rs +++ b/esp-hal/src/soc/esp32h2/mod.rs @@ -17,6 +17,8 @@ pub(crate) mod regi2c; pub(crate) use esp32h2 as pac; +#[cfg(i2s_driver_supported)] +#[cfg_attr(not(feature = "unstable"), allow(unused))] pub(crate) fn i2s_sclk_frequency() -> u32 { clocks::pll_f96m_clk_frequency() } diff --git a/esp-hal/src/soc/esp32s2/mod.rs b/esp-hal/src/soc/esp32s2/mod.rs index c5bd0367724..7c94610e2b4 100644 --- a/esp-hal/src/soc/esp32s2/mod.rs +++ b/esp-hal/src/soc/esp32s2/mod.rs @@ -15,6 +15,8 @@ pub(crate) mod regi2c; pub(crate) use esp32s2 as pac; +#[cfg(i2s_driver_supported)] +#[cfg_attr(not(feature = "unstable"), allow(unused))] 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() { diff --git a/esp-hal/src/soc/esp32s3/mod.rs b/esp-hal/src/soc/esp32s3/mod.rs index 8f03bdf277b..9c24391db4e 100644 --- a/esp-hal/src/soc/esp32s3/mod.rs +++ b/esp-hal/src/soc/esp32s3/mod.rs @@ -17,6 +17,8 @@ pub(crate) mod regi2c; pub use esp32s3 as pac; +#[cfg(i2s_driver_supported)] +#[cfg_attr(not(feature = "unstable"), allow(unused))] pub(crate) fn i2s_sclk_frequency() -> u32 { clocks::pll_160m_frequency() } diff --git a/esp-metadata-generated/src/_build_script_utils.rs b/esp-metadata-generated/src/_build_script_utils.rs index 07cb66b2f4f..fa9b17d7c0b 100644 --- a/esp-metadata-generated/src/_build_script_utils.rs +++ b/esp-metadata-generated/src/_build_script_utils.rs @@ -338,9 +338,13 @@ impl Chip { "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", @@ -542,9 +546,13 @@ impl Chip { "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", @@ -1330,9 +1338,13 @@ impl Chip { "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", @@ -1539,9 +1551,13 @@ impl Chip { "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", @@ -1897,9 +1913,13 @@ impl Chip { "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\"", @@ -2153,9 +2173,13 @@ impl Chip { "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\"", @@ -2565,9 +2589,13 @@ impl Chip { "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\"", @@ -2846,9 +2874,13 @@ impl Chip { "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\"", @@ -3222,9 +3254,13 @@ impl Chip { "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\"", @@ -3418,9 +3454,13 @@ impl Chip { "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\"", @@ -3788,9 +3828,13 @@ impl Chip { "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\"", @@ -4033,9 +4077,13 @@ impl Chip { "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\"", @@ -4897,9 +4945,13 @@ impl Chip { "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\"", @@ -5115,9 +5167,13 @@ impl Chip { "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\"", @@ -5552,9 +5608,13 @@ impl Chip { "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", @@ -5807,9 +5867,13 @@ impl Chip { "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", @@ -6270,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)"); 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/src/cfg.rs b/esp-metadata/src/cfg.rs index 21dd97f9670..f8ce6950bc8 100644 --- a/esp-metadata/src/cfg.rs +++ b/esp-metadata/src/cfg.rs @@ -454,13 +454,13 @@ driver_configs![ name: "I2S", properties: { /// Register-layout generation derived from the chip SVD. - version: u32, + version: Option, /// Default clock source selector written to the I2S clock source register. - default_clock_source: u32, + default_clock_source: Option, /// Width of the MCLK divider field in the I2S clock register. - mclk_divider_bit_width: u32, + mclk_divider_bit_width: Option, /// Largest WS divider value supported by the peripheral. - max_ws_width: u32, + max_ws_width: Option, #[serde(default)] /// Whether I2S clock/reset control is performed via PCR. clock_configured_by_pcr: bool,