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 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<String>,
}
#[derive(Debug)]
struct EnRst {
enable: rcc::Enable,
reset: Option<rcc::Reset>,
clock: String,
enable: rcc::Field,
reset: Option<rcc::Field>,
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(&reg.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) {
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 != &en_rst.clock {
if phclk.is_match(v) && v != &maybe_kernel_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
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()),
})
}
}

View File

@ -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<rcc::Reset>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mux: Option<rcc::Mux>,
pub reset: Option<rcc::Field>,
#[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)]

View File

@ -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<PeripheralRccRegister>,
pub reset: Option<PeripheralRccRegister>,
pub mux: Option<PeripheralRccRegister>,
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]

View File

@ -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<PeripheralRccRegister>,
#[serde(default)]
pub reset: Option<PeripheralRccRegister>,
#[serde(default)]
pub mux: Option<PeripheralRccRegister>,
#[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,

View File

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