2019-12-13 03:53 AM
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.
2023-09-12 05:39 AM
I don't think that you can use debugging in the Sleep mode
2023-09-12 06:02 AM
Hi @Steven.D ,
In case you are using the debugger, you should clear the DBG_SLEEP (bit 0), DBG_STOP (bit1) and DBG_STANBY (bit 2) bits in the DBGMCU_CR register. Some IDE set them by default and you should clear them in the application.
When activated, the core does not allow FCLK or HCLK to be turned off during a debug session. As these are required for the debugger connection, during a debug, they must remain active. The MCU integrates special means to allow the user to debug software in low-power modes.
The easiest way to reproduce the datasheet consumptions is by using the examples available the L4 Cube package STM32Cube_FW_L4_V1.xx.x\Projects\NUCLEO-L432KC\Examples\PWR. You will find examples on how to enter in different low power modes.
Best regards,
Aime