2015-03-27 09:23 AM
It would seem VREFINT magically turns on after coming out of sleep/stop even though it is not being used on the STM32L053 (nucleo board). It turns off for the first sleep/stop, then it wont turn off again. The MCU does not even seem to know about it.
The code is a minimal repro of the issue. It is based on the tamper timestamp example. For the first stop, I get ~7.6uA. Subsequently, it uses ~9.1uA. If one comments out line 45 (HAL_PWREx_EnableUltraLowPower()), usage is ~9.1uA for both. I have the code on Github too:https://gist.github.com/leppie/f3a5a64b2cc1f3622545
/*
stm32l0xx_hal_conf.h
#define HAL_MODULE_ENABLED
#define HAL_DMA_MODULE_ENABLED
#define HAL_FLASH_MODULE_ENABLED
#define HAL_GPIO_MODULE_ENABLED
#define HAL_PWR_MODULE_ENABLED
#define HAL_RCC_MODULE_ENABLED
#define HAL_RTC_MODULE_ENABLED
#define HAL_SPI_MODULE_ENABLED
#define HAL_CORTEX_MODULE_ENABLED
*/
#include ''stm32l0xx_hal.h''
#include ''stm32l0xx_nucleo.h''
#define RTC_ASYNCH_PREDIV 0x07
#define RTC_SYNCH_PREDIV 0x0FFF
RTC_HandleTypeDef RtcHandle;
static
void
SystemClock_Config(
void
);
static
void
RTC_TimeStampConfig(
void
);
int
main(
void
)
{
HAL_Init();
SystemClock_Config();
HAL_SuspendTick();
RtcHandle.Instance = RTC;
RtcHandle.Init.HourFormat = RTC_HOURFORMAT_12;
RtcHandle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV;
RtcHandle.Init.SynchPrediv = RTC_SYNCH_PREDIV;
RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
if
(HAL_RTC_Init(&RtcHandle) != HAL_OK)
while
(1);
RTC_TimeStampConfig();
// this disables VREFINT in sleep/stop
// comment out to see the issue/difference
HAL_PWREx_EnableUltraLowPower();
while
(1)
{
// happens in sleep too
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
}
}
static
void
SystemClock_Config(
void
)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
__PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;
RCC_OscInitStruct.MSICalibrationValue = 0x00;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if
(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
while
(1);
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
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_0) != HAL_OK)
while
(1);
}
static
void
RTC_TimeStampConfig(
void
)
{
RTC_DateTypeDef sdatestructure;
RTC_TimeTypeDef stimestructure;
RTC_TamperTypeDef stamperstructure;
stamperstructure.Filter = RTC_TAMPERFILTER_DISABLE;
stamperstructure.Tamper = RTC_TAMPER_2;
stamperstructure.Trigger = RTC_TAMPERTRIGGER_RISINGEDGE;
stamperstructure.SamplingFrequency = RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV256;
stamperstructure.PrechargeDuration = RTC_TAMPERPRECHARGEDURATION_1RTCCLK ;
stamperstructure.TamperPullUp = RTC_TAMPER_PULLUP_DISABLE;
stamperstructure.TimeStampOnTamperDetection = RTC_TIMESTAMPONTAMPERDETECTION_ENABLE;
HAL_RTCEx_SetTamper(&RtcHandle, &stamperstructure);
HAL_RTCEx_SetTimeStamp_IT(&RtcHandle, RTC_TIMESTAMPEDGE_RISING, RTC_TIMESTAMPPIN_PC13);
__HAL_RTC_TIMESTAMP_CLEAR_FLAG(&RtcHandle,RTC_FLAG_TSF);
sdatestructure.Year = 0x14;
sdatestructure.Month = RTC_MONTH_APRIL;
sdatestructure.Date = 0x14;
sdatestructure.WeekDay = RTC_WEEKDAY_MONDAY;
if
(HAL_RTC_SetDate(&RtcHandle,&sdatestructure,FORMAT_BCD) != HAL_OK)
while
(1);
stimestructure.Hours = 0x08;
stimestructure.Minutes = 0x10;
stimestructure.Seconds = 0x00;
stimestructure.TimeFormat = RTC_HOURFORMAT12_AM;
stimestructure.DayLightSaving = RTC_DAYLIGHTSAVING_NONE ;
stimestructure.StoreOperation = RTC_STOREOPERATION_RESET;
if
(HAL_RTC_SetTime(&RtcHandle,&stimestructure,FORMAT_BCD) != HAL_OK)
while
(1);
}
void
HAL_RTCEx_TimeStampEventCallback(RTC_HandleTypeDef *hrtc)
{
RTC_DateTypeDef sTimeStampDateget;
RTC_TimeTypeDef sTimeStampget;
__HAL_RTC_TAMPER_CLEAR_FLAG(hrtc,RTC_FLAG_TAMP2F);
HAL_RTCEx_GetTimeStamp(&RtcHandle, &sTimeStampget, &sTimeStampDateget, FORMAT_BIN);
}
void
HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc __attribute((unused)))
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
if
(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
while
(1);
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
if
(HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
while
(1);
__HAL_RCC_RTC_ENABLE();
HAL_NVIC_SetPriority(RTC_IRQn, 0x0, 0);
HAL_NVIC_EnableIRQ(RTC_IRQn);
}
void
RTC_IRQHandler(
void
)
{
HAL_RTCEx_TamperTimeStampIRQHandler(&RtcHandle);
}
I have tried just about everything I could think of.
Any ideas?
#stm32l0x #stm32l053
2015-03-29 07:02 AM
I don't use the 'L0xx nor Cube, but can't the magic be hidden in this remark in RM0367?
PWR_CR [...] (reset by wakeup from Standby mode) JW2015-03-30 10:32 AM
Thanks for the reply, but I only use sleep/stop, not standby.
I forgot to add, I have checked all the VREFINT registers and they all report 0.I have also tried setting LPSDSR after wakeup (initial guess), but it is already on and does not have any effect, even when toggled.2015-03-30 10:57 AM
OK so what's the state of PWR_CR (namely bit ULP) after wakeup?
What happens if you explicitly set it before the next sleep? JW2015-03-31 03:56 AM
Sorry, I meant ULP in the previous reply :)
I have tried calling it coming out of sleep/stop via HAL_PWREx_EnableUltraLowPower(). The value of the register is also not changed from previously setting ULP.There is a bit of info in the reference manual that I cannot understand.For EN_VREFINT in REF_CFGR3 (10.2.3)If this bit is locked at 1 in stop mode or sleep mode, VREFINT is always ON.This seems to imply the condition I am getting, but I have no idea how it happens.