Skip to main content
Visitor II
August 17, 2025
Question

Hard Fault after exiting Low Power Sleep Mode

  • August 17, 2025
  • 4 replies
  • 845 views

Hi,

I'm using a STM32L031. When I'm entering the low power sleep mode und an interrupt occurs i'm getting a hard fault. The programm counter from the stack frame has ether the value 0x00000000 or is pointing at the __ISB after the __WFI - depending on the version i'm using. At the beginning i was using Enter_LP_Sleep1() getting 0x00000000. Then i found a blog discussion where they described the entering procedure of version Enter_LP_Sleep2(). This worked for my project and i thought the problem was solved. Unfortunately every now and then i got the problem with the hard fault again (depending on temperature?!). Now I stripped the code down to the following where i always get the hard fault.

int main(void){
	FLASH->ACR |= FLASH_ACR_PRFTEN;
	RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
	RCC->APB1ENR |= RCC_APB1ENR_PWREN;
	RCC->APB1SMENR = 0;
	RCC->APB2SMENR = 0;
	RCC->APB2SMENR |= RCC_APB2SMENR_TIM22SMEN; 
	RCC->APB1SMENR |= RCC_APB1SMENR_PWRSMEN;
	RCC->APB2SMENR |= RCC_APB2SMENR_SYSCFGSMEN;
	RCC->APB2SMENR |= RCC_APB2SMENR_DBGSMEN;
	RCC->APB1SMENR |= RCC_APB1SMENR_LPTIM1SMEN;
	RCC->APB1SMENR |= RCC_APB1SMENR_WWDGSMEN;
	RCC->CSR |= RCC_CSR_LSION;
	while(!(RCC->CSR & RCC_CSR_LSIRDY));
	RCC->CCIPR |= RCC_CCIPR_LPTIM1SEL_0;
	RCC->APB1ENR |= RCC_APB1ENR_LPTIM1EN;
	NVIC_EnableIRQ(LPTIM1_IRQn);
	NVIC_SetPriority(LPTIM1_IRQn, 3);
	LPTIM1->CFGR |= 0b101 << 9;
	LPTIM1->IER |= 0b11;
	LPTIM1->CR |= LPTIM_CR_ENABLE;
	LPTIM1->ARR = (1156.25 / 1000)*(1500);
	LPTIM1->CMP = (1156.25 / 1000)*1000;
	LPTIM1->CR |= LPTIM_CR_SNGSTRT;

	Enter_LP_Sleep1(); // or Enter_LP_Sleep2();
	while(1);
}

void Enter_LP_Sleep1(){
	SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
	FLASH->ACR &= ~FLASH_ACR_SLEEP_PD;
	PWR->CR &= ~PWR_CR_ULP;
	PWR->CR |= PWR_CR_CWUF;
	while (FLASH->SR & FLASH_SR_BSY) {}
	PWR->CR |= PWR_CR_LPSDSR;
	__WFI();
	status_blockade = 0;
}

void Enter_LP_Sleep2(){
	SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
	FLASH->ACR &= ~FLASH_ACR_SLEEP_PD;
	PWR->CR &= ~PWR_CR_ULP;
	PWR->CR |= PWR_CR_CWUF;
	while (FLASH->SR & FLASH_SR_BSY) {}
	PWR->CR |= PWR_CR_LPSDSR;
	__disable_irq();
	__DSB();
	__WFI();
	asm ("nop");
	__ISB();
	__enable_irq();
	status_blockade = 0;
}

 Thanks in advance!

Greetings from Salzburg / Austria

    This topic has been closed for replies.

    4 replies

    BrigeiAuthor
    Visitor II
    August 18, 2025

    I also tried the Enter_LP_Sleep functions as RAM functions with the attribute __attribute__((section(".RamFunc"))) but it didn't work neather.

    As a supplement, the missing ISR from the Low Power Timer.

    void LPTIM1_IRQHandler(void) {
    	if(LPTIM1->ISR & 0b1){
    		LPTIM1->ICR = 0b1;
    	}
    	else{
    		LPTIM1->ICR = 0b1 << 1;
    	}
    }

     

     

    Graduate II
    August 18, 2025

    Check FLASH wait states.

    BrigeiAuthor
    Visitor II
    August 19, 2025

    Hi,

    wait state is 0 but i just use MSI with 2 MHz, so this should be ok?!

    Super User
    August 19, 2025

    Do you have more details about the hard fault, e.g from a fault analyzer or following Cortex-M Fault - SEGGER Knowledge Base

    hth

    KnarfB

    BrigeiAuthor
    Visitor II
    August 19, 2025

    Because it's a Cortex M0 i don't have a lot of Hard Fault information (or do i?). I get the following from the debug window.Bildschirmfoto 2025-08-19 um 22.02.35.png

    Super User
    August 20, 2025

    What says the Fault Analyzer tab next to the Debug tab?

    BrigeiAuthor
    Visitor II
    August 21, 2025

    Hi,

    i noticed, that the 2MHz for the MSI clock is to high for the low power sleep mode. Unfortunately it doesn't work neither. But i did find a work around which surprisingly works with the 2MHz as well. I just inserted another asm ("nop") after waking up (immediately after __wfi). And it definitely works - the mcu goes to sleep - i checked the current consumption.

    Greetings.