rcc: separate fields for bus and kernel clock.

This commit is contained in:
Dario Nieuwenhuis 2024-02-16 01:07:41 +01:00
parent 917db8f71e
commit 87b06bac89
5 changed files with 62 additions and 49 deletions

View File

@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet};
use anyhow::{anyhow, bail, Ok}; use anyhow::{anyhow, bail, Ok};
use chiptool::ir::IR; 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 stm32_data_serde::chip::core::peripheral::{self, rcc};
use crate::regex; use crate::regex;
@ -24,15 +24,15 @@ struct ParsedRcc {
#[derive(Debug)] #[derive(Debug)]
struct MuxInfo { struct MuxInfo {
mux: Mux, mux: Field,
variants: Vec<String>, variants: Vec<String>,
} }
#[derive(Debug)] #[derive(Debug)]
struct EnRst { struct EnRst {
enable: rcc::Enable, enable: rcc::Field,
reset: Option<rcc::Reset>, reset: Option<rcc::Field>,
clock: String, bus_clock: String,
stop_mode: StopMode, stop_mode: StopMode,
} }
@ -173,7 +173,7 @@ impl ParsedRccs {
} }
let val = MuxInfo { let val = MuxInfo {
mux: Mux { mux: Field {
register: reg.clone(), register: reg.clone(),
field: field.name.clone(), field: field.name.clone(),
}, },
@ -205,7 +205,7 @@ impl ParsedRccs {
let mut reset = None; let mut reset = None;
if let Some(rstr) = ir.fieldsets.get(&reg.replace("ENR", "RSTR")) { if let Some(rstr) = ir.fieldsets.get(&reg.replace("ENR", "RSTR")) {
if let Some(_field) = rstr.fields.iter().find(|field| field.name == format!("{peri}RST")) { 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"), register: reg.replace("ENR", "RSTR"),
field: format!("{peri}RST"), field: format!("{peri}RST"),
}); });
@ -220,20 +220,15 @@ impl ParsedRccs {
StopMode::Stop1 StopMode::Stop1
}; };
let mut clock = clock.replace("AHB", "HCLK").replace("APB", "PCLK"); let 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 val = EnRst { let val = EnRst {
enable: peripheral::rcc::Enable { enable: rcc::Field {
register: reg.clone(), register: reg.clone(),
field: field.name.clone(), field: field.name.clone(),
}, },
reset, reset,
clock, bus_clock: clock,
stop_mode, stop_mode,
}; };
@ -297,26 +292,37 @@ impl ParsedRccs {
let mux = get_with_fallback(peri_name, &rcc.mux, FALLBACKS); let mux = get_with_fallback(peri_name, &rcc.mux, FALLBACKS);
let phclk = regex!("^[PH]CLK"); let phclk = regex!("^[PH]CLK");
if let Some(mux) = mux {
if phclk.is_match(&en_rst.clock) { 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 { for v in &mux.variants {
if phclk.is_match(v) && v != &en_rst.clock { if phclk.is_match(v) && v != &maybe_kernel_clock {
panic!( panic!(
"rcc_{}: peripheral {} is on bus {} but mux {}.{} refers to {}", "rcc_{}: peripheral {} is on bus {} but mux {}.{} refers to {}",
rcc_version, peri_name, en_rst.clock, mux.mux.register, mux.mux.field, v 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 { Some(peripheral::Rcc {
clock: en_rst.clock.clone(), bus_clock: en_rst.bus_clock.clone(),
kernel_clock,
enable: en_rst.enable.clone(), enable: en_rst.enable.clone(),
reset: en_rst.reset.clone(), reset: en_rst.reset.clone(),
stop_mode: en_rst.stop_mode.clone(), stop_mode: en_rst.stop_mode.clone(),
mux: mux.map(|m| m.mux.clone()),
}) })
} }
} }

View File

@ -114,12 +114,11 @@ pub mod chip {
#[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
pub struct Rcc { pub struct Rcc {
pub clock: String, pub bus_clock: String,
pub enable: rcc::Enable, pub kernel_clock: rcc::KernelClock,
pub enable: rcc::Field,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub reset: Option<rcc::Reset>, pub reset: Option<rcc::Field>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mux: Option<rcc::Mux>,
#[serde(default, skip_serializing_if = "crate::is_default")] #[serde(default, skip_serializing_if = "crate::is_default")]
pub stop_mode: rcc::StopMode, pub stop_mode: rcc::StopMode,
} }
@ -128,21 +127,16 @@ pub mod chip {
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
pub struct Enable { pub struct Field {
pub register: String, pub register: String,
pub field: String, pub field: String,
} }
#[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
pub struct Reset { #[serde(untagged)]
pub register: String, pub enum KernelClock {
pub field: String, Clock(String),
} Mux(Field),
#[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
pub struct Mux {
pub register: String,
pub field: String,
} }
#[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize, Default)] #[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize, Default)]

View File

@ -194,10 +194,10 @@ pub struct PeripheralInterrupt {
#[derive(Debug, Eq, PartialEq, Clone)] #[derive(Debug, Eq, PartialEq, Clone)]
pub struct PeripheralRcc { pub struct PeripheralRcc {
pub clock: &'static str, pub bus_clock: &'static str,
pub kernel_clock: PeripheralRccKernelClock,
pub enable: Option<PeripheralRccRegister>, pub enable: Option<PeripheralRccRegister>,
pub reset: Option<PeripheralRccRegister>, pub reset: Option<PeripheralRccRegister>,
pub mux: Option<PeripheralRccRegister>,
pub stop_mode: StopMode, pub stop_mode: StopMode,
} }
@ -207,6 +207,12 @@ pub struct PeripheralRccRegister {
pub field: &'static str, pub field: &'static str,
} }
#[derive(Debug, Eq, PartialEq, Clone)]
pub enum PeripheralRccKernelClock {
Clock(&'static str),
Mux(PeripheralRccRegister),
}
#[derive(Debug, Eq, PartialEq, Clone, Default)] #[derive(Debug, Eq, PartialEq, Clone, Default)]
pub enum StopMode { pub enum StopMode {
#[default] #[default]

View File

@ -344,17 +344,23 @@ pub struct PeripheralInterrupt {
#[derive(Debug, Eq, PartialEq, Clone, Deserialize)] #[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
pub struct PeripheralRcc { pub struct PeripheralRcc {
pub clock: String, pub bus_clock: String,
pub kernel_clock: PeripheralRccKernelClock,
#[serde(default)] #[serde(default)]
pub enable: Option<PeripheralRccRegister>, pub enable: Option<PeripheralRccRegister>,
#[serde(default)] #[serde(default)]
pub reset: Option<PeripheralRccRegister>, pub reset: Option<PeripheralRccRegister>,
#[serde(default)] #[serde(default)]
pub mux: Option<PeripheralRccRegister>,
#[serde(default)]
pub stop_mode: StopMode, 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)] #[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
pub struct PeripheralRccRegister { pub struct PeripheralRccRegister {
pub register: String, pub register: String,

View File

@ -220,6 +220,7 @@ impl Gen {
let data = format!( let data = format!(
"include!(\"../{}\"); "include!(\"../{}\");
use crate::metadata::PeripheralRccKernelClock::{{Clock, Mux}};
pub static METADATA: Metadata = Metadata {{ pub static METADATA: Metadata = Metadata {{
name: {:?}, name: {:?},
family: {:?}, family: {:?},