2025-08-17 2:33 PM
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
2025-08-18 1:26 PM
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;
}
}
2025-08-18 4:50 PM
Check FLASH wait states.
2025-08-18 10:24 PM
Hi,
wait state is 0 but i just use MSI with 2 MHz, so this should be ok?!
2025-08-18 11:51 PM
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
2025-08-19 1:05 PM
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.
2025-08-19 9:55 PM
What says the Fault Analyzer tab next to the Debug tab?
2025-08-19 10:08 PM - edited 2025-08-19 10:25 PM
Just „Hard Fault Detected“, nothing else. And the Adress 0x20001fd0 at the bottom right is the one from the MSP. So the Stack Frame is:
2025-08-19 10:25 PM
Then do it "manually", by opening the SCB peripheral in the debugger, and note the fault register values.
Worst case (your debugger has no such feature) look up the register addresses in the reference manual, and check the respective memory locations.
2025-08-19 10:33 PM - edited 2025-08-19 10:54 PM
Are there any for the Cortex M0? I read there aren‘t.