Problems putting KL03 into VLPS and reducing power consumption

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

Problems putting KL03 into VLPS and reducing power consumption

Jump to solution
7,313 Views
willx
Contributor IV

Hi all,

1. What I'm trying to do:

a- Put KL03 into VLPS mode

b- Switch from using the 48MHz HIRC to the 2MHz LIRC2M

c- Reduce power consumption from a few mA's to something lower than 100uA

d- Go from VLPS back to RUN mode on an SPI slave mode receive through AWIC

2. How I'm doing it:

a- Here are the 2 functions I am using to enter and exit VLPS:

void vlps_enter(void)

{

     SMC_PMCTRL = SMC_PMCTRL_STOPM(2));

     dummyread = SMC_PMCTRL;

     (void)dummyread;

     SCB_SCR |= SCB_SCR_SLEEPDEEP_MASK;

     dsb();

     wfi();

     isb();

}

void vlps_exit(void)

{

     SMC_PMCTRL &= ~SMC_PMCTRL_STOPM_MASK;

     SCB_SCR &= ~(SCB_SCR_SLEEPDEEP_MASK | SCB_SCR_SLEEPONEXIT_MASK);

}

b- Here are the 2 functions I use to switch from HIRC to LIRC2M:

void set_HIRC(void)

{

     MCG_MC |= MCG_MC_HIRCEN_MASK;

     MCG_C1 = MCG_C1_CLKS(0);

     MCG_C2 = 0;

     while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x00);

}

void set_LIRC(void)

{

     MCG_MC = 0;

     MCG_C1 = MCG_C1_CLKS(1);

     MCG_C2 = 0;

     while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x01);

}

c- At bootup I run this to enable HIRC and enable going into VLPS and VLLS modes:

     set_HIRC();

     SMC_PMPROT = (SMC_PMPROT_AVLP_MASK | SMC_PMPROT_AVLLS_MASK);

d- When the conditions to enter VLPS are met (KL03 is idle and has no pending tasks), I call the 2 functions like this:

     set_LIRC();

     vlps_enter();

     // KL03 is in VLPS here

     vlps_exit();

     set_HIRC();

d- My KL03 is configured as an SPI slave (with SPISWAI bit set in SPI0_C2 register) and expect that the KL03 would exit VLPS whenever an SPI transfer is coming its way

3. What I'm seeing:

a- With the code I have above, I measured current consumption at 0.9mA which seems very high to me in VLPS and there's no peripherals running (no ADC, no LPUART... nothing)

b- Another problem is that with this code, the KL03 never properly wakes up and processes the SPI transfer it's receiving.

c- However, if I just remove the set_LIRC() call, power consumption goes to 1.8mA and the SPI transfer works great and I have no issues (other than the high power consumption)

4. My questions:

a- The power numbers I'm seeing are high, is there anything else I need to change to get very low numbers in the 100uA range?

b- Any thoughts on wether the switch to LIRC2M is actually needed?

c- Any idea why if I switch to LIRC2M, the SPI wakeup doesn't work?

Any help is greatly appreciated.

Thanks!

Labels (1)
1 Solution
5,245 Views
michaelsteffenf
NXP Employee
NXP Employee

Hi,

The issue is Errata #8068.  The RTC clock is enabled by default.  It has to be disabled before you enter low power.

// Errata 8068 fix

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

The attached code (main.c) get you now to 1.74uA in VLPS.

Michael Steffen

Senior Field Applications Engineer

Member of the Technical Staff

Freescale

View solution in original post

29 Replies
4,875 Views
thomasedel
Contributor III

Will:  Thanks for this post and for persevering to an answer ... Only took me 1 1/2 days to resolve the same problem, thanks to your post (1 1/2 days trying all the application note recommendations, then 1/2 hour to find your post and the solution).

Thanks also to Michael for the correct answer!

-Thomas

0 Kudos
Reply
5,246 Views
michaelsteffenf
NXP Employee
NXP Employee

Hi,

The issue is Errata #8068.  The RTC clock is enabled by default.  It has to be disabled before you enter low power.

// Errata 8068 fix

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

The attached code (main.c) get you now to 1.74uA in VLPS.

Michael Steffen

Senior Field Applications Engineer

Member of the Technical Staff

Freescale

4,876 Views
jrychter
Contributor V

Michael, thanks for the answer, I've just spent more than two days hunting problems with entering VLLS. See Can't enter VLLS0 on KL03

But this begs the question — shouldn't the startup code that KDS generates for the MKL03 be modified to have the errata fix in it?

0 Kudos
Reply
4,876 Views
willx
Contributor IV

Hi Michael,

Thanks for pointing that out. I'll give it a shot.

Do you happen now why a SPI wake up from VLPS is not working for me? Anything special that needs to be done there? Also, is going from HIRC to LIRC needed when going into VLPS (I don't think so I need to do it, but would like to confirm)?

Thanks!

0 Kudos
Reply
4,876 Views
willx
Contributor IV

The errata fix helped Michael. I am now able to see power consumption in the uA level.

I'm still working through some SPI wakeup problems.

0 Kudos
Reply
4,876 Views
rickstuart
Contributor V

Found this in the K20 family pdf:

In stop and VLPS modes, the clocks to the SPI module are disabled. The module is not

functional, but it is powered so that it retains state.

So, 1st verify this is the same as in your K03.

In the same document it goes on to suggest a way to use VLPS and SPI.  It looks like they use a GPIO to sense the SPI CS line activity.  It looks like GPIO pin activity can wake up a processor in VLPS.  However it goes on to say there is a risk that the 1st SPI transaction will not work.

Or you can investigate running in VLPR so that the SPI module still gets a clock.  However I think the SPI speed is limited in VLPR mode.

I don't think there is a reason you can't go from the 48MHz clock to VLPS.  The thing you probably can't do w/o jazzing up the processor is switch between different low speed clock directly.  Like switching from 2MHz to 8MHz with out going to 48MHz first.

0 Kudos
Reply
4,876 Views
willx
Contributor IV

Thanks for your help Rick.

I was finally able to get the power consumption down to the uA level but still have some problems with the SPI wakeup in VLPS. And I'm no longer changing between HIRC and LIRC clocks.

According to the data sheet, an SPI reception should trigger an interrupt that wakes the CPU up. I can see that happening sometimes but some other times, the operations that follow the SPI transfer are failing.

0 Kudos
Reply
4,877 Views
ivansantanna
Contributor III

Hello Will X, I'm finding the same problems that you had to put KL03 to VLPS. I'm doing the same sequence:

SMC_PMPROT = 0x22;      // enabling AVLP and AVLLS

SMC_PMCTRL = (SMC_PMCTRL_RUNM(2) + SMC_PMCTRL_STOPM(2));      // RUN mode VLPR and STOP VLPS

dummyread = SMC_PMCTRL;

while (!(SMC_PMSTAT & 0x04));      // waiting for VLPR

/* HERE I CAN SEE THE CURRENT GOING DOWN AROUND 1mA */

PortInit()      // Config the GPIOs

LPTMR_Init()      // Config LPTimer to generate an Interruption each 1 sec.

while(1) {   

   GoVLPS();

   GPIOA_PTOR = 0x20;   // toogle the PA5 to check if its comming out from VLPS every sec.

}

void GoVLPS(void){

   SCB_SCR |= SCB_SCR_SLEEPDEEP_MASK;

   __asm("DSB");

   __ams("WFI");

}

Did you disable any MCU block as debugger, clock, or somethin else to reach units of uA? 

I can see that the MCU is going to a Low Power mode because it's waitinf for an interrupt (the pin A5 is toogling 1 sec Hi 1 sec Lo). However, the current is around 200uA and I expect something under 50uA. Any idea?

Thanks and regards

Ivan

0 Kudos
Reply
4,878 Views
rickstuart
Contributor V

FYI, I was doing some similar current checks on a LK27 (FRDM-KL27Z Freescale development board). BEWARE!!!  You need to do the current checks with out the debugger!!!  Here's my thread:

Re: VLPS mode started from debugger draws 2mAs . Even if debugger is turned off.  Even after hard re...

As to why the SPI isn't getting you out of VLPS, I thought you needed an interrupt to get out of VLPS.  I went down the path of setting bits in VNIC on the '27 for a timer to get out of VLPS.

0 Kudos
Reply
4,878 Views
willx
Contributor IV

Thanks for your reply Rick.

The numbers I quoted are withe debugger detached. Attaching the debugger adds about 0.5mA for me.

And my SPI interrupt is enabled. If I don't change from HIRC to LIRC2M, the SPI IRQ works fine. Only when I switch to the lower clock that the SPI doesn't wake up.

0 Kudos
Reply
4,878 Views
rickstuart
Contributor V

WRT the current.  So you managed to get the current down to where you expected it??  Note, pressing the red "X" on the debugger tool was not enough for me. Neither was pressing reset on the development board.   I needed to cycle the power to the processor to get really low currents.

I'm not sure about the interrupt.  If the interrupt really works when you stay out of VLPS - I think it should work when you are in VLPS.  Check to make sure you clear the interrupt flag before getting out of the interrupt routine.  But you would have had to do that even if you never entered VLPS.  Humm.  Have to think about this one.  FYI, since I can't use the debugger to tell me where my code is  executing, I started using the LEDs on the Freescale development boards to indicate I was in main() or one of my interrupts.

0 Kudos
Reply
4,878 Views
willx
Contributor IV

No, I'm still having problems getting the current to the low level I expect it to be at.

I'm assuming that to get to the lowest possible power consumption I need to do the following: go into VLPS AND switch from the HIRC 48MHz clock to the LIRC 2MHz clock.

At the moment, I have 2 problems:

1. When I try to do both of these things, my application doesn't work because of the SPI transfer not waking it up.

2. Going into VLPS and not changing the clock used is consuming 1.8mA now which is still high. If I change the clock, it drops even more to 0.9mA but I would expect it to be much lower.

The code I'm using is in my original post and it matches the SDK code that Jeremy pointed me too and other sample codes I found in the community.

Any help or guidance would be greatly appreciated.

0 Kudos
Reply
4,878 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Will,

I was wondering if you can share the whole demo, then I can run it with FRDM-KL03 board for checking.

I'm looking forward to your reply.
Have a great day,
Ping

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

0 Kudos
Reply
4,878 Views
willx
Contributor IV

Hey Jeremy,

Here's the code I have. I trimmed down my project to this and I'm still seeing 0.9mA.

void vlps_enter(void)

{

     SMC_PMCTRL = SMC_PMCTRL_STOPM(2));

     dummyread = SMC_PMCTRL;

     (void)dummyread;

     SCB_SCR |= SCB_SCR_SLEEPDEEP_MASK;

     dsb();

     wfi();

     isb();

}

void vlps_exit(void)

{

     SMC_PMCTRL &= ~SMC_PMCTRL_STOPM_MASK;

     SCB_SCR &= ~(SCB_SCR_SLEEPDEEP_MASK | SCB_SCR_SLEEPONEXIT_MASK);

}

void set_HIRC(void)

{

     MCG_MC |= MCG_MC_HIRCEN_MASK;

     MCG_C1 = MCG_C1_CLKS(0);

     MCG_C2 = 0;

     while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x00);

}

void set_LIRC(void)

{

     MCG_MC = 0;

     MCG_C1 = MCG_C1_CLKS(1);

     MCG_C2 = 0;

     while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x01);

}

void main()

{

   /* Set the KL03 clock to be the max at 48MHz */

   set_HIRC();

   SMC_PMPROT = SMC_PMPROT_AVLP_MASK;

   while(1)

   {

     set_LIRC();

     vlps_enter();

     // KL03 is in VLPS here

     vlps_exit();

     set_HIRC();

   }

}

If I comment out the 2 calls to set_LIRC() and set_HIRC() inside of the while loop, I get a power consumption of 1.6mA.

0 Kudos
Reply
4,877 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Will X,

I'm working on this code now and I'll inform you ASAP if I work it out.

And you can also share some updating in the community.
Have a great day,
Ping

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

0 Kudos
Reply
4,877 Views
willx
Contributor IV

Hi Jeremy,

Were you able to run my code on your end and measure the power consumption?

Thanks!

0 Kudos
Reply
4,877 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Will,

I've got the different result from you, I used the code from the SDK instead of yours, then the current consumption will drop to 1.85uA when the MCU entered the VLPS mode.

I ran the code on the FRDM-KL03Z board.

Wish it helps.
Have a great day,
Ping

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

0 Kudos
Reply
4,877 Views
willx
Contributor IV

Thanks for letting me know.

Can you point me to exactly which sample code from the SDK you used? There's a ton of examples there so pointing me to the one you ran would be great.

0 Kudos
Reply
4,877 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Will,

FSL's shared a Kinetis SDK_1.0.0 Standone for FRDM-KL03Z and it includes a low_power_rtc demo which illustrates the ways to enter and exit different low power modes.

This demo resides in ~\Freescale\KSDK_1.0.0-KL03Z\demos and you can download the SDK through the link as below.

https://cache.freescale.com/secured/sdk/Freescale_KSDK_1.0.0-KL03Z.exe?__gda__=1428466397_9bc09e3adb...

Hope it helps.
Have a great day,
Ping

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

0 Kudos
Reply
4,877 Views
willx
Contributor IV

Thanks Jeremy.

I am trying to look into that but that SDK is a total mess. And me development environment is on Mac so I'm having a lot of problems to figure out how to load it on the FRDM-KL03Z.

Are you able to load my code and run it yourself?

void vlps_enter(void)

{

     SMC_PMCTRL = SMC_PMCTRL_STOPM(2));

     dummyread = SMC_PMCTRL;

     (void)dummyread;

     SCB_SCR |= SCB_SCR_SLEEPDEEP_MASK;

     dsb();

     wfi();

     isb();

}

void vlps_exit(void)

{

     SMC_PMCTRL &= ~SMC_PMCTRL_STOPM_MASK;

     SCB_SCR &= ~(SCB_SCR_SLEEPDEEP_MASK | SCB_SCR_SLEEPONEXIT_MASK);

}

void set_HIRC(void)

{

     MCG_MC |= MCG_MC_HIRCEN_MASK;

     MCG_C1 = MCG_C1_CLKS(0);

     MCG_C2 = 0;

     while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x00);

}

void set_LIRC(void)

{

     MCG_MC = 0;

     MCG_C1 = MCG_C1_CLKS(1);

     MCG_C2 = 0;

     while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x01);

}

void main()

{

   /* Set the KL03 clock to be the max at 48MHz */

   set_HIRC();

   SMC_PMPROT = SMC_PMPROT_AVLP_MASK;

   while(1)

   {

     //set_LIRC();

     vlps_enter();

     // KL03 is in VLPS here

     vlps_exit();

     //set_HIRC();

   }

}

0 Kudos
Reply