STM32CubeWB0: Low-power management


1. Introduction

The STM32CubeWB0 firmware provides a software framework to support all the STM32WB0 devices hardware power save modes.
Once the low-power mode is enabled in the application, the power save software combines the low-power requests coming from the application with the radio operating mode, choosing the best power save mode applicable in the current scenario. The power modes software framework enables the negotiation between the radio module and the application requests, and prevents data loss.

1.1. Supported power modes

STM32WB0 SoC supports four main PWR power modes:

  • Shutdown
  • Deepstop with no low-speed clock
  • Deepstop with low-speed clock
  • Sleep (WFI)

The power save software implements a mechanism to save and restore all the peripheral configurations and the application contexts when a power save procedure is called. So, from the application point of view, the exit from a low-power procedure is fully transparent: when a wake-up from power save occurs, the CPU executes the next instruction after the power save function call.

Info white.png Information
From the application point of view, the exit from a low-power procedure is fully transparent.
1.1.1. Shutdown mode

The shutdown level turns off the device: all voltage regulators, clocks, and the RF interface are not powered.

The only wake-up source is a low pulse on the RSTN pad or a configurable pulse on PB0 (only on STM32WB09xE devices). No smart power management is in place, because there is no memory retention in this power save level configuration.

1.1.2. Deepstop mode without low-speed clock

The Deepstop with no low-speed clock enabled configures the device in deep-sleep. All the peripherals and clock sources are turned off. A wake-up is possible only from GPIOs enabled for this scope. The supported wake-up GPIOs are the following:

  • PA0 to PA15 and PB0 to PB11 on STM32WB07xC/STM32WB06xC devices.
  • All GPIOs on STM32WB05xZ and STM32WB09xE devices.
1.1.3. Deepstop mode with low-speed clock

The deepstop with low-speed clock enabled configures the device in deep-sleep and the timer clock sources (LSI or LSE) remain running. A wake-up is possible from all GPIOs enabled for this scope, RTC, IWDG, LPUART (only on STM32WB05xZ and STM32WB09xE devices), radio IP, and the radio timer. The supported wake-up GPIOs are the following:

  • PA0 to PA15 and PB0 to PB11 on STM32WB07xC/STM32WB06xC devices.
  • All GPIOs on STM32WB05xZ and STM32WB09xE devices.
1.1.4. Sleep mode (WFI)

The sleep (WFI) configures the device in CPU halt. Only the CPU is halted. The rest of the chip continues to run normally. The chip wakes up from any interruption.

1.1. Low-power in Connectivity applications

1.1.1. Low-power manager Utility (LPM)

1.1.1.1. LPM Utility

The low-power manager provides a simple interface to receive the input from up to 32 different users and computes the lowest possible power mode the system can use. Each LPM client can request to disable or to enable Deepstop modes with low-speed clock or not when necessary. The following APIs are available:

Info white.png Information
By default, when no LPM user requests to disable Off on Stop modes, the Deepstop without low-speed clock (lowest low-power mode available) is selected.

Users can obtain the low-power mode that is going to be selected at that time withUTIL_LPM_GetMode API.

1.1.1.2. Platform interfaces

Once it is time to enter in low-power mode, the application is responsible to call UTIL_LPM_EnterLowPower. According to the lowest low-power mode available, LPM Utility calls the appropriate interface to enter Sleep or Deepstop mode at SoC level. Those interfaces have to be defined at application level (system side).

Info white.png Information
UTIL_LPM_EnterLowPower also calls low-power exit function.

The low-power platform interfaces are:

NOTE: On STM32WB0, the low-power platform interfaces are defined on files stm32wb0x_hal_pwr.[ch].

1.1.2. Low-power Stop modes for Connectivity

Both SLEEP and DEEPSTOP (with low-speed clock) are supported. As a reminder, Link Layer (2.4 GHz Radio) requires low-speed clock for Bluetooth Low Energy (BLE) periodic wake-up (adv, connected events, etc.)

1.1.2.1. Save & restore mechanism
1.1.2.1.1. CPU context registers

All the Cortex M0+ registers are saved before entering in Deepstop and restored after wake-up.

Hereafter is the description of the context save mechanism implemented on CS_contextSave() function for the STM32WB0 solution:

  • Load the CONTROL register into R2
  • Load the process stack pointer into R1
  • Switch to Main Stack Pointer
  • Store R4-R7 and LR (5 words) onto the stack
  • Move thread {r8 - r12} to {r3 - r7}
  • Store R8-R12 (5 words) onto the stack
  • Load address of struct RAM_VR into R4
  • Load the stack pointer into R3
  • Store the MSP into RAM_VR.SavedMSP (second word of the structure)
  • Store PSP, CONTROL
  • Trigger WFI (deep sleep)

Hereafter is the description of the context restore mechanism implemented on CS_contextRestore() function for the STM32WB0 solution:

  • Load address of RAM_VR into R4
  • Load the MSP from RAM_VR.SavedMSP (second word of the structure)
  • Restore the MSP from R4
  • Load PSP from the stack in R0, and load CONTROL register from the stack in R1
  • Load R8-R12 (5 words) from the stack
  • Move {r3 - r7} to {r8 - r12}
  • Load R4-R7 (4 words) from the stack
  • Load LR from the stack
  • Restore PSP from R0
  • Restore CONTROL register from R1
  • Load PC (1 words) from the stack

At wake-up, a call to CPUcontextRestore reloads all registers allowing to retrieve peripheral configuration and execution context. As a result, the next executed instruction is the one after __WFI in PWR_EnterSleepMode, PWR_EnteStopMode, PWR_EnterOffMode.

2. Interfaces

2.1. LPM Utility

The low-power manager (LPM) utility APIs are available on a files stm32_lpm.[ch]:

UTIL_LPM_Init

Description

Initialize the LPM resources..
Syntax
void UTIL_LPM_Init( void );
Parameters
None
Return value
None
UTIL_LPM_DeInit

Description

Un-initialize the LPM resources.
Syntax
void UTIL_LPM_DeInit( void );
Parameters
None
Return value
None
UTIL_LPM_GetMode

Description

This API returns the low-power mode selected that is applied when the system enters low-power mode.
Syntax
UTIL_LPM_Mode_t UTIL_LPM_GetMode( void );
Parameters
None
Return value
Type: UTIL_LPM_Mode_t
Description: LPM mode.
UTIL_LPM_SetStopMode

Description

This API notifies the low-power manager if the specified user allows the Stop mode or not (Deepstop with low-speed clock).
Syntax
void UTIL_LPM_SetStopMode( UTIL_LPM_bm_t lpm_id_bm, UTIL_LPM_State_t state );
Parameters
[in] lpm_id_bm
Type: UTIL_LPM_bm_t
Description: Identifier of the user ( 1 bit per user )
[in] state
Type: UTIL_LPM_State_t
Description: Specify whether StopMode is allowed or not by this user.
Return value
None
UTIL_LPM_SetOffMode

Description

This API notifies the low-power manager if the specified user allows the Off mode or not (Deepstop without low-speed clock).
Syntax
void UTIL_LPM_SetOffMode( UTIL_LPM_bm_t lpm_id_bm, UTIL_LPM_State_t state );
Parameters
[in] lpm_id_bm
Type: UTIL_LPM_bm_t
Description: Identifier of the user ( 1 bit per user )
[in] state
Type: UTIL_LPM_State_t
Description: Specify whether Off mode is allowed or not by this user.
Return value
None
UTIL_LPM_EnterLowPower

Description

System enters low-power mode. It is called by the low-power manager in a critical section (PRIMASK bit set) to allow the application to implement dedicated code before entering the low-power mode.
Syntax
void UTIL_LPM_EnterLowPower( void );
Parameters
None
Return value
None

2.2. Low-power platform interfaces

The following low-power functions are available on files stm32wb0x_hal_pwr.[ch]:

PWR_EnterSleepMode

Description

Interface to enter Sleep mode.In Sleep mode, all I/O pins keep the same state as in Run mode. CPU clock is off and all peripherals including Cortex-M0+ core such as NVIC and SysTick can run and wake up the CPU when an interrupt or an event occurs.
Syntax
void PWR_EnterSleepMode(void);
Parameters
None
Return value
None
PWR_ExitSleepMode

Description

Interface to exit Sleep mode.
Syntax
void PWR_ExitSleepMode(void);
Parameters
None
Return value
None
PWR_EnterStopMode

Description

Interface to enter Stop mode (Deepstop with low-speed clock).
Syntax
void PWR_EnterStopMode(void);
Parameters
None
Return value
None
PWR_ExitStopMode

Description

Interface to exit Stop mode (Deepstop with low-speed clock).
Syntax
void PWR_ExitStopMode(void);
Parameters
None
Return value
None
PWR_EnterOffMode

Description

Interface to enter Off mode (Deepstop without low-speed clock).
Syntax
void PWR_EnterOffMode(void);
Parameters
None
Return value
None
PWR_ExitOffMode

Description

Interface to exit Off mode (Deepstop without low-speed clock).
Syntax
void PWR_ExitOffMode(void);
Parameters
None
Return value
None

2.3. CPU context save & restore

The following CPU context save & restore functions are available on file cpu_context_switch.s:

CPUcontextSave

Description

It saves the current Cortex® registers context and triggers sleeping through the 'WFI' instruction.
Syntax
void CPUcontextSave(void);
Parameters
None
Return value
None
CPUcontextRestore

Description

It restores the Cortex® general purpose registers from stack.
Syntax
void CPUcontextRestore(void);
Parameters
None
Return value
None

3. How to setup low-power modes

3.1. Low-power initialization & configuration

In Connectivity applications, the low-power mode is configured in Core/Inc/app_conf.h file where the user can activate

  • CFG_FULL_LOW_POWER to deactivate incompatible features such as debugger and Nucleo LEDs.
  • CFG_LPM_SUPPORTED to activate low-power manager Utility.
  • CFG_LPM_EMULATED to emulate the Deepstop mode without losing the debugger connection and breakpoints nor watchpoints. It requires CFG_LPM_SUPPORTED to be activated.

UTIL_LPM_Init is responsible for initializing low-power manager Utility (in Core/Src/app_entry.c file). Once this is done, the user can dynamically enable or disable Stop/Off mode with UTIL_LPM_SetStopMode/UTIL_LPM_SetOffMode APIs.

3.2. Low-power entrance when IDLE

The low-power mode can only be entered when the application is in Idle mode.
To do so, UTIL_LPM_EnterLowPower has to be called.