K22F - Execution not halting after entering LLS power mode

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

K22F - Execution not halting after entering LLS power mode

Jump to solution
2,230 Views
dbwolfe
Contributor III

Hi,

 I'm having an issue where microcontroller execution doesn't seem to be halting after entering stop modes.

In debug, the SMC_SetPowerModeLls() function is returning success, and when I read the SMC->PMCTRL register it's set to 0x3, which according to the user manual is low leakage stop mode.

The power mode permissions are being set correctly to allow all power modes, which I confirmed by reading the SMC->PMPROT register, and anyways the stop abort flag in PMCTRL isn't being set when I try to enter stop mode.

And yet, after I step over SMC_SetPowerModeLls(), execution doesn't halt - I can immediately step the the next function, and the next.  The debug connection isn't interrupted.  Peripherals seem to be working.

I stuck a breakpoint in my LLWU pin interrupt handler, and it's not being triggered.  Reading SMC->PMCTRL again confirms that i'm still supposedly in LLS mode.

What's going on here? any ideas?

Some extra information - 

I'm using an MK22FN256VLH12 on a custom PCB.  Using MCUXPresso, with SDK 2.7 for MK22FN256xxx12.

-Devin

0 Kudos
1 Solution
2,004 Views
dbwolfe
Contributor III

nxf56274

mjbcswitzerland

I figured it out.  The problem was the systick interrupt waking the processor from LLS immediately.

How to enter STOP mode in KE04? 

My googlemancy failed me until I suspected systick, and then I found this post.  Apparently, the systick counter still runs even in stop modes, which may or may not be a chip/documentation errata.  In any case, I was able to fix the problem by including the following lines of code:

// Disable systick interrupts.
SysTick->CTRL &= ~(0x2);

.....................

// Enable systick interrupts.
SysTick->CTRL |= (0x2);

The disable goes before the SMC_PreEnterStopModes() function, and the enable goes after the SMC_PostExitStopModes() function.

Cortex-M4 Devices Generic User Guide | SysTick Control and Status Register – Arm Developer 

What I'm doing is clearing the TICKINT bit (bit 1) in the SYST_CSR systick control and status register to disable, and setting the same bit to enable systick after sleep.

Regards,

Devin

View solution in original post

0 Kudos
20 Replies
2,005 Views
dbwolfe
Contributor III

nxf56274

mjbcswitzerland

I figured it out.  The problem was the systick interrupt waking the processor from LLS immediately.

How to enter STOP mode in KE04? 

My googlemancy failed me until I suspected systick, and then I found this post.  Apparently, the systick counter still runs even in stop modes, which may or may not be a chip/documentation errata.  In any case, I was able to fix the problem by including the following lines of code:

// Disable systick interrupts.
SysTick->CTRL &= ~(0x2);

.....................

// Enable systick interrupts.
SysTick->CTRL |= (0x2);

The disable goes before the SMC_PreEnterStopModes() function, and the enable goes after the SMC_PostExitStopModes() function.

Cortex-M4 Devices Generic User Guide | SysTick Control and Status Register – Arm Developer 

What I'm doing is clearing the TICKINT bit (bit 1) in the SYST_CSR systick control and status register to disable, and setting the same bit to enable systick after sleep.

Regards,

Devin

0 Kudos
2,004 Views
mjbcswitzerland
Specialist V

Devin

SYSTICK doesn't operate in any low leakage modes but the thing that one needs to be aware of is that low power modes are not exited from due to interrupts, but due to 'pending' interrupts.

That means that any 'pending' interrupts may also stop entry into the low power mode. That is why I suggested using a loop so that if there were a pending interrupt (but not masked) your interrupt handler would be able to to be called to clear it and then next time in the loop it would stick.

From what you report it sounds as though you have code enabling the SYSTCK and its interrupt but you have global interrupts always masked, so that its interrupt are in fact never handled. This 'always' pending interrupt would then stop entry into low power modes. If you program the SYSTICK to not pend its interrupt (with your code change) it then solves it,but the question is why do you have SYSTICK with interrupt programmed that is never handled? Also the same could be true for any other pending interrupt in the system. Are you testing general example code that is maybe not envisaged to work in this configuration?

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]

0 Kudos
2,004 Views
dbwolfe
Contributor III

Mark,

I see what you're saying.  I'm running my own code.  I do have a handler for SYSTICK, however part of the code sequence recommended for entering stop modes is disabling global interrupts - the SMC_PreEnterStopModes() function in the SDK.  Code follows:

void SMC_PreEnterStopModes(void)
{
   g_savedPrimask = DisableGlobalIRQ();
   __ISB();
}

If that is preventing the SYSTICK handler from being called, then that would explain the problem.  The DisableGlobalIRQ() function is obviously not preventing SYSTICK from generating pending interrupts.  So, the handler is disabled, but pending interrupts can still be generated, and one is popping up before the system goes into sleep mode.

-Devin

0 Kudos
2,004 Views
mjbcswitzerland
Specialist V

Devin

It is correct that global interrupts should be disabled before moving to low power modes since it ensures no interrupts are handled 'while' in the process of moving. If the interrupt becomes pending during  this phase the low power mode is not entered and as soon as the global interrupt is unmasked it is taken. Then the low power mode should be taken again (remember the loop which should be a part of any low power enter strategy). Probably there is no loops in the examples since they are there show demonstrate the basic method and possibly won't guarantee entry for productive use. It is however strange that in your case you always had the pending interrupt (this would happen if stepping the code but very rarely when running at full speed).

The Cortex low power mode entry is good. I have always developed products using dynamic low power operation which tends to half the current consumption in general use, with no per-formance disadvantages and 100% reliability.

This is in contrast to ST Micro STR91 family which preceded their Cortex parts; in their strategy one had to enable global interrupts for wake-up to be able to occur which opens a race state when moving to sleep mode. If the interrupt that is supposed to wake up the device happens to occur at this point it will be taken and then the sleep mode entered - if this wake-up is a one-shot interrupt it then leaves the processor in sleep mode forever (wake-up event missed - hard luck). There was an errata about it which proposed a work-around of ensuring no interrupt will occur during the sleep transition - but try ensuring this when the interrupts are asynchronous and arrive form external events. It was therefore unusable.... but thanks to Cortex standardisation pretty much everything is fool-proof nowadays.

Regards

Mark

[uTasker project developer for Kinetis and i.MX RT]

0 Kudos
2,004 Views
dbwolfe
Contributor III

Mark,

I just realized I had my SYSTICK going every 1us, which explains why I was consistently getting a pending interrupt to prevent sleep. It's actually a wonder I was doing any processing at all, since I was blowing 12+ clock cycles for an interrupt and context switch every 8 clock cycles. Oops. Still, knowing that SYSTICK can prevent sleep entry.

The loop idea is intriguing. Could you lay it out in pseudocode? I'm assuming it's something like the following:

1. Disable global interrupts

2. Set up power mode registers

3. Check for pending interrupts

4. If pending, enable global interrupts to allow interrupts to be serviced

5. Disable global interrupts

6. Loop from 3 until no pending interrupts are found

7. Execute WFI instruction

Is there a convenient way to check for ANY pending interrupts, or do you just have to go down the whole list?

-Devin

0 Kudos
2,004 Views
mjbcswitzerland
Specialist V

Devin

You don't need to check for pending interrupts. You just need to retry each time there is a wake-up, or a low power mode doesn't stick (in the case of one that won't wake via normal program flow but instead by reset).

The cycle/loop (using a low power task or simply the main forever loop in a simple scheduler) is all that needs to control it - it is shown in detail in this video:
https://www.youtube.com/watch?v=v4UnfcDiaE4
The general low power functions that you have tested with my binary is shown here:
https://www.youtube.com/watch?v=kWNlsAoMly4

In the case of LLS2 and LLS3 the loop is of relevance if it doesn't make it the first time but the exit is via reset. The principle is, however, for all modes the same.

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]

0 Kudos
2,004 Views
nxf56274
NXP Employee
NXP Employee

Hi,

void LLWU_init(void)
{
      // Initialize the LLWU wakeup pin.
      LLWU_SetExternalWakeupPinMode(LLWU, 3, kLLWU_ExternalPinRisingEdge);
      // Enable LLWU interrupts.
      NVIC_EnableIRQ(LLWU_IRQn);
}

This pin may cause the problem. LLWU3 is PTA4. And its default function is NMI_b. If you do not disable the FOPT[NMI_DIS], the NMI pin reset default to enabled. So I think change the pin or disable the FOPT[NMI_DIS].

Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
2,004 Views
dbwolfe
Contributor III

I changed the flash option array in startup_mk22f25612.c as shown:

pastedImage_1.png

This should disable NMI interrupts, as well as EzPort.  I'm still seeing the same problem though.

Thanks,

Devin

0 Kudos
2,004 Views
nxf56274
NXP Employee
NXP Employee

Hi,

I think we should confirm whether our example "power_mode_switch" works well. Choose lls mode to repeat your debug operation. If work well, our code may have some problems. If not, we will think again. 

Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
2,004 Views
mjbcswitzerland
Specialist V

HI Devin

You can't use the debugger to test such low power modes.

Program the board and make a power cycle (since some settings can only be written once after a power cycle) and test without debugger.

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]

P.S. Open Source uTasker project has industrially proven low power support for immediate solutions for professional needs
- https://www.utasker.com/kinetis/FRDM-K22F.html
- https://www.utasker.com/kinetis/TWR-K22F120M.html
- https://www.utasker.com/kinetis/BLAZE_K22.html
- https://www.utasker.com/kinetis/tinyK22.html

0 Kudos
2,004 Views
dbwolfe
Contributor III

Ok, good to know.  In the past using KDS I was able to debug low power modes, and I could have sworn I'd done the same for a project on the KL26Z.  What I recall happening is that immediately after stepping over the power mode switching function, the debugger would just hang until I asserted the LLWU pin, at which point I could continue debugging as normal.

I went ahead and did as you suggested, using the GUI flash tool to write the program memory, followed by a power cycle.  I'm getting the same result - I send a command to the board that calls the power mode switching function, but instead of becoming unresponsive until a rising edge on the designated LLWU pin, my UART interface is still functioning.  This means I stepped past the power code and back into my main loop.

Here's the code for the power mode switch:

void EnterMCUSleep(void)
{
      smc_power_mode_lls_config_t llsConfig;

      // Set LLS submode to LLS3.
      llsConfig.subMode = kSMC_StopSub3;

      // Disable UART before entering LLS mode.
      UART_Deinit(CLI_UART);


      //Enter LLS mode.
      SMC_PreEnterStopModes();
      SMC_SetPowerModeLls(SMC, &llsConfig);

      // Return from LLS mode.
      SMC_PostExitStopModes();

      // Re-init UART.
      UART_0_init();
}

and previously, in my peripherals.c, a couple functions to set up the SMC and LLWU:

// Initialize power manager.
void SMC_init(void)
{
      // Set power management protections.
      SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll);
}

// Initialize low leakage wakeup unit.
void LLWU_init(void)
{
      // Initialize the LLWU wakeup pin.
      LLWU_SetExternalWakeupPinMode(LLWU, 3, kLLWU_ExternalPinRisingEdge);
      // Enable LLWU interrupts.
      NVIC_EnableIRQ(LLWU_IRQn);
}

plus the LLWU handler:

// Interrupt handler for low leakage wakeup unit. Called on a rising edge of the configured LLWU pin.
void LLWU_IRQHandler(void)
{
      g_justWokeUp = 1;
      LLWU_ClearExternalWakeupPinFlag(LLWU, 3);
}

Finally, the pin mux settings for the LLWU pin are configured to use the pin as a LLWU input.

Am I missing something?

0 Kudos
2,004 Views
mjbcswitzerland
Specialist V

Devin

The LLWU pin configuration will have nothing to do with entering into LLS, which looks like your first problem.

The code for your chip is
SMC_PMPROT = (SMC_PMPROT_LOW_POWER_LEVEL (SMC_PMPROT_AVLLS | SMC_PMPROT_ALLS | SMC_PMPROT_AVLP | SMC_PMPROT_AHSRUN);
SMC_PMCTRL = (SMC_PMCTRL_RUNM_NORMAL | SMC_PMCTRL_STOPM_LLS);

SYSTEM_CONTROL_REGISTER |= SLEEPDEEP;
asm("wfi");

Note that SMC_PMPROT is a write-once register and so if you have initialisation code that has already written it it will stop any further changes. Your device has HSRUN mode and so the SMC_PMPROT_AHSRUN flag should also be set.

After the "wfi" command the processor will move to LLS mode and this can indeed be tested with debugger connected if you don't mind the debugger disconnecting.

As you will be aware a wake-up fro LLS is always via a RESET so whether reset from a LLWU pin or RESET pin the entry into it is the same.

Once you can get the LLS mode you can then check resetting via LLWU.

See also https://www.utasker.com/kinetis/LLWU.html

In case you continue having problems please tell me which UART is connected on your custom board (or whether it supports USB device) and I can send you a binary that shows the operation in a controlled manner so that you can start from a working solution.

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]

0 Kudos
2,004 Views
dbwolfe
Contributor III

nxf56274

mjbcswitzerland

Da Li,

I used the power_mode_switch example for my code - I used all of the flow for configuration of the SMC, LLWU pin for wakeup, and entry into LLS mode.  I'm not using a FRDM board, so I will have to see if I can modify the project to work with my PCB.

Mark,

I included the LLWU setup code in my previous reply just to show that the pin was set correctly for waking from LLS, I get that it doesn't affect LLS entry.

Regarding the code snippet you included:

I confirmed that PMPROT is being set correctly.  Reading the register directly before LLS entry shows that it is set to 0xAA, which per the reference manual means that HSRUN, VLP, VLLS, and LLS modes are allowed.  In any case, I believe that if I tried to enter into a dis-allowed power mode the STOPA stop abort bit would be getting set when the PMCTRL stop mode control bits were set, and I'm not seeing that.

Digging into the SMC_SetPowerModeLls() function from the SDK, it is basically following the code you posted.  Your code explicitly sets the run mode control bits to run, and the stop mode bits to LLS, where the the SetPowerMode code just keeps the current run mode bits and sets the stop mode bits to LLS.

Next, it sets the SCR SLEEPDEEP bit, again so far so good.

Finally, it calls the SMC_EnterStopModeRamFunc.  This one confused me for a second, but it's actually pretty clever.  According to the comments, entering a stop mode can cause pre-fetched instructions or data from flash to become corrupted, so as a workaround, it loads and then executes a short assembly routine from RAM.

/*
* The ram function code is:
*
* uint32_t i;
* for (i=0; i<0x8; i++)
* {
* __NOP();
* }
* __DSB();
* __WFI();
* __ISB();
*
* When entring the stop modes, the flash prefetch might be interrupted, thus
* the prefetched code or data might be broken. To make sure the flash is idle
* when entring the stop modes, the code is moved to ram. And delay for a while
* before WFI to make sure previous flash prefetch is finished.
*
* Only need to do like this when code is in flash, if code is in rom or ram,
* this is not necessary.
*/
static uint16_t s_stopRamFuncArray[] = {
0x2000, /* MOVS R0, #0 */
0x2808, /* CMP R0, #8 */
0xD202, /* BCS.N */
0xBF00, /* NOP */
0x1C40, /* ADDS R0, R0, #1 */
0xE7FA, /* B.N */
0xF3BF, 0x8F4F, /* DSB */
0xBF30, /* WFI */
0xF3BF, 0x8F6F, /* ISB */
0x4770, /* BX LR */
};

/*******************************************************************************
* Code
******************************************************************************/
static void SMC_EnterStopRamFunc(void)
{
uint32_t ramFuncEntry = ((uint32_t)(s_stopRamFuncArray)) + 1U;
smc_stop_ram_func_t stopRamFunc = (smc_stop_ram_func_t)ramFuncEntry;
stopRamFunc();
}

The routine just loops a NOP until flash should be idle, then executes a WFI instruction.

Finally, the function checks the PMCTRL register for the STOPA stop abort bit to see if entry into the stop mode was aborted, presumably in the case that the stop mode was not one of the allowed power modes per the PMPROT register settings.  This is returning no error, and I verified by manually checking PMCTRL.  STOPA is a read only register that is persistent until the next time you write the stop mode control bits.

So, it looks like the SDK is already doing everything you suggested, although with a little fancy detour for running the subroutine from RAM to prevent flash corruption.

Just to see if there was something funny going on with the SDK code,  I commented it all out and went with your suggested snippet.

I had to modify it a little, because I apparently don't have the same defines you used.

SMC->PMCTRL = 0x03;
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
asm("wfi");

The PMPROT register is being written right after power up, so I omitted it from the code above.  Setting PMCTRL to 0x03 just configures the run mode bits for normal run mode, and the sleep mode bits for LLS. SCB_SCR_SLEEPDEEP_Msk is defined as 0x04, which is correct according to the Cortex M4 user guide.

Cortex-M4 Devices Generic User Guide | System Control Register – Arm Developer 

I'm getting the same behavior - no sleep.  I'm a little stumped at this point.  If you want to shoot me that binary, I'm using UART0 - RX on pin 23, TX on pin 24.  My wakeup pin is LLWU 3, pin 26 on the package.  Again, my part is MK22FN256VLH12, the LQFP 64 package.

Thanks,

Devin

0 Kudos
2,004 Views
mjbcswitzerland
Specialist V

Hi Devin

I have attached 2 binary file.
One for the FRDM-K22F (build for operation directly from 48MHz internal clock so that it works on any HW - and configured to use the same 48k SRAM map of your chip).
The green LED flashes at 2.5Hz when running and there is a menu on the UART (115kBaud). In the Administrator menu one can check the present low power mode and change to different ones. VLLS modes can be exited by pressing SW2 (LLUW_6) - which causes a reset.
Note however that LSS modes can only be exited by using the RESET button (see the user's manual):

pastedImage_1.png

Serial number: 00
Software version V1.4.012
Device identification: KINETIS

     Main menu
===================
1              Configure LAN interface
2              Configure serial interface
3              Go to I/O menu
4              Go to administration menu
5              Go to overview/statistics menu
6              Go to USB menu
7              Go to I2C menu
8              Go to utFAT disk interface
9              FTP/TELNET commands
a              CAN commands
help           Display menu specific help
quit           Leave command mode
4


   Admin. menu
===================
up               go to main menu
show_config      Show configuration
save             Save configuration to FLASH
reject           Reset non-saved changes
restore          Restore factory settings
show_lp          Show low power mode and options
set_lp           [option] Set low power mode
wdog             Watchdog
boot             Reset to boot loader
reset            Reset device
last_rst         Reset cause
help             Display menu specific help
quit             Leave command mode
show_lp                 <------- command to show present mode
RUN = 0
WAIT = 1 [active]
STOP = 2
VLPR = 3
VLPW = 4
VLPS = 5
LLS2 = 6
LLS3 = 7
VLLS0 = 8
VLLS1 = 9
VLLS2 = 10
VLLS3 = 11

#set_lp 8           <--- set a VLLS mode

Note that after setting low leakage modes the serial interface will not be usable. The UART does react but can't handle data rate due to wake-up time (it immediately goes back the the same mode again).

I measure the following current in some modes:
RUN mode 19mA
WAIT mode 9 mA
STOP mode 0.3mA
LLS, VLLS modes < 0.1mA

The custom binary was built with the LLWU and UARTs on the pins you specified. I don't have HW to test this but I simulated it successfully: It doesn't flash any LED though.

Note that when I load with the FRDM-K22F's open SDA I need to do a power cycle before low power modes are entered correctly - this is why I don't use the the debugger generally for low power work but this may be specific to this board and loader and not generally so.

Good luck


Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]

0 Kudos
2,004 Views
dbwolfe
Contributor III

Mark,

I loaded up the custom binary.  Looks like it works fine, I can enter stop modes, which is some progress.  The question is, how do I figure out what I'm doing wrong in my code?  It seems like I'm doing everything that should be required to enter a low power mode, but obviously something weird is happening.  What else could be interfering with entry into stop mode or staying in stop mode?

Thanks,

Devin

0 Kudos
2,004 Views
mjbcswitzerland
Specialist V

Hi Devin

The uTasker solution first handles all active communication before switching to the mode and if the mode is not entered for some reason (like there is a pending interrupt that needs to be taken - maybe not allowing the mode to be entered(?)) it is entered after whatever handling was needed. That means that it is more intelligent than the standard examples, but I don't know whether that makes any difference in this case (you could try putting the enter into a loop so that it can't continue until it makes it to the mode).

For optimal dynamic low power strategy I made this video a few years ago and it is a strategy used in various products that achieve improved power efficiency:

https://www.youtube.com/watch?v=v4UnfcDiaE4&list=PLWKlVb_MqDQFZAulrUywU30v869JBYi9Q&index=7

It however is not relevant to LLS type modes that can't work in a dynamic fashion (although the method to enter the mode is essentially the same).

I checked the code again and see something that I didn't show before (the reason being that the uTasker low power code automatically adapts itself to the exact chip used and I was first looking at a slightly different K22 type that doesn't have LLS2 and LLS3).
In the case of your exact chip you need to use LLS2 or LLS3 modes (and not general LLS mode)
The exact LLS mode type is controlled with SMC_STOPCTRL register (and has some additional options too).

That is, the working binary actually does this for LLS2 and LLS3 respectively:

        SMC_STOPCTRL = (unsigned char)(SMC_STOPCTRL_VLLSM_VLLS2 | (new_lp_mode & LOW_POWER_OPTIONS));
        SMC_PMCTRL = (SMC_PMCTRL_RUNM_NORMAL | SMC_PMCTRL_STOPM_LLS);
        SYSTEM_CONTROL_REGISTER |= SLEEPDEEP;


        SMC_STOPCTRL = (unsigned char)(SMC_STOPCTRL_VLLSM_VLLS3 | (new_lp_mode & LOW_POWER_OPTIONS));
        SMC_PMCTRL = (SMC_PMCTRL_RUNM_NORMAL | SMC_PMCTRL_STOPM_LLS);
        SYSTEM_CONTROL_REGISTER |= SLEEPDEEP;

where the special options are combinations of the flags
(LP_DISABLE_POR_IN_VLLS0 | LP_PARTIAL_STOP_1 | LP_PARTIAL_STOP_2)
(which can also be 0).

Re-checking your original code I do however see that you wanted LLS3 so your presumably do have all registers being set (?)


Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]

0 Kudos
2,004 Views
dbwolfe
Contributor III

Mark,

I tried making a little "while" loop that reads the power mode status register and waits for it to be set to 

The SDK function seems to be setting the stop control register correctly.  The code is as follows:

reg = base->STOPCTRL;
reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK;
reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_LLSM_SHIFT);
base->STOPCTRL = reg;

base is a pointer to the SMC base address

SMC_STOPCTRL_LLSM_MASK = 0x7, so an AND with the complement clears the lower 3 bits of stop mode control

config->subMode = 0x3 in this case, for sub mode 3, and SMC_STOPCTRL_LLSM_SHIFT = 0, so it isn't shifted

The results is that after this code is run, the stop mode control register is set to 0x3 - partial stop = normal stop, POR enabled in VLLS0, stop mode = LLS3

The only thing that seems different from the uTasker code is POR being enabled for VLLS0, and possible the partial stop options.  Can you check the exact value being written to the stop mode control register by your code?  I'm wondering what LP_PARTIAL_STOP_1 and LP_PARTIAL_STOP_1 are defined as.

Thanks,

Devin

0 Kudos
2,004 Views
mjbcswitzerland
Specialist V

Devin

Before setting low leakage stop mode:

pastedImage_1.png

After setting LLS2:
pastedImage_2.png
Or after setting LLS3:

pastedImage_3.png

Plus of course the SLEEPDEEP flag set in the Cortex-M4 system control register.

All of the optional flags are 0.

Regards

Mark

[uTasker project developer for Kinetis and i.MX RT]

0 Kudos
2,004 Views
dbwolfe
Contributor III

Well, I'm good and stumped.  Here's my SMC registers right before the WFI command is issued.  The SLEEPDEEP bit is also set at this point.

I'm going to try starting a fresh project with just the sleep code and see if I get any different results.

pastedImage_1.png

Regards,

Devin

0 Kudos
216 Views
jbjoe301
Contributor II

Devin,

   Did you ever solve this?  I just started a new project using KS20 (nearly the same as KS22) and I have the same problem.  If I use the NXP software, no sleep, I use my own, no sleep.  Nothing seems to enter LLS2 mode

0 Kudos