I'm using KS22 and trying to get LLS2 to function. I've tried using the fsl_smc.c routines and I've tried writing my own. I have all clock monitors disabled, and low voltage dropout disabled. I've then disabled sysTick (shouldn't matter), global interrupts, and flash prefetch. I've also ensured that any pending interrupt is serviced and no other interrupts are pending. I can get the board to enter low power mode via WFI instruction, however, as soon as I activate one of the LLWU pins, I get a system reset. Looking at the reset source, it is a core lockup reset. There is little to no documentation on the NXP side, and looking at the Arm site, there isn't much there either. I've submitted a help ticket but it has gone unanswered so hoping the community can lend some advice. Once the software determines it's time to sleep, these routines are called:
void prepareForSleep(void)
{
disableSystemTickTimer(); // Disable system tick to allow sleep/stop modes
SCB->SCR = 0x00000004; // Enable Deep sleep mode
clearWakeSource(); // Clear the wake source before we go to sleep
NVIC_EnableIRQ(LLWU_IRQ); // Enable global interrupt for LLWU
g_savedPrimask = DisableGlobalIRQ();
// __disable_irq(); // Disable Global interrupts to avoid entering flash vector table
__ISB(); // Synchronize any pre-fetched instructions
configureFlashPreFetch(false); // Disable instruction & data pre-fetch
}
void goToSleep(void)
{
__DSB(); // Clear the pipeline instructions
__WFI(); // Go to sleep and wait for Event
__ISB(); // Synchronize fetched instructions
}
void wakeFromSleep(void)
{
configureFlashPreFetch(true); // Enable instruction & data pre-fetch
EnableGlobalIRQ(g_savedPrimask);
// __enable_irq(); // Enable Global interrupts
__ISB(); // Synchronize any pre-fetched instructions
clearWakeSource(); // Clear the wake source once we are awake
SCB->SCR = 0x00000000; // Disable Deep sleep mode
NVIC_DisableIRQ(LLWU_IRQ); // Enable global interrupt for LLWU
initializeSystemTickTimer(); // Re enable system tick timer
}
已解决! 转到解答。
Ok, this is getting stranger by the hour. As shown above, I have 3 routines. What really happens is in the main() routine, it calls a single function called applicationStart(). ApplicationStart() contains all the setup code and a while(1) loop with the program function calls. The last call in the list is checkForSleep() and if that detects the correct conditions, it calls the 3 sleep routines (prepare, sleep, and wake). What appears to be happening is the board does indeed sleep and does actually wake and execute. It resumes from wake and returns to checkForSleep, which then calls wake. Wake executes and returns. But, when the system tries to return from checkForSleep to the ApplicationStart() routine, I get a reset. That tells me that the stack is messed up and the LR gets corrupted. I moved all the code to inside the while(1) loop in ApplicationStart and a similar thing happens that upon wake, I can execute any code that I want, but when it finally hits the end of the while(1) loop, it never returns to the top of the loop. The reset is gone, but I have no idea where the program is at.
Of course, this would be way easier if you could run the debugger through low power modes like you can with an ST part.
More to come
Ok, this is getting stranger by the hour. As shown above, I have 3 routines. What really happens is in the main() routine, it calls a single function called applicationStart(). ApplicationStart() contains all the setup code and a while(1) loop with the program function calls. The last call in the list is checkForSleep() and if that detects the correct conditions, it calls the 3 sleep routines (prepare, sleep, and wake). What appears to be happening is the board does indeed sleep and does actually wake and execute. It resumes from wake and returns to checkForSleep, which then calls wake. Wake executes and returns. But, when the system tries to return from checkForSleep to the ApplicationStart() routine, I get a reset. That tells me that the stack is messed up and the LR gets corrupted. I moved all the code to inside the while(1) loop in ApplicationStart and a similar thing happens that upon wake, I can execute any code that I want, but when it finally hits the end of the while(1) loop, it never returns to the top of the loop. The reset is gone, but I have no idea where the program is at.
Of course, this would be way easier if you could run the debugger through low power modes like you can with an ST part.
More to come
Ok, that was actually the solution! The program does return from the bottom of the while loop, I had disabled an output led which led to that confusion.
In the end, here is what I learned. If you want to use low power mode, you have to call the sleep function from highest execution loop and not from within 1 or 2 layers. Very strange and nowhere is this documented. Clearly, either the registers or part of the stack is corrupt or overwritten.