cancel
Showing results for 
Search instead for 
Did you mean: 

MCU is not waking up from STOP mode when it receives data over USART

NB_Saschen1
Associate

Hi All,

I created a test project to Wake Up the device from STOP Mode when it receives data over UART.

I ported code from "UART_WakeUpFromStopUsingFIFO" available at /STM32Cube/Repository/STM32Cube_FW_L5_V1.3.1/Projects/STM32L562E-DK/Examples/UART/

Example project from STM is working as expected. The Device entered STOP Mode and Woke Up when it received data.

But, My test project is not working.

More Info:

1. The project was created for STM32L562 MCU.

2. Test board is L562-DK

3. LED GREEN is not turn ON in my project if USART 1 configured.

4. Wake Up from STOP Mode is not working.

5. Receving bytes over UART is working when I disabled the code to enter STOP Mode ( SystemClock_Config_fromSTOP() ) and Configure the system clock after wake up from STOP Mode ( SystemClock_Config_fromSTOP() ). USART 1 is used.

I have attached my project in zip file.

Can you advise me, how to resolve it?

Thanks

1 ACCEPTED SOLUTION

Accepted Solutions
Jaroslav BECKA
ST Employee

Hello,

I've downloaded your project, tested it on nucleo-L552ZE-Q and was able to figure out the root cause of the problem.

The execution gets stuck after the first wake-up from STOP in HAL_RCC_OscConfig() called from SystemClock_Config_fromSTOP().

The while loop waiting for RCC_CR_PLLRDY ends with a timeout, since this flag is never set.

The execution then goes to Error_Handler().

A reason for that is a wrong PLL parameter passed in RCC_OscInitStruct, in particular RCC_OscInitStruct->PLL->PLLM is 1 in your case.

The correct value for the given configuration is 4.

The RCC_OscInitStruct values are obtained by calling the function HAL_RCC_GetOscConfig(), which is a previous step in SystemClock_Config_fromSTOP().

STM32 can wake-up from STOP mode with either MSI or HSI clock source. If a different clock settings is then used by the application (e.g. external clock source or PLL is used), the clock tree has to be re-configured after wake-up (that's why SystemClock_Config_fromSTOP() is called) .

In your project the internal HSI RC 16 MHz oscillator is used as wake-up source, see main():

  /* Specify HSI as the clock source used after wake up from stop mode */

  __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI);

In the SystemClock_Config_fromSTOP() the PLL is turned on and the HSI is configured as PLL source.

However, when I check your SystemClock_Config() which is used for initial clock configuration (called at the beginning of main()),

a different internal oscillator is used, namely MSI. It is used as PLL source and all the PLL parameters are set accordingly.

When you then obtain the RCC_OscInitStruct values by calling the function HAL_RCC_GetOscConfig() in SystemClock_Config_fromSTOP(),

you get the values for MSI and not for HSI (so wrong PLL configuration values)!

These are then passed to HAL_RCC_OscConfig(&RCC_OscInitStruct).

This configuration (PLLSource = HSI, PLLM = 1, PLLN = 55, PLLR = 2) results in a frequency 440 MHz generated by the PLL, which is way higher than the CPU max. frequency 110 MHz.

With the correct configuration (PLLSource = HSI, PLLM = 4, PLLN = 55, PLLR = 2), the resulting frequency is 110 MHz (so CPU max.).

There are a few ways how to solve the problem, e.g.:

1) Add the following line in the SystemClock_Config_fromSTOP() just before the HAL_RCC_OscConfig(&RCC_OscInitStruct) call:

RCC_OscInitStruct.PLL.PLLM = 4;

2) Re-write the SystemClock_Config() function to use HSI instead of MSI and set the above parameters PLLSource = HSI, PLLM = 4, PLLN = 55, PLLR = 2 (preferable solution).

Of course, this is for the max. CPU frequency 110 MHz, if you want to use lower frequency, you can adjust the values.

I also recommend to add the two followin lines at the beginning of main():

 DBGMCU->CR &= ~DBGMCU_CR_DBG_STOP;

 DBGMCU->CR &= ~DBGMCU_CR_DBG_STANDBY;

This will disable debug in STOP and STANDBY modes. Some IDEs enable this feature automatically, afterwards the device will wake-up from STOP mode due to an SysTick interrupt (provided that SysTick is activated and its interrupt enabled). A power cycle might be needed to apply this configuration.

You can check these values during debug in DBGMCU->CR. But this is a different story.

I will upload the modified project.

Best regards

Jaroslav Becka

View solution in original post

2 REPLIES 2
Jaroslav BECKA
ST Employee

Hello,

I've downloaded your project, tested it on nucleo-L552ZE-Q and was able to figure out the root cause of the problem.

The execution gets stuck after the first wake-up from STOP in HAL_RCC_OscConfig() called from SystemClock_Config_fromSTOP().

The while loop waiting for RCC_CR_PLLRDY ends with a timeout, since this flag is never set.

The execution then goes to Error_Handler().

A reason for that is a wrong PLL parameter passed in RCC_OscInitStruct, in particular RCC_OscInitStruct->PLL->PLLM is 1 in your case.

The correct value for the given configuration is 4.

The RCC_OscInitStruct values are obtained by calling the function HAL_RCC_GetOscConfig(), which is a previous step in SystemClock_Config_fromSTOP().

STM32 can wake-up from STOP mode with either MSI or HSI clock source. If a different clock settings is then used by the application (e.g. external clock source or PLL is used), the clock tree has to be re-configured after wake-up (that's why SystemClock_Config_fromSTOP() is called) .

In your project the internal HSI RC 16 MHz oscillator is used as wake-up source, see main():

  /* Specify HSI as the clock source used after wake up from stop mode */

  __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI);

In the SystemClock_Config_fromSTOP() the PLL is turned on and the HSI is configured as PLL source.

However, when I check your SystemClock_Config() which is used for initial clock configuration (called at the beginning of main()),

a different internal oscillator is used, namely MSI. It is used as PLL source and all the PLL parameters are set accordingly.

When you then obtain the RCC_OscInitStruct values by calling the function HAL_RCC_GetOscConfig() in SystemClock_Config_fromSTOP(),

you get the values for MSI and not for HSI (so wrong PLL configuration values)!

These are then passed to HAL_RCC_OscConfig(&RCC_OscInitStruct).

This configuration (PLLSource = HSI, PLLM = 1, PLLN = 55, PLLR = 2) results in a frequency 440 MHz generated by the PLL, which is way higher than the CPU max. frequency 110 MHz.

With the correct configuration (PLLSource = HSI, PLLM = 4, PLLN = 55, PLLR = 2), the resulting frequency is 110 MHz (so CPU max.).

There are a few ways how to solve the problem, e.g.:

1) Add the following line in the SystemClock_Config_fromSTOP() just before the HAL_RCC_OscConfig(&RCC_OscInitStruct) call:

RCC_OscInitStruct.PLL.PLLM = 4;

2) Re-write the SystemClock_Config() function to use HSI instead of MSI and set the above parameters PLLSource = HSI, PLLM = 4, PLLN = 55, PLLR = 2 (preferable solution).

Of course, this is for the max. CPU frequency 110 MHz, if you want to use lower frequency, you can adjust the values.

I also recommend to add the two followin lines at the beginning of main():

 DBGMCU->CR &= ~DBGMCU_CR_DBG_STOP;

 DBGMCU->CR &= ~DBGMCU_CR_DBG_STANDBY;

This will disable debug in STOP and STANDBY modes. Some IDEs enable this feature automatically, afterwards the device will wake-up from STOP mode due to an SysTick interrupt (provided that SysTick is activated and its interrupt enabled). A power cycle might be needed to apply this configuration.

You can check these values during debug in DBGMCU->CR. But this is a different story.

I will upload the modified project.

Best regards

Jaroslav Becka

NB_Saschen1
Associate

Hi Jaroslav,

Thanks for your reply.

Last week, I fixed this issue and I wanted to delete/close it but I was not able delete it.

Yesterday, I tried again to delete it but I got pop-up message "Admin not authorize you to delete" or something similar.

I should have added "This issue has been fixed".

Sorry for inconvenience caused.