stm32: Generate PLL tables from pre-processed headers.
Allows boards to configure their HSE and PLL values in variants. Signed-off-by: Andrew Leech <andrew@alelec.net>
This commit is contained in:
committed by
Damien George
parent
22804fccf3
commit
7924b31050
@@ -640,15 +640,15 @@ $(BUILD)/%_$(BOARD).c $(HEADER_BUILD)/%.h $(HEADER_BUILD)/%_af_const.h $(HEADER_
|
|||||||
--output-source $(GEN_PINS_SRC) --output-header $(GEN_PINS_HDR) \
|
--output-source $(GEN_PINS_SRC) --output-header $(GEN_PINS_HDR) \
|
||||||
--output-af-const $(GEN_PINS_AF_CONST) --output-af-defs $(GEN_PINS_AF_DEFS)
|
--output-af-const $(GEN_PINS_AF_CONST) --output-af-defs $(GEN_PINS_AF_DEFS)
|
||||||
|
|
||||||
powerctrl.c: $(GEN_PLLFREQTABLE_HDR)
|
$(BUILD)/powerctrl.o: $(GEN_PLLFREQTABLE_HDR)
|
||||||
$(GEN_PLLFREQTABLE_HDR): $(PLLVALUES) | $(HEADER_BUILD)
|
$(GEN_PLLFREQTABLE_HDR): $(PLLVALUES) | $(HEADER_BUILD)/qstr.i.last
|
||||||
$(ECHO) "GEN $@"
|
$(ECHO) "GEN $@"
|
||||||
$(Q)$(PYTHON) $(PLLVALUES) -c -m $(CMSIS_MCU_LOWER) file:$(BOARD_DIR)/stm32$(MCU_SERIES)xx_hal_conf.h > $@
|
$(Q)$(PYTHON) $(PLLVALUES) -c -m $(CMSIS_MCU_LOWER) file:$(HEADER_BUILD)/qstr.i.last > $@
|
||||||
|
|
||||||
$(TOP)/extmod/machine_i2s.c: $(GEN_PLLI2STABLE_HDR)
|
$(BUILD)/extmod/machine_i2s.o: $(GEN_PLLI2STABLE_HDR)
|
||||||
$(GEN_PLLI2STABLE_HDR): $(PLLI2SVALUES) | $(HEADER_BUILD)
|
$(GEN_PLLI2STABLE_HDR): $(PLLI2SVALUES) | $(HEADER_BUILD)/qstr.i.last
|
||||||
$(ECHO) "GEN $@"
|
$(ECHO) "GEN $@"
|
||||||
$(Q)$(PYTHON) $(PLLI2SVALUES) -c -m $(CMSIS_MCU_LOWER) hse:$(BOARD_DIR)/stm32$(MCU_SERIES)xx_hal_conf.h pllm:$(BOARD_DIR)/mpconfigboard.h > $@
|
$(Q)$(PYTHON) $(PLLI2SVALUES) -c -m $(CMSIS_MCU_LOWER) file:$(HEADER_BUILD)/qstr.i.last > $@
|
||||||
|
|
||||||
$(BUILD)/modstm.o: $(GEN_STMCONST_HDR)
|
$(BUILD)/modstm.o: $(GEN_STMCONST_HDR)
|
||||||
$(HEADER_BUILD)/modstm_const.h: $(CMSIS_MCU_HDR) make-stmconst.py | $(HEADER_BUILD)
|
$(HEADER_BUILD)/modstm_const.h: $(CMSIS_MCU_HDR) make-stmconst.py | $(HEADER_BUILD)
|
||||||
|
|||||||
@@ -123,22 +123,21 @@ def generate_c_table(plli2s_table, hse, pllm):
|
|||||||
print("}")
|
print("}")
|
||||||
|
|
||||||
|
|
||||||
def search_header(filename, re_include, re_define, lookup, val):
|
def search_header(filename, re_define, lookup):
|
||||||
regex_include = re.compile(re_include)
|
|
||||||
regex_define = re.compile(re_define)
|
regex_define = re.compile(re_define)
|
||||||
|
val = None
|
||||||
with open(filename) as f:
|
with open(filename) as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
m = regex_include.match(line)
|
|
||||||
if m:
|
|
||||||
# Search included file
|
|
||||||
search_header(m.group(1), re_include, re_define, lookup, val)
|
|
||||||
continue
|
|
||||||
m = regex_define.match(line)
|
m = regex_define.match(line)
|
||||||
if m:
|
if m:
|
||||||
# found lookup value
|
# found lookup value
|
||||||
|
found = m.group(3)
|
||||||
|
if "*" in found or "/" in found:
|
||||||
|
# process define using multiply or divide to calculate value
|
||||||
|
found = eval(found)
|
||||||
if m.group(1) == lookup:
|
if m.group(1) == lookup:
|
||||||
val[0] = int(m.group(3))
|
val = int(found)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
|
|
||||||
@@ -166,35 +165,37 @@ def main():
|
|||||||
break
|
break
|
||||||
|
|
||||||
if mcu_series in mcu_support_plli2s:
|
if mcu_series in mcu_support_plli2s:
|
||||||
if len(argv) != 2:
|
if len(argv) not in (1, 2):
|
||||||
print("usage: pllvalues.py [-c] [-m <mcu_series>] <hse in MHz> <pllm in MHz>")
|
print("usage: pllvalues.py [-c] [-m <mcu_series>] <hse in MHz> <pllm in MHz>")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if argv[0].startswith("hse:"):
|
if argv[0].startswith("hse:"):
|
||||||
# extract HSE_VALUE from header file
|
hse = int(argv[0][len("hse:") :])
|
||||||
(hse,) = search_header(
|
|
||||||
argv[0][len("hse:") :],
|
|
||||||
r'#include "(boards/[A-Za-z0-9_./]+)"',
|
|
||||||
r"#define +(HSE_VALUE) +\((\(uint32_t\))?([0-9]+)\)",
|
|
||||||
"HSE_VALUE",
|
|
||||||
[None],
|
|
||||||
)
|
|
||||||
if hse is None:
|
|
||||||
raise ValueError("%s does not contain a definition of HSE_VALUE" % argv[0])
|
|
||||||
argv.pop(0)
|
|
||||||
|
|
||||||
if argv[0].startswith("pllm:"):
|
if argv[0].startswith("pllm:"):
|
||||||
# extract MICROPY_HW_CLK_PLLM from header file
|
pllm = int(argv[0][len("pllm:") :])
|
||||||
(pllm,) = search_header(
|
|
||||||
argv[0][len("pllm:") :],
|
if argv[0].startswith("file:"):
|
||||||
r'#include "(boards/[A-Za-z0-9_./]+)"',
|
# extract hse value from processed header files
|
||||||
r"#define +(MICROPY_HW_CLK_PLLM) +\((\(uint32_t\))?([0-9]+)\)",
|
hse = search_header(
|
||||||
"MICROPY_HW_CLK_PLLM",
|
argv[0][len("file:") :],
|
||||||
[None],
|
r"static.* (micropy_hw_hse_value) = +\(*(\(uint32_t\))?([0-9 +-/\*]+)\)*;",
|
||||||
|
"micropy_hw_hse_value",
|
||||||
|
)
|
||||||
|
if hse is None:
|
||||||
|
raise ValueError(
|
||||||
|
"%s does not contain a definition of micropy_hw_hse_value" % argv[0]
|
||||||
|
)
|
||||||
|
|
||||||
|
# extract pllm value from processed header files
|
||||||
|
pllm = search_header(
|
||||||
|
argv[0][len("file:") :],
|
||||||
|
r"static.* (micropy_hw_clk_pllm) = +\(*(\(uint32_t\))?([0-9 +-/\*]+)\)*;",
|
||||||
|
"micropy_hw_clk_pllm",
|
||||||
)
|
)
|
||||||
if pllm is None:
|
if pllm is None:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"%s does not contain a definition of MICROPY_HW_CLK_PLLM" % argv[0]
|
"%s does not contain a definition of micropy_hw_clk_pllm" % argv[0]
|
||||||
)
|
)
|
||||||
argv.pop(0)
|
argv.pop(0)
|
||||||
|
|
||||||
|
|||||||
@@ -228,26 +228,26 @@ def print_table(hse, valid_plls):
|
|||||||
print("found %u valid configurations" % len(valid_plls))
|
print("found %u valid configurations" % len(valid_plls))
|
||||||
|
|
||||||
|
|
||||||
def search_header_for_hsx_values(filename, vals):
|
def search_header_for_hsx_values(filename):
|
||||||
regex_inc = re.compile(r'#include "(boards/[A-Za-z0-9_./]+)"')
|
hse = hsi = None
|
||||||
regex_def = re.compile(r"#define +(HSE_VALUE|HSI_VALUE) +\((\(uint32_t\))?([0-9]+)\)")
|
regex_def = re.compile(
|
||||||
|
r"static.* +(micropy_hw_hs[ei]_value) = +\(*(\(uint32_t\))?([0-9 +-/\*]+)\)*;",
|
||||||
|
)
|
||||||
with open(filename) as f:
|
with open(filename) as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
m = regex_inc.match(line)
|
|
||||||
if m:
|
|
||||||
# Search included file
|
|
||||||
search_header_for_hsx_values(m.group(1), vals)
|
|
||||||
continue
|
|
||||||
m = regex_def.match(line)
|
m = regex_def.match(line)
|
||||||
if m:
|
if m:
|
||||||
# Found HSE_VALUE or HSI_VALUE
|
# Found HSE_VALUE or HSI_VALUE
|
||||||
val = int(m.group(3)) // 1000000
|
found = m.group(3)
|
||||||
if m.group(1) == "HSE_VALUE":
|
if "*" in found or "/" in found:
|
||||||
vals[0] = val
|
found = eval(found)
|
||||||
|
val = int(found) // 1000000
|
||||||
|
if m.group(1) == "micropy_hw_hse_value":
|
||||||
|
hse = val
|
||||||
else:
|
else:
|
||||||
vals[1] = val
|
hsi = val
|
||||||
return vals
|
return hse, hsi
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
@@ -280,9 +280,9 @@ def main():
|
|||||||
|
|
||||||
if argv[0].startswith("file:"):
|
if argv[0].startswith("file:"):
|
||||||
# extract HSE_VALUE, and optionally HSI_VALUE, from header file
|
# extract HSE_VALUE, and optionally HSI_VALUE, from header file
|
||||||
hse, hsi = search_header_for_hsx_values(argv[0][5:], [None, None])
|
hse, hsi = search_header_for_hsx_values(argv[0][5:])
|
||||||
if hse is None:
|
if hse is None:
|
||||||
raise ValueError("%s does not contain a definition of HSE_VALUE" % argv[0])
|
raise ValueError("%s does not contain a definition of micropy_hw_hse_value" % argv[0])
|
||||||
else:
|
else:
|
||||||
# HSE given directly as an integer
|
# HSE given directly as an integer
|
||||||
hse = int(argv[0])
|
hse = int(argv[0])
|
||||||
|
|||||||
@@ -33,7 +33,9 @@
|
|||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
#include "pin.h"
|
#include "pin.h"
|
||||||
#include "dma.h"
|
#include "dma.h"
|
||||||
|
#ifndef NO_QSTR
|
||||||
#include "genhdr/plli2stable.h"
|
#include "genhdr/plli2stable.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// Notes on this port's specific implementation of I2S:
|
// Notes on this port's specific implementation of I2S:
|
||||||
// - the DMA callbacks (1/2 complete and complete) are used to implement the asynchronous background operations
|
// - the DMA callbacks (1/2 complete and complete) are used to implement the asynchronous background operations
|
||||||
|
|||||||
@@ -28,8 +28,23 @@
|
|||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
#include "powerctrl.h"
|
#include "powerctrl.h"
|
||||||
#include "rtc.h"
|
#include "rtc.h"
|
||||||
#include "genhdr/pllfreqtable.h"
|
|
||||||
#include "extmod/modbluetooth.h"
|
#include "extmod/modbluetooth.h"
|
||||||
|
#include "py/mpconfig.h"
|
||||||
|
#ifndef NO_QSTR
|
||||||
|
#include "genhdr/pllfreqtable.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// These will be defined / expanded in pre-processor output for use in the
|
||||||
|
// boards/pllvalues.py script, then generally stripped from final firmware.
|
||||||
|
#ifdef HSI_VALUE
|
||||||
|
static uint32_t __attribute__((unused)) micropy_hw_hsi_value = HSI_VALUE;
|
||||||
|
#endif
|
||||||
|
#ifdef HSE_VALUE
|
||||||
|
static uint32_t __attribute__((unused)) micropy_hw_hse_value = HSE_VALUE;
|
||||||
|
#endif
|
||||||
|
#ifdef MICROPY_HW_CLK_PLLM
|
||||||
|
static uint32_t __attribute__((unused)) micropy_hw_clk_pllm = MICROPY_HW_CLK_PLLM;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(STM32H5) || defined(STM32H7)
|
#if defined(STM32H5) || defined(STM32H7)
|
||||||
#define RCC_SR RSR
|
#define RCC_SR RSR
|
||||||
|
|||||||
Reference in New Issue
Block a user