stm32/powerctrl: Support changing frequency when HSI is clock source.

This patch makes pllvalues.py generate two tables: one for when HSI is used
and one for when HSE is used.  The correct table is then selected at
compile time via the existing MICROPY_HW_CLK_USE_HSI.
pull/1/head
Damien George 2019-05-02 13:00:00 +10:00
parent e70c438c71
commit 3fbf32b947
2 changed files with 48 additions and 21 deletions

View File

@ -5,6 +5,7 @@ for the machine.freq() function.
"""
from __future__ import print_function
import re
def close_int(x):
return abs(x - round(x)) < 0.01
@ -109,12 +110,18 @@ def verify_pll(hse, pll):
assert 1 <= vco_in <= 2
assert 192 <= vco_out <= 432
def compute_pll_table(source_clk, relax_pll48):
valid_plls = []
for sysclk in range(2, 217, 2):
pll = compute_pll2(source_clk, sysclk, relax_pll48)
if pll is not None:
verify_pll(source_clk, pll)
valid_plls.append((sysclk, pll))
return valid_plls
def generate_c_table(hse, valid_plls):
valid_plls = valid_plls + [(16, (0, 0, 2, 0))]
if hse < 16:
valid_plls.append((hse, (1, 0, 2, 0)))
valid_plls.sort()
print("// (M, P/2-1, SYS) values for %u MHz HSE" % hse)
print("// (M, P/2-1, SYS) values for %u MHz source" % hse)
print("static const uint16_t pll_freq_table[%u] = {" % len(valid_plls))
for sys, (M, N, P, Q) in valid_plls:
print(" (%u << 10) | (%u << 8) | %u," % (M, P // 2 - 1, sys))
@ -137,6 +144,8 @@ def main():
c_table = False
relax_pll48 = False
hse = None
hsi = None
while True:
if argv[0] == '-c':
@ -153,32 +162,44 @@ def main():
sys.exit(1)
if argv[0].startswith("file:"):
# extract HSE_VALUE from header file
# extract HSE_VALUE, and optionally HSI_VALUE, from header file
regex = re.compile(r'#define +(HSE_VALUE|HSI_VALUE) +\(\(uint32_t\)([0-9]+)\)')
with open(argv[0][5:]) as f:
for line in f:
line = line.strip()
if line.startswith("#define") and line.find("HSE_VALUE") != -1:
idx_start = line.find("((uint32_t)") + 11
idx_end = line.find(")", idx_start)
hse = int(line[idx_start:idx_end]) // 1000000
break
else:
m = regex.match(line)
if m:
val = int(m.group(2)) // 1000000
if m.group(1) == 'HSE_VALUE':
hse = val
else:
hsi = val
if hse is None:
raise ValueError("%s does not contain a definition of HSE_VALUE" % argv[0])
if hsi is not None and hsi > 16:
# Currently, a HSI value greater than 16MHz is not supported
hsi = None
else:
# HSE given directly as an integer
hse = int(argv[0])
valid_plls = []
for sysclk in range(2, 217, 2):
pll = compute_pll2(hse, sysclk, relax_pll48)
if pll is not None:
verify_pll(hse, pll)
valid_plls.append((sysclk, pll))
hse_valid_plls = compute_pll_table(hse, relax_pll48)
if hsi is not None:
hsi_valid_plls = compute_pll_table(hsi, relax_pll48)
if c_table:
generate_c_table(hse, valid_plls)
print('#if MICROPY_HW_CLK_USE_HSI')
if hsi is not None:
hsi_valid_plls.append((hsi, (0, 0, 2, 0)))
generate_c_table(hsi, hsi_valid_plls)
print('#else')
if hsi is not None:
hse_valid_plls.append((hsi, (0, 0, 2, 0)))
hse_valid_plls.append((hse, (1, 0, 2, 0)))
generate_c_table(hse, hse_valid_plls)
print('#endif')
else:
print_table(hse, valid_plls)
print_table(hse, hse_valid_plls)
if __name__ == "__main__":
main()

View File

@ -136,7 +136,7 @@ int powerctrl_set_sysclk(uint32_t sysclk, uint32_t ahb, uint32_t apb1, uint32_t
}
// Default PLL parameters that give 48MHz on PLL48CK
uint32_t m = HSE_VALUE / 1000000, n = 336, p = 2, q = 7;
uint32_t m = MICROPY_HW_CLK_VALUE / 1000000, n = 336, p = 2, q = 7;
uint32_t sysclk_source;
bool need_pllsai = false;
@ -157,7 +157,7 @@ int powerctrl_set_sysclk(uint32_t sysclk, uint32_t ahb, uint32_t apb1, uint32_t
// use PLL
sysclk_source = RCC_SYSCLKSOURCE_PLLCLK;
uint32_t vco_out = sys * p;
n = vco_out * m / (HSE_VALUE / 1000000);
n = vco_out * m / (MICROPY_HW_CLK_VALUE / 1000000);
q = vco_out / 48;
#if defined(STM32F7)
need_pllsai = vco_out % 48 != 0;
@ -178,7 +178,11 @@ set_clk:
if (sysclk_source == RCC_SYSCLKSOURCE_PLLCLK) {
// Set HSE as system clock source to allow modification of the PLL configuration
// We then change to PLL after re-configuring PLL
#if MICROPY_HW_CLK_USE_HSI
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
#else
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
#endif
} else {
// Directly set the system clock source as desired
RCC_ClkInitStruct.SYSCLKSource = sysclk_source;
@ -217,6 +221,8 @@ set_clk:
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_OscInitStruct.OscillatorType = MICROPY_HW_RCC_OSCILLATOR_TYPE;
RCC_OscInitStruct.HSEState = MICROPY_HW_RCC_HSE_STATE;
RCC_OscInitStruct.HSIState = MICROPY_HW_RCC_HSI_STATE;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = MICROPY_HW_RCC_PLL_SRC;
RCC_OscInitStruct.PLL.PLLM = m;