2025-08-28 12:19 AM
Hey all,
I’m trying to squeeze the lowest possible STOP1 current out of an STM32U031F8P6 (TSSOP-20), no external crystals. The board itself looks fine: in the deepest mode (Shutdown/Standby) I see < 0.5 µA, so I don’t think it’s a hardware leak.
Goal (later): run ADC at 1 kHz triggered by LPTIM1 from LSI, push to DMA (circular), and only wake after 1000 samples (DMA TC). While that runs, the core should sit in STOP1 (low-power regulator).
Problem (now, with everything stripped):
Even with a minimal firmware that goes straight to STOP1 and (supposedly) nothing enabled, I measure ~5–6 µA average at room temp. The current trace shows a baseline of ~4.2–5 µA with short spikes to ~10–12 µA every ~100 ms. That really looks like something waking up periodically.
What I see on the analyzer (≈3 V supply):
Baseline settles around 4.2–5 µA
Spikes to ~10–12 µA every ~100 ms
Average ≈ 5.2 µA
If I switch to the deepest mode, I get < 0.5 µA, which makes me think the PCB is fine and I’m just missing a setting in STOP1.
What I’ve tried/checked:
RTC/LSI/LSE: disabled
SysTick: suspended before STOP
Debug in stop/standby: disabled
Watchdogs: not started
ADC/VREFBUF: off
All common peripheral clocks (DMA/DMAMUX/LPTIM/UART/I2C/SPI/TIM): disabled
GPIOs: Analog + NOPULL, then GPIO clocks off
PVD off, Flash PD in STOP on, lowest VOS
HSI16 turned off before STOP
Questions:
On STM32U031, is there anything “hidden” that could explain a ~100 ms periodic blip in STOP1 (some default monitor/oscillator/retention I’m not switching off)?
Any extra register bits specific to U0 that I should clear for a truly quiet STOP1 beyond the usual suspects above?
Could EXTI/WKUP pins be doing this even if I didn’t configure them? Any default WKUP behavior on U031F8P6 I should double-check?
What’s a realistic STOP1 current (everything off: no RTC/LSI, no ADC, Flash PD, no debug, etc.) that I should expect on this device so I can sanity-check my ~4–5 µA baseline (between spikes)?
/* Minimal STOP1 baseline for STM32U031F8P6 — no wake sources
*
* Purpose:
* Provide a known-good ultra-low-power baseline to measure STOP1 current.
* The MCU enters STOP1 (low-power regulator) immediately with no wake sources.
*
* Expected result:
* ~1–2 µA typical at 3 V, 25 °C on a bare MCU (no external loads).
*
* Notes:
* - Do NOT enable RTC/LSE/LSI, timers, DMA, USART/I2C/SPI, or watchdogs in CubeMX.
* - SysTick is suspended to avoid periodic wake-ups.
* - All GPIOs are set to Analog + NOPULL, then GPIO port clocks are disabled.
* - ADC/VREFBUF are ensured OFF.
* - LSI/LSE/RTC are OFF to avoid periodic wake-ups and extra µA.
* - HSI16 is turned OFF before entering STOP1.
*/
#include "main.h"
/* Prototypes */
static void Minimal_Clocks_On_For_Init(void);
static void All_Gpio_Analog_NoPull_Then_Off(void);
static void Turn_Peripherals_Off(void);
int main(void)
{
HAL_Init();
/* Keep HSI16 just for early init; it will be turned off before STOP */
Minimal_Clocks_On_For_Init();
/* Prevent periodic wake-ups from SysTick; also disable debug in stop/standby */
HAL_SuspendTick();
#if defined(HAL_DBGMCU_MODULE_ENABLED)
HAL_DBGMCU_DisableDBGStopMode();
HAL_DBGMCU_DisableDBGStandbyMode();
#endif
/* Put every available pin to Analog + NOPULL and gate GPIO clocks */
All_Gpio_Analog_NoPull_Then_Off();
/* Make sure all potential leaky IPs and clocks are OFF */
Turn_Peripherals_Off();
/* Lowest voltage scaling allowed saves some nA/µA (if supported) */
#if defined(PWR_REGULATOR_VOLTAGE_SCALE4)
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE4);
#elif defined(PWR_REGULATOR_VOLTAGE_SCALE3)
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE3);
#endif
/* Put Flash into power-down during STOP (if supported on this device) */
#if defined(PWR_FLASHPD_STOP)
HAL_PWREx_EnableFlashPowerDown(PWR_FLASHPD_STOP);
#endif
/* HSI16 OFF before entering STOP — not needed while sleeping */
__HAL_RCC_HSI_DISABLE();
while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) {}
/* --- Measure here: device remains in STOP1 with no wake sources --- */
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
/* Should not wake; if it does (e.g., external noise), re-enter STOP1 */
for (;;)
{
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
}
}
/* ---------- Helpers ---------- */
static void Minimal_Clocks_On_For_Init(void)
{
/* Ensure HSI16 is ON for register access; do not set PLL/LSE/LSI */
__HAL_RCC_HSI_ENABLE();
while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) {}
}
static void All_Gpio_Analog_NoPull_Then_Off(void)
{
/* STM32U031F8P6 (TSSOP20) exposes GPIOA and GPIOB */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitTypeDef g = {0};
g.Mode = GPIO_MODE_ANALOG;
g.Pull = GPIO_NOPULL;
g.Speed = GPIO_SPEED_FREQ_LOW;
g.Pin = GPIO_PIN_ALL;
HAL_GPIO_Init(GPIOA, &g);
HAL_GPIO_Init(GPIOB, &g);
/* Disable GPIO port clocks to minimize leakage in STOP */
__HAL_RCC_GPIOA_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
}
static void Turn_Peripherals_Off(void)
{
/* Ensure ADC is fully disabled; also disable VREFBUF if present */
#if defined(ADC1)
__HAL_RCC_ADC_CLK_ENABLE();
if (READ_BIT(ADC1->CR, ADC_CR_ADEN))
{
SET_BIT(ADC1->CR, ADC_CR_ADDIS);
while (READ_BIT(ADC1->CR, ADC_CR_ADEN)) {}
}
__HAL_RCC_ADC_CLK_DISABLE();
#endif
#if defined(VREFBUF)
__HAL_RCC_VREF_CLK_ENABLE();
CLEAR_BIT(VREFBUF->CSR, VREFBUF_CSR_ENVR); /* VREFBUF off */
__HAL_RCC_VREF_CLK_DISABLE();
#endif
/* RTC/LSI/LSE OFF: avoids periodic wake-ups and extra microamps */
#if defined(__HAL_RCC_RTC_DISABLE)
__HAL_RCC_RTC_DISABLE();
#endif
#if defined(__HAL_RCC_LSI_ENABLE)
__HAL_RCC_LSI_DISABLE();
while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET) {}
#endif
#if defined(RCC_BDCR_LSEON)
__HAL_RCC_LSE_CONFIG(RCC_LSE_OFF);
#endif
/* Do NOT start watchdogs for this baseline measurement */
/* Common IP clocks OFF (DMA/DMAMUX/LPTIM/UART/I2C/SPI/TIM) */
#ifdef __HAL_RCC_DMA1_CLK_DISABLE
__HAL_RCC_DMA1_CLK_DISABLE();
#endif
#ifdef __HAL_RCC_DMAMUX1_CLK_DISABLE
__HAL_RCC_DMAMUX1_CLK_DISABLE();
#endif
#ifdef __HAL_RCC_LPTIM1_CLK_DISABLE
__HAL_RCC_LPTIM1_CLK_DISABLE();
#endif
#ifdef __HAL_RCC_USART1_CLK_DISABLE
__HAL_RCC_USART1_CLK_DISABLE();
#endif
#ifdef __HAL_RCC_I2C1_CLK_DISABLE
__HAL_RCC_I2C1_CLK_DISABLE();
#endif
#ifdef __HAL_RCC_SPI1_CLK_DISABLE
__HAL_RCC_SPI1_CLK_DISABLE();
#endif
#ifdef __HAL_RCC_TIM1_CLK_DISABLE
__HAL_RCC_TIM1_CLK_DISABLE();
#endif
#ifdef __HAL_RCC_TIM3_CLK_DISABLE
__HAL_RCC_TIM3_CLK_DISABLE();
#endif
/* Disable PVD if enabled to shave a bit more current */
#if defined(PWR_CR2_PVDE)
CLEAR_BIT(PWR->CR2, PWR_CR2_PVDE);
#endif
}
current graph showing spikes
2025-09-01 2:15 AM
Hello @leddel32;,
Check for any enabled EXTI lines configured in interrupt or event mode, they may lead to unintended wake-ups or current spikes in STOP1 mode
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.