I'm struggling getting the KL26 into the WAIT power mode.
I'm using KDS 3.0 with KSDK 1.3 (because I'm midway through another project and I don't want to change now).
I'm using the FRDM-KL26Z board stock-standard, no modifications.
I'm using Processor Expert to configure everything.
I now have a clean project with just the Power Manager component added (along with any dependencies it brings in). I have created the project based on the board so the clock configurations are standard as they created out of PE. I have created 2 power modes, Run and Wait as follows:
When I use:
tPowerError = POWER_SYS_SetMode(1, kPowerManagerPolicyForcible);
I can never get the processor into wait and get it to halt what it's doing. The CPU just continues on inside the while(1) loop. Keep in mind, this is a clean simple project I created to try and isolate the problem. In wait mode, I'm expecting the CPU to stop dead in it's tracks waiting for an interrupt.
int i = 0;
tPowerError = POWER_SYS_SetMode(1, kPowerManagerPolicyForcible); //Wait
tCurrentMode = POWER_SYS_GetCurrentMode();
for (i=0; i <100;i++);
I'm clearly doing something wrong and possibly stupid - any suggestion as to why I can't get the processor to change power states using the standard PE functions would be appreciated.
Possibly you are missing executing the wfi() instruction which sets the core to the WAIT mode (?) - also interrupts should be globally disabled before doing this.
WAIT mode is done by the following commands, so check the content of the routines that you are using:
SMC_PMCTRL = (SMC_PMCTRL_STOPM_NORMAL | SMC_PMCTRL_RUNM_NORMAL);
SYSTEM_CONTROL_REGISTER &= ~(SLEEPDEEP); // NOT STOP mode
uDisable_Interrupt(); // globally disable interrupts
uEnable_Interrupt(); // enable interrupts so that the masked interrupt that became pending can be taken
Note that there is no reason not to use WAIT mode as the basic mode of operation (between interrupts) for all projects in order to save power without any performance disadvantage.
KL26 Low Power video: https://www.youtube.com/watch?v=kWNlsAoMly4
Optimised low power response video: https://www.youtube.com/watch?v=v4UnfcDiaE4
P.S: Changing to the uTasker project framework would probably reduce your overall project time even if you have half-finished with less advanced solutions ;-)
Thanks for response Mark,
I am using the Processor Expert component and functions in KDS. I call the POWER_SYS_SetMode(...) and when I step through it with the debugger, it seems to do all of what you say needs to be done, including disabling interrupts. Towards the end, way down in the fsl_smc_hal.c file, the following is called which would indicate WFI is happening:
/* For wait modes. */
/* Clear the SLEEPDEEP bit to disable deep sleep mode - enter wait mode*/
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
* Ensure that all register writes associated with setting up the
* low power mode being entered have completed before the MCU enters
* the low power mode.
dummyRead = SMC_RD_PMCTRL(base);
dummyRead = dummyRead;
Are you aware of any problem using these functions or is there something I need to be doing with some other component first? Or are there any limitations with the clock mode I need to be in, that sort of thing?
I can't see where to attach my project to this thread if it would help? It is in KDS 3.0 though.
If WFI() is being executed I expect that the core will be moving to the WAIT state (the rest should not affect this in any great detail) so it may be that it is immediately waking again (due to an interrupt that is pending) and thus looking like it doesn't work.
If you don't find a solution/explanation you can get support to solve problems also for PE generated code at http://www.utasker.com/support.html