Skip to main content
BFich.1
Associate
January 31, 2021
Question

STM32L476RG detached Nucleo drawing 4.9mA even in Stop 2 Mode

  • January 31, 2021
  • 4 replies
  • 1112 views

The Setup

I'm working on a prototype for a battery powered application on the STM32L476. I seem to have the code working, i.e. I put the MCU in Stop 2 Mode and wake it up after a sleep interval using the RTC. I've detached the base part of the Nucleo board from the ST-Link, and am powering it with a 9V battery attached to VIN (I eventually want to use a lower voltage power supply, but am just prototyping for now). I've desoldered the LD3 LED.

The Problem

The problem is when I measure the power consumption using a multimeter, it bottoms out at 4.9mA in Stop 2 Mode, a far cry from the quoted 1.4µA.

I assume there is some peripheral that I need to disable? Or otherwise some limitation of using the Nucleo board preventing me from dropping to µA levels of consumption? Any help is much appreciated.

Here is my main.c in case it's helpful:

#include "main.h"
 
RTC_HandleTypeDef hrtc;
 
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_RTC_Init(void);
 
 
int main(void)
{
 GPIO_InitTypeDef GPIO_InitStruct;
 HAL_Init();
 SystemClock_Config();
 MX_GPIO_Init();
 MX_RTC_Init();
 
 __HAL_RCC_PWR_CLK_ENABLE();
 __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_MSI);
 
 while (1)
 {
	 __HAL_RCC_GPIOA_CLK_ENABLE();
	 __HAL_RCC_GPIOB_CLK_ENABLE();
	 __HAL_RCC_GPIOC_CLK_ENABLE();
	 __HAL_RCC_GPIOD_CLK_ENABLE();
	 __HAL_RCC_GPIOE_CLK_ENABLE();
	 __HAL_RCC_GPIOF_CLK_ENABLE();
	 __HAL_RCC_GPIOG_CLK_ENABLE();
	 __HAL_RCC_GPIOH_CLK_ENABLE();
 
	 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
	 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	 GPIO_InitStruct.Pull = GPIO_NOPULL;
	 GPIO_InitStruct.Pin = GPIO_PIN_All;
 
	 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
	 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
	 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
	 HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
	 HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
	 HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
	 HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
	 HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
 
	 __HAL_RCC_GPIOA_CLK_DISABLE();
	 __HAL_RCC_GPIOB_CLK_DISABLE();
	 __HAL_RCC_GPIOC_CLK_DISABLE();
	 __HAL_RCC_GPIOD_CLK_DISABLE();
	 __HAL_RCC_GPIOE_CLK_DISABLE();
	 __HAL_RCC_GPIOF_CLK_DISABLE();
	 __HAL_RCC_GPIOG_CLK_DISABLE();
	 __HAL_RCC_GPIOH_CLK_DISABLE();
 
	 HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
 
	 if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x4E20, RTC_WAKEUPCLOCK_RTCCLK_DIV16) != HAL_OK) {
		 Error_Handler();
	 }
	 
	 HAL_SuspendTick();
	 HAL_PWR_EnableSleepOnExit();
	 HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
 }
}
 
/**
 * @brief System Clock Configuration
 * @retval None
 */
void SystemClock_Config(void)
{
 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
 
 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;
 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
 RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
 RCC_OscInitStruct.LSIState = RCC_LSI_ON;
 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
 RCC_OscInitStruct.PLL.PLLM = 1;
 RCC_OscInitStruct.PLL.PLLN = 10;
 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
 RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
 RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 {
 Error_Handler();
 }
 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
 {
 Error_Handler();
 }
 PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_USART2;
 PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
 PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
 {
 Error_Handler();
 }
}
 
static void MX_RTC_Init(void)
{
 hrtc.Instance = RTC;
 hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
 hrtc.Init.AsynchPrediv = 127;
 hrtc.Init.SynchPrediv = 255;
 hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
 hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
 hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
 hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
 if (HAL_RTC_Init(&hrtc) != HAL_OK)
 {
 Error_Handler();
 }
}
 
static void MX_GPIO_Init(void)
{
 GPIO_InitTypeDef GPIO_InitStruct = {0};
 
 /* GPIO Ports Clock Enable */
 __HAL_RCC_GPIOC_CLK_ENABLE();
 __HAL_RCC_GPIOH_CLK_ENABLE();
 __HAL_RCC_GPIOA_CLK_ENABLE();
 __HAL_RCC_GPIOB_CLK_ENABLE();
 
 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
 
 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_RESET);
 
 /*Configure GPIO pin : B1_Pin */
 GPIO_InitStruct.Pin = B1_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);
 
 /*Configure GPIO pin : LD2_Pin */
 GPIO_InitStruct.Pin = LD2_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct);
 
 /*Configure GPIO pins : PC5 PC6 PC8 PC9 */
 GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_8|GPIO_PIN_9;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
}
 
 
 
void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) {
	// Do nothing for now, just trying to test Stop 2 Mode power consumption
}
 
void Error_Handler(void)
{
 __disable_irq();
 while (1)
 {}
}

This topic has been closed for replies.

4 replies

KnarfB
Super User
January 31, 2021

Do not use VIN for current measurement. Check the Nucleo board schematics. There is a dedicated jumper marked IDD or so connecting 3.3V to MCU VDD.

BFich.1
BFich.1Author
Associate
February 1, 2021

That makes sense for specifically measuring MCU current consumption, I will try that. But if 4.9mA is being drawn from the battery, what is causing that? Could it be the quiescent current of some regulators behind VIN? So if I can supply 3.3V directly, maybe I can avoid that ~5mA of draw?

Thank you for the help!

Uwe Bonnes
Chief
February 1, 2021

If WFI/WFE really entered here?

BFich.1
BFich.1Author
Associate
February 1, 2021

Yes I believe it is. At least it sleeps for the amount of time I set, and I observe the current drop (just not as low as I was expecting).

Piranha
Principal III
February 2, 2021

Try my recommendation from this topic:

https://community.st.com/s/question/0D53W00000947bASAQ/stm32l433-iwdg-wakes-up-from-shutdown-mode

https://community.st.com/s/article/Increased-consumption-on-low-power-modes

And disconnect the debug probe physically while you measure the consumption. =)

KnarfB
Super User
February 2, 2021

The UM2243 User manual "STM32 Nucleo expansion board for power consumption measurement" explaines how Nucleo Boards are prepared for low power current measurements. Useful even if you don't use/buy the dedicated X-NUCLEO-LPM01A expansion board.