cancel
Showing results for 
Search instead for 
Did you mean: 

Hard Fault after exiting Low Power Sleep Mode

Brigei
Associate III

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

13 REPLIES 13

To be honest, I mostly dealt with M3 and higher in this regard.
Perhaps this can help you : https://community.arm.com/support-forums/f/embedded-and-microcontrollers-forum/3257/debugging-a-cortex-m0-hard-fault

 

Thanks for the link - i alteady read this but it didn‘t help. The code it self isn‘t that complex any more so i hoped that the problem would be obvious… just not for me ;)

I thought that i maybe do something wrong while goibg to sleep?!

> I thought that i maybe do something wrong while goibg to sleep?!

I think a problem during recovery from sleep is more likely.
Sleep modes have some side effects on peripherals, which need re-initialisation steps in some instances.

It seems you are using VS as IDE, I have no experience with debugging in this environment.
I would suggest to set a breakpoint at the wake-up, perhaps you would need to instruction/assembly mode debugging.

I very rarely work on application that employ sleep-mode, so I can't give much hints - except of a thorough read of the respective reference manual section.

Brigei
Associate III

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.