4

Development for STM32L053R8 on NUCLEO-L053R8 board.

We have a system which "wakes" from sleep every 200 μS or so, does a small amount of work then goes back to sleep (Stop mode). Ideally I'd like to wake from STOP in under 50 μS. The HAL_RCC_OscConfig() function takes around 170 μS which renders this effort pointless.

From what I can see the majority of time is spent with the PLL Configuration, in particular the while loop ("Wait till PLL is ready") which follows the re-enablement of the PLL (about 98 μS).

/* Configure the main PLL clock source, multiplication and division factors. */
__HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
                     RCC_OscInitStruct->PLL.PLLMUL,
                     RCC_OscInitStruct->PLL.PLLDIV);
/* Enable the main PLL. */
__HAL_RCC_PLL_ENABLE();

/* Get timeout */
tickstart = HAL_GetTick();

/* Wait till PLL is ready */  
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
{
  if((HAL_GetTick() - tickstart ) > RCC_PLL_TIMEOUT_VALUE)
  {
    return HAL_TIMEOUT;
  }      
}  

Are there any ways to wake from STOP mode and get back to full speed HSI in under 50 μS? What is the most efficient method to set the clocks when waking from STOP?

Currently I use the method prescribed in the PWR_STOP example which is as follows:

/* Enter Stop Mode */
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);

/* Stop interrupt that woke us up */
int ret = HAL_LPTIM_TimeOut_Stop_IT(&LptimHandle);
SystemDisableWakeupCounter();

/* Configures system clock after wake-up from STOP: enable HSI, PLL and select
PLL as system clock source (HSI and PLL are disabled automatically in STOP mode) */
SystemClockConfig_STOP();

The call to SystemClockConfig_STOP() in turn calls SystemClock_Config() which configures the clocks and includes this long delay in HAL_RCC_OscConfig(&RCC_OscInitStruct).

Many thanks in advance for any assistance offered.

Bence Kaulics
  • 7,066
  • 7
  • 33
  • 63
PsyUk
  • 43
  • 5

2 Answers2

2

Well, the datasheet says PLL locking can take up to 160 μs, so the delay will be there as long as you are trying to use PLL.

enter image description here

Do you need PLL at all?

You can configure RCC to wake up with HSI already running at 16 MHz (see the RCC_CFGR_STOPWUCK bit). You get only half the speed, but it's up and running in 6 us.

Bence Kaulics
  • 7,066
  • 7
  • 33
  • 63
  • Thanks for the reference. I do need PLL for the most part and RCC_CFGR_STOPWUCK was already set. Setting PLLState to None gives a faster wakeup and, after doing necessary tasks, I then set the PLL state to On. – PsyUk Nov 02 '16 at 09:47
1

I do not know what is your PLL source right now, but HSI16 is recommended. All from the reference manual.

The HSI16 clock signal is generated from an internal 16 MHz RC oscillator. It can be used directly as a system clock or as PLL input.

The HSI16 clock can be used after wake-up from the Stop low-power mode, this ensure a smaller wake-up time than a wake-up using MSI clock.


If you can allow the slightly higher consumption, do not disable the internal regulator. It is a compromise: faster wake-up with higher consumption or slower while saving more energy, decide which is the more important.

When exiting Stop mode by issuing an interrupt or a wakeup event, the MSI or HSI16 RC oscillator is selected as system clock depending the bit STOPWUCK in the RCC_CFGR register.

When the voltage regulator operates in low-power mode, an additional startup delay is incurred when waking up from Stop mode. By keeping the internal regulator ON during Stop mode, the consumption is higher although the startup time is reduced.


Now I suppose using the PLL is a must, but then I am afraid apart from the above mentioned you cannot do really much about the startup time. The PLL needs a certain time to lock onto the input reference clock frequency. But first the input frequency must become stable (that's why it is recommended to use the HSI16).

Instead of the blocking wait (while loop) you can use an interrupt.

An interrupt can be generated when the PLL is ready if enabled in the RCC_CIER register (see Section 7.3.5).

And while the PLL is locking you can do some tasks on 16 MHz, and the tasks requiring the full-speed can be started when the interrupt is received (finish clock configuration in the ISR).

Bence Kaulics
  • 7,066
  • 7
  • 33
  • 63
  • 1
    Thank you for the detailed information. I was already setting RCC_CFGR_STOPWUCK but I modified the wake function to not set the PLL with: RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSEState = RCC_HSE_OFF; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; RCC_OscInitStruct.HSICalibrationValue = 0x10; This woke in ~6uS. I was then able to set the GPIO I needed and then wake fully (~160uS) and carry on with the core duties. – PsyUk Nov 02 '16 at 09:39
  • re: "interrupt can be generated when the PLL is ready if enabled in the RCC_CIER register" Do you have a handy example of this? I enabled the interrupt and then entered sleep mode with systick turned off. __HAL_RCC_ENABLE_IT(RCC_IT_PLLRDY); SysTick->CTRL = 0; HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI); but I don't see an event triggered. Does it have to be linked to EXTI in some way? If I add a loop checking PLLRDY instead of waiting in sleep then I can see that the flag is set. What am I missing? – PsyUk Nov 18 '16 at 11:54
  • @PsyUk I have not used this feature myself yet, just knew about it from the reference manual which from I have quoted. I am an unable to look it up right now, but will check it on later. – Bence Kaulics Nov 18 '16 at 12:53