From 87b06bac89e684b25a3e0c9103926b02f832bf69 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Fri, 16 Feb 2024 01:07:41 +0100 Subject: [PATCH] rcc: separate fields for bus and kernel clock. --- stm32-data-gen/src/rcc.rs | 64 +++++++++++++++------------ stm32-data-serde/src/lib.rs | 24 ++++------ stm32-metapac-gen/res/src/metadata.rs | 10 ++++- stm32-metapac-gen/src/data.rs | 12 +++-- stm32-metapac-gen/src/lib.rs | 1 + 5 files changed, 62 insertions(+), 49 deletions(-) diff --git a/stm32-data-gen/src/rcc.rs b/stm32-data-gen/src/rcc.rs index 4c5c4cb..e9cc6fe 100644 --- a/stm32-data-gen/src/rcc.rs +++ b/stm32-data-gen/src/rcc.rs @@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet}; use anyhow::{anyhow, bail, Ok}; use chiptool::ir::IR; -use stm32_data_serde::chip::core::peripheral::rcc::{Mux, StopMode}; +use stm32_data_serde::chip::core::peripheral::rcc::{Field, StopMode}; use stm32_data_serde::chip::core::peripheral::{self, rcc}; use crate::regex; @@ -24,15 +24,15 @@ struct ParsedRcc { #[derive(Debug)] struct MuxInfo { - mux: Mux, + mux: Field, variants: Vec, } #[derive(Debug)] struct EnRst { - enable: rcc::Enable, - reset: Option, - clock: String, + enable: rcc::Field, + reset: Option, + bus_clock: String, stop_mode: StopMode, } @@ -173,7 +173,7 @@ impl ParsedRccs { } let val = MuxInfo { - mux: Mux { + mux: Field { register: reg.clone(), field: field.name.clone(), }, @@ -205,7 +205,7 @@ impl ParsedRccs { let mut reset = None; if let Some(rstr) = ir.fieldsets.get(®.replace("ENR", "RSTR")) { if let Some(_field) = rstr.fields.iter().find(|field| field.name == format!("{peri}RST")) { - reset = Some(stm32_data_serde::chip::core::peripheral::rcc::Reset { + reset = Some(rcc::Field { register: reg.replace("ENR", "RSTR"), field: format!("{peri}RST"), }); @@ -220,20 +220,15 @@ impl ParsedRccs { StopMode::Stop1 }; - let mut clock = clock.replace("AHB", "HCLK").replace("APB", "PCLK"); - - // Timers are a bit special, they may have a x2 freq - if regex!(r"^(HR)?TIM\d+$").is_match(peri) { - clock.push_str("_TIM"); - } + let clock = clock.replace("AHB", "HCLK").replace("APB", "PCLK"); let val = EnRst { - enable: peripheral::rcc::Enable { + enable: rcc::Field { register: reg.clone(), field: field.name.clone(), }, reset, - clock, + bus_clock: clock, stop_mode, }; @@ -297,26 +292,37 @@ impl ParsedRccs { let mux = get_with_fallback(peri_name, &rcc.mux, FALLBACKS); let phclk = regex!("^[PH]CLK"); - if let Some(mux) = mux { - if phclk.is_match(&en_rst.clock) { - for v in &mux.variants { - if phclk.is_match(v) && v != &en_rst.clock { - panic!( - "rcc_{}: peripheral {} is on bus {} but mux {}.{} refers to {}", - rcc_version, peri_name, en_rst.clock, mux.mux.register, mux.mux.field, v - ) - } - } - } + + let mut maybe_kernel_clock = en_rst.bus_clock.clone(); + // Timers are a bit special, they may have a x2 freq + if regex!(r"^(HR)?TIM\d+$").is_match(peri_name) { + maybe_kernel_clock.push_str("_TIM"); } + let kernel_clock = match mux { + Some(mux) => { + // check for mismatch between mux and bus clock. + if phclk.is_match(&en_rst.bus_clock) { + for v in &mux.variants { + if phclk.is_match(v) && v != &maybe_kernel_clock { + panic!( + "rcc_{}: peripheral {} is on bus {} but mux {}.{} refers to {}", + rcc_version, peri_name, maybe_kernel_clock, mux.mux.register, mux.mux.field, v + ) + } + } + } + rcc::KernelClock::Mux(mux.mux.clone()) + } + None => rcc::KernelClock::Clock(maybe_kernel_clock), + }; + Some(peripheral::Rcc { - clock: en_rst.clock.clone(), + bus_clock: en_rst.bus_clock.clone(), + kernel_clock, enable: en_rst.enable.clone(), reset: en_rst.reset.clone(), stop_mode: en_rst.stop_mode.clone(), - - mux: mux.map(|m| m.mux.clone()), }) } } diff --git a/stm32-data-serde/src/lib.rs b/stm32-data-serde/src/lib.rs index c82633c..38a4407 100644 --- a/stm32-data-serde/src/lib.rs +++ b/stm32-data-serde/src/lib.rs @@ -114,12 +114,11 @@ pub mod chip { #[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)] pub struct Rcc { - pub clock: String, - pub enable: rcc::Enable, + pub bus_clock: String, + pub kernel_clock: rcc::KernelClock, + pub enable: rcc::Field, #[serde(skip_serializing_if = "Option::is_none")] - pub reset: Option, - #[serde(skip_serializing_if = "Option::is_none")] - pub mux: Option, + pub reset: Option, #[serde(default, skip_serializing_if = "crate::is_default")] pub stop_mode: rcc::StopMode, } @@ -128,21 +127,16 @@ pub mod chip { use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)] - pub struct Enable { + pub struct Field { pub register: String, pub field: String, } #[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)] - pub struct Reset { - pub register: String, - pub field: String, - } - - #[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)] - pub struct Mux { - pub register: String, - pub field: String, + #[serde(untagged)] + pub enum KernelClock { + Clock(String), + Mux(Field), } #[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize, Default)] diff --git a/stm32-metapac-gen/res/src/metadata.rs b/stm32-metapac-gen/res/src/metadata.rs index 751d9ff..96802ed 100644 --- a/stm32-metapac-gen/res/src/metadata.rs +++ b/stm32-metapac-gen/res/src/metadata.rs @@ -194,10 +194,10 @@ pub struct PeripheralInterrupt { #[derive(Debug, Eq, PartialEq, Clone)] pub struct PeripheralRcc { - pub clock: &'static str, + pub bus_clock: &'static str, + pub kernel_clock: PeripheralRccKernelClock, pub enable: Option, pub reset: Option, - pub mux: Option, pub stop_mode: StopMode, } @@ -207,6 +207,12 @@ pub struct PeripheralRccRegister { pub field: &'static str, } +#[derive(Debug, Eq, PartialEq, Clone)] +pub enum PeripheralRccKernelClock { + Clock(&'static str), + Mux(PeripheralRccRegister), +} + #[derive(Debug, Eq, PartialEq, Clone, Default)] pub enum StopMode { #[default] diff --git a/stm32-metapac-gen/src/data.rs b/stm32-metapac-gen/src/data.rs index 76b8946..9e3549d 100644 --- a/stm32-metapac-gen/src/data.rs +++ b/stm32-metapac-gen/src/data.rs @@ -344,17 +344,23 @@ pub struct PeripheralInterrupt { #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct PeripheralRcc { - pub clock: String, + pub bus_clock: String, + pub kernel_clock: PeripheralRccKernelClock, #[serde(default)] pub enable: Option, #[serde(default)] pub reset: Option, #[serde(default)] - pub mux: Option, - #[serde(default)] pub stop_mode: StopMode, } +#[derive(Debug, Eq, PartialEq, Clone, Deserialize)] +#[serde(untagged)] +pub enum PeripheralRccKernelClock { + Clock(String), + Mux(PeripheralRccRegister), +} + #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct PeripheralRccRegister { pub register: String, diff --git a/stm32-metapac-gen/src/lib.rs b/stm32-metapac-gen/src/lib.rs index 999c750..3e2ea6f 100644 --- a/stm32-metapac-gen/src/lib.rs +++ b/stm32-metapac-gen/src/lib.rs @@ -220,6 +220,7 @@ impl Gen { let data = format!( "include!(\"../{}\"); + use crate::metadata::PeripheralRccKernelClock::{{Clock, Mux}}; pub static METADATA: Metadata = Metadata {{ name: {:?}, family: {:?},