2022-05-29 07:45 PM
Hi there,
I am trying to set PU/PD resistors that will stay set while my STM32WLE is in Standby mode. Am I correct in saying that I need to use the PWR_PUCRx registers to keep the PU/PD resistors active while in Standby? If so, is there anything else that could catch me out? Eg, do I need to reset the GPIOx_PUPDR registers? Can I use the PWR_PUCRx registers while in Run mode, or should I only use the GPIOx_PUPDR registers while running?
A brief explanation of PWR_PUCRx vs GPIOx_PUPDR would be greatly appreciated. :smiling_face_with_smiling_eyes:
Thanks,
Rebecca
2022-06-01 09:02 AM
Hi @RLind.3 ,
In Standby mode, for STM32WLE, you need the PWR_PUCRx registers to keep the PU resistors active and the PWR_PDCRx registers to keep the PD resistors active. There should be no constraints if you use PWR_PUCRx or PWR_PDCRx registers in run mode. However their main purpose is to allow pull-up or pull down while being in a low power mode (GPIO clock disabled).
We can add that, the GPIOx_PUPDR is only one register for pull-up/pull-down resistors while you have PWR_PUCR (Power pull-up control register) dedicated for pull-up resistors and PWR_PDCR (Power pull-down control register) dedicated for pull-up resistors. Also, please note that the I/O pull-up and pull-down configurations defined in the PWR_PUCRx and PWR_PDCRx registers are applied only when APC bit is set in PWR control register 3.
Does this answer your question?
Kaouthar
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.
2022-06-01 12:35 PM
> low power mode (GPIO clock disabled)
Those two are unrelated and the "explanation" in parentheses is confusing.
2022-06-01 12:57 PM
Hi @KDJEM.1 ,
Thanks for your reply and explanation.
I have been doing some tests with the STM32WLE and I have found some unexpected behaviours:
The C1SBF in PWR_EXTSCR is set when I wake from Standby so I believe I am entering it correctly. I clear C1SBF each time the MCU wakes up.
Do you have any clues as to these behaviours?
Thanks,
Rebecca
2022-06-01 03:21 PM
> there is an additional 2mA drawn when I enter standby
When entering low-power mode, set DBGMCU_CR to zero and disconnect the debugger physically.
> When I use only the GPIOx_PUPDR register and enter standby, the PU/PD resistors are kept
Show the code, which enters the low-power mode and configures wake-up features.
2022-06-01 05:41 PM
Hi @Piranha ,
Thank you for your advice. I have set DBGMCU_CR to zero and that has fixed the problem of excessive current.
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 = 0xC3F4; // 1100 0011 1111 0100
// PWR->PDCRB = 0x1035; // 0001 0000 0011 0101
// PWR->PDCRC = 0x3FFF; // 0011 1111 1111 1111
// PWR->PUCRA = 0x3C0A; // 0011 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 debugging in LP modes
DBGMCU->CR = 0;
// 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 need any other code or information.
Thanks,
Rebecca