From 6264e3c3b55d6787d7a13fdc29fcf07f75b9a11a Mon Sep 17 00:00:00 2001 From: Madison Steiner <8176115+mh0pe@users.noreply.github.com> Date: Thu, 26 Mar 2026 06:53:59 -0700 Subject: [PATCH] Fix ESP-IDF v6.0 API compatibility Cherry-picked from @drinkcat (Nicolas Boichat) esp-rs/esp-idf-hal#578: - sleep: GPIO deep sleep wakeup API renames for v6.0 - lcd: DMA2D API change, pixel_format field removal, rgb_ele_order union change, RGB666 format removal, disp_off -> disp_on_off - uart: Clock source changes for v6 (PLL_F80M/PLL_F48M chip guards) - pcnt: Proper PCNT_CHANNELS_PER_UNIT const with alloc/heapless split, clk_src with actual enum value - timer: backup_before_sleep guard fix (removed in v6.0, not v6.1) - CI: Add v6.0 to test matrix with RUSTFLAGS handling Co-Authored-By: Nicolas Boichat Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/ci.yml | 13 +++-- CHANGELOG.md | 8 +++ Cargo.toml | 3 + src/lcd.rs | 78 ++++++++++++++++++++------ src/pcnt.rs | 32 ++++++++++- src/sleep.rs | 11 +++- src/timer.rs | 4 +- src/uart.rs | 118 ++++++++++++++++++++++++++++----------- 8 files changed, 206 insertions(+), 61 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e0a5cf8f8c5..a139a3d1dca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,6 +33,7 @@ jobs: - v5.3.4 - v5.4.3 - v5.5.3 + - v6.0 steps: - name: Setup | Checkout uses: actions/checkout@v3 @@ -59,7 +60,7 @@ jobs: env: ESP_IDF_VERSION: ${{ matrix.idf-version }} ESP_IDF_SDKCONFIG_DEFAULTS: "${{ github.workspace }}/.github/configs/sdkconfig.defaults" - RUSTFLAGS: "${{ matrix.idf-version != 'release/v4.4' && '--cfg espidf_time64' || matrix.idf-version == 'release/v4.4' && '--cfg espidf_time32' }}" + RUSTFLAGS: "${{ startsWith(matrix.idf-version, 'v4') && '--cfg espidf_time32' || '--cfg espidf_time64' }}" run: cargo clippy --features experimental --no-deps --target ${{ matrix.target }} -Zbuild-std=std,panic_abort -- -Dwarnings - name: Build | Compile, all @@ -67,7 +68,7 @@ jobs: env: ESP_IDF_VERSION: ${{ matrix.idf-version }} ESP_IDF_SDKCONFIG_DEFAULTS: "${{ github.workspace }}/.github/configs/sdkconfig.defaults" - RUSTFLAGS: "${{ matrix.idf-version != 'release/v4.4' && '--cfg espidf_time64' || matrix.idf-version == 'release/v4.4' && '--cfg espidf_time32' }}" + RUSTFLAGS: "${{ startsWith(matrix.idf-version, 'v4') && '--cfg espidf_time32' || '--cfg espidf_time64' }}" run: cargo build --target ${{ matrix.target }} --features nightly,experimental,critical-section,embassy-sync -Zbuild-std=std,panic_abort - name: Build | Compile, no_std @@ -75,7 +76,7 @@ jobs: env: ESP_IDF_VERSION: ${{ matrix.idf-version }} ESP_IDF_SDKCONFIG_DEFAULTS: "${{ github.workspace }}/.github/configs/sdkconfig.defaults" - RUSTFLAGS: "${{ matrix.idf-version != 'release/v4.4' && '--cfg espidf_time64' || matrix.idf-version == 'release/v4.4' && '--cfg espidf_time32' }}" + RUSTFLAGS: "${{ startsWith(matrix.idf-version, 'v4') && '--cfg espidf_time32' || '--cfg espidf_time64' }}" run: cargo build --no-default-features --features experimental --target ${{ matrix.target }} -Zbuild-std=std,panic_abort - name: Build | Compile, no_std, alloc @@ -83,7 +84,7 @@ jobs: env: ESP_IDF_VERSION: ${{ matrix.idf-version }} ESP_IDF_SDKCONFIG_DEFAULTS: "${{ github.workspace }}/.github/configs/sdkconfig.defaults" - RUSTFLAGS: "${{ matrix.idf-version != 'release/v4.4' && '--cfg espidf_time64' || matrix.idf-version == 'release/v4.4' && '--cfg espidf_time32' }}" + RUSTFLAGS: "${{ startsWith(matrix.idf-version, 'v4') && '--cfg espidf_time32' || '--cfg espidf_time64' }}" run: cargo build --features alloc --no-default-features --features experimental --target ${{ matrix.target }} -Zbuild-std=std,panic_abort - name: Setup | ldproxy @@ -98,7 +99,7 @@ jobs: env: ESP_IDF_VERSION: ${{ matrix.idf-version }} ESP_IDF_SDKCONFIG_DEFAULTS: "${{ github.workspace }}/.github/configs/sdkconfig.defaults" - RUSTFLAGS: "${{ matrix.idf-version != 'release/v4.4' && '--cfg espidf_time64' || matrix.idf-version == 'release/v4.4' && '--cfg espidf_time32' }}" + RUSTFLAGS: "${{ startsWith(matrix.idf-version, 'v4') && '--cfg espidf_time32' || '--cfg espidf_time64' }}" run: cargo clippy --examples --target ${{ matrix.target }} -Zbuild-std=std,panic_abort -- -Dwarnings - name: Build | Examples @@ -106,5 +107,5 @@ jobs: env: ESP_IDF_VERSION: ${{ matrix.idf-version }} ESP_IDF_SDKCONFIG_DEFAULTS: "${{ github.workspace }}/.github/configs/sdkconfig.defaults" - RUSTFLAGS: "${{ matrix.idf-version != 'release/v4.4' && '--cfg espidf_time64' || matrix.idf-version == 'release/v4.4' && '--cfg espidf_time32' }}" + RUSTFLAGS: "${{ startsWith(matrix.idf-version, 'v4') && '--cfg espidf_time32' || '--cfg espidf_time64' }}" run: cargo build --examples --target ${{ matrix.target }} -Zbuild-std=std,panic_abort diff --git a/CHANGELOG.md b/CHANGELOG.md index b859403e489..b13cd0b2359 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [master] - 2026-03-26 + +### Breaking + - Dropped support for RGB/BGR666 format on ESP-IDF 6.0. + +### Added +- Basic compatibility for ESP-IDF release 6.0. + ## [0.46.2] - 2026-03-10 ### Fixed diff --git a/Cargo.toml b/Cargo.toml index 2c0d2b6b68c..bfa69a3a03d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,6 +70,9 @@ atomic-waker = { version = "1.1.1", default-features = false } embassy-sync = "0.7" embedded-graphics-core = { version = "0.4", optional = true } +[patch.crates-io] +esp-idf-sys = { git = "https://github.com/mh0pe/esp-idf-sys", branch = "esp-idf-v6-support" } + [build-dependencies] embuild = "0.33" diff --git a/src/lcd.rs b/src/lcd.rs index 1b0e973df1a..9501058a2e3 100644 --- a/src/lcd.rs +++ b/src/lcd.rs @@ -113,6 +113,10 @@ pub mod config { pub(crate) dbi_config: esp_lcd_dbi_io_config_t, pub(crate) dpi_config: esp_lcd_dpi_panel_config_t, pixel_format: PixelFormat, + // In IDF >=6.0, use_dma2d was removed from dpi_config.flags; we store it here + // and call esp_lcd_dpi_panel_enable_dma2d() after panel creation instead. + #[cfg(esp_idf_version_at_least_6_0_0)] + pub(super) use_dma2d: bool, } impl LcdConfig { @@ -150,10 +154,13 @@ pub mod config { let color_format: lcd_color_format_t = pixel_format.to_color_format(); let esp_timing: esp_lcd_video_timing_t = video_timing.into(); + let use_dma2d = true; + #[cfg_attr(esp_idf_version_at_least_6_0_0, allow(unused_mut))] let mut dpi_config = esp_lcd_dpi_panel_config_t { virtual_channel: 0, dpi_clk_src: soc_periph_mipi_dsi_dpi_clk_src_t_MIPI_DSI_DPI_CLK_SRC_DEFAULT, + #[cfg(not(esp_idf_version_at_least_6_0_0))] pixel_format: pixel_format.to_rgb_pixel_format(), in_color_format: color_format, out_color_format: color_format, @@ -162,13 +169,16 @@ pub mod config { dpi_clock_freq_mhz: dpi_clock_freq_mhz as _, ..unsafe { core::mem::zeroed() } }; - dpi_config.flags.set_use_dma2d(1); + #[cfg(not(esp_idf_version_at_least_6_0_0))] + dpi_config.flags.set_use_dma2d(use_dma2d as u32); Self { bus_config, dbi_config, dpi_config, pixel_format, + #[cfg(esp_idf_version_at_least_6_0_0)] + use_dma2d, } } @@ -229,7 +239,15 @@ pub mod config { /// Enable or disable DMA2D for pixel data transfer (default: enabled) #[must_use] pub fn use_dma2d(mut self, use_dma2d: bool) -> Self { - self.dpi_config.flags.set_use_dma2d(use_dma2d as u32); + #[cfg(not(esp_idf_version_at_least_6_0_0))] + { + self.dpi_config.flags.set_use_dma2d(use_dma2d as u32); + } + #[cfg(esp_idf_version_at_least_6_0_0)] + { + self.use_dma2d = use_dma2d; + } + self } @@ -263,6 +281,8 @@ pub mod config { dbi_config: self.dbi_config, dpi_config: self.dpi_config, pixel_format: self.pixel_format, + #[cfg(esp_idf_version_at_least_6_0_0)] + use_dma2d: self.use_dma2d, } } } @@ -288,7 +308,14 @@ pub mod config { let mut panel_config: esp_lcd_panel_dev_config_t = unsafe { core::mem::zeroed() }; panel_config.bits_per_pixel = bits_per_pixel; - panel_config.__bindgen_anon_1.rgb_ele_order = rgb_order.into(); + #[cfg(not(esp_idf_version_at_least_6_0_0))] + { + panel_config.__bindgen_anon_1.rgb_ele_order = rgb_order.into(); + } + #[cfg(esp_idf_version_at_least_6_0_0)] + { + panel_config.rgb_ele_order = rgb_order.into(); + } panel_config } @@ -389,9 +416,11 @@ pub mod config { Rgb565, /// 16-bit RGB format with BGR component order Bgr565, - /// 18-bit RGB format with RGB component order + /// 18-bit RGB format with RGB component order (IDF < 6.0 only) + #[cfg(not(esp_idf_version_at_least_6_0_0))] Rgb666, - /// 18-bit RGB format with BGR component order + /// 18-bit RGB format with BGR component order (IDF < 6.0 only) + #[cfg(not(esp_idf_version_at_least_6_0_0))] Bgr666, } @@ -401,6 +430,7 @@ pub mod config { match self { PixelFormat::Rgb888 | PixelFormat::Bgr888 => 24, PixelFormat::Rgb565 | PixelFormat::Bgr565 => 16, + #[cfg(not(esp_idf_version_at_least_6_0_0))] PixelFormat::Rgb666 | PixelFormat::Bgr666 => 18, } } @@ -408,27 +438,27 @@ pub mod config { /// Get the bytes per pixel for this format pub const fn bytes_per_pixel(&self) -> usize { match self { - PixelFormat::Rgb888 - | PixelFormat::Bgr888 - | PixelFormat::Rgb666 - | PixelFormat::Bgr666 => 3, + PixelFormat::Rgb888 | PixelFormat::Bgr888 => 3, PixelFormat::Rgb565 | PixelFormat::Bgr565 => 2, + #[cfg(not(esp_idf_version_at_least_6_0_0))] + PixelFormat::Rgb666 | PixelFormat::Bgr666 => 3, } } /// Get the RGB element order for this format pub const fn rgb_element_order(&self) -> RgbElementOrder { match self { - PixelFormat::Rgb888 | PixelFormat::Rgb565 | PixelFormat::Rgb666 => { - RgbElementOrder::Rgb - } - PixelFormat::Bgr888 | PixelFormat::Bgr565 | PixelFormat::Bgr666 => { - RgbElementOrder::Bgr - } + PixelFormat::Rgb888 | PixelFormat::Rgb565 => RgbElementOrder::Rgb, + PixelFormat::Bgr888 | PixelFormat::Bgr565 => RgbElementOrder::Bgr, + #[cfg(not(esp_idf_version_at_least_6_0_0))] + PixelFormat::Rgb666 => RgbElementOrder::Rgb, + #[cfg(not(esp_idf_version_at_least_6_0_0))] + PixelFormat::Bgr666 => RgbElementOrder::Bgr, } } - /// Convert to `lcd_color_rgb_pixel_format_t` + /// Convert to `lcd_color_rgb_pixel_format_t` (IDF < 6.0 only) + #[cfg(not(esp_idf_version_at_least_6_0_0))] pub fn to_rgb_pixel_format(&self) -> lcd_color_rgb_pixel_format_t { match self { PixelFormat::Rgb888 | PixelFormat::Bgr888 => { @@ -452,6 +482,7 @@ pub mod config { PixelFormat::Rgb565 | PixelFormat::Bgr565 => { lcd_color_format_t_LCD_COLOR_FMT_RGB565 } + #[cfg(not(esp_idf_version_at_least_6_0_0))] PixelFormat::Rgb666 | PixelFormat::Bgr666 => { lcd_color_format_t_LCD_COLOR_FMT_RGB666 } @@ -821,7 +852,10 @@ impl<'d, S: DpiPanelState> LcdDriver<'d, S> { /// Requires that `set_control_panel()` has been called first. pub fn set_display_off(&self, off: bool) -> Result<(), EspError> { let panel = self.require_control_panel()?; - unsafe { esp!(esp_lcd_panel_disp_off(panel, off)) } + #[cfg(not(esp_idf_version_at_least_6_0_0))] + return unsafe { esp!(esp_lcd_panel_disp_off(panel, off)) }; + #[cfg(esp_idf_version_at_least_6_0_0)] + return unsafe { esp!(esp_lcd_panel_disp_on_off(panel, !off)) }; } /// Enter or exit sleep mode (low power mode) @@ -935,6 +969,16 @@ impl<'d> LcdDriver<'d, NoDpiPanel> { // self drops here, cleaning up bus + DBI IO + control panel } + // In IDF 6.0, use_dma2d was removed from dpi_config flags; call API instead + #[cfg(esp_idf_version_at_least_6_0_0)] + if self.config.use_dma2d { + if let Err(e) = esp!(esp_lcd_dpi_panel_enable_dma2d(panel_handle)) { + let _ = esp_lcd_panel_del(panel_handle); + let _ = Box::from_raw(dpi_config_ptr); + return Err(e); + } + } + let handle = match NonNull::new(panel_handle as *mut c_void) { Some(h) => h, None => { diff --git a/src/pcnt.rs b/src/pcnt.rs index c9ab622e794..6fa95ce7433 100644 --- a/src/pcnt.rs +++ b/src/pcnt.rs @@ -55,6 +55,11 @@ //! - Maximum number of units: [`SOC_PCNT_UNITS_PER_GROUP`] //! - Maximum number of channels per unit: [`SOC_PCNT_CHANNELS_PER_UNIT`] //! - Maximum number of extra watchpoints: [`SOC_PCNT_THRES_POINT_PER_UNIT`] +//! +//! These 3 constants disappeared in ESP-IDF 6.0, as they were required by the +//! pcnt-legacy API which was removed. +//! The API rejects additional `new_*` calls beyond the maximum number of supported +//! channels. We do hardcode the maximum to 2 if alloc is not enabled, though. use core::marker::PhantomData; #[cfg(feature = "alloc")] @@ -63,10 +68,20 @@ use core::ptr; #[cfg(feature = "alloc")] use alloc::boxed::Box; +#[cfg(feature = "alloc")] +use alloc::vec::Vec; +#[cfg(not(feature = "alloc"))] use heapless::Vec; use esp_idf_sys::*; +// SOC_PCNT_CHANNELS_PER_UNIT was removed in IDF 6.0; the value is 2 for all supported chips, +// and we support more channels in the alloc case. +#[cfg(esp_idf_version_at_least_6_0_0)] +const PCNT_CHANNELS_PER_UNIT: usize = 2; +#[cfg(not(esp_idf_version_at_least_6_0_0))] +const PCNT_CHANNELS_PER_UNIT: usize = SOC_PCNT_CHANNELS_PER_UNIT as usize; + use crate::gpio::InputPin; #[cfg(feature = "alloc")] use crate::interrupt; @@ -166,6 +181,11 @@ pub mod config { impl From<&UnitConfig> for pcnt_unit_config_t { fn from(value: &UnitConfig) -> Self { pcnt_unit_config_t { + // TODO: Do we want to make this configurable? + // Most chips have only 1 option (APB==DEFAULT), but + // esp32h4 supports XTAL(==DEFAULT) or RC_FAST. + #[cfg(esp_idf_version_at_least_6_0_0)] + clk_src: soc_periph_pcnt_clk_src_t_PCNT_CLK_SRC_DEFAULT, low_limit: value.low_limit, high_limit: value.high_limit, intr_priority: value.intr_priority, @@ -573,7 +593,10 @@ struct DelegateUserData<'d> { /// that have to be added with [`PcntUnitDriver::add_channel`]. pub struct PcntUnitDriver<'d> { handle: pcnt_unit_handle_t, - channels: Vec, { SOC_PCNT_CHANNELS_PER_UNIT as usize }>, + #[cfg(feature = "alloc")] + channels: alloc::vec::Vec>, + #[cfg(not(feature = "alloc"))] + channels: Vec, PCNT_CHANNELS_PER_UNIT>, #[cfg(feature = "alloc")] user_data: Option>>>, _p: PhantomData<&'d mut ()>, @@ -596,6 +619,9 @@ impl<'d> PcntUnitDriver<'d> { Ok(Self { handle, + #[cfg(feature = "alloc")] // Pre-allocate to usual maximum size + channels: Vec::with_capacity(PCNT_CHANNELS_PER_UNIT), + #[cfg(not(feature = "alloc"))] // Fixed size channels: Vec::new(), #[cfg(feature = "alloc")] user_data: None, @@ -785,6 +811,10 @@ impl<'d> PcntUnitDriver<'d> { level_pin: Option, config: &ChannelConfig, ) -> Result<&mut PcntChannel<'d>, EspError> { + #[cfg(feature = "alloc")] + self.channels + .push(unsafe { PcntChannel::new(self.handle, edge_pin, level_pin, config)? }); + #[cfg(not(feature = "alloc"))] self.channels .push(unsafe { PcntChannel::new(self.handle, edge_pin, level_pin, config)? }) .expect("Not enough channels available."); diff --git a/src/sleep.rs b/src/sleep.rs index 14c0efb04a0..265352fd1cf 100644 --- a/src/sleep.rs +++ b/src/sleep.rs @@ -135,10 +135,19 @@ pub mod gpio { pub fn configure_deep(pin: PinId, level: Level) -> Result<(), EspError> { let mask = 1 << pin; let mode = match level { + #[cfg(not(esp_idf_version_at_least_6_0_0))] Level::Low => esp_deepsleep_gpio_wake_up_mode_t_ESP_GPIO_WAKEUP_GPIO_LOW, + #[cfg(not(esp_idf_version_at_least_6_0_0))] Level::High => esp_deepsleep_gpio_wake_up_mode_t_ESP_GPIO_WAKEUP_GPIO_HIGH, + #[cfg(esp_idf_version_at_least_6_0_0)] + Level::Low => esp_sleep_gpio_wake_up_mode_t_ESP_GPIO_WAKEUP_GPIO_LOW, + #[cfg(esp_idf_version_at_least_6_0_0)] + Level::High => esp_sleep_gpio_wake_up_mode_t_ESP_GPIO_WAKEUP_GPIO_HIGH, }; - esp!(unsafe { esp_deep_sleep_enable_gpio_wakeup(mask, mode) }) + #[cfg(not(esp_idf_version_at_least_6_0_0))] + return esp!(unsafe { esp_deep_sleep_enable_gpio_wakeup(mask, mode) }); + #[cfg(esp_idf_version_at_least_6_0_0)] + return esp!(unsafe { esp_sleep_enable_gpio_wakeup_on_hp_periph_powerdown(mask, mode) }); } } diff --git a/src/timer.rs b/src/timer.rs index 380a000124a..abfef91cf61 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -282,10 +282,10 @@ impl<'d> TimerDriver<'d> { { config.allow_pd as _ }, - // The `backup_before_sleep` field is deprecated, and will be removed in 6.1 + // The `backup_before_sleep` field was removed in IDF 6.0 #[cfg(all( esp_idf_version_at_least_5_3_0, - not(esp_idf_version_at_least_6_1_0) + not(esp_idf_version_at_least_6_0_0) ))] { false as _ diff --git a/src/uart.rs b/src/uart.rs index cc8f5a6942a..87ae57ae8a3 100644 --- a/src/uart.rs +++ b/src/uart.rs @@ -228,6 +228,11 @@ pub mod config { } /// UART source clock + // + // esp-idf 6.0 only exposes SOC_UART_SUPPORT_*_CLK config options for APB, + // RTC (a.k.a RC_FAST), XTAL, REF_TICK, and surprisingly PLL_F40M (esp32c2 only). + // For PLL_F48M and PLL_F80M support, we would need to rely on SOC_UART_CLKS array, + // which is tricky to extract from the bindings, so we hardcode supported chips. #[derive(PartialEq, Eq, Copy, Clone, Debug)] pub enum SourceClock { /// UART source clock from `APB` @@ -245,17 +250,28 @@ pub mod config { Crystal, /// UART source clock from `PLL_F80M` #[allow(non_camel_case_types)] - #[cfg(esp_idf_soc_uart_support_pll_f80m_clk)] + #[cfg(any( + esp_idf_soc_uart_support_pll_f80m_clk, + all( + esp_idf_version_at_least_6_0_0, + any(esp32c5, esp32c6, esp32c61, esp32p4) + ) + ))] PLL_F80M, - /// UART source clock from `PLL_F48M` (ESP32-H2) + /// UART source clock from `PLL_F48M` (ESP32-H2, ESP32-H4, ESP32-H21) #[allow(non_camel_case_types)] - #[cfg(not(any( - esp_idf_soc_uart_support_apb_clk, - esp_idf_soc_uart_support_pll_f40m_clk, - esp_idf_soc_uart_support_pll_f80m_clk, - esp_idf_soc_uart_support_ref_tick, - esp_idf_version_major = "4" - )))] + #[cfg(any( + // IDF < 6: rely on soc caps flags + all(not(esp_idf_version_at_least_6_0_0), not(any( + esp_idf_soc_uart_support_apb_clk, + esp_idf_soc_uart_support_pll_f40m_clk, + esp_idf_soc_uart_support_pll_f80m_clk, + esp_idf_soc_uart_support_ref_tick, + esp_idf_version_major = "4", + ))), + // IDF >= 6: only H-series chips have PLL_F48M + all(esp_idf_version_at_least_6_0_0, any(esp32h2, esp32h4, esp32h21)), + ))] PLL_F48M, /// UART source clock from `REF_TICK` #[cfg(esp_idf_soc_uart_support_ref_tick)] @@ -283,15 +299,27 @@ pub mod config { RTC_SCLK => SourceClock::RTC, #[cfg(esp_idf_soc_uart_support_xtal_clk)] XTAL_SCLK => SourceClock::Crystal, - #[cfg(esp_idf_soc_uart_support_pll_f80m_clk)] - PLL_F80M_SCLK => SourceClock::PLL_F80M, - #[cfg(not(any( - esp_idf_soc_uart_support_apb_clk, - esp_idf_soc_uart_support_pll_f40m_clk, + #[cfg(any( esp_idf_soc_uart_support_pll_f80m_clk, - esp_idf_soc_uart_support_ref_tick, - esp_idf_version_major = "4" - )))] + all( + esp_idf_version_at_least_6_0_0, + any(esp32c5, esp32c6, esp32c61, esp32p4) + ) + ))] + PLL_F80M_SCLK => SourceClock::PLL_F80M, + #[cfg(any( + all( + not(esp_idf_version_at_least_6_0_0), + not(any( + esp_idf_soc_uart_support_apb_clk, + esp_idf_soc_uart_support_pll_f40m_clk, + esp_idf_soc_uart_support_pll_f80m_clk, + esp_idf_soc_uart_support_ref_tick, + esp_idf_version_major = "4", + )) + ), + all(esp_idf_version_at_least_6_0_0, any(esp32h2, esp32h4, esp32h21)), + ))] PLL_F48M_SCLK => SourceClock::PLL_F48M, #[cfg(esp_idf_soc_uart_support_ref_tick)] REF_TICK_SCLK => SourceClock::RefTick, @@ -332,20 +360,30 @@ pub mod config { #[cfg(all( not(esp_idf_version_major = "4"), - esp_idf_soc_uart_support_pll_f80m_clk + any( + esp_idf_soc_uart_support_pll_f80m_clk, + all( + esp_idf_version_at_least_6_0_0, + any(esp32c5, esp32c6, esp32c61, esp32p4) + ) + ) ))] const PLL_F80M_SCLK: uart_sclk_t = soc_periph_uart_clk_src_legacy_t_UART_SCLK_PLL_F80M; #[cfg(all(esp_idf_version_major = "4", esp_idf_soc_uart_support_pll_f80m_clk))] const PLL_F80M_SCLK: uart_sclk_t = uart_sclk_t_UART_SCLK_PLL_F80M; - #[cfg(all( - not(esp_idf_version_major = "4"), - not(any( - esp_idf_soc_uart_support_apb_clk, - esp_idf_soc_uart_support_pll_f40m_clk, - esp_idf_soc_uart_support_pll_f80m_clk, - esp_idf_soc_uart_support_ref_tick - )) + #[cfg(any( + all( + not(esp_idf_version_major = "4"), + not(esp_idf_version_at_least_6_0_0), + not(any( + esp_idf_soc_uart_support_apb_clk, + esp_idf_soc_uart_support_pll_f40m_clk, + esp_idf_soc_uart_support_pll_f80m_clk, + esp_idf_soc_uart_support_ref_tick, + )) + ), + all(esp_idf_version_at_least_6_0_0, any(esp32h2, esp32h4, esp32h21)), ))] const PLL_F48M_SCLK: uart_sclk_t = soc_periph_uart_clk_src_legacy_t_UART_SCLK_PLL_F48M; @@ -373,15 +411,27 @@ pub mod config { SourceClock::RTC => RTC_SCLK, #[cfg(esp_idf_soc_uart_support_xtal_clk)] SourceClock::Crystal => XTAL_SCLK, - #[cfg(esp_idf_soc_uart_support_pll_f80m_clk)] - SourceClock::PLL_F80M => PLL_F80M_SCLK, - #[cfg(not(any( - esp_idf_soc_uart_support_apb_clk, - esp_idf_soc_uart_support_pll_f40m_clk, + #[cfg(any( esp_idf_soc_uart_support_pll_f80m_clk, - esp_idf_soc_uart_support_ref_tick, - esp_idf_version_major = "4" - )))] + all( + esp_idf_version_at_least_6_0_0, + any(esp32c5, esp32c6, esp32c61, esp32p4) + ) + ))] + SourceClock::PLL_F80M => PLL_F80M_SCLK, + #[cfg(any( + all( + not(esp_idf_version_at_least_6_0_0), + not(any( + esp_idf_soc_uart_support_apb_clk, + esp_idf_soc_uart_support_pll_f40m_clk, + esp_idf_soc_uart_support_pll_f80m_clk, + esp_idf_soc_uart_support_ref_tick, + esp_idf_version_major = "4", + )) + ), + all(esp_idf_version_at_least_6_0_0, any(esp32h2, esp32h4, esp32h21)), + ))] SourceClock::PLL_F48M => PLL_F48M_SCLK, #[cfg(esp_idf_soc_uart_support_ref_tick)] SourceClock::RefTick => REF_TICK_SCLK,