diff options
Diffstat (limited to 'stmhal/modmachine.c')
| -rw-r--r-- | stmhal/modmachine.c | 71 |
1 files changed, 21 insertions, 50 deletions
diff --git a/stmhal/modmachine.c b/stmhal/modmachine.c index bcbf43fde..df75d393c 100644 --- a/stmhal/modmachine.c +++ b/stmhal/modmachine.c @@ -52,6 +52,7 @@ #include "spi.h" #include "uart.h" #include "wdt.h" +#include "genhdr/pllfreqtable.h" #if defined(MCU_SERIES_F4) // the HAL does not define these constants @@ -276,61 +277,31 @@ STATIC mp_obj_t machine_freq(mp_uint_t n_args, const mp_obj_t *args) { uint32_t m = HSE_VALUE / 1000000, n = 336, p = 2, q = 7; uint32_t sysclk_source; - // the following logic assumes HSE < HSI - if (HSE_VALUE / 1000000 <= wanted_sysclk && wanted_sysclk < HSI_VALUE / 1000000) { - // use HSE as SYSCLK - sysclk_source = RCC_SYSCLKSOURCE_HSE; - } else if (HSI_VALUE / 1000000 <= wanted_sysclk && wanted_sysclk < 24) { - // use HSI as SYSCLK - sysclk_source = RCC_SYSCLKSOURCE_HSI; - } else { - // search for a valid PLL configuration that keeps USB at 48MHz - for (; wanted_sysclk > 0; wanted_sysclk--) { - for (p = 2; p <= 8; p += 2) { - // compute VCO_OUT - mp_uint_t vco_out = wanted_sysclk * p; - // make sure VCO_OUT is between 192MHz and 432MHz - if (vco_out < 192 || vco_out > 432) { - continue; - } - // make sure Q is an integer - if (vco_out % 48 != 0) { - continue; - } - // solve for Q to get PLL48CK at 48MHz - q = vco_out / 48; - // make sure Q is in range - if (q < 2 || q > 15) { - continue; - } - // make sure N/M is an integer - if (vco_out % (HSE_VALUE / 1000000) != 0) { - continue; - } - // solve for N/M - mp_uint_t n_by_m = vco_out / (HSE_VALUE / 1000000); - // solve for M, making sure VCO_IN (=HSE/M) is between 1MHz and 2MHz - m = 192 / n_by_m; - while (m < (HSE_VALUE / 2000000) || n_by_m * m < 192) { - m += 1; - } - if (m > (HSE_VALUE / 1000000)) { - continue; - } - // solve for N - n = n_by_m * m; - // make sure N is in range - if (n < 192 || n > 432) { - continue; - } - - // found values! + // search for a valid PLL configuration that keeps USB at 48MHz + for (const uint16_t *pll = &pll_freq_table[MP_ARRAY_SIZE(pll_freq_table) - 1]; pll >= &pll_freq_table[0]; --pll) { + uint32_t sys = *pll & 0xff; + if (sys <= wanted_sysclk) { + m = (*pll >> 10) & 0x3f; + p = ((*pll >> 7) & 0x6) + 2; + if (m == 0) { + // special entry for using HSI directly + sysclk_source = RCC_SYSCLKSOURCE_HSI; + goto set_clk; + } else if (m == 1) { + // special entry for using HSE directly + sysclk_source = RCC_SYSCLKSOURCE_HSE; + goto set_clk; + } else { + // use PLL sysclk_source = RCC_SYSCLKSOURCE_PLLCLK; + uint32_t vco_out = sys * p; + n = vco_out * m / (HSE_VALUE / 1000000); + q = vco_out / 48; goto set_clk; } } - mp_raise_ValueError("can't make valid freq"); } + mp_raise_ValueError("can't make valid freq"); set_clk: //printf("%lu %lu %lu %lu %lu\n", sysclk_source, m, n, p, q); |
