@@ -22,131 +22,109 @@ def prepare(module, options):
22
22
if not options [":target" ].has_driver ("rcc:stm32*" ):
23
23
return False
24
24
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" )
28
27
return True
29
28
30
29
def build (env ):
31
30
device = env [":target" ]
32
- driver = device .get_driver ( "rcc" )
31
+ target = device .identifier
33
32
regs = env .query (":cmsis:device:registers" )
34
33
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
+ # These definitions must exist on all devices
35
+ boot_frequency = "HSI_VALUE"
36
+ if target .family in ["c0" ]:
37
+ boot_frequency = "12'000'000"
38
+ elif target .family in ["l0" , "l1" ]:
39
+ boot_frequency = "2'097'000"
40
+ elif target .family in ["l5" ]:
41
+ boot_frequency = "4'000'000"
42
+
43
+ # We're using two regex here, since some headers have both PLLSOURCE *and* PLL1SOURCE
44
+ pll_source = regs .findall (r"(LL_RCC_PLLSOURCE_(.+?))" ) or regs .findall (r"(LL_RCC_PLL1SOURCE_(.+?))" )
45
+ assert pll_source , "Cannot find PllSource enums"
46
+
47
+ cfgr_sws_pos = regs .search ("RCC_.*?_SWS_Pos" )
48
+ assert (sys_source := regs .findall (r"(LL_RCC_SYS_CLKSOURCE_(.{1,9}))" )), "Cannot find SystemClockSource enums"
49
+ assert (rtc_source := regs .findall (r"(LL_RCC_RTC_CLKSOURCE_(.+?))" )), "Cannot find RealTimeClockSource enums"
50
+ assert (ahb_prescaler := regs .findall (r"(LL_RCC_SYSCLK_DIV_(\d+?))" )), "Cannot find AhbPrescaler enums"
51
+
52
+ apb_prescaler = defaultdict (list )
53
+ for reg , bus , div in regs .findall (r"(LL_RCC_APB(\d)?_DIV_(\d+?))" ):
54
+ apb_prescaler [bus ].append ((reg , div ))
55
+ assert apb_prescaler , "Cannot find any ApbPrescaler enums"
56
+
57
+ mco_source = defaultdict (lambda : ([], []))
58
+ for reg , mco , name in regs .findall (r"(LL_RCC_MCO(\d?)SOURCE_(.+?))" ):
59
+ mco_source [mco ][0 ].append ((reg , name ))
60
+ for reg , mco , div in regs .findall (r"(LL_RCC_MCO(\d?)_DIV_(\d+?))" ):
61
+ mco_source [mco ][1 ].append ((reg , div ))
62
+ assert mco_source , "Cannot find any ClockOutputSource enums"
63
+
64
+ # These may not exist on all devices
65
+ can_source = regs .findall (r"(LL_RCC_FDCAN_CLKSOURCE_(.+?))" )
66
+ pll_mul = regs .findall (r"(LL_RCC_PLL_MUL_(\d+_?\d?))" )
67
+ pll_input_range = regs .findall (r"(LL_RCC_PLLINPUTRANGE_(\d+_\d+))" )
68
+ usbprescaler = regs .search (r"RCC_CFGR_USBPRE" )
69
+ lse_drive = regs .findall (r"(LL_RCC_LSEDRIVE_(.+?))" )
70
+ hsi48 = regs .search (r"RCC_.*?_HSI48ON" )
71
+ hsi14 = regs .search (r"RCC_.*?_HSI14ON" )
72
+ msi_range_selection = regs .search (r"RCC_.+?_MSIRGSEL" )
73
+ epod_booster = regs .findall (r"(LL_RCC_PLL1MBOOST_DIV_(\d+))" )
74
+
75
+ if (hsi_div4 := regs .search (r"RCC_.*?_HSIDIVEN" )):
76
+ # Normalize the HSIDIVEN to be Div4 on the STM32L0 family
77
+ hsi_div = [("0" , "1" ), (hsi_div4 , "4" )]
62
78
else :
63
- properties ["hsi_frequency" ] = 16_000_000
64
- properties ["lsi_frequency" ] = 32_000
65
- properties ["boot_frequency" ] = properties ["hsi_frequency" ]
66
-
67
- # 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" ) \
79
+ hsi_div = regs .findall (r"(LL_RCC_HSI_DIV_?(\d+))" )
80
+
81
+ # There is sadly no easy way to find the MSI range values, so we have to hardcode them
82
+ msi_range = regs .findall (r"(LL_RCC_MSIK?RANGE_)\d+" ) or ("" , [])
83
+ if len (msi_range ) == 7 :
84
+ msi_range = (msi_range [0 ], ("kHz65_536" , "kHz131_072" , "kHz262_144" , "kHz524_288" , "MHz1_048" , "MHz2_097" , "MHz4_194" ))
85
+ elif len (msi_range ) == 12 :
86
+ msi_range = (msi_range [0 ], ("kHz100" , "kHz200" , "kHz400" , "kHz800" , "MHz1" , "MHz2" ,
87
+ "MHz4" , "MHz8" , "MHz16" , "MHz24" , "MHz32" , "MHz48" ))
88
+ elif len (msi_range ) == 16 :
89
+ msi_range = (msi_range [0 ], ("MHz48" , "MHz24" , "MHz16" , "MHz12" , "MHz4" , "MHz2" , "MHz1_5" , "MHz1" , "MHz3_072" ,
90
+ "MHz1_536" , "MHz1_024" , "kHz768" , "kHz400" , "kHz200" , "kHz133" , "kHz100" ))
91
+ msi_clocks = (["K" , "S" ] if "K" in msi_range [0 ] else ["" ]) if msi_range else []
92
+
93
+ clk48_source = []
94
+ if regs .search (r"RCC_.+?_(?:CL?K48M?SEL|ICLKSEL)" ):
95
+ clk48_source = regs .findall (r"(LL_RCC_(?:USB|CL?K48)_CLKSOURCE_(.+?))" )
96
+
97
+ # -------------------------------------------------------------------------
98
+ # TODO: Replace this data with register queries
99
+ pllprediv = \
100
+ (target .family in ["f0" , "f3" ] or (target .family == "f1" and target .name in ["00" , "05" , "07" ]))
101
+ pllprediv2 = False # FIXME: not sure what value this should have
102
+ pll_hse_prediv2 = target .family == "f1" and target .name in ["01" , "02" , "03" ]
103
+ pll_p = ((target .family == "l4" and target .name not in ["12" , "22" ]) or target .family == "g4" )
104
+ overdrive = (target .family == "f7" ) or \
105
+ ((target .family == "f4" ) and target .name in ["27" , "29" , "37" , "39" , "46" , "69" , "79" ])
106
+ vos0_overdrive = (target .family == "h7" ) and \
107
+ target .name in ["42" , "43" , "45" , "47" , "50" , "53" , "55" , "57" ]
108
+ has_r1mode = (target .family == "g4" ) or \
109
+ (target .family == "l4" and target .name [0 ] in ["p" , "q" , "r" , "s" ])
110
+ pllsai_p_usb = (target .family == "f7" ) or \
111
+ ((target .family == "f4" ) and target .name in ["46" , "69" , "79" ])
112
+
113
+ d2 = ("CD" if target .name in ["a3" , "b0" , "b3" ] else "D2" ) \
126
114
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" ))
115
+ d3 = ("SRD" if target .name in ["a0" , "a3" , "b0" , "b3" ] else "D3" )
116
+ pll_ids = ["1" , "2" , "3" ] if target .family in ["h7" , "u5" ] else [] if target .family in ["c0" ] else ["" ]
117
+ has_smps = target .family == "h7" and (target .name in ["25" , "35" , "45" , "47" , "55" , "57" ] or \
118
+ (target .name in ["30" , "a3" , "b0" , "b3" ] and target ["variant" ] == "q" ))
119
+ # -------------------------------------------------------------------------
135
120
136
121
flash_latencies = {}
137
122
for vcore in device .get_driver ("flash" )["latency" ]:
138
123
flash_latencies [int (vcore ["vcore-min" ])] = sorted ([int (f ["hclk-max" ]) for f in vcore ["wait-state" ]])
139
124
140
- properties ["table" ] = flash_latencies
141
- env .substitutions = properties
142
- env .outbasepath = "modm/src/modm/platform/clock"
143
-
144
- env .template ("rcc.cpp.in" )
145
- env .template ("rcc.hpp.in" )
146
-
147
125
all_peripherals = env .query (":cmsis:device:peripherals" )
148
126
rcc_map = defaultdict (dict )
149
- for (reg , per , typ ) in regs .findall (r"RCC_([A-Z0-9]*?)_([A-Z0-9]+ ?)(EN|RST)" ):
127
+ for (reg , per , typ ) in regs .findall (r"RCC_(A[HP]B\d?(?:ENR|RSTR)\d?)_(.* ?)(EN|RST)" ):
150
128
rcc_map [per ][typ ] = reg
151
129
rcc_enable = {}
152
130
rcc_reset = {}
@@ -214,8 +192,9 @@ def build(env):
214
192
if "RST" in mode :
215
193
rcc_reset [per .capitalize ()] = (nper , mode ["RST" ])
216
194
217
- env .substitutions .update ({
218
- "rcc_enable" : rcc_enable ,
219
- "rcc_reset" : rcc_reset ,
220
- })
195
+
196
+ env .outbasepath = "modm/src/modm/platform/clock"
197
+ env .substitutions = locals ()
198
+ env .template ("rcc.cpp.in" )
199
+ env .template ("rcc.hpp.in" )
221
200
env .template ("rcc_impl.hpp.in" )
0 commit comments