Skip to main content
Graduate
February 14, 2024
Question

Current consumption of STM32L4R5 in low power modes not as per datasheet

  • February 14, 2024
  • 7 replies
  • 4379 views

I'm attempting to enable the Stop mode on the STM32L4R5ZIP, but it appears to significantly deviate from the specifications outlined in the datasheet, exhibiting a higher current consumption ranging from 7 to 9 mA in both sleep and stop modes.
Even after setting all free pins to default mode, deactivating all GPIOs, the power consumption remains consistent. I have experimented with both FreeRTOS and a non-FreeRTOS project, yet I consistently observe a 7mA current consumption in STOP Low-Power modes.

In the FreeRTOS project, I implemented tickless mode with the following code snippet:

void PreSleepProcessing(uint32_t ulExpectedIdleTime)
{
/* Called by the kernel before it places the MCU into a sleep mode because
  configPRE_SLEEP_PROCESSING() is #defined to PreSleepProcessing().
 
  NOTE:  Additional actions can be taken here to get the power consumption
  even lower.  For example, peripherals can be turned off here, and then back
  on again in the post sleep processing function.  For maximum power saving
  ensure all unused pins are in their lowest power state. */
 
HAL_SuspendTick();
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x801, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
__disable_irq();
 __HAL_RCC_USB_OTG_FS_CLK_DISABLE();
__HAL_RCC_GPIOE_CLK_DISABLE();
__HAL_RCC_GPIOC_CLK_DISABLE();
__HAL_RCC_GPIOF_CLK_DISABLE();
__HAL_RCC_GPIOH_CLK_DISABLE();
__HAL_RCC_GPIOA_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
__HAL_RCC_GPIOG_CLK_DISABLE();
__HAL_RCC_GPIOD_CLK_DISABLE();
  HAL_PWREx_DisableVddIO2();
 
//STOP2 MODE
HAL_PWREx_EnterSTOP2Mode(PWR_SLEEPENTRY_WFI); /
}
 
void PostSleepProcessing(uint32_t ulExpectedIdleTime)
{
/* Called by the kernel when the MCU exits a sleep mode because
  configPOST_SLEEP_PROCESSING is #defined to PostSleepProcessing(). */
 
/* WAKE UP WITH RTC */
HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
 
HAL_RCC_DeInit();
__enable_irq();
 
/* resume systicks */
HAL_ResumeTick();
SystemClock_Config();
 
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
}
I would highly appreciate any insights or suggestions to minimize the current consumption in this scenario.
    This topic has been closed for replies.

    7 replies

    Super User
    February 14, 2024

    Do you have debugger connected?

    JW

    SD0509Author
    Graduate
    February 15, 2024

    Yes i do and I have enabled the debug in low power modes.
    But that doesn't justify a power consumption of 7mA in stop modes

    Super User
    February 15, 2024

    @SD0509 wrote:

     I have enabled the debug in low power modes.


    Then the low power modes are not really low power at all!

     

    @SD0509 wrote:

    But that doesn't justify a power consumption of 7mA in stop modes


    Oh yes it does - It explains it entirely!

     

    Addendum - from the Reference Manual:

    AndrewNeil_1-1708017187505.png

     

     

    Super User
    February 14, 2024

    Use this button to properly post source code:

    AndrewNeil_0-1707934668925.png

     

    What board is the chip on?

    Have you taken care to ensure that what you're measuring is just the chip and not anything else?

    SD0509Author
    Graduate
    February 15, 2024

    I am using the Nucleo STM32L4R5ZI-P board.
    I removed the jumper JP5 (labeled IDD) on the board and connected a multimeter in series to measure the MCU consumption.

    Super User
    February 15, 2024

    @SD0509 wrote:

    I removed the jumper JP5 (labelled IDD) on the board and connected a multimeter in series to measure the MCU consumption.


    Remember that's still going to measure leakage to other things on the board - in particular, the ST-Link.

    There will be directions in the User Manual on other links that will need to be broken to minimise the "stray" currents.

    You will also need to check the schematics carefully - sometimes the UM text does not tell the whole story...
    :frowning_face:

    (but these should all be on the order of uA - shouldn't account for 7mA!)

    Technical Moderator
    February 14, 2024

    Dear @SD0509 ,

    A first hypothesis, the MCU is not entering STOP mode but only sleep mode as there is an active IRQ or pending , such as the Systick used as time base for FreeRTOS . I would suggest to start by basic examples as provided in the HAL use case for standby, so we can eliminate any unnecessary debug on hardware side and also measuring only MCU IDD .  Let us know your correct environment such as the board schematics and software, we will try to help . Chokran :) 

    Cheers,

    STOne-32

    Graduate II
    February 14, 2024

    That's not actually disabling the IO's in any meaningful way..

    Turning off the clock precludes register access, it doesn't change what they are doing, or driving into.

    Change all to Analogue Input mode, where safe to do so, then disable the clock. Watch for debug pins, or those being used for telemetry or diagnostics if you need to understand what's happening internally.

    Super User
    February 15, 2024

    > But that doesn't justify a power consumption of 7mA in stop modes

    Why do you think so?

    Have you tried with disconnected debugger, after a reset (in order to clear given bits)?

    JW

    SD0509Author
    Graduate
    February 15, 2024
    void PreSleepProcessing(uint32_t ulExpectedIdleTime)
    {
    	/* Called by the kernel before it places the MCU into a sleep mode because
    	 configPRE_SLEEP_PROCESSING() is #defined to PreSleepProcessing().
    
    	 NOTE: Additional actions can be taken here to get the power consumption
    	 even lower. For example, peripherals can be turned off here, and then back
    	 on again in the post sleep processing function. For maximum power saving
    	 ensure all unused pins are in their lowest power state. */
    	HAL_DBGMCU_EnableDBGStopMode();
    	//__disable_irq();
    	LP_GPIO_Init();
    
     HAL_SuspendTick();
     HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x500B, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
    
    	//STOP2 MODE
    	HAL_PWREx_EnterSTOP2Mode(PWR_SLEEPENTRY_WFI);
    
    }
    void PostSleepProcessing(uint32_t ulExpectedIdleTime)
    {
    	/* Called by the kernel when the MCU exits a sleep mode because
    	 configPOST_SLEEP_PROCESSING is #defined to PostSleepProcessing(). */
    
    	/* WAKE UP WITH RTC */
    	//HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
    
    	MX_GPIO_Init();
    	//__enable_irq();
    	//
    	/* resume systicks */
    	HAL_ResumeTick();
    	SystemClock_Config();
    
    }

    After configuring pins to Analog mode in  LP_GPIO_Init function and adding HAL_DBGMCU_EnableDBGStopMode the power consumption dropped to 0.4mA.

    Super User
    February 15, 2024

    > It explains it entirely!

    Whoa there. It may be *one* of the explanation - others brought up valid points, too.

    JW

    Super User
    February 15, 2024

    @waclawek.jan wrote:

    It may be *one* of the explanation - others brought up valid points, too.


    It explains the current being in the many-mA range.

    I don't think the other things would explain that much excess ?

    Super User
    February 20, 2024

    I meant:

    - disconnect debugger

    - remove power

    - connect power

    JW

    SD0509Author
    Graduate
    February 21, 2024

    Thank you all ! I appreciate all your suggestions. The consumption has significantly decreased frome 7mA to 250uA.
    But I'm still puzzled by this value that differs from what is indicated in the datasheet. Do you notice anything else that might be causing this issue?
    Here's my clock configuration:
    Clock Configuration.PNG

    and this is my code snippet:

    void PreSleepProcessing(uint32_t ulExpectedIdleTime)
    {
    	/* Called by the kernel before it places the MCU into a sleep mode because
    	 configPRE_SLEEP_PROCESSING() is #defined to PreSleepProcessing().
    
    	 NOTE: Additional actions can be taken here to get the power consumption
    	 even lower. For example, peripherals can be turned off here, and then back
    	 on again in the post sleep processing function. For maximum power saving
    	 ensure all unused pins are in their lowest power state. */
    	HAL_DBGMCU_DisableDBGStopMode();
    	LP_GPIO_Init();
    	HAL_SuspendTick();
     HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x500B, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
    	//STOP2 MODE
    	HAL_PWREx_EnterSTOP2Mode(PWR_SLEEPENTRY_WFI);
    }
    void PostSleepProcessing(uint32_t ulExpectedIdleTime)
    {
    	/* Called by the kernel when the MCU exits a sleep mode because
    	 configPOST_SLEEP_PROCESSING is #defined to PostSleepProcessing(). */
    
    	/* WAKE UP WITH RTC */
    	HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
    	MX_GPIO_Init();
    	HAL_ResumeTick();
    	SystemClock_Config();
    }
    void LP_GPIO_Init(void)
    {
    
     GPIO_InitTypeDef GPIO_InitStruct = {0};
    
     /* GPIO Ports Clock Enable */
     __HAL_RCC_GPIOE_CLK_ENABLE();
     __HAL_RCC_GPIOC_CLK_ENABLE();
     __HAL_RCC_GPIOF_CLK_ENABLE();
     __HAL_RCC_GPIOH_CLK_ENABLE();
     __HAL_RCC_GPIOA_CLK_ENABLE();
     __HAL_RCC_GPIOB_CLK_ENABLE();
     __HAL_RCC_GPIOG_CLK_ENABLE();
     __HAL_RCC_GPIOD_CLK_ENABLE();
     HAL_PWREx_EnableVddIO2();
    
     /*Configure GPIO pins : PE2 PE3 PE4 PE5
     PE6 PE7 PE8 PE9
     PE10 PE11 PE12 PE13
     PE14 PE15 PE0 PE1 */
     GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5
     |GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9
     |GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13
     |GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1;
     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
    
     /*Configure GPIO pins : PC13 PC14 PC15 PC0
     PC1 PC2 PC3 PC4
     PC5 PC6 PC7 PC8
     PC9 PC10 PC11 PC12 */
     GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0
     |GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4
     |GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8
     |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    
     /*Configure GPIO pins : PF0 PF1 PF2 PF3
     PF4 PF5 PF6 PF7
     PF8 PF9 PF10 PF11
     PF12 PF13 PF14 PF15 */
     GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
     |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7
     |GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
     |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
    
     /*Configure GPIO pins : PH0 PH1 PH3 */
     GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_3;
     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
    
     /*Configure GPIO pins : PA0 PA1 PA2 PA3
     PA4 PA5 PA6 PA7
     PA8 PA9 PA10 PA11
     PA12 PA15 */
     GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
     |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7
     |GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
     |GPIO_PIN_12|GPIO_PIN_15;
     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
     /*Configure GPIO pins : PB0 PB1 PB2 PB10
     PB12 PB13 PB14 PB15
     PB3 PB4 PB5 PB6
     PB7 PB8 PB9 */
     GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10
     |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15
     |GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6
     |GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
     /*Configure GPIO pins : PG0 PG1 PG2 PG3
     PG4 PG5 PG6 PG7
     PG8 PG9 PG10 PG11
     PG12 PG13 PG14 */
     GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
     |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7
     |GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
     |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14;
     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
    
     /*Configure GPIO pins : PD8 PD9 PD10 PD11
     PD12 PD13 PD14 PD15
     PD0 PD1 PD2 PD3
     PD4 PD5 PD6 PD7 */
     GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
     |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15
     |GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
     |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
    
     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
    
     __HAL_RCC_GPIOE_CLK_DISABLE();
     __HAL_RCC_GPIOC_CLK_DISABLE();
     __HAL_RCC_GPIOF_CLK_DISABLE();
     __HAL_RCC_GPIOH_CLK_DISABLE();
     //__HAL_RCC_GPIOA_CLK_DISABLE();
     __HAL_RCC_GPIOB_CLK_DISABLE();
     __HAL_RCC_GPIOG_CLK_DISABLE();
     __HAL_RCC_GPIOD_CLK_DISABLE();
    }
    Super User
    February 21, 2024

    @SD0509 wrote:

    I'm still puzzled by this value that differs from what is indicated in the datasheet. 


    Again, the datasheet covers just the chip itself - it cannot take anything outside the chip into account.

    It also knows nothing of your application.

     


    @SD0509 wrote:

     anything else that might be causing this issue?


    See: https://community.st.com/t5/stm32-mcus-products/current-consumption-of-stm32l4r5-in-low-power-modes-not-as-per/m-p/640406/highlight/true#M235685