STM32L4 wakes up instantly from low-power sleep
Hi all,
I want to measure the power consumption on my board which has a STM32L431CC. Other than the µC, there is nothing left on the board excepted for an RC filter on the NRST pin, I removed the RTC quartz.
Inspired by the example code i found, i wrote this :
int main(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* STM32L4xx HAL library initialization:
- Configure the Flash prefetch
- Systick timer is configured by default as source of time base, but user
can eventually implement his proper time base source (a general purpose
timer for example or other time source), keeping in mind that Time base
duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
handled in milliseconds basis.
- Set NVIC Group Priority to 4
- Low Level Initialization
*/
HAL_Init();
/* Configure the system clock for the RUN mode */
SystemClock_Config();
/* Disable Prefetch Buffer */
__HAL_FLASH_PREFETCH_BUFFER_DISABLE();
/* Enable Power Clock */
__HAL_RCC_PWR_CLK_ENABLE();
/* Enable Flash power down mode during Sleep mode */
/* (uncomment this line if power consumption figures */
/* must be measured with Flash still on in Low Power */
/* Sleep mode) */
__HAL_FLASH_SLEEP_POWERDOWN_ENABLE();
/* Reset all RCC Sleep and Stop modes register to */
/* improve power consumption */
RCC->AHB1SMENR = 0x0;
RCC->AHB2SMENR = 0x0;
RCC->AHB3SMENR = 0x0;
RCC->APB1SMENR1 = 0x0;
RCC->APB1SMENR2 = 0x0;
RCC->APB2SMENR = 0x0;
/* Configure the system Power */
SystemPower_Config();
/* Reduce the System clock to below 2 MHz */
SystemClock_Decrease();
/* Suspend Tick increment to prevent wakeup by Systick interrupt. */
/* Otherwise the Systick interrupt will wake up the device within 1ms */
/* (HAL time base). */
HAL_SuspendTick();
/* Enter Sleep Mode , wake up is done once jumper is put between PA.12 (Arduino D2) and GND */
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
/* ... Low-power SLEEP mode ... */
/* System is Low Power Run mode when exiting Low Power Sleep mode,
disable low power run mode and reset the clock to initialization configuration */
HAL_PWREx_DisableLowPowerRunMode();
SystemClock_Config();
/* Re-init LED3 to toggle during Run mode */
/* Resume Tick interrupt if disabled prior to Low Power Sleep mode entry */
// HAL_ResumeTick();
}
void SystemClock_Decrease(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
/* MSI is enabled after System reset, activate PLL with MSI as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.HSEState = RCC_HSE_OFF;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_0;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
/* Select MSI as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
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;
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
/* Disable HSI to reduce power consumption since MSI is used from that point */
__HAL_RCC_HSI_DISABLE();
}
static void SystemPower_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOs clock */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_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);
/* Disable GPIOs clock */
__HAL_RCC_GPIOA_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
}So anyway, when i'm debugging I can see that the L4 is waking-up immediately after he calls the WFI instruction. Considering that I don't see any interrupt triggered in the NVIC register and that the systick interrupt is also being disabled, I don't get why the µC wakes up.
Also, when i measure my board consumption, considering that I am in low-power run mode, I have 230µA. The power spec says that we should have 112µA/MHz @2MHz. I am running at 100kHz in this mode so I would expect better performances.
