stm32/powerctrl: Improve support for changing system freq on H7 MCUs.
This commit improves pllvalues.py to generate PLL values for H7 MCUs that are valid (VCO in and out are in range) and extend for the entire range of SYSCLK values up to 400MHz (up to 480MHz is currently unsupported).
This commit is contained in:
parent
03b73ce329
commit
2c8c2b935e
@ -649,7 +649,7 @@ CMSIS_MCU_HDR = $(CMSIS_DIR)/$(CMSIS_MCU_LOWER).h
|
||||
modmachine.c: $(GEN_PLLFREQTABLE_HDR)
|
||||
$(GEN_PLLFREQTABLE_HDR): $(PLLVALUES) | $(HEADER_BUILD)
|
||||
$(ECHO) "GEN $@"
|
||||
$(Q)$(PYTHON) $(PLLVALUES) -c $(if $(filter $(MCU_SERIES),f7),--relax-pll48,) file:$(BOARD_DIR)/stm32$(MCU_SERIES)xx_hal_conf.h > $@
|
||||
$(Q)$(PYTHON) $(PLLVALUES) -c -m $(MCU_SERIES) file:$(BOARD_DIR)/stm32$(MCU_SERIES)xx_hal_conf.h > $@
|
||||
|
||||
$(BUILD)/modstm.o: $(GEN_STMCONST_HDR)
|
||||
# Use a pattern rule here so that make will only call make-stmconst.py once to
|
||||
|
@ -7,6 +7,36 @@ for the machine.freq() function.
|
||||
from __future__ import print_function
|
||||
import re
|
||||
|
||||
class MCU:
|
||||
def __init__(self, range_sysclk, range_m, range_n, range_p, range_q, range_vco_in, range_vco_out):
|
||||
self.range_sysclk = range_sysclk
|
||||
self.range_m = range_m
|
||||
self.range_n = range_n
|
||||
self.range_p = range_p
|
||||
self.range_q = range_q
|
||||
self.range_vco_in = range_vco_in
|
||||
self.range_vco_out = range_vco_out
|
||||
|
||||
mcu_default = MCU(
|
||||
range_sysclk=range(2, 216 + 1, 2),
|
||||
range_m=range(2, 63 + 1),
|
||||
range_n=range(192, 432 + 1),
|
||||
range_p=range(2, 8 + 1, 2),
|
||||
range_q=range(2, 15 + 1),
|
||||
range_vco_in=range(1, 2 + 1),
|
||||
range_vco_out=range(192, 432 + 1),
|
||||
)
|
||||
|
||||
mcu_h7 = MCU(
|
||||
range_sysclk=range(2, 400 + 1, 2), # above 400MHz currently unsupported
|
||||
range_m=range(1, 63 + 1),
|
||||
range_n=range(4, 512 + 1),
|
||||
range_p=range(2, 128 + 1, 2),
|
||||
range_q=range(1, 128 + 1),
|
||||
range_vco_in=range(1, 16 + 1),
|
||||
range_vco_out=range(150, 960 + 1), # 150-420=medium, 192-960=wide
|
||||
)
|
||||
|
||||
def close_int(x):
|
||||
return abs(x - round(x)) < 0.01
|
||||
|
||||
@ -42,41 +72,40 @@ def compute_pll(hse, sys):
|
||||
# improved version that doesn't require N/M to be an integer
|
||||
def compute_pll2(hse, sys, relax_pll48):
|
||||
# Loop over the allowed values of P, looking for a valid PLL configuration
|
||||
# that gives the desired "sys" frequency. We use floats for P to force
|
||||
# floating point arithmetic on Python 2.
|
||||
# that gives the desired "sys" frequency.
|
||||
fallback = None
|
||||
for P in (2.0, 4.0, 6.0, 8.0):
|
||||
NbyM = sys * P / hse
|
||||
for P in mcu.range_p:
|
||||
# VCO_OUT must be between 192MHz and 432MHz
|
||||
if not (192 <= hse * NbyM <= 432):
|
||||
if not sys * P in mcu.range_vco_out:
|
||||
continue
|
||||
NbyM = float(sys * P) / hse # float for Python 2
|
||||
# scan M
|
||||
M = int(192 // NbyM) # starting value
|
||||
while 2 * M < hse:
|
||||
M += 1
|
||||
# VCO_IN must be between 1MHz and 2MHz (2MHz recommended)
|
||||
for M in range(M, hse + 1):
|
||||
if NbyM * M < 191.99 or not close_int(NbyM * M):
|
||||
continue
|
||||
M_min = mcu.range_n[0] // int(round(NbyM)) # starting value
|
||||
while mcu.range_vco_in[-1] * M_min < hse:
|
||||
M_min += 1
|
||||
# VCO_IN must be >=1MHz, but higher is better for stability so start high (low M)
|
||||
for M in range(M_min, hse + 1):
|
||||
# compute N
|
||||
N = NbyM * M
|
||||
# N must be an integer
|
||||
if not close_int(N):
|
||||
continue
|
||||
N = round(N)
|
||||
# N is restricted
|
||||
if not (192 <= N <= 432):
|
||||
if N not in mcu.range_n:
|
||||
continue
|
||||
Q = (sys * P / 48)
|
||||
Q = float(sys * P) / 48 # float for Python 2
|
||||
# Q must be an integer in a set range
|
||||
if not (2 <= Q <= 15):
|
||||
if close_int(Q) and round(Q) in mcu.range_q:
|
||||
# found valid values
|
||||
return (M, N, P, Q)
|
||||
# Re-try Q to get at most 48MHz
|
||||
Q = (sys * P + 47) // 48
|
||||
if Q not in mcu.range_q:
|
||||
continue
|
||||
if not close_int(Q):
|
||||
if int(M) == int(hse) and fallback is None:
|
||||
# the values don't give 48MHz on PLL48 but are otherwise OK
|
||||
fallback = M, N, P, int(Q)
|
||||
continue
|
||||
# found valid values
|
||||
return (M, N, P, Q)
|
||||
if fallback is None:
|
||||
# the values don't give 48MHz on PLL48 but are otherwise OK
|
||||
fallback = M, N, P, Q
|
||||
if relax_pll48:
|
||||
# might have found values which don't give 48MHz on PLL48
|
||||
return fallback
|
||||
@ -85,6 +114,7 @@ def compute_pll2(hse, sys, relax_pll48):
|
||||
return None
|
||||
|
||||
def compute_derived(hse, pll):
|
||||
hse = float(hse) # float for Python 2
|
||||
M, N, P, Q = pll
|
||||
vco_in = hse / M
|
||||
vco_out = hse * N / M
|
||||
@ -103,16 +133,16 @@ def verify_pll(hse, pll):
|
||||
assert close_int(Q)
|
||||
|
||||
# verify range
|
||||
assert 2 <= M <= 63
|
||||
assert 192 <= N <= 432
|
||||
assert P in (2, 4, 6, 8)
|
||||
assert 2 <= Q <= 15
|
||||
assert 1 <= vco_in <= 2
|
||||
assert 192 <= vco_out <= 432
|
||||
assert M in mcu.range_m
|
||||
assert N in mcu.range_n
|
||||
assert P in mcu.range_p
|
||||
assert Q in mcu.range_q
|
||||
assert mcu.range_vco_in[0] <= vco_in <= mcu.range_vco_in[-1]
|
||||
assert mcu.range_vco_out[0] <= vco_out <= mcu.range_vco_out[-1]
|
||||
|
||||
def compute_pll_table(source_clk, relax_pll48):
|
||||
valid_plls = []
|
||||
for sysclk in range(2, 217, 2):
|
||||
for sysclk in mcu.range_sysclk:
|
||||
pll = compute_pll2(source_clk, sysclk, relax_pll48)
|
||||
if pll is not None:
|
||||
verify_pll(source_clk, pll)
|
||||
@ -121,10 +151,34 @@ def compute_pll_table(source_clk, relax_pll48):
|
||||
|
||||
def generate_c_table(hse, valid_plls):
|
||||
valid_plls.sort()
|
||||
if mcu.range_sysclk[-1] <= 0xff and mcu.range_m[-1] <= 0x3f and mcu.range_p[-1] // 2 - 1 <= 0x3:
|
||||
typedef = 'uint16_t'
|
||||
sys_mask = 0xff
|
||||
m_shift = 10
|
||||
m_mask = 0x3f
|
||||
p_shift = 8
|
||||
p_mask = 0x3
|
||||
else:
|
||||
typedef = 'uint32_t'
|
||||
sys_mask = 0xffff
|
||||
m_shift = 24
|
||||
m_mask = 0xff
|
||||
p_shift = 16
|
||||
p_mask = 0xff
|
||||
print("#define PLL_FREQ_TABLE_SYS(pll) ((pll) & %d)" % (sys_mask,))
|
||||
print("#define PLL_FREQ_TABLE_M(pll) (((pll) >> %d) & %d)" % (m_shift, m_mask))
|
||||
print("#define PLL_FREQ_TABLE_P(pll) (((((pll) >> %d) & %d) + 1) * 2)" % (p_shift, p_mask))
|
||||
print("typedef %s pll_freq_table_t;" % (typedef,))
|
||||
print("// (M, P/2-1, SYS) values for %u MHz source" % hse)
|
||||
print("static const uint16_t pll_freq_table[%u] = {" % len(valid_plls))
|
||||
print("static const pll_freq_table_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))
|
||||
print(" (%u << %u) | (%u << %u) | %u," % (M, m_shift, P // 2 - 1, p_shift, sys), end='')
|
||||
if M >= 2:
|
||||
vco_in, vco_out, pllck, pll48ck = compute_derived(hse, (M, N, P, Q))
|
||||
print(" // M=%u N=%u P=%u Q=%u vco_in=%.2f vco_out=%.2f pll48=%.2f"
|
||||
% (M, N, P, Q, vco_in, vco_out, pll48ck), end=''
|
||||
)
|
||||
print()
|
||||
print("};")
|
||||
|
||||
def print_table(hse, valid_plls):
|
||||
@ -157,6 +211,7 @@ def search_header_for_hsx_values(filename, vals):
|
||||
return vals
|
||||
|
||||
def main():
|
||||
global mcu
|
||||
global out_format
|
||||
|
||||
# parse input args
|
||||
@ -164,7 +219,7 @@ def main():
|
||||
argv = sys.argv[1:]
|
||||
|
||||
c_table = False
|
||||
relax_pll48 = False
|
||||
mcu_series = 'f4'
|
||||
hse = None
|
||||
hsi = None
|
||||
|
||||
@ -172,14 +227,14 @@ def main():
|
||||
if argv[0] == '-c':
|
||||
c_table = True
|
||||
argv.pop(0)
|
||||
elif argv[0] == '--relax-pll48':
|
||||
relax_pll48 = True
|
||||
elif argv[0] == '-m':
|
||||
argv.pop(0)
|
||||
mcu_series = argv.pop(0).lower()
|
||||
else:
|
||||
break
|
||||
|
||||
if len(argv) != 1:
|
||||
print("usage: pllvalues.py [-c] <hse in MHz>")
|
||||
print("usage: pllvalues.py [-c] [-m <mcu_series>] <hse in MHz>")
|
||||
sys.exit(1)
|
||||
|
||||
if argv[0].startswith("file:"):
|
||||
@ -194,6 +249,15 @@ def main():
|
||||
# HSE given directly as an integer
|
||||
hse = int(argv[0])
|
||||
|
||||
# Select MCU parameters
|
||||
if mcu_series == 'h7':
|
||||
mcu = mcu_h7
|
||||
else:
|
||||
mcu = mcu_default
|
||||
|
||||
# Relax constraight on PLLQ being 48MHz on F7 and H7 MCUs, which have separate PLLs for 48MHz
|
||||
relax_pll48 = mcu_series in ('f7', 'h7')
|
||||
|
||||
hse_valid_plls = compute_pll_table(hse, relax_pll48)
|
||||
if hsi is not None:
|
||||
hsi_valid_plls = compute_pll_table(hsi, relax_pll48)
|
||||
|
@ -310,6 +310,11 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
|
||||
#else
|
||||
mp_int_t sysclk = mp_obj_get_int(args[0]);
|
||||
mp_int_t ahb = sysclk;
|
||||
#if defined (STM32H7)
|
||||
if (ahb > 200000000) {
|
||||
ahb /= 2;
|
||||
}
|
||||
#endif
|
||||
mp_int_t apb1 = ahb / 4;
|
||||
mp_int_t apb2 = ahb / 2;
|
||||
if (n_args > 1) {
|
||||
|
@ -93,12 +93,48 @@ void powerctrl_check_enter_bootloader(void) {
|
||||
|
||||
#if !defined(STM32F0) && !defined(STM32L0) && !defined(STM32WB)
|
||||
|
||||
typedef struct _sysclk_scaling_table_entry_t {
|
||||
uint16_t mhz;
|
||||
uint16_t value;
|
||||
} sysclk_scaling_table_entry_t;
|
||||
|
||||
#if defined(STM32F7)
|
||||
STATIC const sysclk_scaling_table_entry_t volt_scale_table[] = {
|
||||
{ 151, PWR_REGULATOR_VOLTAGE_SCALE3 },
|
||||
{ 180, PWR_REGULATOR_VOLTAGE_SCALE2 },
|
||||
// Above 180MHz uses default PWR_REGULATOR_VOLTAGE_SCALE1
|
||||
};
|
||||
#elif defined(STM32H7)
|
||||
STATIC const sysclk_scaling_table_entry_t volt_scale_table[] = {
|
||||
// See table 55 "Kernel clock distribution overview" of RM0433.
|
||||
{200, PWR_REGULATOR_VOLTAGE_SCALE3},
|
||||
{300, PWR_REGULATOR_VOLTAGE_SCALE2},
|
||||
// Above 300MHz uses default PWR_REGULATOR_VOLTAGE_SCALE1
|
||||
// (above 400MHz needs special handling for overdrive, currently unsupported)
|
||||
};
|
||||
#endif
|
||||
|
||||
STATIC int powerctrl_config_vos(uint32_t sysclk_mhz) {
|
||||
#if defined(STM32F7) || defined(STM32H7)
|
||||
uint32_t volt_scale = PWR_REGULATOR_VOLTAGE_SCALE1;
|
||||
for (int i = 0; i < MP_ARRAY_SIZE(volt_scale_table); ++i) {
|
||||
if (sysclk_mhz <= volt_scale_table[i].mhz) {
|
||||
volt_scale = volt_scale_table[i].value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (HAL_PWREx_ControlVoltageScaling(volt_scale) != HAL_OK) {
|
||||
return -MP_EIO;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Assumes that PLL is used as the SYSCLK source
|
||||
int powerctrl_rcc_clock_config_pll(RCC_ClkInitTypeDef *rcc_init, uint32_t sysclk_mhz, bool need_pllsai) {
|
||||
uint32_t flash_latency;
|
||||
|
||||
#if defined(STM32F7)
|
||||
|
||||
if (need_pllsai) {
|
||||
// Configure PLLSAI at 48MHz for those peripherals that need this freq
|
||||
// (calculation assumes it can get an integral value of PLLSAIN)
|
||||
@ -118,20 +154,16 @@ int powerctrl_rcc_clock_config_pll(RCC_ClkInitTypeDef *rcc_init, uint32_t sysclk
|
||||
}
|
||||
RCC->DCKCFGR2 |= RCC_DCKCFGR2_CK48MSEL;
|
||||
}
|
||||
#endif
|
||||
|
||||
// If possible, scale down the internal voltage regulator to save power
|
||||
uint32_t volt_scale;
|
||||
if (sysclk_mhz <= 151) {
|
||||
volt_scale = PWR_REGULATOR_VOLTAGE_SCALE3;
|
||||
} else if (sysclk_mhz <= 180) {
|
||||
volt_scale = PWR_REGULATOR_VOLTAGE_SCALE2;
|
||||
} else {
|
||||
volt_scale = PWR_REGULATOR_VOLTAGE_SCALE1;
|
||||
}
|
||||
if (HAL_PWREx_ControlVoltageScaling(volt_scale) != HAL_OK) {
|
||||
return -MP_EIO;
|
||||
int ret = powerctrl_config_vos(sysclk_mhz);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(STM32F7)
|
||||
|
||||
// These flash_latency values assume a supply voltage between 2.7V and 3.6V
|
||||
if (sysclk_mhz <= 30) {
|
||||
flash_latency = FLASH_LATENCY_0;
|
||||
@ -172,6 +204,17 @@ int powerctrl_rcc_clock_config_pll(RCC_ClkInitTypeDef *rcc_init, uint32_t sysclk
|
||||
#if !defined(STM32F0) && !defined(STM32L0) && !defined(STM32L4) && !defined(STM32WB)
|
||||
|
||||
STATIC uint32_t calc_ahb_div(uint32_t wanted_div) {
|
||||
#if defined(STM32H7)
|
||||
if (wanted_div <= 1) { return RCC_HCLK_DIV1; }
|
||||
else if (wanted_div <= 2) { return RCC_HCLK_DIV2; }
|
||||
else if (wanted_div <= 4) { return RCC_HCLK_DIV4; }
|
||||
else if (wanted_div <= 8) { return RCC_HCLK_DIV8; }
|
||||
else if (wanted_div <= 16) { return RCC_HCLK_DIV16; }
|
||||
else if (wanted_div <= 64) { return RCC_HCLK_DIV64; }
|
||||
else if (wanted_div <= 128) { return RCC_HCLK_DIV128; }
|
||||
else if (wanted_div <= 256) { return RCC_HCLK_DIV256; }
|
||||
else { return RCC_HCLK_DIV512; }
|
||||
#else
|
||||
if (wanted_div <= 1) { return RCC_SYSCLK_DIV1; }
|
||||
else if (wanted_div <= 2) { return RCC_SYSCLK_DIV2; }
|
||||
else if (wanted_div <= 4) { return RCC_SYSCLK_DIV4; }
|
||||
@ -181,14 +224,35 @@ STATIC uint32_t calc_ahb_div(uint32_t wanted_div) {
|
||||
else if (wanted_div <= 128) { return RCC_SYSCLK_DIV128; }
|
||||
else if (wanted_div <= 256) { return RCC_SYSCLK_DIV256; }
|
||||
else { return RCC_SYSCLK_DIV512; }
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC uint32_t calc_apb_div(uint32_t wanted_div) {
|
||||
STATIC uint32_t calc_apb1_div(uint32_t wanted_div) {
|
||||
#if defined(STM32H7)
|
||||
if (wanted_div <= 1) { return RCC_APB1_DIV1; }
|
||||
else if (wanted_div <= 2) { return RCC_APB1_DIV2; }
|
||||
else if (wanted_div <= 4) { return RCC_APB1_DIV4; }
|
||||
else if (wanted_div <= 8) { return RCC_APB1_DIV8; }
|
||||
else { return RCC_APB1_DIV16; }
|
||||
#else
|
||||
if (wanted_div <= 1) { return RCC_HCLK_DIV1; }
|
||||
else if (wanted_div <= 2) { return RCC_HCLK_DIV2; }
|
||||
else if (wanted_div <= 4) { return RCC_HCLK_DIV4; }
|
||||
else if (wanted_div <= 8) { return RCC_HCLK_DIV8; }
|
||||
else { return RCC_SYSCLK_DIV16; }
|
||||
else { return RCC_HCLK_DIV16; }
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC uint32_t calc_apb2_div(uint32_t wanted_div) {
|
||||
#if defined(STM32H7)
|
||||
if (wanted_div <= 1) { return RCC_APB2_DIV1; }
|
||||
else if (wanted_div <= 2) { return RCC_APB2_DIV2; }
|
||||
else if (wanted_div <= 4) { return RCC_APB2_DIV4; }
|
||||
else if (wanted_div <= 8) { return RCC_APB2_DIV8; }
|
||||
else { return RCC_APB2_DIV16; }
|
||||
#else
|
||||
return calc_apb1_div(wanted_div);
|
||||
#endif
|
||||
}
|
||||
|
||||
int powerctrl_set_sysclk(uint32_t sysclk, uint32_t ahb, uint32_t apb1, uint32_t apb2) {
|
||||
@ -207,11 +271,11 @@ int powerctrl_set_sysclk(uint32_t sysclk, uint32_t ahb, uint32_t apb1, uint32_t
|
||||
|
||||
// Search for a valid PLL configuration that keeps USB at 48MHz
|
||||
uint32_t sysclk_mhz = sysclk / 1000000;
|
||||
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;
|
||||
for (const pll_freq_table_t *pll = &pll_freq_table[MP_ARRAY_SIZE(pll_freq_table) - 1]; pll >= &pll_freq_table[0]; --pll) {
|
||||
uint32_t sys = PLL_FREQ_TABLE_SYS(*pll);
|
||||
if (sys <= sysclk_mhz) {
|
||||
m = (*pll >> 10) & 0x3f;
|
||||
p = ((*pll >> 7) & 0x6) + 2;
|
||||
m = PLL_FREQ_TABLE_M(*pll);
|
||||
p = PLL_FREQ_TABLE_P(*pll);
|
||||
if (m == 0) {
|
||||
// special entry for using HSI directly
|
||||
sysclk_source = RCC_SYSCLKSOURCE_HSI;
|
||||
@ -259,8 +323,13 @@ set_clk:
|
||||
#if !defined(STM32H7)
|
||||
ahb = sysclk >> AHBPrescTable[RCC_ClkInitStruct.AHBCLKDivider >> RCC_CFGR_HPRE_Pos];
|
||||
#endif
|
||||
RCC_ClkInitStruct.APB1CLKDivider = calc_apb_div(ahb / apb1);
|
||||
RCC_ClkInitStruct.APB2CLKDivider = calc_apb_div(ahb / apb2);
|
||||
RCC_ClkInitStruct.APB1CLKDivider = calc_apb1_div(ahb / apb1);
|
||||
RCC_ClkInitStruct.APB2CLKDivider = calc_apb2_div(ahb / apb2);
|
||||
#if defined(STM32H7)
|
||||
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
|
||||
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_CLK_LAST_FREQ
|
||||
// Save the bus dividers for use later
|
||||
@ -294,6 +363,26 @@ set_clk:
|
||||
RCC_OscInitStruct.PLL.PLLN = n;
|
||||
RCC_OscInitStruct.PLL.PLLP = p;
|
||||
RCC_OscInitStruct.PLL.PLLQ = q;
|
||||
|
||||
#if defined(STM32H7)
|
||||
RCC_OscInitStruct.PLL.PLLR = 0;
|
||||
if (MICROPY_HW_CLK_VALUE / 1000000 <= 2 * m) {
|
||||
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_0; // 1-2MHz
|
||||
} else if (MICROPY_HW_CLK_VALUE / 1000000 <= 4 * m) {
|
||||
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_1; // 2-4MHz
|
||||
} else if (MICROPY_HW_CLK_VALUE / 1000000 <= 8 * m) {
|
||||
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; // 4-8MHz
|
||||
} else {
|
||||
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3; // 8-16MHz
|
||||
}
|
||||
if (MICROPY_HW_CLK_VALUE / 1000000 * n <= 420 * m) {
|
||||
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOMEDIUM; // 150-420MHz
|
||||
} else {
|
||||
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; // 192-960MHz
|
||||
}
|
||||
RCC_OscInitStruct.PLL.PLLFRACN = 0;
|
||||
#endif
|
||||
|
||||
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
|
||||
return -MP_EIO;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user