2020-02-10 08:36 AM
Hello!. I Have two firmwares: bootloader and application. MCU is STM32L031K6U6
First launched bootloader checking backdoor pin and launching appliction or starting firmware update process. If need just start firmware all work fine (bootloader don't change any registers - just executing jump to application)
BUT! If need to update firmware - bootloader do init of LPUART and switch system clock to HSI 16MHz then processing commands from host. After this operations bootloader deinit LPUART and sys clock back to MSI and executind same jump to applistion.
Main Application work at MSI 2.1MHz, but do initing this mode in any way at start.
In result if Bootloader do change System Clock to HSI and then back to MSI - in appliction LPUART will not work. Appliction work fine, but can't send or receive bytes via LPUART.
IF I change code of bootloader to skip change System Clock (continue work on MSI in bootloader) then application work fine after bootloader jump to them.
What I do wrong?
In Bootloader CPU Clock Init:
static void SystemClock_Config(void)
{
LL_RCC_LSI_Disable();
/* Set flash latency. */
LL_FLASH_SetLatency(LL_FLASH_LATENCY_0);
/* Verify flash latency setting. */
if(LL_FLASH_GetLatency() != LL_FLASH_LATENCY_0)
{
/* Error setting flash latency. */
ASSERT_RT(BLT_FALSE);
}
#ifndef __USE_HSI_16MHZ
LL_RCC_MSI_Enable();
/* Wait till MSI is ready */
while(LL_RCC_MSI_IsReady() != 1)
{
}
LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_5);
LL_RCC_MSI_SetCalibTrimming(0);
LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_MSI);
/* Wait till System clock is ready */
while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_MSI)
{
}
LL_RCC_HSI_Disable();
#else
LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
LL_RCC_HSI_Enable();
/* Wait till HSI is ready */
while(LL_RCC_HSI_IsReady() != 1)
{
}
LL_RCC_HSI_SetCalibTrimming(16);
LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
/* Wait till System clock is ready */
while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI)
{
}
LL_RCC_MSI_Disable();
#endif
LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_SYSCLK);
/* Update the system clock speed setting. */
LL_SetSystemCoreClock(BOOT_CPU_SYSTEM_SPEED_KHZ * 1000u);
} /*** end of SystemClock_Config ***/
CPU Clock deinti before jump to applition:
void ClockDeinit(void)
{
#ifdef __USE_HSI_16MHZ
LL_RCC_MSI_Enable();
/* Wait till MSI is ready */
while(LL_RCC_MSI_IsReady() != 1)
{
}
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_MSI);
while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_MSI)
{
}
//LL_RCC_PLL_Disable();
LL_RCC_HSI_Disable();
LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE3);
#endif
LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_PCLK1);
/* SYSCFG clock disable. */
LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
} /*** end of HAL_MspDeInit ***/
Help. PLS.
Solved! Go to Solution.
2020-02-10 08:50 AM
In the deinit phase, try switching the LPUART clock source back to MSI before HSI is disabled.
Reset LPUART in RCC.
Dump RCC registers at startup, and after deinit, check if there is some difference.
2020-02-10 08:50 AM
In the deinit phase, try switching the LPUART clock source back to MSI before HSI is disabled.
Reset LPUART in RCC.
Dump RCC registers at startup, and after deinit, check if there is some difference.
2020-02-10 07:37 PM
Thx!
Before changing System Clock sourec do that:
LL_LPUART_Disable(USART_CHANNEL);
LL_LPUART_DeInit(USART_CHANNEL);
And all work fine.