cancel
Showing results for 
Search instead for 
Did you mean: 

STM32WLE Standby Mode - Unresponsive at Low Voltages (<2.15V)

RLind.3
Associate III

Hi there,

I am using an STM32WLE with an input voltage range of 2 - 3.3V. It will eventually be powered by a lithium coin cell, but I am currently using a benchtop power supply. The datasheet states that both the MCU and the radio should function down to 1.8V, and my testing has confirmed this. However, I am finding that at voltages lower than 2.15V the MCU becomes unresponsive after entering Standby mode. Here are some of the behaviours I have observed at VDD < 2.15V:

  • Watchdog timer (IWDG) triggers a reset when the MCU has 'entered standby' - the option byte IWDG_STDBY is cleared, and the watchdog doesn't trigger a reset when the voltage is above 2.15V.
  • After a watchdog reset, the C1STOPF bit in PWR_EXTSCR is set, not the C1SBF. This indicates to me that the MCU is not correctly entering standby.
  • The first entry into standby mode after POR does not cause the MCU to become unresponsive, but the subsequent entry does.
  • Only a POR allows the first entry into standby to proceed correctly - reprogramming and NRST pin do not, and the MCU becomes unresponsive after entering standby for the first time.
  • The debugger appears to exacerbate the issue - when it is connected, the MCU becomes unresponsive at voltages up to 2.45V.

The code functions as expected when the voltage is above 2.15V, and enters and exits standby with no issues.

Any clues as to what could be going on would be greatly appreciated.

Thanks,

Rebecca

1 ACCEPTED SOLUTION

Accepted Solutions
RLind.3
Associate III

Hi all,

Turns out it was an issue between the seat and the steering wheel. I was looking at an updated schematic that used a pin for a different function, so my PU/PD resistors were set incorrectly. The MCU now enters and exits Standby mode correctly all the way down to 1.85V.

Thanks,

Rebecca

View solution in original post

4 REPLIES 4
Piranha
Chief II

The same thing as in the other topic - show the code, which enters the low-power mode and configures wake-up features.

Hi @Piranha​ ,

Here is my standby_begin() function:

void standby_begin(void)
{
	// Keep SRAM2
	PWR->CR3 |= PWR_CR3_RRS;
 
	// Enable WKUP1 pin PA0
	PWR->CR3 |= PWR_CR3_EWUP1;
	PWR->CR4 &= ~PWR_CR4_WP1; // Rising edge
 
	// Set SLEEPDEEP bit
	SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
 
	// Set to enter standby
	PWR->CR1 &= ~PWR_CR1_LPMS;
	PWR->CR1 |= PWR_LOWPOWERMODE_STANDBY;
 
	// Change to periodic sampling of VDD
	PWR->CR3 |= PWR_CR3_ULPEN;
 
	// Wait for radio to finish (if not under reset)
	if (!(RCC->CSR & RCC_CSR_RFRST))
	{
		while((PWR->SR2 & PWR_SR2_RFBUSYMS) && (PWR->SR2 & PWR_SR2_RFBUSYS));
 
	    // Shutdown radio
	    RCC->CSR |= RCC_CSR_RFRST;
	}
 
	// Clear wake up flags
	PWR->SCR |= 0x4907; // Clear all flags
 
	// Set all GPIO to input
        GPIOA->MODER = 0x00;
	GPIOB->MODER = 0x00;
	GPIOC->MODER = 0x00;
 
	// Set all GPIO to pull down except LEDs, ADC input, SWDIO, OSC32, WKUP1
	GPIOA->PUPDR = 0xA556AAA4; // 1010 0101 0101 1010 1010 1010 1010 0100
	GPIOB->PUPDR = 0xAAA95AAA; // 1010 1010 1010 1001 0101 1010 1010 1010
	GPIOC->PUPDR = 0x0AAAAAAA;
 
        // Use PWR PU/PD instead of GPIOx
//      PWR->PDCRA = 0xD3F4; // 1101 0011 1111 0100
//      PWR->PDCRB = 0x1035; // 0001 0000 0011 0101
//      PWR->PDCRC = 0x3FFF; // 0011 1111 1111 1111
//      PWR->PUCRA = 0x2C0A; // 0010 1100 0000 1010
//      PWR->PUCRB = 0x01C0; // 0000 0001 1100 0000
//      PWR->PUCRC = 0x0000;
//
//      GPIOA->PUPDR = 0x00;
//      GPIOB->PUPDR = 0x00;
//      GPIOC->PUPDR = 0x00;
//      PWR->CR3 |= PWR_CR3_APC;
 
	// Disable RTC alarm interrupt
	NVIC_DisableIRQ(RTC_Alarm_IRQn);
	NVIC_ClearPendingIRQ(RTC_Alarm_IRQn);
 
	// Disable radio interrupt
	NVIC_DisableIRQ(SUBGHZ_Radio_IRQn);
	NVIC_ClearPendingIRQ(SUBGHZ_Radio_IRQn);
 
	// Disable ADC interrupt
	NVIC_DisableIRQ(ADC_IRQn);
	NVIC_ClearPendingIRQ(ADC_IRQn);
 
        // Disable TIM1 interrupt
        NVIC_DisableIRQ(TIM1_CC_IRQn);
        NVIC_ClearPendingIRQ(TIM1_CC_IRQn);
 
	// Disable low power timer interrupts
	NVIC_DisableIRQ(LPTIM1_IRQn);
	NVIC_ClearPendingIRQ(LPTIM1_IRQn);
	NVIC_DisableIRQ(LPTIM2_IRQn);
	NVIC_ClearPendingIRQ(LPTIM2_IRQn);
	NVIC_DisableIRQ(LPTIM3_IRQn);
	NVIC_ClearPendingIRQ(LPTIM3_IRQn);
 
	// Disable SysTick and interrupt
	SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk);
        NVIC_ClearPendingIRQ(SysTick_IRQn);
 
        watchdog_kick();
 
	// Check low power regulator is ready
	while((PWR->SR2 & PWR_SR2_REGLPS) == 0);
 
	// Enter standby
	__WFI();
}

Please let me know if you would like any other pieces of code.

Thanks,

Rebecca

RLind.3
Associate III

Hi all,

Turns out it was an issue between the seat and the steering wheel. I was looking at an updated schematic that used a pin for a different function, so my PU/PD resistors were set incorrectly. The MCU now enters and exits Standby mode correctly all the way down to 1.85V.

Thanks,

Rebecca

The chair and the keyboard in this case... 😉

PWR_SCR register and it's bits are write-only - read and OR operations are unnecessary.

There is no point in configuring the GPIOx and NVIC registers before going into standby or shutdown modes because those will be reset immediately anyway and will not have an impact in those modes. Indeed, if you need pull-up/down to be active in those modes, you must use PWR_PUCRx/PWR_PDCRx registers and PWR_CR3_APC bit.