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.

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

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.

981 Views
rickstuart
Contributor V

Hi,

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?

-thanks

// 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

  RGB(0,0,0); 

 

  __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.

  SMC_PMPROT=SMC_PMPROT_ALLS_MASK;

  SMC_PMCTRL=SMC_PMCTRL_STOPM(0x3);

  ***/

  // 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.

  SMC_PMPROT=SMC_PMPROT_AVLP_MASK;

  SMC_PMCTRL=SMC_PMCTRL_STOPM(0x2);

 

  // 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.)

  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

 

  for(;;) 

  {

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

   

    dummyread = PMC_REGSC;

   

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

    MCU_Delay(200);                            // Delay 200ms

    RGB(0,0,0); 

  }

}

//-------------------------------------------------------------------

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

// 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=(SysTick_CTRL_ENABLE_Msk

                 |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

  RGB(0,0,0);

}

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

  RGB(0,0,0);

}

// code end

Tags (3)
0 Kudos
1 Reply

512 Views
rickstuart
Contributor V

I have been told that VLPS may behave unexpectedly until the debugger has been physically removed and power restored to the KL27.  I found interrupting the power just to the KL27 adequate for returning the KL27 to the expected low power behavior.