Getting started with LPBAM

Revision as of 11:23, 15 March 2023 by Registered User (→‎Code configuration)

This article explains the LPBAM feature, when and how to use it, it also provides code examples.

1. Introduction to LPBAM

1.1. Definition

The LPBAM stands for low-power background autonomous mode. It is an operating mode available in STM32U5 products series that allows peripherals to be functional and autonomous independently from the device power modes, down to Stop 2 mode, without any software running.

LPBAM Feature in U5.png

LPBAM subsystem can chain different operations thanks to DMA linked-list transfers.
The DMA operations can be related to:

  • Peripheral data transfer
  • Peripheral reconfiguration

1.2. Benefits

Two major advantages result from using LPBAM subsystem mechanisms:

  • Power consumption is optimized:

Bus and kernel clocks are distributed only when needed.
Most of the product can be shut down.
Analog peripherals / oscillators are powered on only when necessary.

  • CPU bandwidth is offloaded:

Peripheral configurations are done by DMA instead of CPU.
Data transfers are done by DMA instead of CPU.

1.3. Smart Run Domain (SRD)

The STM32U5 is split into two domains: CPU domain (CD) and SmartRun domain (SRD) File:Smart Run Domain.png

The SRD architecture relies on a DMA allowing autonomous operation during low-power modes down to Stop 2. This architecture also features a 32-bit AHB bus matrix that interconnects:

  • two masters:
    • the main AHB bus matrix
    • LPDMA1 (low-power DMA featuring one master port)
  • two slaves:
    • AHB3 peripherals including AHB to APB bridge connected to APB3
    • internal SRAM4
Info white.png Information
The SRAM4 is the only SRAM that can be accessed by the LPDMA1.

1.4. Peripherals supporting LPBAM

There are 2 types of peripherals :

  • Autonomous peripherals : which have clock request capability and support DMA transfer in STOP mode.
  • Passive peripherals : can only be reconfigured or used as trigger, they do not support DMA or clock request.

LPBAM is an operating mode that allows peripherals to function autonomously, independently of power modes, and without running any software. So autonomous peripherals can request their clock (kernel or bus clocks), and can then stay functional in Stop mode where the clocks are disabled by default to reduce consumption (except for LSE and LSI low-power low-speed oscillators).
The table below lists all peripherals that support LPBAM

Low-power mode Peripherals
Stop 0 and Stop 1 ADC4, ADF1, DAC1, GPDMA1, LPDMA1, LPTIMx (x = 1 to 4), LPUART1, MDF1, I2Cx (x = 1 to 4),

SPIx (x = 1 to 3), USARTx (x = 1 to 5)

Stop 2 ADC4, ADF1, DAC1, LPDMA1, LPTIM1, LPTIM3, LPTIM4, LPUART1, I2C3, SPI3
Info white.png Information
Refer to AN5652 [1] to know more about peripherals supporting LPBAM.

2. How to use LPBAM to drive LPGPIO

To follow along with this example, you will need a NUCLEO-U575 board.
Before starting the hands-on, make sure you have installed the following software :

  • STM32CubeMX 6.5.0 (minimum version)
  • STM32CubeIDE 1.9.0
  • Cube U5 software package

2.1. Block Diagram

The purpose of this example is to drive a GPIO pin (PA1) in low power domain controlled by linked-list DMA which is triggered by a low power timer LPTIM with 2 different frequencies

  • LPTIM with 50ms period
  • LPTIM with 100ms period

LPGPIO Triggered by LPTIM.png

2.2. Objectives

The purpose of this example is to demonstrate how to :

  • Configure LPBAM scenario
  • Measure the power consumption in STOP2 mode

2.3. STM32CubeMX LPBAM Configuration

To create an LPBAM application using the STM32CubeMX tool, you needs the STM32CubeMX standard view. This sets up the main application and code generation, and the LPBAM view to build the LPBAM applications.

Info white.png Information
Check AN5816 [2] and this Video [3] as it explains step by step how to configure an LPBAM application in STM32CubeMX.
  • Open STM32CubeMX and choose your board in the board selector menu :

stm32U575 board selection.png

Then choose start project with no peripheral initialization pushing on "NO" button. (To avoid generation of useless project code, the required peripherals are initialized later.)

File:peripheral initialization .png

To build an LPBAM application when TrustZone® is deactivated:

  • Choose "without TrustZone activated".
  • Click on OK.

Without TrustZone activated.png

The STM32CubeMX tool entry point is always the standard view. Opening the project manager and saving the main project is recommended. For this application:

  • Click on project manager panel.
  • Name the project LPGPIO_drive
  • For the "Project Location", save the project with the other examples in the firmware package.

At this point, the project is configured and the .IOC file is saved under the selected path. To increase the system performance, enabling the ICACHE peripheral in one-way configuration is recommended. To do this, click on the "System Core" menu, then on the "ICACHE" peripheral, and change "Mode" to "1-way (direct mapped cache)".

ICache Mode .png

To reach the highest performance, configure the system clock to the highest value. PLL 1 configuration is as follows:

  • PLLM = 1
  • PLLN = 80
  • PLLP = 2
  • PLLQ = 2
  • PLLR = 2

CubeMX-Clock Configuration.png

Choose Systick as a timebase

File:Time base Souce Systick.png

2.3.1. LPBAM scenario & configuration

At this point, the main project system is configured. On the next step, we will build the "LPGPIO driving" application. Click on the "LPBAM Scenario & Configuration" panel

File:LPBAM scenario & Configuration .png

Click on the “+ Add Application” option to add an LPBAM application
When adding an LPBAM application, the STM32CubeMX tool shows the LBPAM view. As for the standard view, it contains “LPBAM Scenario & Configuration”, “Pinout & Configuration” and “Clock Configuration” panels.

Info white.png Information
The naming chosen in the project should be reused in code-generated APIs and variables. This ensures consistency between STM32CubeMX LPBAM tool views and LPBAM generated application code.
Warning white.png Warning
It is recommended to carefully choose application naming for clear and readable generated code.

To do so :

  • Change the name of the application from LpbamAp1 to "LPGPIO_drive".
  • Change the name of the Scenario to "TrigGPIO".
  • Change the name of the Queue to "GPIOstate".

To reach the lowest power consumption regarding the hardware target, you need to shut off all unused resources through the PWR peripheral. To do so :

  • Click on the "Pinout & Configuration", then on "Power and Thermal", then on "PWR".
  • Enable the power-down for all the SRAMs, except SRAM4 and ICACHE.

File:PWR configuration.png

Now configure the LPBAM peripherals in Pinout & Configuration:

  • Click on Timers then "LPTIM1". The "LPTIM1 Mode and Configuration" window appears
  • Configure the following changes :

LPTIM configuration.png

In the “User Constants” panel, click on "add "and create three "Constants":

User constants (timer).png

Info white.png Information
Check AN5816 [2] to know how to calculate the user constants

At this point, the LPTIM only needs the LPTIM clock configuration before it can generate a PWM signal.

LPTIM1 clock config.png

The next step is to configure the LPGPIO : PA1

File:LPGPIO config.png

The next step is to configure the DMA channel that ensures the transfer of LPTIM signal to trigger the LPGPIO.
In LPBAM mode, the DMA channel must be configured in linked-list mode

File:LPDMA linked list.png

When DMA transfer is done in an infinite loop, the DMA channel execution mode should be configured in circular mode:

  • Left-click on "System core", then on "LPDMA1". Enable the "Linked-List Mode" for "CH0".
  • Click on "CH0". Then change the "Execution Mode" to "Circular" so that ADC conversion tasks are run in an infinite loop.

File:LPDMA config1.png

Next, go to "NVIC Settings" and enable "LPDMA1 SmartRun Channel 0 global interrupt". All LPBAM peripherals are now configured and ready for scenario queue building.

Info white.png Information
Note that the LPDMA is chosen because it is functionnal down to Stop2 mode.

2.3.2. Scenario queue building

STEP1 : The LPTIM1 configuration sequence for the first node is as follows:
1. Go to LPTIM1 and click on the "+" in front of Start
2. Change the function name to "Start_1".
3. Change the start Mode as "Continuous Mode"
5. Under "Trigger Configuration", keep "The Function execution is" as "Not conditioned by a trigger".

LPTIM Start 1.png

STEP2 : configure the LPTIM1 configuration sequence for the second node as follows:
1. Go to LPTIM1 and click on the "+" in front of PWM.
2. Change the function name to "PWM_1".
3. Enable the period update state, and insert 3270 as the period value.
4. Enable the pulse update state, and insert 1630 as the pulse value.
5. Under "Trigger Configuration", keep "The Function execution is" as "Not conditioned by a trigger".

LPTIM PWM 1.png

STEP3 : we will configure the LPGPIO that will be triggered by the previous LPTIM signal with 100ms period, We will create 2 nodes; one for the Set and the other for the Reset

1. Go to LPGPIO1 and click on the "+" in front of "Write Pin".
2. Change the function name to "Write_Pin_1".
3. Choose PA1 as pin Name .
4. Choose Set as pin State.
5.Under "Trigger Configuration", change "The Function execution is" from "Not conditioned by a trigger" to "Triggered on the Rising edge of the hardware Signal".
6. Change "Trigger hardware Signal is" from "EXTI line 0" to "LPTIM CH1".

LPGPIO WritePin1.png


STEP 4 : For the second node, only do the following changes :

  • Change the function name to "Write_Pin_2".
  • Choose Reset as pin State.
  • Change The function execuion to : triggered on the falling edge of the hardware signal.

LPGPIO WritePin2.png

Now, we will configure the LPTIM1 with 50ms period to trigger the LPGPIO, we chose to configure the LPTIM with 2 different frequencies to show the independence of the queue.
To do so, repeat the steps 2.3.4 and only change the period and pulse values in step 2 as following :

  • Enable the period update state, and insert 1630 as the period value.
  • Enable the pulse update state, and insert 815 as the pulse value.

LPTIM PWM 2.png

Following these steps, your queue should look like this :

File:Queue (non circular).png

Now, click on the queue and check Circular mode so put the queue in a while(1) loop.

File:Queue (circular mode) .png

Info white.png Information
Check UM1718 [4] for queues and nodes managing.
Warning white.png Warning
Respecting the order of function execution : first function, first execution is mandatory to configure the queue parameter.

At this point, the "LPGPIO driving" application is built in the STM32CubeMX LPBAM tool. It is then recommended to check the LPBAM design via the “Check LPBAM design” button. The STM32CubeMX tool checks, in the background, the consistency of the built application. It returns detected issues in the LPBAM log.

Check LPBAM design.png

Now, all the LPBAM application dependencies are configured.

2.4. Code configuration

The main and the LPBAM applications are ready to be generated.

  • Click on "GENERATE CODE" or CTRL+ S

For the LPBAM application, the generated files are :
• lpbam_lpgpio_drive.h
• lpbam_lpgpio_drive_config.c
• lpbam_lpgpio_drive_build.c
• lpbam_lpgpio_drive_config.c
They contain all the APIs needed by the main application to manage any LPBAM application correctly.

This application uses the BSP library, so you must include board resources in the main application.
Go to the main.h and add «#include "stm32u5xx_nucleo.h"» in the user section named “USER CODE BEGIN Includes”.

/* Includes ------------------------------------------------------------------*/
#include "stm32u5xx_hal.h"
/* Private includes ----------------------------------------------------------*/

In the main.c file, add «#include "lpbam_lpgpio_drive.h"» in the “USER CODE BEGIN Includes” user section.

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#include "lpbam_lpgpio_drive.h"
/* USER CODE END PTD */''''

In this application we will be using the user push-button pin (PC13) as an input with external interrupt Add the button declaration to the “USER CODE BEGIN PV” user section in main.c.

* USER CODE BEGIN PV */
/* Push Button State */
__IO uint32_t PushButtonState = PB_NOT_PRESSED;
/* USER CODE END PV */

Any additional service can be added under user codes in the main.c file. For this application, an application API is needed that:

  • Enters Stop2 mode and checks whether or not the system was in stop mode

These functionalities are added to the “USER CODE BEGIN 4” user section.

/* USER CODE BEGIN 4 */
static void Enter_Stop2_Mode(void)
{
  /* Enter the system to STOP2 mode */
  __HAL_RCC_PWR_CLK_ENABLE();
  HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);

  /* Check that the system was resumed from stop 2 */
  if (__HAL_PWR_GET_FLAG(PWR_FLAG_STOPF) == 0U)
  {
    Error_Handler();
  }

  /* Clear stop flag */
  __HAL_PWR_CLEAR_FLAG(PWR_FLAG_STOPF);

  /* Check that stop flag is cleared */
  if (__HAL_PWR_GET_FLAG(PWR_FLAG_STOPF) != 0U)
  {
    Error_Handler();
  }
}
void BSP_PB_Callback(Button_TypeDef Button)
{
  PushButtonState = PB_PRESSED;
}
/* USER CODE END 4 */

Now, add the functions declarations in the main.c under the user section named “USER CODE BEGIN PFP”.

/* USER CODE BEGIN PFP */
static void Enter_Stop2_Mode(void);
/* USER CODE END PFP */

To reach the lowest power consumption, all pins unused by the LPBAM scenario are configured in analog mode, including the debug pins. but we can use LEDs to observe the project runtime status.
To do so, in the core of the main() API, the LEDs and the push-button must be initialized using the BSP layer inside the “USER CODE BEGIN 2” user section.

/* USER CODE BEGIN 2 */
/* Initialize LED1, LED2 and LED3 : GREEN, BLUE and RED leds */
  BSP_LED_Init(LED1);
  BSP_LED_Init(LED2);
  BSP_LED_Init(LED3);
/* Initialize Push Button */
  BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);

After initializing the LEDs and the push-button, you need to call the LPBAM generated APIs to initialize, build, link, and start the LPBAM application within the “USER CODE BEGIN 2” user section.

Warning white.png Warning
It is mandatory to follow the following call sequence to make any LPBAM application run.
/*  LPBAM_LPGPIO_drive application init */
  MX_LPGPIO_drive_Init();

  /* LPBAM_LPGPIO_drive application TrigGPIO init */
  MX_LPGPIO_drive_TrigGPIO_Init();

  /* LPBAM_LPGPIO_drive application TrigGPIO build */
  MX_LPGPIO_drive_TrigGPIO_Build();

  /*  LPBAM_LPGPIO_drive application TrigGPIO link */
  MX_LPGPIO_drive_TrigGPIO_Link(&handle_LPDMA1_Channel0);

  /*  LPBAM_LPGPIO_drive application TrigGPIOstart */
  MX_LPGPIO_drive_TrigGPIO_Start(&handle_LPDMA1_Channel0);

At this point the LPBAM application is operating. Stop2 mode must be entered :

 /* Enter Stop2 mode */
  Enter_Stop2_Mode();

User push-button pin (PC.13) is configured as input with external interrupt (EXTI_Line13), falling edge. When it is pressed, the system wakes up from Stop2 mode.
The board LEDs are used to monitor the transfer status:

  • LED1 (green led) : ON at the end of the application
  • LED2 (blue led) : ON after wake up from Stop2 mode and before pressing the user push-button.
  /* Reset push button state */
  PushButtonState = PB_NOT_PRESSED;

  /* Turn LED2 on */
  BSP_LED_On(LED2);

  /* Wait for next push button press to stop the LPBAM LPGPIO_drive application TrigGPIO scenario */
  while (PushButtonState == PB_NOT_PRESSED);

  /* Turn LED2 off */
  BSP_LED_Off(LED2);

For this application, you need to call the following API also in “USER CODE BEGIN 2” user section. This stops, unlinks and de-initializes the LPBAM application and the green led turns on.

/*LPBAM_LPGPIO_drive application TrigGPIO scenario stop */
  MX_LPGPIO_drive_TrigGPIO_Stop(&handle_LPDMA1_Channel0);

  /* LPBAM_LPGPIO_driveapplication TrigGPIO scenario unlink */
  MX_LPGPIO_drive_TrigGPIO_UnLink(&handle_LPDMA1_Channel0);

  /* LPBAM_LPGPIO_drive application TrigGPIO scenario de-init */
  MX_LPGPIO_drive_TrigGPIO_DeInit();
  BSP_LED_On(LED1);
Warning white.png Warning
For this application, the DMA channel used can access only SRAM4 in the same power domain. So change the start address of the RAM to be accessible by the DMA channel

To do so, In the STM32CubeIDE go to the STM32U575ZITXQ_FLASH.ld and configure the RAM ORIGIN = 0x28000000 and the LENGTH = 16 Kbytes

File:Memory region in STM32CubeIDE.png

Since this example uses the BSP driver for the LEDs and the push-button, you have to add it to the STM32CubeIDE project.

You can simply copy the BSP file from : STM32Cube\Repository\STM32Cube_FW_U5\Drivers\BSP and paste it in your project drivers : STM32Cube\Repository\STM32Cube_FW_U5\Projects\NUCLEO-U575ZI-Q\Applications\LPBAM\LPGPIO_drive\Drivers

Now refresh the project by left clicking on the Project Name and selecting Refresh:

File:refresh F5.png

2.4.1. Compile and flash

  • Click the Build button Built.png
  • Click the Run button to execute Run.png

After downloading the code, the LPBAM scenario is repeated in infinite loop.
Using a logic analyzer, we visualized the LPTIM and LPGPIO signals

LPTIM and LPGPIO signals.png

As shown in the above image, LPGPIO0_PA1 is set or reset following to the LPTIM_PC1 signal with 50ms and 100ms periods

2.5. Power Consumption measurement

As the LPBAM targets the lowest possible power consumption, it is recommended that all unused pins are set to analog mode:
1. Click on "Pinout" and choose "Set unused GPIOs".
2. Set the highest number of GPIOs available (111 in this application).
3. Change "GPIO Type" from "Input" to "Analog".

Pinout configuration.png

GPIO Configuration.png

To measure the power consumption of the application, the STM32 Power Shield application is used to supply the Nucleo board. To do so, you need the X-NUCLEO-LPM01A [5] expansion board for power consumption measurement and its user manual [6]

Info white.png Information
Regarding the power consumption using LPBAM, check AN5845 [7] for more details.

The Power Shield is a plug-and-play solution intended to ease power consumption measurements.
Using the power shield with the STM32U575 Nucleo board in stop2 mode, we measured 4.06µA which is aligned with the datasheet [8].

Power consumption.png

3. How to use LPBAM for I2C or SPI transfer

This case is applicable when interfacing with external components like a MEM sensor for example over I2C or SPI. LPBAM and LPDMA can be used to transfer data from the peripheral into memory, and the MCU core will only wake up when the transfer is completed : Wakeup on Complete.
I2C-SPI transfer.png

For an example of SPI or I2C transfer, check the examples in the STM32U5 Cube Firmware following these paths :
1) STM32Cube\Repository\STM32Cube_FW_U5\Projects\NUCLEO-U575ZI-Q\Applications\LPBAM\LPBAM_I2C_TransmitReceive
2) STM32Cube\Repository\STM32Cube_FW_U5\Projects\NUCLEO-U575ZI-Q\Applications\LPBAM\LPBAM_SPI_TransmitReceive

4. How to use LPBAM for ADC or DAC conversion

We can also trigger ADC with a periodic timer and store the data into memory while the rest of the device is sleeping

ADC triggered by LPTIM.png

For examples of ADC or DAC, check the example in the STM32U5 Cube Firmware following this path :
STM32Cube\Repository\STM32Cube_FW_U5\Projects\NUCLEO-U575ZI-Q\Applications\LPBAM\LPBAM_ADC_TempSense
STM32Cube\Repository\STM32Cube_FW_U5\Projects\NUCLEO-U575ZI-Q\Applications\LPBAM\LPBAM_DAC_OPAMP_SigAmpli

Info white.png Information
Check AN5816 [2] for the STM32CubeMX LPBAM TempSense application description and building.

5. How to use LPBAM for LPTIM PWM ration change, Input Capture, Pulse Counter

The LPTIM can be used for timing and for output generation while the STM32 device is in low-power mode. it provides the basic functions of the STM32 general-purpose timers with the advantage of a very‑low power consumption. Additionally, when configured in Asynchronous counting mode, the LPTIM keeps running even when no internal clock source is active.

LPTIM Trigger.png

For an example of LPTIM PWM ration change, check the example in the STM32U5 Cube Firmware following this path :
STM32Cube\Repository\STM32Cube_FW_U5\Projects\NUCLEO-U575ZI-Q\Applications\LPBAM\LPBAM_LPTIM_PWMGen

Info white.png Information
Check AN4865 [9] for Low-power timer (LPTIM) applicative use cases on STM32 MCUs and MPUs.

More complex applications can be built using several DMA channels or chaining operations from different peripherals on the same channel as it is the case in AN5834 [10] which describes the LC sensor metering feature included in the STM32U5 Nucleo board NUCLEO-U575ZI-Q[11].

6. References

[[category:Getting_started_with_STM32_system_peripherals | 25]]