From bb50746e9c50ca148002f2dbb598ce93365aa58a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 28 Jul 2025 09:10:58 +0200 Subject: [PATCH] Move TIMG clock source defaults to metadata (#3864) * Read register once * Move TIMG clock sources to metadata * Also describe C2/3/S2/S3 clock source options * H2: Use PLL as WDT clock source * Fix H2 WDT calculation * Initialize clocks before setting up WDT * Set clock source for all timers in the timer group --- esp-hal/src/clock/clocks_ll/esp32c6.rs | 5 +- esp-hal/src/lib.rs | 4 +- esp-hal/src/soc/esp32c6/mod.rs | 3 - esp-hal/src/soc/esp32h2/mod.rs | 3 - esp-hal/src/timer/timg.rs | 82 +++++++++++-------- .../src/_build_script_utils.rs | 53 ++++++++++++ .../src/_generated_esp32c2.rs | 12 +++ .../src/_generated_esp32c3.rs | 12 +++ .../src/_generated_esp32c6.rs | 12 +++ .../src/_generated_esp32h2.rs | 12 +++ .../src/_generated_esp32s2.rs | 6 ++ .../src/_generated_esp32s3.rs | 6 ++ esp-metadata/devices/esp32c2.toml | 2 + esp-metadata/devices/esp32c3.toml | 2 + esp-metadata/devices/esp32c6.toml | 2 + esp-metadata/devices/esp32h2.toml | 2 + esp-metadata/devices/esp32s2.toml | 1 + esp-metadata/devices/esp32s3.toml | 1 + esp-metadata/src/cfg.rs | 13 ++- esp-metadata/src/cfg/gpio.rs | 6 +- esp-metadata/src/cfg/rsa.rs | 4 +- esp-metadata/src/lib.rs | 46 +++++++---- 22 files changed, 223 insertions(+), 66 deletions(-) diff --git a/esp-hal/src/clock/clocks_ll/esp32c6.rs b/esp-hal/src/clock/clocks_ll/esp32c6.rs index a657e80be..95b980619 100644 --- a/esp-hal/src/clock/clocks_ll/esp32c6.rs +++ b/esp-hal/src/clock/clocks_ll/esp32c6.rs @@ -181,8 +181,9 @@ pub(crate) fn esp32c6_cpu_get_ls_divider() -> u8 { // clk_ll_cpu_get_hs_divider pub(crate) fn esp32c6_cpu_get_hs_divider() -> u8 { - let force_120m = PCR::regs().cpu_freq_conf().read().cpu_hs_120m_force().bit(); - let cpu_hs_div = PCR::regs().cpu_freq_conf().read().cpu_hs_div_num().bits(); + let cpu_freq_conf = PCR::regs().cpu_freq_conf().read(); + let force_120m = cpu_freq_conf.cpu_hs_120m_force().bit(); + let cpu_hs_div = cpu_freq_conf.cpu_hs_div_num().bits(); if cpu_hs_div == 0 && force_120m { return 4; } diff --git a/esp-hal/src/lib.rs b/esp-hal/src/lib.rs index a72badaa3..e54f7fdb6 100644 --- a/esp-hal/src/lib.rs +++ b/esp-hal/src/lib.rs @@ -640,6 +640,8 @@ pub fn init(config: Config) -> Peripherals { // RTC domain must be enabled before we try to disable let mut rtc = crate::rtc_cntl::Rtc::new(peripherals.LPWR.reborrow()); + Clocks::init(config.cpu_clock); + // Handle watchdog configuration with defaults cfg_if::cfg_if! { if #[cfg(feature = "unstable")] @@ -700,8 +702,6 @@ pub fn init(config: Config) -> Peripherals { } } - Clocks::init(config.cpu_clock); - #[cfg(esp32)] crate::time::time_init(); diff --git a/esp-hal/src/soc/esp32c6/mod.rs b/esp-hal/src/soc/esp32c6/mod.rs index ba23874a3..a7be33aa0 100644 --- a/esp-hal/src/soc/esp32c6/mod.rs +++ b/esp-hal/src/soc/esp32c6/mod.rs @@ -24,9 +24,6 @@ pub(crate) use esp32c6 as pac; pub(crate) mod constants { use crate::time::Rate; - /// The default clock source for the timer group. - pub const TIMG_DEFAULT_CLK_SRC: u8 = 1; - /// 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. diff --git a/esp-hal/src/soc/esp32h2/mod.rs b/esp-hal/src/soc/esp32h2/mod.rs index 7f58fd2b9..d24f3b042 100644 --- a/esp-hal/src/soc/esp32h2/mod.rs +++ b/esp-hal/src/soc/esp32h2/mod.rs @@ -23,9 +23,6 @@ pub(crate) use esp32h2 as pac; pub(crate) mod constants { use crate::time::Rate; - /// Default clock source for the timer group (TIMG) peripheral. - pub const TIMG_DEFAULT_CLK_SRC: u8 = 2; - /// Default clock source for the I2S peripheral. pub const I2S_DEFAULT_CLK_SRC: u8 = 1; /// Clock frequency for the I2S peripheral, in Hertz. diff --git a/esp-hal/src/timer/timg.rs b/esp-hal/src/timer/timg.rs index 877f932c3..f948b6786 100644 --- a/esp-hal/src/timer/timg.rs +++ b/esp-hal/src/timer/timg.rs @@ -71,8 +71,6 @@ use core::marker::PhantomData; use super::Error; #[cfg(timergroup_timg1)] use crate::peripherals::TIMG1; -#[cfg(any(esp32c6, esp32h2))] -use crate::soc::constants::TIMG_DEFAULT_CLK_SRC; use crate::{ asynch::AtomicWaker, clock::Clocks, @@ -84,6 +82,10 @@ use crate::{ time::{Duration, Instant, Rate}, }; +#[cfg(timergroup_default_clock_source_is_set)] +const DEFAULT_CLK_SRC: u8 = property!("timergroup.default_clock_source"); +#[cfg(timergroup_default_wdt_clock_source_is_set)] +const DEFAULT_WDT_CLK_SRC: u8 = property!("timergroup.default_wdt_clock_source"); const NUM_TIMG: usize = 1 + cfg!(timergroup_timg1) as usize; cfg_if::cfg_if! { @@ -143,19 +145,19 @@ impl TimerGroupInstance for TIMG0<'_> { fn configure_src_clk() { cfg_if::cfg_if! { - if #[cfg(esp32)] { - // ESP32 has only APB clock source, do nothing - } else if #[cfg(any(esp32c2, esp32c3, esp32s2, esp32s3))] { + if #[cfg(not(timergroup_default_clock_source_is_set))] { + // Clock source is not configurable + } else if #[cfg(soc_has_pcr)] { + crate::peripherals::PCR::regs() + .timergroup0_timer_clk_conf() + .modify(|_, w| unsafe { w.tg0_timer_clk_sel().bits(DEFAULT_CLK_SRC) }); + } else { unsafe { (*::register_block()) .t(0) .config() - .modify(|_, w| w.use_xtal().clear_bit()); + .modify(|_, w| w.use_xtal().bit(DEFAULT_CLK_SRC == 1)); } - } else if #[cfg(any(esp32c6, esp32h2))] { - crate::peripherals::PCR::regs() - .timergroup0_timer_clk_conf() - .modify(|_, w| unsafe { w.tg0_timer_clk_sel().bits(TIMG_DEFAULT_CLK_SRC) }); } } } @@ -171,18 +173,18 @@ impl TimerGroupInstance for TIMG0<'_> { fn configure_wdt_src_clk() { cfg_if::cfg_if! { - if #[cfg(any(esp32, esp32s2, esp32s3))] { - // ESP32, ESP32-S2, and ESP32-S3 use only ABP, do nothing - } else if #[cfg(any(esp32c2, esp32c3))] { + if #[cfg(not(timergroup_default_wdt_clock_source_is_set))] { + // Clock source is not configurable + } else if #[cfg(soc_has_pcr)] { + crate::peripherals::PCR::regs() + .timergroup0_wdt_clk_conf() + .modify(|_, w| unsafe { w.tg0_wdt_clk_sel().bits(DEFAULT_WDT_CLK_SRC) }); + } else { unsafe { (*::register_block()) .wdtconfig0() - .modify(|_, w| w.wdt_use_xtal().clear_bit()); + .modify(|_, w| w.wdt_use_xtal().bit(DEFAULT_WDT_CLK_SRC == 1)); } - } else if #[cfg(any(esp32c6, esp32h2))] { - crate::peripherals::PCR::regs() - .timergroup0_wdt_clk_conf() - .modify(|_, w| unsafe { w.tg0_wdt_clk_sel().bits(1) }); } } } @@ -205,19 +207,23 @@ impl TimerGroupInstance for crate::peripherals::TIMG1<'_> { fn configure_src_clk() { cfg_if::cfg_if! { - if #[cfg(any(esp32, esp32c2, esp32c3))] { - // ESP32 has only APB clock source, do nothing - // ESP32-C2 and ESP32-C3 don't have t1config only t0config, do nothing - } else if #[cfg(any(esp32c6, esp32h2))] { + if #[cfg(not(timergroup_default_clock_source_is_set))] { + // Clock source is not configurable + } else if #[cfg(soc_has_pcr)] { crate::peripherals::PCR::regs() .timergroup1_timer_clk_conf() - .modify(|_, w| unsafe { w.tg1_timer_clk_sel().bits(TIMG_DEFAULT_CLK_SRC) }); - } else if #[cfg(any(esp32s2, esp32s3))] { + .modify(|_, w| unsafe { w.tg1_timer_clk_sel().bits(DEFAULT_CLK_SRC) }); + } else { unsafe { + (*::register_block()) + .t(0) + .config() + .modify(|_, w| w.use_xtal().bit(DEFAULT_CLK_SRC == 1)); + #[cfg(timergroup_timg_has_timer1)] (*::register_block()) .t(1) .config() - .modify(|_, w| w.use_xtal().clear_bit()); + .modify(|_, w| w.use_xtal().bit(DEFAULT_CLK_SRC == 1)); } } } @@ -233,13 +239,18 @@ impl TimerGroupInstance for crate::peripherals::TIMG1<'_> { fn configure_wdt_src_clk() { cfg_if::cfg_if! { - if #[cfg(any(esp32, esp32s2, esp32s3, esp32c2, esp32c3))] { - // ESP32-C2 and ESP32-C3 don't have t1config only t0config, do nothing - // ESP32, ESP32-S2, and ESP32-S3 use only ABP, do nothing - } else if #[cfg(any(esp32c6, esp32h2))] { + if #[cfg(not(timergroup_default_wdt_clock_source_is_set))] { + // Clock source is not configurable + } else if #[cfg(soc_has_pcr)] { crate::peripherals::PCR::regs() .timergroup1_wdt_clk_conf() - .modify(|_, w| unsafe { w.tg1_wdt_clk_sel().bits(TIMG_DEFAULT_CLK_SRC) }); + .modify(|_, w| unsafe { w.tg1_wdt_clk_sel().bits(DEFAULT_WDT_CLK_SRC) }); + } else { + unsafe { + (*::register_block()) + .wdtconfig0() + .modify(|_, w| w.wdt_use_xtal().bit(DEFAULT_WDT_CLK_SRC == 1)); + } } } } @@ -726,8 +737,15 @@ where /// Set the timeout, in microseconds, of the watchdog timer pub fn set_timeout(&mut self, stage: MwdtStage, timeout: Duration) { - // Assume default 80MHz clock source - let timeout_ticks = timeout.as_micros() * 10_000 / 125; + cfg_if::cfg_if! { + if #[cfg(esp32h2)] { + // ESP32-H2 is using PLL_48M_CLK source instead of APB_CLK + let clk_src = Clocks::get().pll_48m_clock; + } else { + let clk_src = Clocks::get().apb_clock; + } + } + let timeout_ticks = timeout.as_micros() * clk_src.as_mhz() as u64; let reg_block = unsafe { &*TG::register_block() }; diff --git a/esp-metadata-generated/src/_build_script_utils.rs b/esp-metadata-generated/src/_build_script_utils.rs index 469d83f56..78a14d580 100644 --- a/esp-metadata-generated/src/_build_script_utils.rs +++ b/esp-metadata-generated/src/_build_script_utils.rs @@ -271,6 +271,7 @@ impl Chip { "gpio_output_signal_max=\"256\"", "i2c_master_separate_filter_config_registers", "i2c_master_i2c0_data_register_ahb_address=\"1610690588\"", + "i2c_master_i2c0_data_register_ahb_address_is_set", "i2c_master_max_bus_timeout=\"1048575\"", "i2c_master_ll_intr_mask=\"262143\"", "i2c_master_fifo_size=\"32\"", @@ -418,6 +419,7 @@ impl Chip { "cargo:rustc-cfg=gpio_output_signal_max=\"256\"", "cargo:rustc-cfg=i2c_master_separate_filter_config_registers", "cargo:rustc-cfg=i2c_master_i2c0_data_register_ahb_address=\"1610690588\"", + "cargo:rustc-cfg=i2c_master_i2c0_data_register_ahb_address_is_set", "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\"", @@ -543,6 +545,10 @@ impl Chip { "sha_algo_sha_224", "sha_algo_sha_256", "timergroup_timg_has_divcnt_rst", + "timergroup_default_clock_source=\"0\"", + "timergroup_default_clock_source_is_set", + "timergroup_default_wdt_clock_source=\"0\"", + "timergroup_default_wdt_clock_source_is_set", "uart_ram_size=\"128\"", "has_dram_region", ], @@ -652,6 +658,10 @@ impl Chip { "cargo:rustc-cfg=sha_algo_sha_224", "cargo:rustc-cfg=sha_algo_sha_256", "cargo:rustc-cfg=timergroup_timg_has_divcnt_rst", + "cargo:rustc-cfg=timergroup_default_clock_source=\"0\"", + "cargo:rustc-cfg=timergroup_default_clock_source_is_set", + "cargo:rustc-cfg=timergroup_default_wdt_clock_source=\"0\"", + "cargo:rustc-cfg=timergroup_default_wdt_clock_source_is_set", "cargo:rustc-cfg=uart_ram_size=\"128\"", "cargo:rustc-cfg=has_dram_region", ], @@ -792,6 +802,10 @@ impl Chip { "sha_algo_sha_224", "sha_algo_sha_256", "timergroup_timg_has_divcnt_rst", + "timergroup_default_clock_source=\"0\"", + "timergroup_default_clock_source_is_set", + "timergroup_default_wdt_clock_source=\"0\"", + "timergroup_default_wdt_clock_source_is_set", "uart_ram_size=\"128\"", "has_dram_region", ], @@ -928,6 +942,10 @@ impl Chip { "cargo:rustc-cfg=sha_algo_sha_224", "cargo:rustc-cfg=sha_algo_sha_256", "cargo:rustc-cfg=timergroup_timg_has_divcnt_rst", + "cargo:rustc-cfg=timergroup_default_clock_source=\"0\"", + "cargo:rustc-cfg=timergroup_default_clock_source_is_set", + "cargo:rustc-cfg=timergroup_default_wdt_clock_source=\"0\"", + "cargo:rustc-cfg=timergroup_default_wdt_clock_source_is_set", "cargo:rustc-cfg=uart_ram_size=\"128\"", "cargo:rustc-cfg=has_dram_region", ], @@ -1122,6 +1140,10 @@ impl Chip { "sha_algo_sha_224", "sha_algo_sha_256", "timergroup_timg_has_divcnt_rst", + "timergroup_default_clock_source=\"1\"", + "timergroup_default_clock_source_is_set", + "timergroup_default_wdt_clock_source=\"1\"", + "timergroup_default_wdt_clock_source_is_set", "uart_ram_size=\"128\"", "lp_uart_ram_size=\"32\"", "wifi_has_wifi6", @@ -1314,6 +1336,10 @@ impl Chip { "cargo:rustc-cfg=sha_algo_sha_224", "cargo:rustc-cfg=sha_algo_sha_256", "cargo:rustc-cfg=timergroup_timg_has_divcnt_rst", + "cargo:rustc-cfg=timergroup_default_clock_source=\"1\"", + "cargo:rustc-cfg=timergroup_default_clock_source_is_set", + "cargo:rustc-cfg=timergroup_default_wdt_clock_source=\"1\"", + "cargo:rustc-cfg=timergroup_default_wdt_clock_source_is_set", "cargo:rustc-cfg=uart_ram_size=\"128\"", "cargo:rustc-cfg=lp_uart_ram_size=\"32\"", "cargo:rustc-cfg=wifi_has_wifi6", @@ -1486,6 +1512,10 @@ impl Chip { "sha_algo_sha_224", "sha_algo_sha_256", "timergroup_timg_has_divcnt_rst", + "timergroup_default_clock_source=\"2\"", + "timergroup_default_clock_source_is_set", + "timergroup_default_wdt_clock_source=\"2\"", + "timergroup_default_wdt_clock_source_is_set", "uart_ram_size=\"128\"", "has_dram_region", ], @@ -1652,6 +1682,10 @@ impl Chip { "cargo:rustc-cfg=sha_algo_sha_224", "cargo:rustc-cfg=sha_algo_sha_256", "cargo:rustc-cfg=timergroup_timg_has_divcnt_rst", + "cargo:rustc-cfg=timergroup_default_clock_source=\"2\"", + "cargo:rustc-cfg=timergroup_default_clock_source_is_set", + "cargo:rustc-cfg=timergroup_default_wdt_clock_source=\"2\"", + "cargo:rustc-cfg=timergroup_default_wdt_clock_source_is_set", "cargo:rustc-cfg=uart_ram_size=\"128\"", "cargo:rustc-cfg=has_dram_region", ], @@ -1799,6 +1833,7 @@ impl Chip { "i2c_master_separate_filter_config_registers", "i2c_master_has_arbitration_en", "i2c_master_i2c0_data_register_ahb_address=\"1610690588\"", + "i2c_master_i2c0_data_register_ahb_address_is_set", "i2c_master_max_bus_timeout=\"16777215\"", "i2c_master_ll_intr_mask=\"131071\"", "i2c_master_fifo_size=\"32\"", @@ -1816,6 +1851,8 @@ impl Chip { "sha_algo_sha_512_t", "spi_master_has_octal", "timergroup_timg_has_timer1", + "timergroup_default_clock_source=\"0\"", + "timergroup_default_clock_source_is_set", "uart_ram_size=\"128\"", "has_dram_region", ], @@ -1959,6 +1996,7 @@ impl Chip { "cargo:rustc-cfg=i2c_master_separate_filter_config_registers", "cargo:rustc-cfg=i2c_master_has_arbitration_en", "cargo:rustc-cfg=i2c_master_i2c0_data_register_ahb_address=\"1610690588\"", + "cargo:rustc-cfg=i2c_master_i2c0_data_register_ahb_address_is_set", "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\"", @@ -1976,6 +2014,8 @@ impl Chip { "cargo:rustc-cfg=sha_algo_sha_512_t", "cargo:rustc-cfg=spi_master_has_octal", "cargo:rustc-cfg=timergroup_timg_has_timer1", + "cargo:rustc-cfg=timergroup_default_clock_source=\"0\"", + "cargo:rustc-cfg=timergroup_default_clock_source_is_set", "cargo:rustc-cfg=uart_ram_size=\"128\"", "cargo:rustc-cfg=has_dram_region", ], @@ -2159,6 +2199,8 @@ impl Chip { "sha_algo_sha_512_t", "spi_master_has_octal", "timergroup_timg_has_timer1", + "timergroup_default_clock_source=\"0\"", + "timergroup_default_clock_source_is_set", "uart_ram_size=\"128\"", "has_dram_region", ], @@ -2338,6 +2380,8 @@ impl Chip { "cargo:rustc-cfg=sha_algo_sha_512_t", "cargo:rustc-cfg=spi_master_has_octal", "cargo:rustc-cfg=timergroup_timg_has_timer1", + "cargo:rustc-cfg=timergroup_default_clock_source=\"0\"", + "cargo:rustc-cfg=timergroup_default_clock_source_is_set", "cargo:rustc-cfg=uart_ram_size=\"128\"", "cargo:rustc-cfg=has_dram_region", ], @@ -2477,6 +2521,7 @@ impl Config { println!("cargo:rustc-check-cfg=cfg(gpio_has_bank_1)"); 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(sha_algo_sha_1)"); println!("cargo:rustc-check-cfg=cfg(sha_algo_sha_256)"); println!("cargo:rustc-check-cfg=cfg(sha_algo_sha_384)"); @@ -2526,6 +2571,8 @@ impl Config { println!("cargo:rustc-check-cfg=cfg(i2c_master_bus_timeout_is_exponential)"); println!("cargo:rustc-check-cfg=cfg(sha_algo_sha_224)"); println!("cargo:rustc-check-cfg=cfg(timergroup_timg_has_divcnt_rst)"); + println!("cargo:rustc-check-cfg=cfg(timergroup_default_clock_source_is_set)"); + println!("cargo:rustc-check-cfg=cfg(timergroup_default_wdt_clock_source_is_set)"); println!("cargo:rustc-check-cfg=cfg(esp32c3)"); println!("cargo:rustc-check-cfg=cfg(soc_has_ds)"); println!("cargo:rustc-check-cfg=cfg(soc_has_fe)"); @@ -2655,6 +2702,12 @@ impl Config { println!("cargo:rustc-check-cfg=cfg(rmt_channel_ram_size, values(\"64\",\"48\"))"); println!("cargo:rustc-check-cfg=cfg(rng_apb_cycle_wait_num, values(\"16\"))"); println!("cargo:rustc-check-cfg=cfg(uart_ram_size, values(\"128\"))"); + println!( + "cargo:rustc-check-cfg=cfg(timergroup_default_clock_source, values(\"0\",\"1\",\"2\"))" + ); + println!( + "cargo:rustc-check-cfg=cfg(timergroup_default_wdt_clock_source, values(\"0\",\"1\",\"2\"))" + ); println!("cargo:rustc-check-cfg=cfg(lp_i2c_master_fifo_size, values(\"16\"))"); println!("cargo:rustc-check-cfg=cfg(lp_uart_ram_size, values(\"32\"))"); for cfg in self.cfgs { diff --git a/esp-metadata-generated/src/_generated_esp32c2.rs b/esp-metadata-generated/src/_generated_esp32c2.rs index f2d3fe00e..0a52763a5 100644 --- a/esp-metadata-generated/src/_generated_esp32c2.rs +++ b/esp-metadata-generated/src/_generated_esp32c2.rs @@ -159,6 +159,18 @@ macro_rules! property { ("timergroup.timg_has_divcnt_rst") => { true }; + ("timergroup.default_clock_source") => { + 0 + }; + ("timergroup.default_clock_source", str) => { + stringify!(0) + }; + ("timergroup.default_wdt_clock_source") => { + 0 + }; + ("timergroup.default_wdt_clock_source", str) => { + stringify!(0) + }; ("uart.ram_size") => { 128 }; diff --git a/esp-metadata-generated/src/_generated_esp32c3.rs b/esp-metadata-generated/src/_generated_esp32c3.rs index dd4343656..b682c8fc0 100644 --- a/esp-metadata-generated/src/_generated_esp32c3.rs +++ b/esp-metadata-generated/src/_generated_esp32c3.rs @@ -174,6 +174,18 @@ macro_rules! property { ("timergroup.timg_has_divcnt_rst") => { true }; + ("timergroup.default_clock_source") => { + 0 + }; + ("timergroup.default_clock_source", str) => { + stringify!(0) + }; + ("timergroup.default_wdt_clock_source") => { + 0 + }; + ("timergroup.default_wdt_clock_source", str) => { + stringify!(0) + }; ("uart.ram_size") => { 128 }; diff --git a/esp-metadata-generated/src/_generated_esp32c6.rs b/esp-metadata-generated/src/_generated_esp32c6.rs index 6bed3475b..ef8f91345 100644 --- a/esp-metadata-generated/src/_generated_esp32c6.rs +++ b/esp-metadata-generated/src/_generated_esp32c6.rs @@ -180,6 +180,18 @@ macro_rules! property { ("timergroup.timg_has_divcnt_rst") => { true }; + ("timergroup.default_clock_source") => { + 1 + }; + ("timergroup.default_clock_source", str) => { + stringify!(1) + }; + ("timergroup.default_wdt_clock_source") => { + 1 + }; + ("timergroup.default_wdt_clock_source", str) => { + stringify!(1) + }; ("uart.ram_size") => { 128 }; diff --git a/esp-metadata-generated/src/_generated_esp32h2.rs b/esp-metadata-generated/src/_generated_esp32h2.rs index 535a739f2..46c019ac9 100644 --- a/esp-metadata-generated/src/_generated_esp32h2.rs +++ b/esp-metadata-generated/src/_generated_esp32h2.rs @@ -174,6 +174,18 @@ macro_rules! property { ("timergroup.timg_has_divcnt_rst") => { true }; + ("timergroup.default_clock_source") => { + 2 + }; + ("timergroup.default_clock_source", str) => { + stringify!(2) + }; + ("timergroup.default_wdt_clock_source") => { + 2 + }; + ("timergroup.default_wdt_clock_source", str) => { + stringify!(2) + }; ("uart.ram_size") => { 128 }; diff --git a/esp-metadata-generated/src/_generated_esp32s2.rs b/esp-metadata-generated/src/_generated_esp32s2.rs index 544b67357..ae7fbabdb 100644 --- a/esp-metadata-generated/src/_generated_esp32s2.rs +++ b/esp-metadata-generated/src/_generated_esp32s2.rs @@ -168,6 +168,12 @@ macro_rules! property { ("timergroup.timg_has_divcnt_rst") => { false }; + ("timergroup.default_clock_source") => { + 0 + }; + ("timergroup.default_clock_source", str) => { + stringify!(0) + }; ("uart.ram_size") => { 128 }; diff --git a/esp-metadata-generated/src/_generated_esp32s3.rs b/esp-metadata-generated/src/_generated_esp32s3.rs index a588c8615..60d388490 100644 --- a/esp-metadata-generated/src/_generated_esp32s3.rs +++ b/esp-metadata-generated/src/_generated_esp32s3.rs @@ -168,6 +168,12 @@ macro_rules! property { ("timergroup.timg_has_divcnt_rst") => { false }; + ("timergroup.default_clock_source") => { + 0 + }; + ("timergroup.default_clock_source", str) => { + stringify!(0) + }; ("uart.ram_size") => { 128 }; diff --git a/esp-metadata/devices/esp32c2.toml b/esp-metadata/devices/esp32c2.toml index b7a8835a0..609951be5 100644 --- a/esp-metadata/devices/esp32c2.toml +++ b/esp-metadata/devices/esp32c2.toml @@ -264,6 +264,8 @@ instances = [ support_status = "partial" instances = [{ name = "timg0" }] timg_has_divcnt_rst = true +default_clock_source = 0 # use_xtal = false +default_wdt_clock_source = 0 # use_wdt_xtal = false [device.uart] support_status = "supported" diff --git a/esp-metadata/devices/esp32c3.toml b/esp-metadata/devices/esp32c3.toml index 67ce92752..ac27b8cfd 100644 --- a/esp-metadata/devices/esp32c3.toml +++ b/esp-metadata/devices/esp32c3.toml @@ -324,6 +324,8 @@ instances = [ support_status = "partial" instances = [{ name = "timg0" }, { name = "timg1" }] timg_has_divcnt_rst = true +default_clock_source = 0 # use_xtal = false +default_wdt_clock_source = 0 # use_wdt_xtal = false [device.uart] support_status = "supported" diff --git a/esp-metadata/devices/esp32c6.toml b/esp-metadata/devices/esp32c6.toml index 04602a118..1036e7b6e 100644 --- a/esp-metadata/devices/esp32c6.toml +++ b/esp-metadata/devices/esp32c6.toml @@ -479,6 +479,8 @@ instances = [ support_status = "partial" instances = [{ name = "timg0" }, { name = "timg1" }] timg_has_divcnt_rst = true +default_clock_source = 1 +default_wdt_clock_source = 1 [device.uart] support_status = "supported" diff --git a/esp-metadata/devices/esp32h2.toml b/esp-metadata/devices/esp32h2.toml index 2532cfd56..9cdad013c 100644 --- a/esp-metadata/devices/esp32h2.toml +++ b/esp-metadata/devices/esp32h2.toml @@ -396,6 +396,8 @@ instances = [ support_status = "partial" instances = [{ name = "timg0" }, { name = "timg1" }] timg_has_divcnt_rst = true +default_clock_source = 2 +default_wdt_clock_source = 2 [device.uart] support_status = "supported" diff --git a/esp-metadata/devices/esp32s2.toml b/esp-metadata/devices/esp32s2.toml index 42d09b4f3..0dfdefafd 100644 --- a/esp-metadata/devices/esp32s2.toml +++ b/esp-metadata/devices/esp32s2.toml @@ -453,6 +453,7 @@ support_status = "partial" timg_has_timer1 = true timg_has_divcnt_rst = false instances = [{ name = "timg0" }, { name = "timg1" }] +default_clock_source = 0 # use_xtal = false [device.uart] support_status = "supported" diff --git a/esp-metadata/devices/esp32s3.toml b/esp-metadata/devices/esp32s3.toml index 8ed6aa466..92ea8b746 100644 --- a/esp-metadata/devices/esp32s3.toml +++ b/esp-metadata/devices/esp32s3.toml @@ -627,6 +627,7 @@ support_status = "partial" timg_has_timer1 = true timg_has_divcnt_rst = false instances = [{ name = "timg0" }, { name = "timg1" }] +default_clock_source = 0 # use_xtal = false [device.uart] support_status = "supported" diff --git a/esp-metadata/src/cfg.rs b/esp-metadata/src/cfg.rs index 158dfb5eb..a1895873f 100644 --- a/esp-metadata/src/cfg.rs +++ b/esp-metadata/src/cfg.rs @@ -116,6 +116,8 @@ macro_rules! driver_configs { (@property (Vec) $self:ident, $config:ident) => { Value::StringList($self.$config.clone()) }; (@property (Option) $self:ident, $config:ident) => { Value::from($self.$config) }; (@property ($($other:ty)*) $self:ident, $config:ident) => { Value::Generic(Box::new($self.$config.clone())) }; + (@is_optional Option<$t:ty>) => { true }; + (@is_optional $t:ty) => { false }; (@default $default:literal) => { $default }; (@default $default:literal $opt:literal) => { $opt }; @@ -143,10 +145,11 @@ macro_rules! driver_configs { } impl $struct { - fn properties(&self) -> impl Iterator { + fn properties(&self) -> impl Iterator { [$( // for each property, generate a tuple ( /* name: */ concat!(stringify!($group), ".", stringify!($config)), + /* is_optional: */ driver_configs!(@is_optional $ty $(<$generic>)?), /* value: */ driver_configs!(@property ($ty $(<$generic>)?) self, $config), ), )*].into_iter() @@ -222,7 +225,9 @@ macro_rules! driver_configs { } /// Returns an iterator over all properties of all peripherals. - pub fn properties(&self) -> impl Iterator { + /// + /// (property name, optional?, value) + pub fn properties(&self) -> impl Iterator { // Collect into a vector. This compiles faster than chaining iterators. let mut properties = vec![]; $( @@ -523,6 +528,10 @@ driver_configs![ timg_has_timer1: bool, #[serde(default)] timg_has_divcnt_rst: bool, + #[serde(default)] + default_clock_source: Option, + #[serde(default)] + default_wdt_clock_source: Option, } }, TouchProperties { diff --git a/esp-metadata/src/cfg/gpio.rs b/esp-metadata/src/cfg/gpio.rs index 76cfc402a..459c9c799 100644 --- a/esp-metadata/src/cfg/gpio.rs +++ b/esp-metadata/src/cfg/gpio.rs @@ -186,7 +186,7 @@ pub(crate) struct IoMuxSignal { } impl super::GpioProperties { - pub(super) fn computed_properties(&self) -> impl Iterator { + pub(super) fn computed_properties(&self) -> impl Iterator { let input_max = self .pins_and_signals .input_signals @@ -203,8 +203,8 @@ impl super::GpioProperties { .unwrap_or(0) as u32; [ - ("gpio.input_signal_max", Value::Number(input_max)), - ("gpio.output_signal_max", Value::Number(output_max)), + ("gpio.input_signal_max", false, Value::Number(input_max)), + ("gpio.output_signal_max", false, Value::Number(output_max)), ] .into_iter() } diff --git a/esp-metadata/src/cfg/rsa.rs b/esp-metadata/src/cfg/rsa.rs index 28206f6fd..ebc9cb024 100644 --- a/esp-metadata/src/cfg/rsa.rs +++ b/esp-metadata/src/cfg/rsa.rs @@ -17,14 +17,16 @@ impl RsaLengths { impl GenericProperty for RsaLengths {} impl super::RsaProperties { - pub(super) fn computed_properties(&self) -> impl Iterator { + pub(super) fn computed_properties(&self) -> impl Iterator { [ ( "rsa.exponentiation", + false, Value::NumberList(self.exponentiation.generate()), ), ( "rsa.multiplication", + false, Value::NumberList(self.multiplication.generate()), ), ] diff --git a/esp-metadata/src/lib.rs b/esp-metadata/src/lib.rs index 28c20a658..188fd530d 100644 --- a/esp-metadata/src/lib.rs +++ b/esp-metadata/src/lib.rs @@ -405,23 +405,32 @@ impl Config { self.device .peri_config .properties() - .filter_map(|(name, value)| match value { - Value::Boolean(true) => Some(vec![name.to_string()]), - Value::NumberList(_) => None, - Value::Generic(v) => v.cfgs(), - Value::StringList(values) => Some( - values - .iter() - .map(|val| { - format!( - "{name}_{}", - val.to_lowercase().replace("-", "_").replace("/", "_") - ) - }) - .collect(), - ), - Value::Number(value) => Some(vec![format!("{name}=\"{value}\"")]), - _ => None, + .filter_map(|(name, optional, value)| { + let is_unset = matches!(value, Value::Unset); + let mut syms = match value { + Value::Boolean(true) => Some(vec![name.to_string()]), + Value::NumberList(_) => None, + Value::Generic(v) => v.cfgs(), + Value::StringList(values) => Some( + values + .iter() + .map(|val| { + format!( + "{name}_{}", + val.to_lowercase().replace("-", "_").replace("/", "_") + ) + }) + .collect(), + ), + Value::Number(value) => Some(vec![format!("{name}=\"{value}\"")]), + _ => None, + }; + + if optional && !is_unset { + syms.get_or_insert_default().push(format!("{name}_is_set")); + } + + syms }) .flatten(), ); @@ -479,7 +488,7 @@ impl Config { self.device .peri_config .properties() - .flat_map(|(name, value)| match value { + .flat_map(|(name, _optional, value)| match value { Value::Number(value) => { let value = number(value); // ensure no numeric suffix is added quote! { @@ -662,6 +671,7 @@ impl Config { cfgs } + /// For each symbol generates a cargo directive that activates it. pub fn list_of_cfgs(&self) -> Vec { self.active_cfgs() .iter()