AnsweredAssumed Answered

VLPS mode started from debugger draws 2mAs . Even if debugger is turned off.  Even after hard reset. Only draws exepcted current (4.9uA) after a power cycle.

Question asked by rick stuart on Mar 19, 2015
Latest reply on Mar 19, 2015 by rick stuart



I am using a Freescale FRDM-KL27Z development board and the short program listed below.  I expected to enter the VLPS mode where the current should have dropped from several mAs to several uAs.  Instead the current, when I expected to be in the VLPS mode, is 2.6mA!  Am I in VLPS mode?  Well, if you follow the code you will see that I flash the RGB LED different colors to indicate where I am.  If I press SW3 I should exit VLPS and generate a green (in the PORTBCDE interrupt) then red (executing after the WFI code line) flash.  And that does happen.  If I press the reset button I should generate a white flash then enter VLPS (i.e. no red flash so execution did stop).  And that happens.  So code execution looks orderly.  And I do wait when I hit the WFI code line.


Here's the part that really confuses me...


If I cycle the power to the KL27 processor, it all works!!  When I expect to be in the VLPS mode I am drawing only 5.3uA.  From here I can press SW3 and see a green then red flash then return to drawing only 5.3uA.  Exactly what I expected.  If I press reset I see a white flash then return to drawing only 5.3uA.  Again, exactly what I expected.


What is going on?  What could possibly be unaffected by a reset only to change on a power cycle.  Why would programming / debugging the chip put it back into a mode where VLPS appears broken?




// code start


// INCLUDES /////////////////////////////////////////////////////////


#include "MKL27Z644.h"                       // KL27 M0+ register definitions



// FUNCTION HEADERS /////////////////////////////////////////////////


void MCU_Init(void);                         // initializes MCU for Freedom Board

void MCU_Delay(uint32_t delay);              // delay in multiples of 1ms



void RGB(uint8_t Red,uint8_t Green,uint8_t Blue);    // RGB-LED Control: 1=on, 0=off, for each of the 3 colors


// *** MAIN *********************************************************


int main(void)


  volatile int dummyread;


  MCU_Init();                                  // MCU Initialization; has to be done prior to anything else


  RGB(1,1,1);                                // Turn on white LED

  MCU_Delay(200);                            // Delay 200ms



  __asm("CPSIE i");                            // Enable all Interrupts



  // Set up interrupts.

  NVIC->ICPR[0] = (uint32_t)(1 << (LLWU_IRQn & 0x1F));         // Clear LLUW Interrupt in NVIC Core register

  NVIC->ISER[0] = (uint32_t)(1 << (LLWU_IRQn & 0x1F));         // Set LLUW Interrupt in NVIC Core register

  // Set up low power mode.





  // Set up interrupts.

  PORTC->PCR[1]|= PORT_PCR_ISF_MASK;         // Clear interrupt flag

  NVIC->ICPR[0] = (uint32_t)(1 << (PORTBCDE_IRQn & 0x1F));

  NVIC->ISER[0] = (uint32_t)(1 << (PORTBCDE_IRQn & 0x1F));

  // Set up low power mode.




  // Enable hi to lo transition for LLWU_P6 / pin-C1.

  LLWU_PE2 = 0x20;


  // Set the SLEEPDEEP bit to enable deep sleep mode.

  // (W/o this we only drop to about 3.1mA down from 4.6mA.)





    __asm("WFI");                                              // Enter low power mode


    dummyread = PMC_REGSC;


    RGB(1,0,0);                                // Turn on RED LED

    MCU_Delay(200);                            // Delay 200ms





// ******************************************************************



// FUNCTION BODIES //////////////////////////////////////////////////


void MCU_Init(void)


  // Crucial

  __asm("CPSID i");                            // Disable interrupts


  //Disable Watchdog

  SIM_COPC=0x00;                               // Disable COP watchdog


  //System Registers

  SIM_SCGC5|=SIM_SCGC5_PORTA_MASK;             // Enable PortA clock

  SIM_SCGC5|=SIM_SCGC5_PORTB_MASK;             // Enable PortB clock

  SIM_SCGC5|=SIM_SCGC5_PORTC_MASK;             // Enable PortC clock

  SIM_SCGC5|=SIM_SCGC5_PORTD_MASK;             // Enable PortD clock

  SIM_SCGC5|=SIM_SCGC5_PORTE_MASK;             // Enable PortE clock


  // System clock initialization

  MCG_MC|=MCG_MC_HIRCEN_MASK;                  // Enable 48MHz HIRC

  MCG_C1=MCG_C1_CLKS(0);                       // Enable Main Clock Source of the 48MHz HIRC

  SIM_CLKDIV1&=~(SIM_CLKDIV1_OUTDIV1(1));      // Set Core Clock/1=48MHz

  SIM_CLKDIV1|=(SIM_CLKDIV1_OUTDIV4(1));       // Set Bus Clock/2=24MHz


  // System Tick Init

  SysTick->CTRL=0;                             // Disable the SysTick Timer

  SysTick->LOAD=48000;                         // Core Clock/1=48MHz, Period=1ms/(1/48000000Hz)=48000

  SysTick->VAL=0;                              // Clear the current counter value to 0


                 |SysTick_CTRL_CLKSOURCE_Msk);   // Enable SYS TICK timer and set clock source to processor clock (core clock)


  // GPIO Init

  PORTC->PCR[1] |= PORT_PCR_MUX(1)|            // Enable Port Pin PTC1 as GPIO

    PORT_PCR_PE_MASK|           // Select the resistor to pull up or down on port pin

      PORT_PCR_PS_MASK|           // Select a pull up resistor

        PORT_PCR_IRQC(0x08);        // Configure interrupt pin to trigger on a logic low (0)


  GPIOC->PDDR&=~(1<<1);                        // make sure GPIO PTC1 pin is configured as an input


  PORTB_PCR18=PORT_PCR_MUX(1);                 // Set Pin B18 to GPIO function

  PORTB_PCR19=PORT_PCR_MUX(1);                 // Set Pin B19 to GPIO function

  PORTA_PCR13=PORT_PCR_MUX(1);                 // Set Pin A13 to GPIO function

  GPIOB_PDDR|=(1<<18);                         // Set Pin B18 as output

  GPIOB_PDDR|=(1<<19);                         // Set Pin B19 as output

  GPIOA_PDDR|=(1<<13);                         // Set Pin A13 as output



void MCU_Delay (uint32_t delay)              // Delay in multiples of 1ms (e.g. use 1000 for 1 second)


  uint32_t delw;

  for (delw=0;delw<delay;delw++)


    while (!(SysTick->CTRL&SysTick_CTRL_COUNTFLAG_Msk));




void RGB(uint8_t Red,uint8_t Green,uint8_t Blue) // RGB-LED Control: 1=on, 0=off, for each of the 3 colors


  if (Red   ==1) GPIOB_PCOR|=(1<<18); else GPIOB_PSOR|=(1<<18);

  if (Green ==1) GPIOB_PCOR|=(1<<19); else GPIOB_PSOR|=(1<<19);

  if (Blue  ==1) GPIOA_PCOR|=(1<<13); else GPIOA_PSOR|=(1<<13);





// INTERRUPT BODIES /////////////////////////////////////////////////


void LLWU_IRQHandler (void)


  // Clear WUF6 (aka LLWU_P6) by writing a 1 to the flag bit.

  LLWU_F1 = 0x40;                            // Clear interrupt flag


  RGB(0,0,1);                                // Turn on BLUE LED

  MCU_Delay(200);                            // Delay 200ms





void PORTBCDE_IRQHandler(void)


  // Clear flag.

  PORTC->PCR[1]|= PORT_PCR_ISF_MASK;         // Clear interrupt flag


  RGB(0,1,0);                                // Turn on green LED

  MCU_Delay(200);                            // Delay 200ms




// code end