2024-04-09 06:51 AM
Hi,
I'm currently debugging what I think to be a code issue. I have a custom board with all peripherals physically disconnected and a NUCLEO-U575ZI-Q dev kit. The lowest current I see is about 250uA on both setups, with a sawtooth charge/discharge waveform from what I think is the internal switching regulator (consistent when using other stop mode functions). I've implemented a few examples for entering stop mode, and review any application notes I could find for how to handle it. Stop1 and Stop2 both yield current in the ~200uA range, and Stop3 yields about 35uA. The only way I have found to decrease the current the most were changing the "PWR_CR1_LPMS_X" parameters in the HAL_PWREx_EnterSTOP1Mode function:
Original: MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_0);
New 1: MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_1); -> Gave me <200uA on my custom board
New 2: MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_2); -> Gave me 90uA on my custom board
Changing the LPMS bit to 1 or 2 gets rid of the sawtooth waveform, but I know these bits depending on the Stop mode, so it's strange that setting a different LPMS bit eliminates that behavior?
Here is my function that handles entering Stop1:
DBGMCU->CR = 0;
RCC_OscInitTypeDef RCC_OscInitStruct;
/* Disable HSI oscillator */
// May or may not be shut off automatically depending on peripheral configuration. This ensures its off
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
GPIO_InitTypeDef GPIO_InitStruct;
// Put all GPIOs into analog state
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOI_CLK_ENABLE();
// Set parameters to be configured
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Pin = GPIO_PIN_ALL;
/* Initialize all GPIO pins */
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
/* Disable all GPIO clocks */
__HAL_RCC_GPIOA_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
__HAL_RCC_GPIOC_CLK_DISABLE();
__HAL_RCC_GPIOD_CLK_DISABLE();
__HAL_RCC_GPIOE_CLK_DISABLE();
__HAL_RCC_GPIOF_CLK_DISABLE();
__HAL_RCC_GPIOG_CLK_DISABLE();
__HAL_RCC_GPIOH_CLK_DISABLE();
__HAL_RCC_GPIOI_CLK_DISABLE();
HAL_ADC_DeInit(&hadc1);
if(huart2.gState != HAL_UART_STATE_RESET)
HAL_UART_DeInit(&huart2);
if(huart3.gState != HAL_UART_STATE_RESET)
HAL_UART_DeInit(&huart3);
if(huart4.gState != HAL_UART_STATE_RESET)
HAL_UART_DeInit(&huart4);
if(huart5.gState != HAL_UART_STATE_RESET)
HAL_UART_DeInit(&huart5);
if(hlpuart1.gState != HAL_UART_STATE_RESET)
HAL_UART_DeInit(&hlpuart1);
HAL_SuspendTick();
__HAL_RCC_PLL_DISABLE();
HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI);
HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI)
/* Check the parameters */
assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
/* Stop 1 mode */
MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_0);
/* Set SLEEPDEEP bit of Cortex System Control Register */
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
/* Select Stop mode entry */
if (STOPEntry == PWR_STOPENTRY_WFI)
{
/* Request Wait For Interrupt */
__WFI();
}
else
{
/* Request Wait For Event */
__SEV();
__WFE();
__WFE();
}
/* Reset SLEEPDEEP bit of Cortex System Control Register */
CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
I've also probed every pin on my MCU to see if there's still some leakage, and I didn't see any improvement. It seems like there's something wrong with the firmware
2024-04-15 06:29 AM
Hi @mrask
Thank you for the content furnished in your post. In RM0456, page 440, you have all the different values possible for LPMS.
The function HAL_PWREx_EnterSTOP1Mode is using the MODIFY_REG macro, which clears LPMS and set the bit LPMS0. That, way, LPMS value is now 001, or STOP1 mode.
If you want to lower your power consumption, you have to change the LPMS register value as you did, or you can use the following available functions:
Attention 1: Stop 3 mode is actually quite different, please read Tables 99 and 100 in order to check the compliancy with your application.
Attention 2: Standby and Shutdown mode will trigger an internal hardware reset during the wake up.
Hope this will help you.
Best regards,
___________________________________________________________________________________________
Alexis LOUIS
ST Embedded Software Engineer