cancel
Showing results for 
Search instead for 
Did you mean: 

STM32U031F8P6 stop1 current

leddel32
Associate II

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:

  1. 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)?

  2. Any extra register bits specific to U0 that I should clear for a truly quiet STOP1 beyond the usual suspects above?

  3. Could EXTI/WKUP pins be doing this even if I didn’t configure them? Any default WKUP behavior on U031F8P6 I should double-check?

  4. 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 spikescurrent graph showing spikes

 

 

0 REPLIES 0