parent
028efe4e6e
commit
0c921dde2e
@ -750,8 +750,8 @@ fieldset/CCIPR:
|
|||||||
bit_offset: 12
|
bit_offset: 12
|
||||||
bit_size: 2
|
bit_size: 2
|
||||||
enum: I2C1SEL
|
enum: I2C1SEL
|
||||||
- name: I2S2SEL
|
- name: I2C2I2S1SEL
|
||||||
description: I2S1 clock source selection
|
description: I2C2 or I2S1 clock source selection
|
||||||
bit_offset: 14
|
bit_offset: 14
|
||||||
bit_size: 2
|
bit_size: 2
|
||||||
enum: I2C2I2S1SEL
|
enum: I2C2I2S1SEL
|
||||||
|
@ -1596,11 +1596,11 @@ fieldset/CCIPR5:
|
|||||||
bit_offset: 0
|
bit_offset: 0
|
||||||
bit_size: 3
|
bit_size: 3
|
||||||
enum: ADCDACSEL
|
enum: ADCDACSEL
|
||||||
- name: DACSEL
|
- name: DACHOLDSEL
|
||||||
description: DAC hold clock
|
description: DAC hold clock
|
||||||
bit_offset: 3
|
bit_offset: 3
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
enum: DACSEL
|
enum: DACHOLDSEL
|
||||||
- name: RNGSEL
|
- name: RNGSEL
|
||||||
description: RNG kernel clock source selection
|
description: RNG kernel clock source selection
|
||||||
bit_offset: 4
|
bit_offset: 4
|
||||||
@ -2156,7 +2156,7 @@ enum/CKPERSEL:
|
|||||||
- name: HSE
|
- name: HSE
|
||||||
description: hse_ck selected as kernel clock
|
description: hse_ck selected as kernel clock
|
||||||
value: 2
|
value: 2
|
||||||
enum/DACSEL:
|
enum/DACHOLDSEL:
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
variants:
|
variants:
|
||||||
- name: DAC_HOLD
|
- name: DAC_HOLD
|
||||||
|
@ -895,11 +895,11 @@ fieldset/CCIPR5:
|
|||||||
bit_offset: 0
|
bit_offset: 0
|
||||||
bit_size: 3
|
bit_size: 3
|
||||||
enum: ADCDACSEL
|
enum: ADCDACSEL
|
||||||
- name: DACSEL
|
- name: DACHOLDSEL
|
||||||
description: DAC hold clock
|
description: DAC hold clock
|
||||||
bit_offset: 3
|
bit_offset: 3
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
enum: DACSEL
|
enum: DACHOLDSEL
|
||||||
- name: RNGSEL
|
- name: RNGSEL
|
||||||
description: RNG kernel clock source selection
|
description: RNG kernel clock source selection
|
||||||
bit_offset: 4
|
bit_offset: 4
|
||||||
@ -1365,7 +1365,7 @@ enum/CKPERSEL:
|
|||||||
- name: HSE
|
- name: HSE
|
||||||
description: hse_ck selected as kernel clock
|
description: hse_ck selected as kernel clock
|
||||||
value: 2
|
value: 2
|
||||||
enum/DACSEL:
|
enum/DACHOLDSEL:
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
variants:
|
variants:
|
||||||
- name: DAC_HOLD
|
- name: DAC_HOLD
|
||||||
|
@ -920,7 +920,7 @@ fieldset/APB1HENR:
|
|||||||
description: Clock Recovery System peripheral clock enable
|
description: Clock Recovery System peripheral clock enable
|
||||||
bit_offset: 1
|
bit_offset: 1
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
- name: SWPEN
|
- name: SWPMIEN
|
||||||
description: SWPMI Peripheral Clocks Enable
|
description: SWPMI Peripheral Clocks Enable
|
||||||
bit_offset: 2
|
bit_offset: 2
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
@ -951,7 +951,7 @@ fieldset/APB1HLPENR:
|
|||||||
description: Clock Recovery System peripheral clock enable during CSleep mode
|
description: Clock Recovery System peripheral clock enable during CSleep mode
|
||||||
bit_offset: 1
|
bit_offset: 1
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
- name: SWPLPEN
|
- name: SWPMILPEN
|
||||||
description: SWPMI Peripheral Clocks Enable During CSleep Mode
|
description: SWPMI Peripheral Clocks Enable During CSleep Mode
|
||||||
bit_offset: 2
|
bit_offset: 2
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
@ -982,7 +982,7 @@ fieldset/APB1HRSTR:
|
|||||||
description: Clock Recovery System reset
|
description: Clock Recovery System reset
|
||||||
bit_offset: 1
|
bit_offset: 1
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
- name: SWPRST
|
- name: SWPMIRST
|
||||||
description: SWPMI block reset
|
description: SWPMI block reset
|
||||||
bit_offset: 2
|
bit_offset: 2
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
@ -2186,7 +2186,7 @@ fieldset/C1_APB1HENR:
|
|||||||
description: Clock Recovery System peripheral clock enable
|
description: Clock Recovery System peripheral clock enable
|
||||||
bit_offset: 1
|
bit_offset: 1
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
- name: SWPEN
|
- name: SWPMIEN
|
||||||
description: SWPMI Peripheral Clocks Enable
|
description: SWPMI Peripheral Clocks Enable
|
||||||
bit_offset: 2
|
bit_offset: 2
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
@ -2209,7 +2209,7 @@ fieldset/C1_APB1HLPENR:
|
|||||||
description: Clock Recovery System peripheral clock enable during CSleep mode
|
description: Clock Recovery System peripheral clock enable during CSleep mode
|
||||||
bit_offset: 1
|
bit_offset: 1
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
- name: SWPLPEN
|
- name: SWPMILPEN
|
||||||
description: SWPMI Peripheral Clocks Enable During CSleep Mode
|
description: SWPMI Peripheral Clocks Enable During CSleep Mode
|
||||||
bit_offset: 2
|
bit_offset: 2
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
@ -3142,11 +3142,11 @@ fieldset/D2CCIP1R:
|
|||||||
bit_offset: 28
|
bit_offset: 28
|
||||||
bit_size: 2
|
bit_size: 2
|
||||||
enum: FDCANSEL
|
enum: FDCANSEL
|
||||||
- name: SWPSEL
|
- name: SWPMISEL
|
||||||
description: SWPMI kernel clock source selection
|
description: SWPMI kernel clock source selection
|
||||||
bit_offset: 31
|
bit_offset: 31
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
enum: SWPSEL
|
enum: SWPMISEL
|
||||||
fieldset/D2CCIP2R:
|
fieldset/D2CCIP2R:
|
||||||
description: RCC Domain 2 Kernel Clock Configuration Register
|
description: RCC Domain 2 Kernel Clock Configuration Register
|
||||||
fields:
|
fields:
|
||||||
@ -5395,8 +5395,8 @@ enum/SPDIFRXSEL:
|
|||||||
enum/SPI45SEL:
|
enum/SPI45SEL:
|
||||||
bit_size: 3
|
bit_size: 3
|
||||||
variants:
|
variants:
|
||||||
- name: APB
|
- name: PCLK2
|
||||||
description: APB clock selected as peripheral clock
|
description: APB2 clock selected as peripheral clock
|
||||||
value: 0
|
value: 0
|
||||||
- name: PLL2_Q
|
- name: PLL2_Q
|
||||||
description: pll2_q selected as peripheral clock
|
description: pll2_q selected as peripheral clock
|
||||||
@ -5458,10 +5458,10 @@ enum/SW:
|
|||||||
- name: PLL1_P
|
- name: PLL1_P
|
||||||
description: PLL1 selected as system clock
|
description: PLL1 selected as system clock
|
||||||
value: 3
|
value: 3
|
||||||
enum/SWPSEL:
|
enum/SWPMISEL:
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
variants:
|
variants:
|
||||||
- name: PCLK
|
- name: PCLK1
|
||||||
description: pclk selected as peripheral clock
|
description: pclk selected as peripheral clock
|
||||||
value: 0
|
value: 0
|
||||||
- name: HSI
|
- name: HSI
|
||||||
|
@ -852,7 +852,7 @@ fieldset/APB1HENR:
|
|||||||
description: Clock Recovery System peripheral clock enable
|
description: Clock Recovery System peripheral clock enable
|
||||||
bit_offset: 1
|
bit_offset: 1
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
- name: SWPEN
|
- name: SWPMIEN
|
||||||
description: SWPMI Peripheral Clocks Enable
|
description: SWPMI Peripheral Clocks Enable
|
||||||
bit_offset: 2
|
bit_offset: 2
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
@ -883,7 +883,7 @@ fieldset/APB1HLPENR:
|
|||||||
description: Clock Recovery System peripheral clock enable during CSleep mode
|
description: Clock Recovery System peripheral clock enable during CSleep mode
|
||||||
bit_offset: 1
|
bit_offset: 1
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
- name: SWPLPEN
|
- name: SWPMILPEN
|
||||||
description: SWPMI Peripheral Clocks Enable During CSleep Mode
|
description: SWPMI Peripheral Clocks Enable During CSleep Mode
|
||||||
bit_offset: 2
|
bit_offset: 2
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
@ -914,7 +914,7 @@ fieldset/APB1HRSTR:
|
|||||||
description: Clock Recovery System reset
|
description: Clock Recovery System reset
|
||||||
bit_offset: 1
|
bit_offset: 1
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
- name: SWPRST
|
- name: SWPMIRST
|
||||||
description: SWPMI block reset
|
description: SWPMI block reset
|
||||||
bit_offset: 2
|
bit_offset: 2
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
@ -2093,11 +2093,11 @@ fieldset/D2CCIP1R:
|
|||||||
bit_offset: 28
|
bit_offset: 28
|
||||||
bit_size: 2
|
bit_size: 2
|
||||||
enum: FDCANSEL
|
enum: FDCANSEL
|
||||||
- name: SWPSEL
|
- name: SWPMISEL
|
||||||
description: SWPMI kernel clock source selection
|
description: SWPMI kernel clock source selection
|
||||||
bit_offset: 31
|
bit_offset: 31
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
enum: SWPSEL
|
enum: SWPMISEL
|
||||||
fieldset/D2CCIP2R:
|
fieldset/D2CCIP2R:
|
||||||
description: RCC Domain 2 Kernel Clock Configuration Register
|
description: RCC Domain 2 Kernel Clock Configuration Register
|
||||||
fields:
|
fields:
|
||||||
@ -4309,8 +4309,8 @@ enum/SPDIFRXSEL:
|
|||||||
enum/SPI45SEL:
|
enum/SPI45SEL:
|
||||||
bit_size: 3
|
bit_size: 3
|
||||||
variants:
|
variants:
|
||||||
- name: APB
|
- name: HCLK2
|
||||||
description: APB clock selected as peripheral clock
|
description: APB2 clock selected as peripheral clock
|
||||||
value: 0
|
value: 0
|
||||||
- name: PLL2_Q
|
- name: PLL2_Q
|
||||||
description: pll2_q selected as peripheral clock
|
description: pll2_q selected as peripheral clock
|
||||||
@ -4372,10 +4372,10 @@ enum/SW:
|
|||||||
- name: PLL1_P
|
- name: PLL1_P
|
||||||
description: PLL1 selected as system clock
|
description: PLL1 selected as system clock
|
||||||
value: 3
|
value: 3
|
||||||
enum/SWPSEL:
|
enum/SWPMISEL:
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
variants:
|
variants:
|
||||||
- name: PCLK
|
- name: PCLK1
|
||||||
description: pclk selected as peripheral clock
|
description: pclk selected as peripheral clock
|
||||||
value: 0
|
value: 0
|
||||||
- name: HSI
|
- name: HSI
|
||||||
|
@ -908,7 +908,7 @@ fieldset/APB1HENR:
|
|||||||
description: Clock Recovery System peripheral clock enable
|
description: Clock Recovery System peripheral clock enable
|
||||||
bit_offset: 1
|
bit_offset: 1
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
- name: SWPEN
|
- name: SWPMIEN
|
||||||
description: SWPMI Peripheral Clocks Enable
|
description: SWPMI Peripheral Clocks Enable
|
||||||
bit_offset: 2
|
bit_offset: 2
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
@ -939,7 +939,7 @@ fieldset/APB1HLPENR:
|
|||||||
description: Clock Recovery System peripheral clock enable during CSleep mode
|
description: Clock Recovery System peripheral clock enable during CSleep mode
|
||||||
bit_offset: 1
|
bit_offset: 1
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
- name: SWPLPEN
|
- name: SWPMILPEN
|
||||||
description: SWPMI Peripheral Clocks Enable During CSleep Mode
|
description: SWPMI Peripheral Clocks Enable During CSleep Mode
|
||||||
bit_offset: 2
|
bit_offset: 2
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
@ -970,7 +970,7 @@ fieldset/APB1HRSTR:
|
|||||||
description: Clock Recovery System reset
|
description: Clock Recovery System reset
|
||||||
bit_offset: 1
|
bit_offset: 1
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
- name: SWPRST
|
- name: SWPMIRST
|
||||||
description: SWPMI block reset
|
description: SWPMI block reset
|
||||||
bit_offset: 2
|
bit_offset: 2
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
@ -2174,7 +2174,7 @@ fieldset/C1_APB1HENR:
|
|||||||
description: Clock Recovery System peripheral clock enable
|
description: Clock Recovery System peripheral clock enable
|
||||||
bit_offset: 1
|
bit_offset: 1
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
- name: SWPEN
|
- name: SWPMIEN
|
||||||
description: SWPMI Peripheral Clocks Enable
|
description: SWPMI Peripheral Clocks Enable
|
||||||
bit_offset: 2
|
bit_offset: 2
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
@ -2197,7 +2197,7 @@ fieldset/C1_APB1HLPENR:
|
|||||||
description: Clock Recovery System peripheral clock enable during CSleep mode
|
description: Clock Recovery System peripheral clock enable during CSleep mode
|
||||||
bit_offset: 1
|
bit_offset: 1
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
- name: SWPLPEN
|
- name: SWPMILPEN
|
||||||
description: SWPMI Peripheral Clocks Enable During CSleep Mode
|
description: SWPMI Peripheral Clocks Enable During CSleep Mode
|
||||||
bit_offset: 2
|
bit_offset: 2
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
@ -3125,11 +3125,11 @@ fieldset/D2CCIP1R:
|
|||||||
bit_offset: 28
|
bit_offset: 28
|
||||||
bit_size: 2
|
bit_size: 2
|
||||||
enum: FDCANSEL
|
enum: FDCANSEL
|
||||||
- name: SWPSEL
|
- name: SWPMISEL
|
||||||
description: SWPMI kernel clock source selection
|
description: SWPMI kernel clock source selection
|
||||||
bit_offset: 31
|
bit_offset: 31
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
enum: SWPSEL
|
enum: SWPMISEL
|
||||||
fieldset/D2CCIP2R:
|
fieldset/D2CCIP2R:
|
||||||
description: RCC Domain 2 Kernel Clock Configuration Register
|
description: RCC Domain 2 Kernel Clock Configuration Register
|
||||||
fields:
|
fields:
|
||||||
@ -5378,8 +5378,8 @@ enum/SPDIFRXSEL:
|
|||||||
enum/SPI45SEL:
|
enum/SPI45SEL:
|
||||||
bit_size: 3
|
bit_size: 3
|
||||||
variants:
|
variants:
|
||||||
- name: APB
|
- name: PCLK2
|
||||||
description: APB clock selected as peripheral clock
|
description: APB2 clock selected as peripheral clock
|
||||||
value: 0
|
value: 0
|
||||||
- name: PLL2_Q
|
- name: PLL2_Q
|
||||||
description: pll2_q selected as peripheral clock
|
description: pll2_q selected as peripheral clock
|
||||||
@ -5441,10 +5441,10 @@ enum/SW:
|
|||||||
- name: PLL1_P
|
- name: PLL1_P
|
||||||
description: PLL1 selected as system clock
|
description: PLL1 selected as system clock
|
||||||
value: 3
|
value: 3
|
||||||
enum/SWPSEL:
|
enum/SWPMISEL:
|
||||||
bit_size: 1
|
bit_size: 1
|
||||||
variants:
|
variants:
|
||||||
- name: PCLK
|
- name: PCLK1
|
||||||
description: pclk selected as peripheral clock
|
description: pclk selected as peripheral clock
|
||||||
value: 0
|
value: 0
|
||||||
- name: HSI
|
- name: HSI
|
||||||
|
@ -834,7 +834,7 @@ fn process_group(
|
|||||||
headers: &header::Headers,
|
headers: &header::Headers,
|
||||||
af: &gpio_af::Af,
|
af: &gpio_af::Af,
|
||||||
chip_interrupts: &interrupts::ChipInterrupts,
|
chip_interrupts: &interrupts::ChipInterrupts,
|
||||||
peripheral_to_clock: &rcc::PeripheralToClock,
|
peripheral_to_clock: &rcc::ParsedRccs,
|
||||||
dma_channels: &dma::DmaChannels,
|
dma_channels: &dma::DmaChannels,
|
||||||
chips: &HashMap<String, Chip>,
|
chips: &HashMap<String, Chip>,
|
||||||
memories: &memory::Memories,
|
memories: &memory::Memories,
|
||||||
@ -889,7 +889,7 @@ fn process_core(
|
|||||||
group: &ChipGroup,
|
group: &ChipGroup,
|
||||||
chip_interrupts: &interrupts::ChipInterrupts,
|
chip_interrupts: &interrupts::ChipInterrupts,
|
||||||
peri_matcher: &mut PeriMatcher,
|
peri_matcher: &mut PeriMatcher,
|
||||||
peripheral_to_clock: &rcc::PeripheralToClock,
|
peripheral_to_clock: &rcc::ParsedRccs,
|
||||||
rcc_block: (&str, &str, &str),
|
rcc_block: (&str, &str, &str),
|
||||||
chip_af: Option<&HashMap<String, Vec<stm32_data_serde::chip::core::peripheral::Pin>>>,
|
chip_af: Option<&HashMap<String, Vec<stm32_data_serde::chip::core::peripheral::Pin>>>,
|
||||||
dma_channels: &dma::DmaChannels,
|
dma_channels: &dma::DmaChannels,
|
||||||
@ -1115,15 +1115,8 @@ fn process_core(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(rcc_info) = peripheral_to_clock.match_peri_clock(
|
if let Some(rcc_info) = peripheral_to_clock.match_peri_clock(rcc_block.1, &pname) {
|
||||||
&(
|
p.rcc = Some(rcc_info);
|
||||||
rcc_block.0.to_string(),
|
|
||||||
rcc_block.1.to_string(),
|
|
||||||
rcc_block.2.to_string(),
|
|
||||||
),
|
|
||||||
&pname,
|
|
||||||
) {
|
|
||||||
p.rcc = Some(rcc_info.clone());
|
|
||||||
}
|
}
|
||||||
if let Some(pins) = periph_pins.get_mut(&pname) {
|
if let Some(pins) = periph_pins.get_mut(&pname) {
|
||||||
// merge the core xml info with GPIO xml info to hopefully get the full picture
|
// merge the core xml info with GPIO xml info to hopefully get the full picture
|
||||||
@ -1468,7 +1461,7 @@ pub fn dump_all_chips(
|
|||||||
headers: header::Headers,
|
headers: header::Headers,
|
||||||
af: gpio_af::Af,
|
af: gpio_af::Af,
|
||||||
chip_interrupts: interrupts::ChipInterrupts,
|
chip_interrupts: interrupts::ChipInterrupts,
|
||||||
peripheral_to_clock: rcc::PeripheralToClock,
|
peripheral_to_clock: rcc::ParsedRccs,
|
||||||
dma_channels: dma::DmaChannels,
|
dma_channels: dma::DmaChannels,
|
||||||
chips: std::collections::HashMap<String, Chip>,
|
chips: std::collections::HashMap<String, Chip>,
|
||||||
memories: memory::Memories,
|
memories: memory::Memories,
|
||||||
|
@ -76,7 +76,7 @@ fn main() -> anyhow::Result<()> {
|
|||||||
let chip_interrupts = interrupts::ChipInterrupts::parse()?;
|
let chip_interrupts = interrupts::ChipInterrupts::parse()?;
|
||||||
|
|
||||||
// stopwatch.section("Parsing RCC registers");
|
// stopwatch.section("Parsing RCC registers");
|
||||||
let peripheral_to_clock = rcc::PeripheralToClock::parse(®isters)?;
|
let peripheral_to_clock = rcc::ParsedRccs::parse(®isters)?;
|
||||||
|
|
||||||
// stopwatch.section("Parsing docs");
|
// stopwatch.section("Parsing docs");
|
||||||
let docs = docs::Docs::parse()?;
|
let docs = docs::Docs::parse()?;
|
||||||
|
@ -1,42 +1,49 @@
|
|||||||
use std::cmp::Ordering;
|
|
||||||
use std::collections::hash_map::Entry;
|
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::hash::Hash;
|
|
||||||
|
|
||||||
use anyhow::{anyhow, Ok};
|
use anyhow::{anyhow, bail, Ok};
|
||||||
use chiptool::ir::{BlockItemInner, Enum};
|
use chiptool::ir::{BlockItemInner, Enum, IR};
|
||||||
use stm32_data_serde::chip::core::peripheral;
|
|
||||||
use stm32_data_serde::chip::core::peripheral::rcc::{Mux, StopMode};
|
use stm32_data_serde::chip::core::peripheral::rcc::{Mux, StopMode};
|
||||||
|
use stm32_data_serde::chip::core::peripheral::{self, rcc};
|
||||||
|
|
||||||
use crate::regex;
|
use crate::regex;
|
||||||
use crate::registers::Registers;
|
use crate::registers::Registers;
|
||||||
|
|
||||||
/// Deterministically insert into a `HashMap`
|
#[derive(Debug)]
|
||||||
fn insert_into_map<K, V, F>(hash_map: &mut HashMap<K, V>, key: K, value: V, mut compare: F)
|
pub struct ParsedRccs {
|
||||||
where
|
/// RCC version -> parsed info
|
||||||
K: Eq + Hash,
|
rccs: HashMap<String, ParsedRcc>,
|
||||||
F: FnMut(&V, &V) -> Ordering,
|
|
||||||
{
|
|
||||||
match hash_map.entry(key) {
|
|
||||||
Entry::Vacant(e) => {
|
|
||||||
e.insert(value);
|
|
||||||
}
|
|
||||||
Entry::Occupied(mut e) => {
|
|
||||||
if compare(&value, e.get()) == Ordering::Less {
|
|
||||||
e.insert(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PeripheralToClock(
|
struct ParsedRcc {
|
||||||
HashMap<(String, String, String), HashMap<String, stm32_data_serde::chip::core::peripheral::Rcc>>,
|
/// name -> en/rst bit info
|
||||||
);
|
en_rst: HashMap<String, EnRst>,
|
||||||
|
/// name -> mux info
|
||||||
|
mux: HashMap<String, Mux>,
|
||||||
|
}
|
||||||
|
|
||||||
impl PeripheralToClock {
|
#[derive(Debug)]
|
||||||
|
struct EnRst {
|
||||||
|
enable: rcc::Enable,
|
||||||
|
reset: Option<rcc::Reset>,
|
||||||
|
clock: String,
|
||||||
|
stop_mode: StopMode,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParsedRccs {
|
||||||
pub fn parse(registers: &Registers) -> anyhow::Result<Self> {
|
pub fn parse(registers: &Registers) -> anyhow::Result<Self> {
|
||||||
let mut peripheral_to_clock = HashMap::new();
|
let mut rccs = HashMap::new();
|
||||||
|
|
||||||
|
for (rcc_name, ir) in ®isters.registers {
|
||||||
|
if let Some(rcc_name) = rcc_name.strip_prefix("rcc_") {
|
||||||
|
rccs.insert(rcc_name.to_string(), Self::parse_rcc(rcc_name, ir)?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self { rccs })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_rcc(rcc_version: &str, ir: &IR) -> anyhow::Result<ParsedRcc> {
|
||||||
let allowed_variants = HashSet::from([
|
let allowed_variants = HashSet::from([
|
||||||
"DISABLE",
|
"DISABLE",
|
||||||
"SYS",
|
"SYS",
|
||||||
@ -118,8 +125,6 @@ impl PeripheralToClock {
|
|||||||
"HSI256_MSIK1024_MSIK4",
|
"HSI256_MSIK1024_MSIK4",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
for (rcc_name, ir) in ®isters.registers {
|
|
||||||
if let Some(rcc_name) = rcc_name.strip_prefix("rcc_") {
|
|
||||||
let rcc_enum_map: HashMap<&String, HashMap<&String, (&String, &Enum)>> = {
|
let rcc_enum_map: HashMap<&String, HashMap<&String, (&String, &Enum)>> = {
|
||||||
let rcc_blocks = &ir.blocks.get("RCC").unwrap().items;
|
let rcc_blocks = &ir.blocks.get("RCC").unwrap().items;
|
||||||
|
|
||||||
@ -166,7 +171,7 @@ impl PeripheralToClock {
|
|||||||
"rcc: prohibited variant name {} in enum {} for rcc_{}",
|
"rcc: prohibited variant name {} in enum {} for rcc_{}",
|
||||||
v.name.as_str(),
|
v.name.as_str(),
|
||||||
enumm_name,
|
enumm_name,
|
||||||
rcc_name
|
rcc_version
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
} else if !allowed_variants.contains(v.name.as_str()) {
|
} else if !allowed_variants.contains(v.name.as_str()) {
|
||||||
@ -174,7 +179,7 @@ impl PeripheralToClock {
|
|||||||
"rcc: prohibited variant name {} in enum {} for rcc_{}",
|
"rcc: prohibited variant name {} in enum {} for rcc_{}",
|
||||||
v.name.as_str(),
|
v.name.as_str(),
|
||||||
enumm_name,
|
enumm_name,
|
||||||
rcc_name
|
rcc_version
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -182,77 +187,64 @@ impl PeripheralToClock {
|
|||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut family_muxes = HashMap::new();
|
let mux_regexes = &[
|
||||||
|
regex!(r"^DCKCFGR\d?/(.+)SEL$"),
|
||||||
|
regex!(r"^CCIPR\d?/(.+)SEL$"),
|
||||||
|
regex!(r"^D\dCCIP\d?R/(.+)SEL$"),
|
||||||
|
regex!(r"^CFGR\d/(.+)SW$"),
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut mux = HashMap::new();
|
||||||
for (reg, body) in &ir.fieldsets {
|
for (reg, body) in &ir.fieldsets {
|
||||||
let key = format!("fieldset/{reg}");
|
|
||||||
if regex!(r"^fieldset/(CCIPR|DCKCFGR)\d?$").captures(&key).is_some() {
|
|
||||||
for field in &body.fields {
|
for field in &body.fields {
|
||||||
if let Some(peri) = field.name.strip_suffix("SEL") {
|
let key = format!("{}/{}", reg, field.name);
|
||||||
check_mux(reg, &field.name)?;
|
if let Some(capture) = mux_regexes.iter().find_map(|r| r.captures(&key)) {
|
||||||
|
let peri = capture.get(1).unwrap().as_str();
|
||||||
|
|
||||||
insert_into_map(
|
// TODO: these bits are duplicated on F4, we need to split the F4 RCCs more.
|
||||||
&mut family_muxes,
|
if rcc_version.starts_with("f4") && reg == "DCKCFGR2" && (peri == "CLK48" || peri == "SDIO") {
|
||||||
peri.to_string(),
|
|
||||||
Mux {
|
|
||||||
register: reg.to_ascii_lowercase(),
|
|
||||||
field: field.name.to_ascii_lowercase(),
|
|
||||||
},
|
|
||||||
|mux1: &Mux, mux2: &Mux| mux1.register.cmp(&mux2.register),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if regex!(r"^fieldset/CFGR\d?$").captures(&key).is_some() {
|
|
||||||
for field in &body.fields {
|
|
||||||
if let Some(peri) = field.name.strip_suffix("SW") {
|
|
||||||
check_mux(reg, &field.name)?;
|
|
||||||
|
|
||||||
insert_into_map(
|
|
||||||
&mut family_muxes,
|
|
||||||
peri.to_string(),
|
|
||||||
Mux {
|
|
||||||
register: reg.to_ascii_lowercase(),
|
|
||||||
field: field.name.to_ascii_lowercase(),
|
|
||||||
},
|
|
||||||
|mux1: &Mux, mux2: &Mux| mux1.register.cmp(&mux2.register),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if regex!(r"^fieldset/D\d?CCIPR$").captures(&key).is_some() {
|
|
||||||
for field in &body.fields {
|
|
||||||
if let Some(peri) = field.name.strip_suffix("SEL") {
|
|
||||||
if family_muxes.get(peri).is_some() && reg != "D1CCIPR" {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
check_mux(reg, &field.name)?;
|
check_mux(reg, &field.name)?;
|
||||||
|
|
||||||
insert_into_map(
|
let val = Mux {
|
||||||
&mut family_muxes,
|
|
||||||
peri.to_string(),
|
|
||||||
Mux {
|
|
||||||
register: reg.to_ascii_lowercase(),
|
register: reg.to_ascii_lowercase(),
|
||||||
field: field.name.to_ascii_lowercase(),
|
field: field.name.to_ascii_lowercase(),
|
||||||
},
|
};
|
||||||
|mux1: &Mux, mux2: &Mux| mux1.register.cmp(&mux2.register),
|
|
||||||
);
|
if mux.insert(peri.to_string(), val).is_some() {
|
||||||
|
bail!("rcc: duplicate mux for {} for rcc_{}", peri, rcc_version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut family_clocks = HashMap::new();
|
// Parse xxEN/xxRST bits.
|
||||||
|
let mut en_rst = HashMap::new();
|
||||||
for (reg, body) in &ir.fieldsets {
|
for (reg, body) in &ir.fieldsets {
|
||||||
let key = format!("fieldset/{reg}");
|
if let Some(m) = regex!(r"^((A[PH]B\d?)|GPIO)[LH]?ENR\d?$").captures(reg) {
|
||||||
if let Some(m) = regex!(r"^fieldset/((A[PH]B\d?)|GPIO)[LH]?ENR\d?$").captures(&key) {
|
|
||||||
let clock = m.get(1).unwrap().as_str();
|
let clock = m.get(1).unwrap().as_str();
|
||||||
let clock = match clock {
|
let clock = match clock {
|
||||||
"AHB" => "AHB1",
|
"AHB" => "AHB1",
|
||||||
"APB" => "APB1",
|
"APB" => "APB1",
|
||||||
clock => clock,
|
clock => clock,
|
||||||
};
|
};
|
||||||
|
|
||||||
for field in &body.fields {
|
for field in &body.fields {
|
||||||
if let Some(peri) = field.name.strip_suffix("EN") {
|
if let Some(peri) = field.name.strip_suffix("EN") {
|
||||||
let peri = if peri == "RTCAPB" { "RTC" } else { peri };
|
let peri = if peri == "RTCAPB" { "RTC" } else { peri };
|
||||||
|
|
||||||
|
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 {
|
||||||
|
register: reg.replace("ENR", "RSTR").to_ascii_lowercase(),
|
||||||
|
field: format!("{peri}RST").to_ascii_lowercase(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let stop_mode = if peri == "RTC" {
|
let stop_mode = if peri == "RTC" {
|
||||||
StopMode::Standby
|
StopMode::Standby
|
||||||
} else if peri.starts_with("LP") {
|
} else if peri.starts_with("LP") {
|
||||||
@ -262,68 +254,44 @@ impl PeripheralToClock {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Timers are a bit special, they may have a x2 freq
|
// Timers are a bit special, they may have a x2 freq
|
||||||
let peri_clock = {
|
let peri_clock = if regex!(r"^TIM\d+$").is_match(peri) {
|
||||||
if regex!(r"^TIM\d+$").is_match(peri) {
|
|
||||||
format!("{clock}_TIM")
|
format!("{clock}_TIM")
|
||||||
} else {
|
} else {
|
||||||
clock.to_string()
|
clock.to_string()
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut reset = None;
|
let peri_clock = peri_clock
|
||||||
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 {
|
|
||||||
register: reg.replace("ENR", "RSTR").to_ascii_lowercase(),
|
|
||||||
field: format!("{peri}RST").to_ascii_lowercase(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mux = family_muxes.get(peri).cloned();
|
|
||||||
|
|
||||||
match family_clocks.entry(peri.to_string()) {
|
|
||||||
Entry::Vacant(e) => {
|
|
||||||
e.insert(peripheral::Rcc {
|
|
||||||
clock: peri_clock
|
|
||||||
.to_ascii_lowercase()
|
.to_ascii_lowercase()
|
||||||
.replace("ahb", "hclk")
|
.replace("ahb", "hclk")
|
||||||
.replace("apb", "pclk"),
|
.replace("apb", "pclk");
|
||||||
|
|
||||||
|
let val = EnRst {
|
||||||
enable: peripheral::rcc::Enable {
|
enable: peripheral::rcc::Enable {
|
||||||
register: reg.to_ascii_lowercase(),
|
register: reg.to_ascii_lowercase(),
|
||||||
field: field.name.to_ascii_lowercase(),
|
field: field.name.to_ascii_lowercase(),
|
||||||
},
|
},
|
||||||
stop_mode,
|
|
||||||
reset,
|
reset,
|
||||||
mux,
|
clock: peri_clock,
|
||||||
});
|
stop_mode,
|
||||||
}
|
|
||||||
Entry::Occupied(_) => {
|
|
||||||
return Err(anyhow!("rcc: duplicate clock for {} for rcc_{}", peri, rcc_name));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if en_rst.insert(peri.to_string(), val).is_some() {
|
||||||
|
bail!("rcc: duplicate en/rst for {} for rcc_{}", peri, rcc_version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
peripheral_to_clock.insert(
|
|
||||||
("rcc".to_string(), rcc_name.to_string(), "RCC".to_string()),
|
|
||||||
family_clocks,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self(peripheral_to_clock))
|
Ok(ParsedRcc { en_rst, mux })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn match_peri_clock(
|
pub fn match_peri_clock(
|
||||||
&self,
|
&self,
|
||||||
rcc_block: &(String, String, String),
|
rcc_version: &str,
|
||||||
peri_name: &str,
|
peri_name: &str,
|
||||||
) -> Option<&stm32_data_serde::chip::core::peripheral::Rcc> {
|
) -> Option<stm32_data_serde::chip::core::peripheral::Rcc> {
|
||||||
const PERI_OVERRIDE: &[(&str, &[&str])] = &[
|
const FALLBACKS: &[(&str, &[&str])] = &[
|
||||||
("DCMI", &["DCMI_PSSI"]),
|
("DCMI", &["DCMI_PSSI"]),
|
||||||
("PSSI", &["DCMI_PSSI"]),
|
("PSSI", &["DCMI_PSSI"]),
|
||||||
("FDCAN1", &["FDCAN12", "FDCAN"]),
|
("FDCAN1", &["FDCAN12", "FDCAN"]),
|
||||||
@ -339,27 +307,63 @@ impl PeripheralToClock {
|
|||||||
("DAC1", &["DAC12", "DAC"]),
|
("DAC1", &["DAC12", "DAC"]),
|
||||||
("DAC2", &["DAC12", "DAC"]),
|
("DAC2", &["DAC12", "DAC"]),
|
||||||
("ETH", &["ETHMAC", "ETH1MAC"]),
|
("ETH", &["ETHMAC", "ETH1MAC"]),
|
||||||
|
("SPI1", &["SPI12", "SPI123"]),
|
||||||
|
("SPI2", &["SPI12", "SPI123"]),
|
||||||
|
("SPI3", &["SPI123"]),
|
||||||
|
("SPI4", &["SPI145"]),
|
||||||
|
("SPI5", &["SPI145"]),
|
||||||
|
("SAI1", &["SAI12"]),
|
||||||
|
("SAI2", &["SAI12"]),
|
||||||
|
("USART2", &["USART234578"]),
|
||||||
|
("USART3", &["USART234578"]),
|
||||||
|
("UART4", &["USART234578"]),
|
||||||
|
("UART5", &["USART234578"]),
|
||||||
|
("UART7", &["USART234578"]),
|
||||||
|
("UART8", &["USART234578"]),
|
||||||
|
("USART1", &["USART16910"]),
|
||||||
|
("USART6", &["USART16910"]),
|
||||||
|
("USART10", &["USART16910"]),
|
||||||
|
("UART9", &["USART16910"]),
|
||||||
|
("I2C1", &["I2C1235"]),
|
||||||
|
("I2C2", &["I2C1235"]),
|
||||||
|
("I2C3", &["I2C1235"]),
|
||||||
|
("I2C5", &["I2C1235"]),
|
||||||
];
|
];
|
||||||
|
|
||||||
let clocks = self.0.get(rcc_block)?;
|
let rcc = self.rccs.get(rcc_version)?;
|
||||||
if let Some(res) = clocks.get(peri_name) {
|
|
||||||
|
let en_rst = get_with_fallback(peri_name, &rcc.en_rst, FALLBACKS)?;
|
||||||
|
let mux = get_with_fallback(peri_name, &rcc.mux, FALLBACKS);
|
||||||
|
|
||||||
|
Some(peripheral::Rcc {
|
||||||
|
clock: en_rst.clock.clone(),
|
||||||
|
enable: en_rst.enable.clone(),
|
||||||
|
reset: en_rst.reset.clone(),
|
||||||
|
stop_mode: en_rst.stop_mode.clone(),
|
||||||
|
|
||||||
|
mux: mux.cloned(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_with_fallback<'a, T>(key: &str, map: &'a HashMap<String, T>, fallbacks: &[(&str, &[&str])]) -> Option<&'a T> {
|
||||||
|
if let Some(res) = map.get(key) {
|
||||||
return Some(res);
|
return Some(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((_, rename)) = PERI_OVERRIDE.iter().find(|(n, _)| *n == peri_name) {
|
if let Some((_, rename)) = fallbacks.iter().find(|(n, _)| *n == key) {
|
||||||
for &n in *rename {
|
for &n in *rename {
|
||||||
if let Some(res) = clocks.get(n) {
|
if let Some(res) = map.get(n) {
|
||||||
return Some(res);
|
return Some(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(n) = peri_name.strip_suffix('1') {
|
if let Some(n) = key.strip_suffix('1') {
|
||||||
if let Some(res) = clocks.get(n) {
|
if let Some(res) = map.get(n) {
|
||||||
return Some(res);
|
return Some(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user