stm32/mboot: Use PLL3 for USB clock source on H7 MCUs.
PLL3-Q is more reliable than PLL1-Q for the USB clock source when entering mboot from various reset states (eg power on vs MCU reset). (It was found that if the main application used PLL3-Q then sometimes the USB clock source would stay stuck on PLL3-Q and not switch to PLL1-Q after a reset.) Other related changes: - SystemCoreClockUpdate() should be called on H7 because the calculation can be involved in some cases. - __set_PRIMASK(0) should be called because on H7 the built-in ST DFU bootloader exits with IRQs disabled. Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
parent
c99ed8d6fa
commit
c8c229b96c
|
@ -265,27 +265,48 @@ void SystemClock_Config(void) {
|
|||
while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) {
|
||||
}
|
||||
|
||||
// Configure PLL1 factors and source
|
||||
RCC->PLLCKSELR =
|
||||
MICROPY_HW_CLK_PLLM << RCC_PLLCKSELR_DIVM1_Pos
|
||||
| 2 << RCC_PLLCKSELR_PLLSRC_Pos; // HSE selected as PLL source
|
||||
// Disable PLL3
|
||||
__HAL_RCC_PLL3_DISABLE();
|
||||
while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL3RDY) != RESET) {
|
||||
}
|
||||
|
||||
// Select HSE as PLLx source
|
||||
RCC->PLLCKSELR = 2 << RCC_PLLCKSELR_PLLSRC_Pos;
|
||||
RCC->PLLCFGR = 0;
|
||||
|
||||
// Configure PLL1 for use by SYSCLK
|
||||
RCC->PLLCKSELR |= MICROPY_HW_CLK_PLLM << RCC_PLLCKSELR_DIVM1_Pos;
|
||||
RCC->PLLCFGR |= RCC_PLLCFGR_DIVP1EN;
|
||||
RCC->PLL1FRACR = 0;
|
||||
RCC->PLL1DIVR =
|
||||
(MICROPY_HW_CLK_PLLN - 1) << RCC_PLL1DIVR_N1_Pos
|
||||
| (MICROPY_HW_CLK_PLLP - 1) << RCC_PLL1DIVR_P1_Pos // only even P allowed
|
||||
| (MICROPY_HW_CLK_PLLQ - 1) << RCC_PLL1DIVR_Q1_Pos
|
||||
| (MICROPY_HW_CLK_PLLR - 1) << RCC_PLL1DIVR_R1_Pos;
|
||||
|
||||
// Enable PLL1 outputs for SYSCLK and USB
|
||||
RCC->PLLCFGR = RCC_PLLCFGR_DIVP1EN | RCC_PLLCFGR_DIVQ1EN;
|
||||
// Configure PLL3 for use by USB at Q=48MHz
|
||||
RCC->PLLCKSELR |= MICROPY_HW_CLK_PLL3M << RCC_PLLCKSELR_DIVM3_Pos;
|
||||
RCC->PLLCFGR |= RCC_PLLCFGR_DIVQ3EN;
|
||||
RCC->PLL3FRACR = 0;
|
||||
RCC->PLL3DIVR =
|
||||
(MICROPY_HW_CLK_PLL3N - 1) << RCC_PLL3DIVR_N3_Pos
|
||||
| (MICROPY_HW_CLK_PLL3P - 1) << RCC_PLL3DIVR_P3_Pos // only even P allowed
|
||||
| (MICROPY_HW_CLK_PLL3Q - 1) << RCC_PLL3DIVR_Q3_Pos
|
||||
| (MICROPY_HW_CLK_PLL3R - 1) << RCC_PLL3DIVR_R3_Pos;
|
||||
|
||||
// Select PLL1-Q for USB clock source
|
||||
RCC->D2CCIP2R |= 1 << RCC_D2CCIP2R_USBSEL_Pos;
|
||||
// Select PLL3-Q for USB clock source
|
||||
MODIFY_REG(RCC->D2CCIP2R, RCC_D2CCIP2R_USBSEL, RCC_D2CCIP2R_USBSEL_1);
|
||||
|
||||
// Enable PLL1
|
||||
__HAL_RCC_PLL_ENABLE();
|
||||
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) {
|
||||
}
|
||||
|
||||
// Enable PLL3
|
||||
__HAL_RCC_PLL3_ENABLE();
|
||||
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL3RDY) == RESET) {
|
||||
}
|
||||
|
||||
// Increase latency before changing SYSCLK
|
||||
if (MICROPY_HW_FLASH_LATENCY > (FLASH->ACR & FLASH_ACR_LATENCY)) {
|
||||
__HAL_FLASH_SET_LATENCY(MICROPY_HW_FLASH_LATENCY);
|
||||
|
@ -320,7 +341,7 @@ void SystemClock_Config(void) {
|
|||
;
|
||||
|
||||
// Update clock value and reconfigure systick now that the frequency changed
|
||||
SystemCoreClock = CORE_PLL_FREQ;
|
||||
SystemCoreClockUpdate();
|
||||
systick_init();
|
||||
}
|
||||
|
||||
|
@ -1486,6 +1507,9 @@ enter_bootloader:
|
|||
// set the system clock to be HSE
|
||||
SystemClock_Config();
|
||||
|
||||
// Ensure IRQs are enabled (needed coming out of ST bootloader on H7)
|
||||
__set_PRIMASK(0);
|
||||
|
||||
#if USE_USB_POLLING
|
||||
// irqs with a priority value greater or equal to "pri" will be disabled
|
||||
// "pri" should be between 1 and 15 inclusive
|
||||
|
|
Loading…
Reference in New Issue