2019-04-03 12:14 AM
Hello,
the observed bug is the following.
We are using STM32L433RC and generating some code from CubeMX using low-level libraries. We are currently evaluating precision of the hardware clock compensation, when using internal MSI RC oscillator with external crystal of 32.768kHz connected, and PLL mode (in order to do the compensation) enabled.
The sequence generated by the CubeMX is the following:
void SystemClock_Config(void)
{
LL_FLASH_SetLatency(LL_FLASH_LATENCY_4);
if(LL_FLASH_GetLatency() != LL_FLASH_LATENCY_4)
{
Error_Handler();
}
LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
LL_RCC_MSI_Enable();
/* Wait till MSI is ready */
while(LL_RCC_MSI_IsReady() != 1)
{
}
LL_RCC_MSI_EnablePLLMode();
LL_RCC_MSI_EnableRangeSelection();
LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_11);
LL_RCC_MSI_SetCalibTrimming(0);
LL_PWR_EnableBkUpAccess();
LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_LOW);
LL_RCC_LSE_Enable();
/* Wait till LSE is ready */
while(LL_RCC_LSE_IsReady() != 1)
{
}
LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_MSI, LL_RCC_PLLM_DIV_3, 10, LL_RCC_PLLR_DIV_2);
LL_RCC_PLL_EnableDomain_SYS();
LL_RCC_PLL_Enable();
/* Wait till PLL is ready */
while(LL_RCC_PLL_IsReady() != 1)
{
}
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
/* Wait till System clock is ready */
while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
{
}
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_Init1msTick(80000000);
LL_SYSTICK_SetClkSource(LL_SYSTICK_CLKSOURCE_HCLK);
LL_SetSystemCoreClock(80000000);
LL_RCC_SetUSARTClockSource(LL_RCC_USART2_CLKSOURCE_PCLK1);
}
The problem is, that there is a hardware protection to enable MSI PLL mode, when the external crystal clock is not stable. As it is stated for example in the RM0394 manual, for RCC_CR register, page 195:
"Bit 2 MSIPLLEN: MSI clock PLL enable
Set and cleared by software to enable/ disable the PLL part of the MSI clock source.
MSIPLLEN must be enabled after LSE is enabled (LSEON enabled) and ready (LSERDY set
by hardware).There is a hardware protection to avoid enabling MSIPLLEN if LSE is not
ready.
This bit is cleared by hardware when LSE is disabled (LSEON = 0) or when the Clock
Security System on LSE detects a LSE failure (refer to RCC_CSR register)."
Therefore, the above stated code will enable the compensation correctly only in the case, when the chip is powered up for a while and therefore the clock of external 32.768kHz crystal is stable. Which is not true after fresh power up of the chip. In that case hardware will protect the MSI PLL mode to be enabled, and the compensation will not work.
To fix this issue, the code must be generated in such order, to reflect the datasheet recommendation. For example, the following fixes the problem:
....
....
....
/* Wait till LSE is ready */
while(LL_RCC_LSE_IsReady() != 1)
{
}
LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_MSI, LL_RCC_PLLM_DIV_3, 10, LL_RCC_PLLR_DIV_2);
LL_RCC_PLL_EnableDomain_SYS();
LL_RCC_PLL_Enable();
LL_RCC_MSI_EnablePLLMode(); /* HERE IS THE PROBLEM FIX */
/* Wait till PLL is ready */
while(LL_RCC_PLL_IsReady() != 1)
{
}
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
....
....
....
While we are enabling the PLL mode only after the external crystal clock is stable.
Thank you for fixing this issue in the future releases! =)
Michal M.
2021-06-17 12:45 AM
unfortunately, two years later the issue still persists...