cancel
Showing results for 
Search instead for 
Did you mean: 

LPUART not work after SYS Clock Source change :(

Spider
Associate II

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.

1 ACCEPTED SOLUTION

Accepted Solutions
berendi
Principal

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.

View solution in original post

2 REPLIES 2
berendi
Principal

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.

Spider
Associate II

Thx!

Before changing System Clock sourec do that:

LL_LPUART_Disable(USART_CHANNEL);
LL_LPUART_DeInit(USART_CHANNEL);

And all work fine.