Skip to main content
Thomas Hoppe
Associate III
July 17, 2023
Solved

High current draw in STOP mode when RTC Alarm has been used

  • July 17, 2023
  • 7 replies
  • 4794 views

We have a very weird behavior in a battery powered IoT device. We should have a very low STOP mode current draw of 1.4 uA @ 3 VCC. The problem is, as soon as we use the RTC Alarm just once and although the alarm already fired during NORMAL operation, the current consumption is ~20 uA in STOP mode. The use of the wake up feature of the RTC does not cause this behavior, it's just alarms. Here is an example to reproduce this:

 

// Globals
volatile int alarmVal = 0;
void HAL_RTC_AlarmAEventCallback( RTC_HandleTypeDef *hrtc ) {
alarmVal = 1;
}

// Event Loop
while(1) {
RTC_AlarmTypeDef alarm;
RTC_TimeTypeDef ts;
RTC_DateTypeDef ds;

// Disable Alarm
HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_A); // Disable Interrupt
__HAL_RTC_ALARM_CLEAR_FLAG(&hrtc, RTC_FLAG_ALRAF); // Clear Flag (RTC ALARM A)
__HAL_RTC_ALARM_EXTI_CLEAR_FLAG(); // Clear Flag (EXTI)

// Get Time
do {
HAL_RTC_GetTime(&hrtc, &ts, FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &ds, FORMAT_BIN);
} while(ts.Seconds == 59); // cheat: Increment second without care of real clock

// Set Alarm
alarm.AlarmTime.SubSeconds = ts.SubSeconds; // 210
alarm.AlarmSubSecondMask = 8 << RTC_ALRMASSR_MASKSS_Pos; // 0x8000000
alarm.AlarmTime.Seconds = ts.Seconds + 1; // 27
alarm.AlarmTime.Minutes = ts.Minutes; // 0
alarm.AlarmTime.Hours = ts.Hours; // 0
alarm.AlarmDateWeekDay = ds.WeekDay; // 1
alarm.AlarmTime.TimeFormat = ts.TimeFormat; // 0
alarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE; // 0
alarm.AlarmMask = RTC_ALARMMASK_NONE; // 0
alarm.Alarm = RTC_ALARM_A; // 0x100
alarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; // 0
alarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET; // 0
HAL_RTC_SetAlarm_IT(&hrtc, &alarm, RTC_FORMAT_BIN);

// Wait Alarm
for(alarmVal = 0; !alarmVal;);
HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_A);
__HAL_RTC_ALARM_CLEAR_FLAG(&hrtc, RTC_FLAG_ALRAF);
__HAL_RTC_ALARM_EXTI_CLEAR_FLAG();

// Stop Mode
HAL_RTC_MspDeInit(&hrtc);
HW_EnterStopMode();
HAL_RTC_MspInit(&hrtc);
}

We are using the LSE clock for the RTC

We have tried multiple ways to de-init the RTC before going to STOP mode but nothing helps.

How can this be explained and resolved?

BG

 

This topic has been closed for replies.
Best answer by Thomas Hoppe

Hello @KDJEM.1 , this is not really the point of the problem and the demo I have provided. The point is that after the RTC triggered a wake-up, via Alarm or wake-up timer, the current draw was highly increased (20uA in our case). We have found the cause now which is that clearing of the Interrupt was missed:

--- Core/Src/main.c
+++ Core/Src/main.c
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
if(GPIO_Pin == Button0_Pin)
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
}

void HW_EnterStopMode() {
HAL_ADC_DeInit(&hadc);
HAL_GPIO_WritePin(DC_Conv_Mode_GPIO_Port, DC_Conv_Mode_Pin, GPIO_PIN_RESET); // useful: Disable LEDs, I2C/SPI ICs, from 900 uA

HAL_PWREx_EnableUltraLowPower(); // useful: STOP Mode from 16.3 uA to 870 nA (when RTC ALARM never fired)
HAL_PWREx_EnableFastWakeUp(); // required: To wakeup via [PA0, GPIO_EXTI0, Button0, Button Press]

+ __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); // fixes the 20 uA
__HAL_RCC_PWR_CLK_ENABLE(); // Enable power control clock

hwSlept = 1;
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
HW_ExitStopMode();
}

So with this addition in the demo code, it was solved. Can you confirm that?

7 replies

KDJEM.1
ST Technical Moderator
July 18, 2023

Hello @Thomas Hoppe ,

Could you please precise which STM32L0 device are you using? STM32L051, STM32L041...?

Please make sure to set all free pins as analog to optimize the power consumption.

For that I recommend you to take a look to How to minimize the power consumption in low power mode: An example using NUCLEO-F401RE board FAQ.

I hop this help you to solve the issue!

Kaouthar

To give better visibility on the answered topics, please click on "Best answer" on the reply which solved your issue or answered your question.
Thomas Hoppe
Associate III
July 18, 2023

Hello, we are using the STM32L071KZU6. Yes, we set al pins to analog before going to STOP mode. We have also disabled all other peripherals and could track it down to the RTC Alarm.

BG, Thomas

KDJEM.1
ST Technical Moderator
July 18, 2023

Hi @Thomas Hoppe,

The current consumption depends from the VDD and the temperature. This phenomenon is presented in the datasheet and precisely figure 19 . IDD vs VDD, at TA= 25/55/ 85/105/125 °C, Stop mode with RTC enabled and running on LSE Low drive.

For VDD=3V the current consumption range between ~1 µA and ~14.1 µA when the temperature range [-40°C 125°C]

Note that, it is mentioned in RM0377 6.3.9 Stop mode section: to minimize the consumption In Stop mode, VREFINT, the BOR, PVD, and temperature sensor can be switched off before entering Stop mode. This functionality is controlled by the ULP bit in the PWR_CR register. If the ULP bit is set, the reference is switched off on Stop mode entry and enabled again on wakeup.

For that please try to add this code line before entering in STOP mode in your main.c.

SET_BIT(PWR->CR, PWR_CR_ULP);

Please let me know if the problem is solved.

Thank you

Kaouthar

To give better visibility on the answered topics, please click on "Best answer" on the reply which solved your issue or answered your question.
Thomas Hoppe
Associate III
July 18, 2023

We have this already, because we are calling:

 

HAL_PWREx_EnableUltraLowPower() {
 SET_BIT(PWR->CR, PWR_CR_ULP);
}

 

Thomas Hoppe
Associate III
July 19, 2023

I need to add, that the problem only occurs, if we are initializing the ADC via `MX_ADC_Init();`. If we do not use the ADC, we have 1 - 2uA current draw in STOP mode. Also, we do de-init the ADC before entering STOP mode but even this does not help. I'm really having problems to see how the RTC/ ADC are related here.

Thomas Hoppe
Associate III
July 20, 2023

@KDJEM.1do you have any explanation for this behavior?

KDJEM.1
ST Technical Moderator
July 21, 2023

Hello @Thomas Hoppe ,

Could you please share you project to help you?

Thank you,

Kaouthar

To give better visibility on the answered topics, please click on "Best answer" on the reply which solved your issue or answered your question.
Thomas Hoppe
Associate III
August 2, 2023

@KDJEM.1please find the example project here: https://fx.n-fuse.co/JAHo5/BISABaKO45.zip

Thomas Hoppe
Associate III
August 8, 2023

@KDJEM.1could you reproduce the issue with my project?

KDJEM.1
ST Technical Moderator
August 9, 2023

Hello @Thomas Hoppe ,

The typical current consumption in stop mode depends on the temperature and also on the RTC and Clocks.

  • When the RTC disabled and all clocks OFF the typical current consumption, for VDD=3V, can be ranged between  0,43µA and 12.5 µA  when the temperature range [-40°C 125°C].
  • When the RTC enabled and running on LSE, the typical current consumption increased and becomes range between 1µA and 14.1µA when the temperature range [-40°C 125°C], for VDD=3V.

So, the RTC is related to current consumption in stop mode. For more explanation, please take a look to the datasheet figure 18 and 19.

Thank you.  

To give better visibility on the answered topics, please click on "Best answer" on the reply which solved your issue or answered your question.
Thomas Hoppe
Thomas HoppeAuthorBest answer
Associate III
August 10, 2023

Hello @KDJEM.1 , this is not really the point of the problem and the demo I have provided. The point is that after the RTC triggered a wake-up, via Alarm or wake-up timer, the current draw was highly increased (20uA in our case). We have found the cause now which is that clearing of the Interrupt was missed:

--- Core/Src/main.c
+++ Core/Src/main.c
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
if(GPIO_Pin == Button0_Pin)
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
}

void HW_EnterStopMode() {
HAL_ADC_DeInit(&hadc);
HAL_GPIO_WritePin(DC_Conv_Mode_GPIO_Port, DC_Conv_Mode_Pin, GPIO_PIN_RESET); // useful: Disable LEDs, I2C/SPI ICs, from 900 uA

HAL_PWREx_EnableUltraLowPower(); // useful: STOP Mode from 16.3 uA to 870 nA (when RTC ALARM never fired)
HAL_PWREx_EnableFastWakeUp(); // required: To wakeup via [PA0, GPIO_EXTI0, Button0, Button Press]

+ __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); // fixes the 20 uA
__HAL_RCC_PWR_CLK_ENABLE(); // Enable power control clock

hwSlept = 1;
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
HW_ExitStopMode();
}

So with this addition in the demo code, it was solved. Can you confirm that?

KDJEM.1
ST Technical Moderator
August 10, 2023

Hi @Thomas Hoppe ,

Glad to know that the issue is solved and thank you for your sharing the solution this may help other users.

Entering low-power mode through WFI or WFE will be executed only is no interrupt and no event is pending.

Thank you for your contribution.

Kaouthar

To give better visibility on the answered topics, please click on "Best answer" on the reply which solved your issue or answered your question.