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
This commit is contained in:
Dániel Buga 2025-07-28 09:10:58 +02:00 committed by GitHub
parent 73ef8d9227
commit bb50746e9c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 223 additions and 66 deletions

View File

@ -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;
}

View File

@ -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();

View File

@ -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.

View File

@ -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.

View File

@ -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 {
(*<Self as TimerGroupInstance>::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 {
(*<Self as TimerGroupInstance>::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 {
(*<Self as TimerGroupInstance>::register_block())
.t(0)
.config()
.modify(|_, w| w.use_xtal().bit(DEFAULT_CLK_SRC == 1));
#[cfg(timergroup_timg_has_timer1)]
(*<Self as TimerGroupInstance>::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 {
(*<Self as TimerGroupInstance>::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() };

View File

@ -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 {

View File

@ -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
};

View File

@ -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
};

View File

@ -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
};

View File

@ -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
};

View File

@ -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
};

View File

@ -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
};

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -116,6 +116,8 @@ macro_rules! driver_configs {
(@property (Vec<String>) $self:ident, $config:ident) => { Value::StringList($self.$config.clone()) };
(@property (Option<u32>) $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<Item = (&str, Value)> {
fn properties(&self) -> impl Iterator<Item = (&str, bool, Value)> {
[$( // 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<Item = (&str, Value)> {
///
/// (property name, optional?, value)
pub fn properties(&self) -> impl Iterator<Item = (&str, bool, Value)> {
// 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<u32>,
#[serde(default)]
default_wdt_clock_source: Option<u32>,
}
},
TouchProperties {

View File

@ -186,7 +186,7 @@ pub(crate) struct IoMuxSignal {
}
impl super::GpioProperties {
pub(super) fn computed_properties(&self) -> impl Iterator<Item = (&str, Value)> {
pub(super) fn computed_properties(&self) -> impl Iterator<Item = (&str, bool, Value)> {
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()
}

View File

@ -17,14 +17,16 @@ impl RsaLengths {
impl GenericProperty for RsaLengths {}
impl super::RsaProperties {
pub(super) fn computed_properties(&self) -> impl Iterator<Item = (&str, Value)> {
pub(super) fn computed_properties(&self) -> impl Iterator<Item = (&str, bool, Value)> {
[
(
"rsa.exponentiation",
false,
Value::NumberList(self.exponentiation.generate()),
),
(
"rsa.multiplication",
false,
Value::NumberList(self.multiplication.generate()),
),
]

View File

@ -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<String> {
self.active_cfgs()
.iter()