How to set MCG to PEE right before any ISR runs from waking VLPS?

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

How to set MCG to PEE right before any ISR runs from waking VLPS?

Jump to solution
2,671 Views
thasin_akhand
Contributor III

Hello,


I am trying to figure out a way to set MCG to PEE mode as soon as Interrupt wakes up my device from VPLS mode. The original configuration was set to PEE but when I place the device to VPLS, if it wakes up, the MCG is set to PBE mode. I know how to set it back to PEE but I need to set it back before any ISR runs. Essentially my main question is where can I set MCG to PEE mode after waking up from VPLS? 

Labels (1)
Tags (3)
1 Solution
2,277 Views
mjbcswitzerland
Specialist V

Hi Thasin

Here is the general low power interface from the uTasker project (available on GitHub) which is compatible with the K50 and shows recovery back to PEE mode after a low leakage wake-up (which is also skipped when the mode retained PEE).

register unsigned char ucMCG_C1;
ucMCG_C1 = MCG_C1;                                                   // backup the original MCG_C1 setting
__sleep_mode();                                                      // enter low power mode using wait for interrupt processor state (eg. asm("wfi") with GCC)
if (((SYSTEM_CONTROL_REGISTER & SLEEPDEEP) != 0) && ((MC_PMPROT & MC_PMPROT_AVLP) != 0) {                                                                    // LLS/VLPS sleep mode exit requires the PLL to be reconfigured
    MCG_C5 = ((CLOCK_DIV - 1) | MCG_C5_PLLSTEN0);                    // move from state FEE to state PBE (or FBE) PLL remains enabled in normal stop modes
    MCG_C6 = ((CLOCK_MUL - MCG_C6_VDIV0_LOWEST) | MCG_C6_PLLS);
    while ((MCG_S & MCG_S_PLLST) == 0) {                             // loop until the PLLS clock source becomes valid
    }
    while ((MCG_S & MCG_S_LOCK) == 0) {                              // loop until PLL locks
    }
    MCG_C1 = ucMCG_C1;                                               // finally move from PBE to PEE mode - switch to PLL clock (the original settings are returned)
    while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST_PLL) {          // loop until the PLL clock is selected
    }
}

uEnable_Interrupt();                                                 // enable interrupts so that the masked interrupt that became pending can be taken

..

Regards

Mark

View solution in original post

19 Replies
2,277 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Thasin Akhand,

    Next time, when you post the question, please also let us know the kinetis chip part number, then we can help you to check the details.

    Yes,  when you enter VLPS in PEE mode, after exit, it will be in PBE mode.

    If you want to change to the PEE mode, you need to transfer the clock mode through this way:

pastedImage_1.png

Actually, in the kinetis reference manual, we have a example tell you how to change the PBE to PEE:

pastedImage_2.png

pastedImage_3.png

Wish it helps you!


Have a great day,
Kerry

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

2,277 Views
thasin_akhand
Contributor III

Hi Kerry,

Sorry, here is my Chip number, MK50DX256CMC10. 


My question was not about how to set it back to PEE mode. I already knew how to do so, rather my question is where I can possibly place it? many of my ISR interrupts, which wakes up the processor from VPLS, requires the MCG to be in PEE mode. I know I can place that code in the beginning of each ISR, however I was wondering if there was some sort of hook or a place where context switching happens where I can place the code to switch to PEE mode instead of placing it before every single ISR that wakes up the processor? 

I have seen some post here where people have placed it in LLWU IRQ, but I am using VPLS that wakes up from AWIC. I also don't have any LPTMR in place.

0 Kudos
2,278 Views
mjbcswitzerland
Specialist V

Hi Thasin

Here is the general low power interface from the uTasker project (available on GitHub) which is compatible with the K50 and shows recovery back to PEE mode after a low leakage wake-up (which is also skipped when the mode retained PEE).

register unsigned char ucMCG_C1;
ucMCG_C1 = MCG_C1;                                                   // backup the original MCG_C1 setting
__sleep_mode();                                                      // enter low power mode using wait for interrupt processor state (eg. asm("wfi") with GCC)
if (((SYSTEM_CONTROL_REGISTER & SLEEPDEEP) != 0) && ((MC_PMPROT & MC_PMPROT_AVLP) != 0) {                                                                    // LLS/VLPS sleep mode exit requires the PLL to be reconfigured
    MCG_C5 = ((CLOCK_DIV - 1) | MCG_C5_PLLSTEN0);                    // move from state FEE to state PBE (or FBE) PLL remains enabled in normal stop modes
    MCG_C6 = ((CLOCK_MUL - MCG_C6_VDIV0_LOWEST) | MCG_C6_PLLS);
    while ((MCG_S & MCG_S_PLLST) == 0) {                             // loop until the PLLS clock source becomes valid
    }
    while ((MCG_S & MCG_S_LOCK) == 0) {                              // loop until PLL locks
    }
    MCG_C1 = ucMCG_C1;                                               // finally move from PBE to PEE mode - switch to PLL clock (the original settings are returned)
    while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST_PLL) {          // loop until the PLL clock is selected
    }
}

uEnable_Interrupt();                                                 // enable interrupts so that the masked interrupt that became pending can be taken

..

Regards

Mark

2,277 Views
thasin_akhand
Contributor III

What value is MCG_S_CLKST_PLL? I don't have that macro.

0 Kudos
2,277 Views
mjbcswitzerland
Specialist V

#define MCG_S_CLKST_PLL          0x0c                            // PLL output is selected

0 Kudos
2,277 Views
thasin_akhand
Contributor III

Hi Mark,

Base on Kerry comments, when entering from Run to VLPS during PEE mode, on wake up the MCG is set to PBE mode. However base on the code you provided, I have to set it to FEE to PBE and then set it to PBE to PEE. I was wondering exactly which MCG mode it is when waking up from VLPS.

0 Kudos
2,277 Views
mjbcswitzerland
Specialist V

Hi

There may be some difference between different low power modes but the code that I use is compatible will all - it may check a status more than needed in some cases - you can also read this to get some more practical background into the principles of the modes (which are in fact just logical states based on some switches and the requirement to have the next clock source ready) - http://www.utasker.com/kinetis/MCG.html

Regards

Mark

0 Kudos
2,277 Views
thasin_akhand
Contributor III

Also what does status_t CLOCK_SetPeeMode ( void ) do exactly? I called this function and when I check if my ISR is in PEE mode using CLOCK_GetMode(), it return PEE Mode. I looked at the code inside CLOCK_SetPeeMode and I don't see PLL locking while loop? 

0 Kudos
2,277 Views
thasin_akhand
Contributor III

__sleep_mode(); // enter low power mode using wait for interrupt processor state (eg. asm("wfi") with GCC)

Shouldn't I disable the interrupt before entering this state? 

0 Kudos
2,277 Views
mjbcswitzerland
Specialist V

Hi

Yes, interrupts should be disabled before entering the sleep mode. I don't have this in the low power routine since I already enter with them disabled (since the scheduler disabled them when it checks whether there are critical tasks that first need to run before moving to the new state).

Regards

Mark

0 Kudos
2,277 Views
thasin_akhand
Contributor III

Thank you, if we disable the interrupt, how can it wake up the cpu during VLPS? does the CPU enter VLPS after you enable the interrupt? 

0 Kudos
2,277 Views
thasin_akhand
Contributor III

Hi Mark, 

I think I understand. It disable the interrupt but the interrupt can still wake up the processor in VLPS mode, and the interrupt that woke it up, is pending to have its request served. After enabling the interrupt it resume its request that goes from pending to run.


Let me know if this is how it is works. I have read the document but it is not entirely clear exactly what's happening so I was hoping you can clarify this for me. 

Thank you.

0 Kudos
2,277 Views
mjbcswitzerland
Specialist V

Hi

Yes, you have correctly understood. It is not the interrupt that wakes the processor but instead the "pending" interrupt.

If only interrupts could wake there would be a race state which could fail - there is in fact an errata in the ST-Micro STR9xx ARM9 family since they can only wake with an interrupt - which means that one needed to enable the interrupt before the sleep command and if the interrupt happens to fire it could then sleep 'after' the interrupt had been taken and then get to a state where it would never wake again. The ST-Micro workaround was to "not put the chip to sleep mode when interrupts could occur", which is obviously something that can't always be guaranteed and the sleep mode was essentially un-usable Fortunately this is something now well designed in the Cortex core itself.

The Coldfire processors also have a similar technique (to the Cortex) which is equally well-designed and thus fool-proof.

Regards

Mark

Low Power mode:
http://www.utasker.com/kinetis/LLWU.html

2,277 Views
thasin_akhand
Contributor III

Does it have to be from LLWU wake up or can it be from any wake up interrupt? 

0 Kudos
2,277 Views
mjbcswitzerland
Specialist V

Hi

Any wake up source works.

Regards

Mark

0 Kudos
2,277 Views
sylvainasselin
Contributor I

Mark,

how much time does it takes for the PLL to lock?  (Because this will induce interrupt latency)

while ((MCG_S & MCG_S_LOCK) == 0) {} // loop until PLL locks

..

uEnable_Interrupt();   
   

0 Kudos
2,277 Views
mjbcswitzerland
Specialist V

Hi

The time that it takes to move to PEE is given in the data sheet to the specific part. It is however indeed quite long (several ms) and so is a wake-up latency (or interrupt latency, depending on how you look at it). This is something that can't be avoided when the PLL is used for main operation.

Regards

Mark

0 Kudos
2,277 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Thasin,

   Sorry for misunderstanding your question, and thank you for your updated information:)

   You want to know where you put the change back to PEE code, as you know, after the code wake up from the VLPS, the code will run from the code point where you enter the VLPS, so you just need to put the change to PEE mode code under the enter VLPS code, then when the MCU is waked up from the VLPS, the code will run your back to PEE mode code.

Wish it helps you!

If you still have question about it, please kindly let me know.


Have a great day,
Kerry

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

0 Kudos
2,277 Views
thasin_akhand
Contributor III

The way I have my code is design basically the following

- disable interrupts

- enter VPLS

- enable interrupts

do I switch it to PEE mode after and before the enabling of interrupts? If after, than what if interrupt happens right after enabling of the interrupt and before PEE mode switch?

Thank you!

0 Kudos