cancel
Showing results for 
Search instead for 
Did you mean: 

What could be consuming power in stop mode after flashing an STM32L073?

ron239955_stm1_st
Associate II
Posted on December 13, 2016 at 00:28

So I'm running a program on an STM32L073 that puts the device into stop mode to minimise power consumption.

After flashing the device (via ST-LinkV2) it starts up and enters stop mode where it is consuming around 135 uA

After a soft reset (reset button or program) when the device enters stop mode again it consumes the same current.

However if the power is re-cycled upon entering stop mode it consumes around 5 uA

After a soft reset it consumes the same.

So I'd appreciate views on what could be running, or how to identify what could be running, in stop mode after flashing. As I'd like to switch that off!

Pretty sure that it is actually entering stop mode in the former case as putting it into sleep mode the consumption is significantly higher than 135 uA.

(maybe something to do with RTC and backup domains,which survive normal flashing, but can't think what would cause that level of consumption).   Thanks, Ron

1 ACCEPTED SOLUTION

Accepted Solutions
Jaroslav BECKA
ST Employee
Posted on December 20, 2016 at 16:18

Hi Ron

Have you tried the example from STM32CubeL0 FW package?(STM32Cube\Repository\STM32Cube_FW_L0_V1.7.0\Projects\STM32L073RZ-Nucleo\Examples\PWR\PWR_STOP)

What consumption do you have with this example?

One thing which is removed after power-on reset is debug support in low power modes. In this case it is not enough to just comment the corresponding lines in the code. 

Also be sure to check 'Reset and run', 'Reset after download' or similar option in your IDE.

View solution in original post

6 REPLIES 6
Walid FTITI_O
Senior II
Posted on December 13, 2016 at 12:57

Hi

Segal.Ron

,

As mentionned in the datasheet device you expect the following :

– 0.43 μA Stop mode (16 wakeup lines)

– 0.86 μA Stop mode + RTC + 20 KB RAM retention)

To reproduce the same power consumption value measured, you should apply the same conditions described in the '6.3.4 supply current characteristics' part.

I presume the you missed to configureAll I/O pins in analog input mode before entering the low power mode.

you would follow this recommandation.

If the answer is correct, press correct.

-Walid F-

Posted on December 13, 2016 at 20:51

Hi Walid

Maybe I didn't explain the situation very well.  The entire board is running at 5 uA in stop mode with RTC and RAM, including the power supply, a LoRa radio and a few other parts besides (LPTIM is also running to count pulses during stop mode) .  So I'm reasonably happy with that.  (It's not possible to isolate measurement of mcu consumption on the board) The GPIO configuration is probably ok (I'm aware of low power mode requirements in that regard). However the 5 uA current is only achieved after an initial power down reset (disconnect and reconnect the power supply). It's a different story when the board restarts after flashing (via SWD) without a power recycle. In that case the board is consuming around 135 uA in stop mode.  So am looking for ideas on how to track that down and/or resolve. The issue seems unlikely to be directly related to pin consumption as the configuration in that regard is of course the same after starting via any reset mode. Thanks, Ron.

Posted on December 14, 2016 at 11:24

Hi Ron, 

You would share the main code of the application ( the part which commande the state machine of power cycle / reset/ wakeup ..and the low power mode configuration ..) to be able to help you on the subject. 

-WAlid F-

Posted on December 15, 2016 at 03:07

Hi Walid,

Thanks for getting back gain and for assistance, which is very much appreciated.  The code is quite spread out but I'll try to provide apparently relevant pieces.  You're correct, it is based on the STM / Semtech cubemx lorawan example, which implements a state machine in (middleware) lora.c. The state machine is implemented as a switch statement in an endless while loop.  This initialises the lorawan stack and radio, joins the network, transmits/receives data, then goes into state 'Sleep'. What happens in state 'Sleep' is defined in main.c.  So in the regular program path (i.e. when there are no network exceptions) I check first that the LoraWAN MAC layer is idle, set the RTC to wake-up the mcu after a period and then enter deep sleep, as follows:

(apologies the code indentation is lost)

else if ( GetMacStatus( ) == 0 ) { // Ensure internal MAC status is idle before sleeping

resetResendCount();

deepSleep(deepsleep_minutes);

Here's the deepsleep function:

/**

* @brief Sets the device in low power, stop mode

* @param uint16_t minutestosleep

* @retval None

*/

void deepSleep (uint16_t minutestosleep) {

PRINTF ('DeepSleep ..zzz.\r\n');

TimerStop( &WatchdogDelayTimer );

//HW_RTC_SetAlarm(minutestosleep * 60 * 1000); // Set Wakeup Alarm

HW_RTC_SetAlarm(minutestosleep * 60 * 100); // Set Wakeup Alarm

do {

wakeforcount = false;

LowPower_Handler();

} while (wakeforcount); // Go back to sleep if wake was a count interrupt

ENABLE_IRQ();

TimerStart(&WatchdogDelayTimer);

PRINTF ('Wakeup ..!!\r\n');

}

The do/while loop puts the mcu back to sleep after it is temporarily woken by an LPTIM interrupt, which then stores a pulse count total into an RTC backup register before going back to sleep.

Lowpower_Handler() is as follows:

void LowPower_Handler( void )

{

// DBG_GPIO_RST(GPIOB, GPIO_PIN_15);

// DBG_GPIO_RST(GPIOB, GPIO_PIN_14);

if ( LowPower_State == 0 )

{

DBG_PRINTF('dz\n');

HW_EnterStopMode( );

/* mcu dependent. to be implemented by user*/

HW_ExitStopMode();

// DBG_GPIO_SET(GPIOB, GPIO_PIN_15);

// HW_RTC_setMcuWakeUpTime( ); // Commented out as not required with RTC Alarm

}

else

{

DBG_PRINTF('z\n');

HW_EnterSleepMode( ); // Note sleep mode is > 2mA

// DBG_GPIO_SET(GPIOB, GPIO_PIN_14);

}

}

and HW_EnterStopeMode() is:

void HW_EnterStopMode( void)

{

BACKUP_PRIMASK();

DISABLE_IRQ( );

HW_DeInit( );

/*clear wake up flag*/

SET_BIT(PWR->CR, PWR_CR_CWUF);

RESTORE_PRIMASK( );

/* Enter Stop Mode */

HAL_PWR_EnterSTOPMode ( PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI );

}

HW_DeInit() is also pretty important for low power and to avoid immediately waking:

void HW_DeInit( void )

{

Radio.Sleep( );  // force the radio to sleep before de-initialising pins

Radio.IoDeInit( );

HW_SPI_DeInit( );

//HW_LPTIM_DeInit( );

HW_AdcDeInit();

vcom_DeInit( );

HW_BatGpioDeInit ( );

McuInitialized = false;

}

LPTIM must continue to run as it counts pulses from an external source during deep sleep.  HW_BatGpioDeInit configures pins that control battery voltage sensing..

Two other functions that may be relevant are SystemClock_Config and SystemPower_Config as follows:

void SystemClock_Config( void )

{

RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

RCC_OscInitTypeDef RCC_OscInitStruct = {0};

RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; // added

// Enable HSE Oscillator and Activate PLL with HSE as source

//RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSE; // changed

RCC_OscInitStruct.HSEState = RCC_HSE_OFF;

RCC_OscInitStruct.HSIState = RCC_HSI_ON;

RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; // (16MHz)

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;

//RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;

//RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;

// HSI Clock is 16MHz with 16MHz input and these parameters

RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_3;

RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

{

Error_Handler();

}

// Set Voltage scale1 as MCU will run at 32MHz

__HAL_RCC_PWR_CLK_ENABLE();

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

// Poll VOSF bit of in PWR_CSR. Wait until it is reset to 0

while (__HAL_PWR_GET_FLAG(PWR_FLAG_VOS) != RESET) {};

// Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2

// clocks dividers

RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | 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_1) != HAL_OK)

//if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)

{

Error_Handler();

}

// Added

PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2|RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_LPTIM1;

PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;

PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;

PeriphClkInit.LptimClockSelection = RCC_LPTIM1CLKSOURCE_LSE;

HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);

// SysTick_IRQn interrupt configuration

HAL_NVIC_SetPriority(SysTick_IRQn, 0x0, 0);

}

SystemPower_Config is used as part of initialisation:

static void SystemPower_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/* Enable Power Control clock */

__HAL_RCC_PWR_CLK_ENABLE();

/* Enable Ultra low power mode */

HAL_PWREx_EnableUltraLowPower();

/* Enable the fast wake up from Ultra low power mode */

HAL_PWREx_EnableFastWakeUp();

/* Enable GPIOs clock */

__HAL_RCC_GPIOA_CLK_ENABLE();

__HAL_RCC_GPIOB_CLK_ENABLE();

__HAL_RCC_GPIOC_CLK_ENABLE();

__HAL_RCC_GPIOD_CLK_ENABLE();

__HAL_RCC_GPIOH_CLK_ENABLE();

__HAL_RCC_GPIOE_CLK_ENABLE();

/* Configure all GPIO port pins in Analog Input mode (floating input trigger OFF) */

/* Note: Debug using ST-Link is not possible during the execution of this */

/* example because communication between ST-link and the device */

/* under test is done through UART. All GPIO pins are disabled (set */

/* to analog input mode) including UART I/O pins. */

GPIO_InitStructure.Pin = GPIO_PIN_All;

GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;

GPIO_InitStructure.Pull = GPIO_NOPULL;

HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);

HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);

HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);

HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);

HAL_GPIO_Init(GPIOH, &GPIO_InitStructure);

HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);

/* Disable GPIOs clock */

__HAL_RCC_GPIOA_CLK_DISABLE();

__HAL_RCC_GPIOB_CLK_DISABLE();

__HAL_RCC_GPIOC_CLK_DISABLE();

__HAL_RCC_GPIOD_CLK_DISABLE();

__HAL_RCC_GPIOH_CLK_DISABLE();

__HAL_RCC_GPIOE_CLK_DISABLE();

}

Note that if I set it into sleep mode rather than stop mode in the deepSleep() function for testing purposes, current consumption is over 2mA.

So not sure if the above is of any help at all with diagnosis. Please let me know you require anything else.  Am prepared to try almost anything to resolve!  Cheers, Ron.

Jaroslav BECKA
ST Employee
Posted on December 20, 2016 at 16:18

Hi Ron

Have you tried the example from STM32CubeL0 FW package?(STM32Cube\Repository\STM32Cube_FW_L0_V1.7.0\Projects\STM32L073RZ-Nucleo\Examples\PWR\PWR_STOP)

What consumption do you have with this example?

One thing which is removed after power-on reset is debug support in low power modes. In this case it is not enough to just comment the corresponding lines in the code. 

Also be sure to check 'Reset and run', 'Reset after download' or similar option in your IDE.

Posted on December 20, 2016 at 19:32

Hi Jaroslav, thanks, your point about debug support in low power modes is exactly what I was hoping for. So I implemented a debug de-initialisation function that has solved the problem!  As follows:

/**

* @brief This function Deinitializes Debug

* @param None

* @retval None

*/

void HW_debug_DeInit(void) {

/* sw interface off*/

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;

GPIO_InitStructure.Pull = GPIO_NOPULL;

GPIO_InitStructure.Pin = (GPIO_PIN_13 | GPIO_PIN_14);

HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);

__HAL_RCC_DBGMCU_CLK_ENABLE( );

HAL_DBGMCU_DisableDBGSleepMode( );

HAL_DBGMCU_DisableDBGStopMode( );

HAL_DBGMCU_DisableDBGStandbyMode( );

__HAL_RCC_DBGMCU_CLK_DISABLE( );

}

It is now possible to flash the device whilst retaining RTC backup register contents, which is very useful for the particular application.

The goal now is to possibly reduce the board's stop mode current even further and also run time power consumption. Longer delays in the radio stack in particular I think could benefit from a sleep based approach.

In any case, thanks again for taking the time to help.  Best wishes, Ron.