I am trying to prove that I can put the K64 module on the FRDM board to LLS sleep mode, but when I execute the __asm("WFI") command, it skips over any sleep attempts and moves on to the next line of code.
A brief into to my code, and the order of operation: Green LED is turned on and the wake handler is supposed to turn it off. This never happens. In fact with debugger I have seen that the asm("WFI") code is practically skipped over. An external pin is supposed to be used to trigger wake on rising edge. Any help is appreciated.
[code begin]
#define GLED_ON (GPIOE_PDOR &= ~(1<< 26))
#define GLED_OFF (GPIOE_PDOR |= (1<<26) )
static void
disableRTC()
{
//This function is used when RTC is known to keep pending interrupt at startup...(erratta note)
SIM->SCGC6 |=SIM_SCGC6_RTC_MASK; // enable clock to RTC
RTC->TSR = 0x00; // dummy write to RTC TSR per errata 8068
SIM->SCGC6 &= ~SIM_SCGC6_RTC_MASK; // disable clock to RTC
}
wakeIRQHandler()
{
//Is only used to turn off the GREEN led on board
{
sleep_init()
{
PORTC_PCR11 = 0x00090102; // PTC11 Wakeup rising edge, Pull-down, rising edge reset, enable IRQ
LLWU_PE3 = 0x40; // LLWU_P11 rising edge detection
OSA_InstallIntHandler(LLWU_IRQn, wakeIRQHandler);
}
init()
{
SIM_HAL_EnableClock(SIM,kSimClockGatePortC); //For wake pin
SIM_HAL_EnableClock(SIM,kSimClockGatePortE); //For green led pin
PORTE_PCR26 = 0x00000103;
GPIOE_PDDR = (1 << 26); // Make led-green an output
GLED_ON; // Make sure green LED is on
sleep_init();
}
goto_sleep()
{
volatile unsigned int sync_read; |
LLWU_F1 = 0xFF;
LLWU_F2 = 0xFF;
SMC_PMCTRL = 0x03; // set stop mode to LLS
sync_read = SMC_PMCTRL;
sync_read++; // Silence compiler warning
__asm("WFI"); //Issue wait for interrupt asm
sync_read++; // Silence compiler warning
}
int main()
{
/*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
PE_low_level_init();
/*** End of Processor Expert internal initialization. ***/
init();
goto_sleep();
while(1);
//never get here
return 0;
}
[code end]
Hi Brian,
Please use this code to enter your lls mode:
void enter_lls(void)
{
volatile unsigned int dummyread;
/* Write to PMPROT to allow LLS power modes this write-once
bit allows the MCU to enter the LLS low power mode*/
SMC_PMPROT = SMC_PMPROT_ALLS_MASK; //0x8u
/* Set the STOPM field to 0b011 for LLS mode */
SMC_PMCTRL &= ~SMC_PMCTRL_STOPM_MASK;
SMC_PMCTRL |= SMC_PMCTRL_STOPM(0x3);
/*wait for write to complete to SMC before stopping core */
dummyread = SMC_PMCTRL;
/* Now execute the stop instruction to go into LLS */
stop();
}
void stop (void)
{
/* Set the SLEEPDEEP bit to enable deep sleep mode (STOP) */
SCB_SCR |= SCB_SCR_SLEEPDEEP_MASK;
/* WFI instruction will start entry into STOP mode */
asm("WFI");
}
You should enable the lls mode in SMC_PMPROT register, and please note, the PMPROT register can be written only once after any system reset, so you should make sure the PMPROT register has not been wrote before.
Wish it helps you!
If you still have question, please contact me!
Have a great day,
Jingjing
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Just a correction to the IRQ handler:
wakeIRQHandler()
{
//Is only used to turn off the GREEN led on board
GLED_OFF;
{