Skip to content

Commit d646fa7

Browse files
committed
[stm32] Use register map query for RCC module
1 parent a1dc260 commit d646fa7

File tree

3 files changed

+340
-946
lines changed

3 files changed

+340
-946
lines changed

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

Lines changed: 100 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -22,131 +22,129 @@ 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"]
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["pll_mul"] = regs.findall(r"(LL_RCC_PLL_MUL_(\d+_?\d?))")
79+
p["pll_input_range"] = regs.findall(r"(LL_RCC_PLLINPUTRANGE_(\d+_\d+))")
80+
p["usbprescaler"] = regs.search(r"RCC_CFGR_USBPRE")
81+
p["lse_drive"] = regs.findall(r"(LL_RCC_LSEDRIVE_(.+?))")
82+
p["hsi48"] = regs.search(r"RCC_.*?_HSI48ON")
83+
p["hsi14"] = regs.search(r"RCC_.*?_HSI14ON")
84+
85+
p["hsi_div"] = regs.findall(r"(LL_RCC_HSI_DIV_?(\d+))")
86+
p["hsi_div4"] = regs.search(r"RCC_.*?_HSIDIV")
87+
88+
# There is sadly no easy way to find the MSI range values, so we have to hardcode them
89+
msi_range = regs.findall(r"(LL_RCC_MSIK?RANGE_)\d+")
90+
p["msi_clocks"] = (["K", "S"] if "K" in msi_range[0] else [""]) if msi_range else []
91+
92+
if len(msi_range) == 7:
93+
msi_range = (msi_range[0], ("kHz65_536", "kHz131_072", "kHz262_144", "kHz524_288", "MHz1_048", "MHz2_097", "MHz4_194"))
94+
elif len(msi_range) == 12:
95+
msi_range = (msi_range[0], ("kHz100", "kHz200", "kHz400", "kHz800", "MHz1", "MHz2",
96+
"MHz4", "MHz8", "MHz16", "MHz24", "MHz32", "MHz48"))
97+
elif len(msi_range) == 16:
98+
msi_range = (msi_range[0], ("MHz48", "MHz24", "MHz16", "MHz12", "MHz4", "MHz2", "MHz1_5", "MHz1", "MHz3_072",
99+
"MHz1_536", "MHz1_024", "kHz768", "kHz400", "kHz200", "kHz133", "kHz100"))
100+
p["msi_range"] = msi_range or ("", [])
101+
p["msi_range_selection"] = regs.search(r"RCC_.+?_MSIRGSEL")
102+
103+
if regs.search(r"RCC_.+?_(?:CL?K48M?SEL|ICLKSEL)"):
104+
p["clk48_source"] = regs.findall(r"(LL_RCC_(?:USB|CL?K48)_CLKSOURCE_(.+?))")
62105
else:
63-
properties["hsi_frequency"] = 16_000_000
64-
properties["lsi_frequency"] = 32_000
65-
properties["boot_frequency"] = properties["hsi_frequency"]
106+
p["clk48_source"] = []
107+
print(p["clk48_source"])
66108

67109
# 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"])
94-
95-
if target.family in ["h7"]:
96-
if target.name in ["a3", "b0", "b3"]:
97-
properties["cfgr_prescaler"] = "CDCFGR1"
98-
else:
99-
properties["cfgr_prescaler"] = "D1CFGR"
100-
elif target.family in ["u5"]:
101-
properties["cfgr_prescaler"] = "CFGR2"
102-
else:
103-
properties["cfgr_prescaler"] = "CFGR"
104-
105-
if target.family in ["h7"]:
106-
if target.name in ["a3", "b0", "b3"]:
107-
properties["cfgr2"] = "CDCFGR2"
108-
else:
109-
properties["cfgr2"] = "D2CFGR"
110-
elif target.family in ["u5"]:
111-
properties["cfgr2"] = "CFGR2"
112-
else:
113-
properties["cfgr2"] = "CFGR"
114-
115-
if target.family in ["h7"]:
116-
if target.name in ["a3", "b0", "b3"]:
117-
properties["ccipr1"] = "CDCCIP1R"
118-
else:
119-
properties["ccipr1"] = "D2CCIP1R"
120-
elif target.family in ["l5", "u5"]:
121-
properties["ccipr1"] = "CCIPR1"
122-
else:
123-
properties["ccipr1"] = "CCIPR"
124-
125-
properties["d1"] = ("CD" if target.name in ["a3", "b0", "b3"] else "D1") \
110+
p["pllprediv"] = \
111+
(target.family in ["f0", "f3"] or (target.family == "f1" and target.name in ["00", "05", "07"]))
112+
p["pllprediv2"] = False # FIXME: not sure what value this should have
113+
p["pll_hse_prediv2"] = target.family == "f1" and target.name in ["01", "02", "03"]
114+
p["pll_p"] = ((target.family == "l4" and target.name not in ["12", "22"]) or target.family == "g4")
115+
p["overdrive"] = (target.family == "f7") or \
116+
((target.family == "f4") and target.name in ["27", "29", "37", "39", "46", "69", "79"])
117+
p["vos0_overdrive"] = (target.family == "h7") and \
118+
target.name in ["42", "43", "45", "47", "50", "53", "55", "57"]
119+
p["has_r1mode"] = (target.family == "g4") or \
120+
(target.family == "l4" and target.name[0] in ["p", "q", "r", "s"])
121+
p["pllsai_p_usb"] = (target.family == "f7") or \
122+
((target.family == "f4") and target.name in ["46", "69", "79"])
123+
124+
p["d2"] = ("CD" if target.name in ["a3", "b0", "b3"] else "D2") \
126125
if target.family == "h7" else ""
127-
properties["d2"] = ("CD" if target.name in ["a3", "b0", "b3"] else "D2") \
128-
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"))
126+
p["d3"] = ("SRD" if target.name in ["a0", "a3", "b0", "b3"] else "D3")
127+
p["pll_ids"] = ["1", "2", "3"] if target.family in ["h7", "u5"] else [] if target.family in ["c0"] else [""]
128+
p["has_smps"] = target.family == "h7" and (target.name in ["25", "35", "45", "47", "55", "57"] or \
129+
(target.name in ["30", "a3", "b0", "b3"] and target["variant"] == "q"))
130+
131+
132+
135133

136134
flash_latencies = {}
137135
for vcore in device.get_driver("flash")["latency"]:
138136
flash_latencies[int(vcore["vcore-min"])] = sorted([int(f["hclk-max"]) for f in vcore["wait-state"]])
139137

140-
properties["table"] = flash_latencies
141-
env.substitutions = properties
138+
p["table"] = flash_latencies
139+
env.substitutions = p
142140
env.outbasepath = "modm/src/modm/platform/clock"
143141

144142
env.template("rcc.cpp.in")
145143
env.template("rcc.hpp.in")
146144

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

0 commit comments

Comments
 (0)