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.
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.