Hello everyone,
I have a problem with WFI instruction and deep sleep mode.Normally everything work correct, but sometimes processor ignore instruction WFI and continue work.
I use ARM Cortex-M0+ (exactly STM32L051), and below is my sleep procedure:
__ASM volatile ("cpsid i" : : : "memory"); // if WKUP pins are already high, the WUF bit will be set PWR->CSR |= PWR_CSR_EWUP2; PWR->CR |= PWR_CR_CWUF | // clear the WUF flag after 2 clock cycles PWR_CR_CSBF | // clear StandBy flag PWR_CR_ULP; // V_{REFINT} is off in low-power mode PWR->CR |= PWR_CR_LPSDSR | // PWR_CR_PDDS; // Enter Standby mode when the CPU enters deepsleep SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; // low-power mode = stop mode __WFI(); // enter low-power mode while(1) { uprintf("Interrupt loop"); }
I haven't found information on the conditions that must be met before use WFI in deep sleep mode.
Not sure, but you might have to clear the "active" bit as well.
And, you may need to clear the EXTI pending bit also.
Now I have:
EXTI->IMR = 0; // clear all interrupt mask NVIC_DisableIRQ( EXTI2_3_IRQn ); // disable interrupt from INT pin EXTI->PR |= EXTI_PR_PIF2; // clear interrupt pending flag __disable_irq(); // if WKUP pins are already high, the WUF bit will be set PWR->CSR |= PWR_CSR_EWUP2; PWR->CR |= PWR_CR_CWUF | // clear the WUF flag after 2 clock cycles PWR_CR_CSBF | // clear StandBy flag PWR_CR_ULP; // V_{REFINT} is off in low-power mode PWR->CR |= PWR_CR_LPSDSR | // PWR_CR_PDDS; // Enter Standby mode when the CPU enters deepsleep SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; // low-power mode = stop mode if(NVIC->ICPR[0]) { Send_USART("Interrupt!->"); USART_unr32(NVIC->ICPR[0]); USART_send( 0x0D ); USART_send( 0x0A ); NVIC->ICPR[0] = 64; USART_send( ' ' ); USART_unr32(NVIC->ICPR[0]); USART_send( 0x0D ); USART_send( 0x0A ); } __WFI(); // enter low-power mode
Now it's working fine, registry NVIC->ICPR[0] newer have penging bits.
I will be watching the operation of the program, but I think that this is the solution to the problem.