Skip to main content
ivan239955_stm1_stmicro_com
Associate III
March 11, 2016
Question

Higher consumption of STM32L052 during next sleeping (STOP mode) - SOLVED

  • March 11, 2016
  • 1 reply
  • 602 views
Posted on March 11, 2016 at 18:52

I have found a strange behavior of STM32L Low consumption 1.0 uA (as stated in the datasheet) is reached in the first sleeping with the STOP mode after reset but in sleepings that follow the first and next wake-ups the uC further consumes 2.3 uA.

It cannot depend on the external circuitry but in my minimalistic code that isolates the problem I have switched all GPIOs in the Analog Mode for sure.

#include <
stdbool.h
>
#include ''stm32l0xx_hal.h''
RTC_HandleTypeDef hrtc;
volatile bool rtcwake = false;
int wakeperiod = 5; // [s]
//--------------------------------------------------------------
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
__SYSCFG_CLK_ENABLE();
__PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = 0;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
__HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
//--------------------------------------------------------------
void MX_RTC_Init(void)
{
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
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;
HAL_RTC_Init(&hrtc);
sTime.Hours = 0x0;
sTime.Minutes = 0x0;
sTime.Seconds = 0x0;
sTime.TimeFormat = RTC_HOURFORMAT_24;
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET;
HAL_RTC_SetTime(&hrtc, &sTime, FORMAT_BIN);
sDate.WeekDay = RTC_WEEKDAY_MONDAY;
sDate.Month = RTC_MONTH_JANUARY;
sDate.Date = 0x1;
sDate.Year = 16;
HAL_RTC_SetDate(&hrtc, &sDate, FORMAT_BIN);
}
//--------------------------------------------------------------
void RTCClock_Config()
{
RCC_PeriphCLKInitTypeDef PeriphClkInit;
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
__HAL_RCC_RTC_ENABLE();
HAL_NVIC_SetPriority(RTC_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(RTC_IRQn);
}
//--------------------------------------------------------------
void DisableAllGPIO()
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pin = GPIO_PIN_All;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
//--------------------------------------------------------------
int main(void)
{
HAL_Init();
SystemClock_Config();
RTCClock_Config(); // only once, at start
DisableAllGPIO();
MX_RTC_Init();
// Disable the Power Voltage Detector(PVD)
HAL_PWR_DisablePVD();
// Enable Ultra low power mode - disable internal voltage reference
HAL_PWREx_EnableUltraLowPower();
// Select MSI as system clock source after Wake Up from Stop mode
__HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_MSI);
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, wakeperiod-1, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);
while (1)
{
HAL_Delay(1000);
HAL_SuspendTick();
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
// Waiting for wake-up *******************************
__HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF);
__HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG();
SystemClock_Config();
}
}

// stm32l0xx_it.c
#include <
stdbool.h
>
#include ''stm32l0xx_hal.h''
/* External variables --------------------------------------------------------*/
extern RTC_HandleTypeDef hrtc;
extern volatile bool rtcwake;
//--------------------------------------------------------------
void SysTick_Handler(void)
{
HAL_IncTick();
}
//--------------------------------------------------------------
void RTC_IRQHandler(void)
{
NVIC_ClearPendingIRQ(RTC_IRQn);
/* Get the pending status of the WAKEUPTIMER Interrupt */
if (__HAL_RTC_WAKEUPTIMER_GET_FLAG(&hrtc, RTC_FLAG_WUTF) != RESET)
{
/* Clear the WAKEUPTIMER interrupt pending bit */
__HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF);
rtcwake = true;
}
/* Clear the EXTI's line Flag for RTC WakeUpTimer */
__HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG();
}

Any opinion, please? Ivan
    This topic has been closed for replies.

    1 reply

    ivan239955_stm1_stmicro_com
    Associate III
    March 13, 2016
    Posted on March 14, 2016 at 00:13

    Although I do not know why, clearing of another flag in the RTC interrupt handler is important:

    void RTC_IRQHandler(void)
    {
    NVIC_ClearPendingIRQ(RTC_IRQn);
    /* Get the pending status of the WAKEUPTIMER Interrupt */
    if (__HAL_RTC_WAKEUPTIMER_GET_FLAG(&hrtc, RTC_FLAG_WUTF) != RESET)
    {
    /* Clear the WAKEUPTIMER interrupt pending bit */
    __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF);
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); // NECESSARY FOR LOW CONSUMPTION !!!
    rtcwake = true;
    }
    /* Clear the EXTI's line Flag for RTC WakeUpTimer */
    __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG();
    }