Skip to content

Commit 010d337

Browse files
committed
[stm32] Use register map query for RCC module
1 parent 2a93250 commit 010d337

File tree

3 files changed

+318
-828
lines changed

3 files changed

+318
-828
lines changed

src/modm/platform/clock/stm32/module.lb

+104-83
Original file line numberDiff line numberDiff line change
@@ -22,131 +22,152 @@ def prepare(module, options):
2222
if not options[":target"].has_driver("rcc:stm32*"):
2323
return False
2424

25-
module.depends(":cmsis:device", ":utils", ":platform:clock", ":architecture:delay")
26-
# FIXME: Move Peripherals enum somewhere better
27-
module.depends(":platform:gpio")
25+
module.depends(":cmsis:device", ":utils", ":platform:clock",
26+
":architecture:delay", ":platform:gpio", ":cmsis:ll:rcc")
2827
return True
2928

3029
def build(env):
3130
device = env[":target"]
3231
driver = device.get_driver("rcc")
3332
regs = env.query(":cmsis:device:registers")
3433

35-
properties = {}
36-
properties["target"] = target = device.identifier
37-
properties["partname"] = device.partname
38-
properties["core"] = core = device.get_driver("core")["type"]
39-
40-
if target["family"] in ["c0"]:
41-
properties["hsi_frequency"] = 48_000_000
42-
properties["lsi_frequency"] = 32_000
43-
properties["boot_frequency"] = 12_000_000
44-
elif target["family"] in ["f0", "f1", "f3"]:
45-
properties["hsi_frequency"] = 8_000_000
46-
properties["lsi_frequency"] = 40_000
47-
properties["boot_frequency"] = properties["hsi_frequency"]
48-
elif target["family"] in ["h7"]:
49-
properties["hsi_frequency"] = 64_000_000
50-
properties["lsi_frequency"] = 32_000
51-
properties["boot_frequency"] = properties["hsi_frequency"]
52-
elif target["family"] in ["l0", "l1"]:
53-
properties["hsi_frequency"] = 16_000_000
54-
properties["lsi_frequency"] = 37_000
55-
properties["msi_frequency"] = 2_097_000
56-
properties["boot_frequency"] = properties["msi_frequency"]
57-
elif target["family"] in ["l5"]:
58-
properties["hsi_frequency"] = 16_000_000
59-
properties["lsi_frequency"] = 32_000
60-
properties["msi_frequency"] = 4_000_000
61-
properties["boot_frequency"] = properties["msi_frequency"]
62-
else:
63-
properties["hsi_frequency"] = 16_000_000
64-
properties["lsi_frequency"] = 32_000
65-
properties["boot_frequency"] = properties["hsi_frequency"]
34+
p = {"regs": regs}
35+
p["target"] = target = device.identifier
36+
p["partname"] = device.partname
37+
p["core"] = core = device.get_driver("core")["type"]
38+
39+
# These definitions must exist on all devices
40+
p["boot_frequency"] = "HSI_VALUE"
41+
if target.family in ["c0"]:
42+
p["boot_frequency"] = "12'000'000"
43+
elif target.family in ["l0", "l1"]:
44+
p["boot_frequency"] = "2'097'000"
45+
elif target.family in ["l5"]:
46+
p["boot_frequency"] = "4'000'000"
47+
48+
# We're using two regex here, since some headers have both PLLSOURCE *and* PLL1SOURCE
49+
p["pll_source"] = regs.findall(r"(LL_RCC_PLLSOURCE_(.+?))") or regs.findall(r"(LL_RCC_PLL1SOURCE_(.+?))")
50+
assert p["pll_source"], "Cannot find PllSource enums"
51+
52+
p["sys_source"] = regs.findall(r"(LL_RCC_SYS_CLKSOURCE_(.{1,9}))")
53+
assert p["sys_source"], "Cannot find SystemClockSource enums"
54+
p["cfgr_sws_pos"] = regs.search("RCC_.*?_SWS_Pos")
55+
56+
p["rtc_source"] = regs.findall(r"(LL_RCC_RTC_CLKSOURCE_(.+?))")
57+
assert p["rtc_source"], "Cannot find RealTimeClockSource enums"
58+
59+
p["ahb_prescaler"] = regs.findall(r"(LL_RCC_SYSCLK_DIV_(\d+?))")
60+
assert p["ahb_prescaler"], "Cannot find AhbPrescaler enums"
61+
62+
apb_prescaler = defaultdict(list)
63+
for reg, bus, div in regs.findall(r"(LL_RCC_APB(\d)?_DIV_(\d+?))"):
64+
apb_prescaler[bus].append((reg, div))
65+
assert apb_prescaler, "Cannot find any ApbPrescaler enums"
66+
p["apb_prescaler"] = apb_prescaler
67+
68+
mco_source = defaultdict(lambda: ([], []))
69+
for reg, mco, name in regs.findall(r"(LL_RCC_MCO(\d?)SOURCE_(.+?))"):
70+
mco_source[mco][0].append((reg, name))
71+
for reg, mco, div in regs.findall(r"(LL_RCC_MCO(\d?)_DIV_(\d+?))"):
72+
mco_source[mco][1].append((reg, div))
73+
assert mco_source, "Cannot find any ClockOutputSource enums"
74+
p["mco_source"] = mco_source
75+
76+
# These may not exist on all devices
77+
p["can_source"] = regs.findall(r"(LL_RCC_FDCAN_CLKSOURCE_(.+?))")
78+
p["hsi_div"] = regs.findall(r"(LL_RCC_HSI_DIV_?(\d+))")
79+
p["pll_mul"] = regs.findall(r"(LL_RCC_PLL_MUL_(\d+_?\d?))")
80+
p["pll_input_range"] = regs.findall(r"(LL_RCC_PLLINPUTRANGE_(\d+_\d+))")
81+
p["usbprescaler"] = regs.search(r"RCC_CFGR_USBPRE")
82+
83+
# There is sadly no easy way to find the MSI range values, so we have to hardcode them
84+
msi_range = regs.findall(r"(LL_RCC_MSIK?RANGE_)\d+")
85+
p["msi_clocks"] = ["K", "S"] if "K" in msi_range[0] else ([""] if msi_range else [])
86+
if len(msi_range) == 7:
87+
msi_range = (msi_range[0], ("kHz65_536", "kHz131_072", "kHz262_144", "kHz524_288", "MHz1_048", "MHz2_097", "MHz4_194"))
88+
elif len(msi_range) == 12:
89+
msi_range = (msi_range[0], ("kHz100", "kHz200", "kHz400", "kHz800", "MHz1", "MHz2",
90+
"MHz4", "MHz8", "MHz16", "MHz24", "MHz32", "MHz48"))
91+
elif len(msi_range) == 16:
92+
msi_range = (msi_range[0], ("MHz48", "MHz24", "MHz16", "MHz12", "MHz4", "MHz2", "MHz1_5", "MHz1", "MHz3_072",
93+
"MHz1_536", "MHz1_024", "kHz768", "kHz400", "kHz200", "kHz133", "kHz100"))
94+
p["msi_range"] = msi_range
95+
96+
97+
p["hsi48"] = regs.search(r"RCC_.*?_HSI48ON")
98+
p["hsi14"] = regs.search(r"RCC_.*?_HSI14ON")
99+
p["bdcr"] = regs.search(r"RCC_(.*?)_RTCSEL_\d")
100+
66101

67102
# TODO: Move this data into the device files
68-
properties["usbprescaler"] = device.has_driver("usb") and target.family in ["f0", "f1", "f3"]
69-
properties["pllprediv"] = \
70-
(target["family"] in ["f0", "f3"] or (target["family"] == "f1" and target["name"] in ["00", "05", "07"]))
71-
properties["pllprediv2"] = False # FIXME: not sure what value this should have
72-
properties["pll_hse_prediv2"] = target["family"] == "f1" and target["name"] in ["01", "02", "03"]
73-
properties["hsi48"] = \
74-
(target["family"] in ["g4", "h5", "h7", "l5", "u0", "u5"]) or \
75-
(target["family"] == "f0" and target["name"] in ["42", "48", "71", "72", "78", "91", "98"]) or \
76-
(target["family"] == "g0" and target["name"] in ["b1", "c1"]) or \
77-
(target["family"] == "l0" and target["name"][1] == "2") or \
78-
(target["family"] == "l4" and target["name"][0] not in ["7", "8"])
79-
if target["family"] in ["g4", "l0", "l4", "l5", "u0"]:
80-
properties["hsi48_cr"] = "CRRCR"
81-
elif target["family"] in ["g0", "h5", "h7", "u5"]:
82-
properties["hsi48_cr"] = "CR"
83-
elif target["family"] in ["f0"]:
84-
properties["hsi48_cr"] = "CR2"
85-
properties["pll_p"] = ((target["family"] == "l4" and target["name"] not in ["12", "22"]) or target["family"] == "g4")
86-
properties["overdrive"] = (target["family"] == "f7") or \
87-
((target["family"] == "f4") and target["name"] in ["27", "29", "37", "39", "46", "69", "79"])
88-
properties["vos0_overdrive"] = (target["family"] == "h7") and \
89-
target["name"] in ["42", "43", "45", "47", "50", "53", "55", "57"]
90-
properties["has_r1mode"] = (target["family"] == "g4") or \
91-
(target["family"] == "l4" and target["name"][0] in ["p", "q", "r", "s"])
92-
properties["pllsai_p_usb"] = (target["family"] == "f7") or \
93-
((target["family"] == "f4") and target["name"] in ["46", "69", "79"])
103+
p["pllprediv"] = \
104+
(target.family in ["f0", "f3"] or (target.family == "f1" and target.name in ["00", "05", "07"]))
105+
p["pllprediv2"] = False # FIXME: not sure what value this should have
106+
p["pll_hse_prediv2"] = target.family == "f1" and target.name in ["01", "02", "03"]
107+
p["pll_p"] = ((target.family == "l4" and target.name not in ["12", "22"]) or target.family == "g4")
108+
p["overdrive"] = (target.family == "f7") or \
109+
((target.family == "f4") and target.name in ["27", "29", "37", "39", "46", "69", "79"])
110+
p["vos0_overdrive"] = (target.family == "h7") and \
111+
target.name in ["42", "43", "45", "47", "50", "53", "55", "57"]
112+
p["has_r1mode"] = (target.family == "g4") or \
113+
(target.family == "l4" and target.name[0] in ["p", "q", "r", "s"])
114+
p["pllsai_p_usb"] = (target.family == "f7") or \
115+
((target.family == "f4") and target.name in ["46", "69", "79"])
94116

95117
if target.family in ["h7"]:
96118
if target.name in ["a3", "b0", "b3"]:
97-
properties["cfgr_prescaler"] = "CDCFGR1"
119+
p["cfgr_prescaler"] = "CDCFGR1"
98120
else:
99-
properties["cfgr_prescaler"] = "D1CFGR"
121+
p["cfgr_prescaler"] = "D1CFGR"
100122
elif target.family in ["u5"]:
101-
properties["cfgr_prescaler"] = "CFGR2"
123+
p["cfgr_prescaler"] = "CFGR2"
102124
else:
103-
properties["cfgr_prescaler"] = "CFGR"
125+
p["cfgr_prescaler"] = "CFGR"
104126

105127
if target.family in ["h7"]:
106128
if target.name in ["a3", "b0", "b3"]:
107-
properties["cfgr2"] = "CDCFGR2"
129+
p["cfgr2"] = "CDCFGR2"
108130
else:
109-
properties["cfgr2"] = "D2CFGR"
131+
p["cfgr2"] = "D2CFGR"
110132
elif target.family in ["u5"]:
111-
properties["cfgr2"] = "CFGR2"
133+
p["cfgr2"] = "CFGR2"
112134
else:
113-
properties["cfgr2"] = "CFGR"
135+
p["cfgr2"] = "CFGR"
114136

115137
if target.family in ["h7"]:
116138
if target.name in ["a3", "b0", "b3"]:
117-
properties["ccipr1"] = "CDCCIP1R"
139+
p["ccipr1"] = "CDCCIP1R"
118140
else:
119-
properties["ccipr1"] = "D2CCIP1R"
141+
p["ccipr1"] = "D2CCIP1R"
120142
elif target.family in ["l5", "u5"]:
121-
properties["ccipr1"] = "CCIPR1"
143+
p["ccipr1"] = "CCIPR1"
122144
else:
123-
properties["ccipr1"] = "CCIPR"
145+
p["ccipr1"] = "CCIPR"
124146

125-
properties["d1"] = ("CD" if target.name in ["a3", "b0", "b3"] else "D1") \
147+
p["d1"] = ("CD" if target.name in ["a3", "b0", "b3"] else "D1") \
126148
if target.family == "h7" else ""
127-
properties["d2"] = ("CD" if target.name in ["a3", "b0", "b3"] else "D2") \
149+
p["d2"] = ("CD" if target.name in ["a3", "b0", "b3"] else "D2") \
128150
if target.family == "h7" else ""
129-
properties["cfgr3"] = ("SRDCFGR" if target.name in ["a0", "a3", "b0", "b3"] else "D3CFGR")
130-
properties["d3"] = ("SRD" if target.name in ["a0", "a3", "b0", "b3"] else "D3")
131-
properties["bdcr"] = "CSR1" if target.family in ["c0"] else "CSR" if target.family in ["l0", "l1"] else "BDCR"
132-
properties["pll_ids"] = ["1", "2", "3"] if target.family in ["h7", "u5"] else [] if target.family in ["c0"] else [""]
133-
properties["has_smps"] = target["family"] == "h7" and (target["name"] in ["25", "35", "45", "47", "55", "57"] or \
134-
(target["name"] in ["30", "a3", "b0", "b3"] and target["variant"] == "q"))
151+
p["cfgr3"] = ("SRDCFGR" if target.name in ["a0", "a3", "b0", "b3"] else "D3CFGR")
152+
p["d3"] = ("SRD" if target.name in ["a0", "a3", "b0", "b3"] else "D3")
153+
p["pll_ids"] = ["1", "2", "3"] if target.family in ["h7", "u5"] else [] if target.family in ["c0"] else [""]
154+
p["has_smps"] = target.family == "h7" and (target.name in ["25", "35", "45", "47", "55", "57"] or \
155+
(target.name in ["30", "a3", "b0", "b3"] and target["variant"] == "q"))
135156

136157
flash_latencies = {}
137158
for vcore in device.get_driver("flash")["latency"]:
138159
flash_latencies[int(vcore["vcore-min"])] = sorted([int(f["hclk-max"]) for f in vcore["wait-state"]])
139160

140-
properties["table"] = flash_latencies
141-
env.substitutions = properties
161+
p["table"] = flash_latencies
162+
env.substitutions = p
142163
env.outbasepath = "modm/src/modm/platform/clock"
143164

144165
env.template("rcc.cpp.in")
145166
env.template("rcc.hpp.in")
146167

147168
all_peripherals = env.query(":cmsis:device:peripherals")
148169
rcc_map = defaultdict(dict)
149-
for (reg, per, typ) in regs.findall(r"RCC_([A-Z0-9]*?)_([A-Z0-9]+?)(EN|RST)"):
170+
for (reg, per, typ) in regs.findall(r"RCC_(A[HP]B\d?(?:ENR|RSTR)\d?)_(.*?)(EN|RST)"):
150171
rcc_map[per][typ] = reg
151172
rcc_enable = {}
152173
rcc_reset = {}

src/modm/platform/clock/stm32/rcc.cpp.in

+3-82
Original file line numberDiff line numberDiff line change
@@ -27,83 +27,6 @@ constinit uint16_t modm_fastdata delay_fcpu_MHz(computeDelayMhz(Rcc::BootFrequen
2727
constinit uint16_t modm_fastdata delay_ns_per_loop(computeDelayNsPerLoop(Rcc::BootFrequency));
2828

2929
// ----------------------------------------------------------------------------
30-
%% if target.family == "f0"
31-
bool
32-
Rcc::enableInternalClockMHz14(uint32_t waitCycles)
33-
{
34-
bool retval;
35-
RCC->CR2 |= RCC_CR2_HSI14ON;
36-
while (not (retval = (RCC->CR2 & RCC_CR2_HSI14RDY)) and --waitCycles)
37-
;
38-
return retval;
39-
}
40-
%% endif
41-
42-
%% if hsi48
43-
bool
44-
Rcc::enableInternalClockMHz48(uint32_t waitCycles)
45-
{
46-
bool retval;
47-
RCC->{{hsi48_cr}} |= RCC_{{hsi48_cr}}_HSI48ON;
48-
while (not (retval = (RCC->{{hsi48_cr}} & RCC_{{hsi48_cr}}_HSI48RDY)) and --waitCycles)
49-
;
50-
return retval;
51-
}
52-
%% endif
53-
54-
bool
55-
Rcc::enableInternalClock(uint32_t waitCycles)
56-
{
57-
bool retval;
58-
RCC->CR |= RCC_CR_HSION;
59-
while (not (retval = (RCC->CR & RCC_CR_HSIRDY)) and --waitCycles)
60-
;
61-
return retval;
62-
}
63-
64-
%% if target.family in ["l0", "l1", "l4", "l5"]
65-
bool
66-
Rcc::enableMultiSpeedInternalClock(MsiFrequency msi_frequency, uint32_t waitCycles)
67-
{
68-
bool retval;
69-
%% if target.family in ["l0", "l1"]
70-
RCC->ICSCR = (RCC->ICSCR & ~RCC_ICSCR_MSIRANGE) | static_cast<uint32_t>(msi_frequency);
71-
RCC->CR |= RCC_CR_MSION;
72-
while (not (retval = (RCC->CR & RCC_CR_MSIRDY)) and --waitCycles)
73-
%% else
74-
RCC->CR = (RCC->CR & ~RCC_CR_MSIRANGE) | static_cast<uint32_t>(msi_frequency) | RCC_CR_MSIRGSEL | RCC_CR_MSION;
75-
while (not (retval = (RCC->CR & RCC_CR_MSIRDY)) and --waitCycles)
76-
%% endif
77-
;
78-
return retval;
79-
}
80-
%% endif
81-
82-
%% if target.family in ["u5"]
83-
// MSIxRANGE can be modified when MSIx is OFF (MSISON = 0) or when MSIx is
84-
// ready (MSIxRDY = 1). MSIxRANGE must NOT be modified when MSIx is ON
85-
// and NOT ready (MSIxON = 1 and MSIxRDY = 0)
86-
%% for msi in ["S", "K"]
87-
bool
88-
Rcc::enableMultiSpeedInternalClock{{msi}}(MsiFrequency msi_frequency, uint32_t waitCycles)
89-
{
90-
bool retval;
91-
uint32_t waitCycles_ = waitCycles;
92-
while ((not (retval = (((RCC->CR & RCC_CR_MSI{{msi}}ON) == 0) || ((RCC->CR & RCC_CR_MSI{{msi}}RDY) == RCC_CR_MSI{{msi}}RDY)))) || --waitCycles_)
93-
;
94-
if (!retval)
95-
return false;
96-
RCC->ICSCR1 = (RCC->ICSCR1 & ~RCC_ICSCR1_MSI{{msi}}RANGE_Msk) | RCC_ICSCR1_MSIRGSEL | (static_cast<uint32_t>(msi_frequency) << RCC_ICSCR1_MSI{{msi}}RANGE_Pos);
97-
RCC->CR |= RCC_CR_MSI{{msi}}ON;
98-
waitCycles_ = waitCycles;
99-
while (not (retval = (RCC->CR & RCC_CR_MSI{{msi}}RDY)) and --waitCycles)
100-
;
101-
return retval;
102-
}
103-
104-
%% endfor
105-
%% endif
106-
10730
bool
10831
Rcc::enableExternalClock(uint32_t waitCycles)
10932
{
@@ -576,15 +499,13 @@ Rcc::setHsiPredivider4Enabled(bool divideBy4, uint32_t waitCycles)
576499
}
577500
%% endif
578501

579-
%% set sysclksrcf_cfgr="CFGR1" if target.family in ["u5"] else "CFGR"
580502
bool
581503
Rcc::enableSystemClock(SystemClockSource src, uint32_t waitCycles)
582504
{
583-
RCC->{{sysclksrcf_cfgr}} = (RCC->{{sysclksrcf_cfgr}} & ~RCC_{{sysclksrcf_cfgr}}_SW) | uint32_t(src);
505+
LL_RCC_SetSysClkSource(uint32_t(src));
584506

585-
// Wait till the main PLL is used as system clock source
586-
src = SystemClockSource(uint32_t(src) << RCC_{{sysclksrcf_cfgr}}_SWS_Pos);
587-
while ((RCC->{{sysclksrcf_cfgr}} & RCC_{{sysclksrcf_cfgr}}_SWS) != uint32_t(src))
507+
const uint32_t sws = uint32_t(src) << {{cfgr_sws_pos}};
508+
while (LL_RCC_GetSysClkSource() != uint32_t(src))
588509
if (not --waitCycles) return false;
589510

590511
return true;

0 commit comments

Comments
 (0)