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

0 REPLIES 0