Port interrupts from LLS (AN4503) don't wake Kinetis

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

Port interrupts from LLS (AN4503) don't wake Kinetis

804 Views
derikdevecchio
Contributor II

I am using a Kinetis K10DX64VLH7.

I am following the examples of SEction 3 of the AN4503.  I can see the chip going to sleep (current down to 575 uA - which still seems high for LLS).  When I toggle the port switch I can see the increase in current from the ports internal pull up that suggests that the line did indeed change state.  But no interrupt occurs and I never exit sleep mode.

I have attached my code below.  There are alot of extra commands in there to see if I could figure out what was going on. 

one of the things I noticed was that no matter what values I write to PMPROT and PMCTRL, when I read those registers, I get junk.  Even values that are impossible (like PMPROT reading back 0x17 when bits 0 and 2 are supposed to always read 0.

I have tried this with and without the debugger attached.  The results are the same.  They system just hangs no matter how many times I swithc the switch.    After running the program in the debugger things will hang.  When I "stop" the debugger I will find myself on the instruction after the asm("WFI"); instruction.  From there, the program will run as normal.  Basically the Debugger can wake the chip from LLS.  But the interrupt from the port can not.

The following code executes immediately after reset.

void INIT_System (void) {

  // Disable the WDOG module  - BootStub doesn't handle this for us like a real bootloader

  WDOG_UNLOCK = (uint16_t)0xC520u;     /* Key 1 */

  // WDOG_UNLOCK : WDOGUNLOCK=0xD928 */

  WDOG_UNLOCK  = (uint16_t)0xD928u;    /* Key 2 */

// WDOG_STCTRLH: DISTESTWDOG=0,BYTESEL=0,TESTSEL=0,TESTWDOG=0,STNDBYEN=1,WAITEN=1,STOPEN=1,DBGEN=0,ALLOWUPDATE=1,WINEN=0,IRQRSTEN=0,CLKSRC=1,WDOGEN=0 */

  WDOG_STCTRLH = (uint16_t)0x01D2u;

      // DEBUG  This just puts the CPU to LLS immediately after reset.

      // I configure 2 GPIO's necesary to wake the chip.

      {

          volatile static unsigned int temp1;

          volatile static unsigned int temp2;

           // enable gates for ports C and D, we use one pin on each

           // as an interupt to wake from sleep                                                                                                                                                               SIM_SCGC5 |=  (SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTB_MASK);

        SIM_SCGC5 |= (

                   SIM_SCGC5_PORTC_MASK |

                   SIM_SCGC5_PORTD_MASK

              );

          // set POWER_SWITCH_DETECT pin as an interrupt,

          // this pin shorts to ground when switch is turned on.

          #define PSD_PIN_MASK     ((uint32_t)0x01 << 11)

          PORTC_PCR11  = (PORT_PCR_MUX(0x1) |    //pin 0 is GPIO

                          PORT_PCR_ISF_MASK |    // clear interupt flag

                          PORT_PCR_IRQC(0x0B) |  // interrupt on FALLING edge 0A

                          PORT_PCR_PE_MASK    |  // pull up/down enabled

                          PORT_PCR_PS_MASK);     // pull towards Vdd

          GPIOC_PDDR &= ~PSD_PIN_MASK;     // configure this pin as input

          LLWU_PE3 = LLWU_PE3_WUPE11(3);   // 2 enable low leakage mode interupt on RISING edge

          // set Extertnal Power Detect (EPD) pin as interrupt.

          // this pin is shorted to ground until barrel connector inserted

          // an external pull up on the board pulls it high.

          #define EPD_PIN_MASK     ((uint32_t)0x01 << 4)

          PORTD_PCR11  = (PORT_PCR_MUX(0x1) |    //pin 0 is GPIO

                          PORT_PCR_ISF_MASK |    // clear interupt flag

                          PORT_PCR_IRQC(0x0B));  // interrupt on RISING edge 09

          GPIOD_PDDR &= ~EPD_PIN_MASK;     // configure this pin as input

          LLWU_PE4 = LLWU_PE4_WUPE14(3);   // 1 enable low leakage mode interupt on RISING edge

          SIM_SCGC4 = SIM_SCGC4_LLWU_MASK;   // enables LLWU (seems to be not necessary on K10)

          MCG_C6 &= ~MCG_C6_CME_MASK;    // turns off clock monitoring, should be off

         

       // prepare to enter sleep mode

      

       temp1 = MC_PMPROT;

       temp1 = MC_PMCTRL;

      //MC_PMPROT = MC_PMPROT_ALLS_MASK;

      MC_PMPROT= 0x2A;  // just enable everythying (debug)

       temp1 = MC_PMPROT;

       temp1 = MC_PMCTRL;

       asm("NOP");

       asm("NOP");

       asm("NOP");

 

    

   MC_PMCTRL = ( MC_PMCTRL_LPLLSM(0x3)) ;

       /*wait for write to MC_PMCTRL to complete to SMC before stopping core */

       temp1 = MC_PMCTRL;

       asm("NOP");

       asm("NOP");

       asm("NOP");

       asm("NOP");

       asm("NOP");

       /* Now execute the stop instruction to go into LLSS */

      // deepsleep();

        SCB_SCR |= SCB_SCR_SLEEPDEEP_MASK;

       asm("NOP");

       asm("NOP");

       asm("NOP");

       asm("NOP");

        asm("WFI");

       asm("NOP");    // first instruction after wake - never executes!

       asm("NOP");   

       asm("NOP");

       

      } // end debug

  

// normal program execution begins here. 

 

  //Enable gate for all port clocks.   We use at least one pin in every port.

  SIM_SCGC5 |= (SIM_SCGC5_PORTA_MASK

   | SIM_SCGC5_PORTB_MASK

   | SIM_SCGC5_PORTC_MASK

   | SIM_SCGC5_PORTD_MASK

   | SIM_SCGC5_PORTE_MASK );

  INIT_SystemClock();

}

0 Kudos
1 Reply

350 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi Derik,

Actually in LLS mode, LLWU module is used to wake up the MCU, so you have to enable the LLWU interrupt before entering, and PTD4 is one wakeup source for LLWU, not PTD11, please kindly refer to RM's Chapter 3 Chip Configuration for more details.

Additional information on PMPROT and PMCTRL, I think that might be the root cause for your issue.

PMPROT

Write-once register after any reset

Protection to insure code does not enter an unsupported mode.

PMCTRL

You cannot write a mode that is not allowed in the PMPROT

You can always write the LPLLSM bits back to 00. 

Since you are using the Kinetis 72MHz part, we also provide useful barematel projects on that kind of device, you may download the example from http://cache.freescale.com/files/32bit/software/KINETIS_72MHz_SRC.zip, and find the low power demo in "KINETIS_72MHz_SRC\build\cw\low_power_demo" or "KINETIS_72MHz_SRC\build\iar\low_power_demo", depending on the IDE tool you are using. Please kindly refer to "KINETIS_72MHz_SRC\build\iar\low_power_demo\low_power_demo_readme.txt" and "KINETIS_72MHz_SRC\K20 72MHz_LAB.pdf" for more details.

Hope that helps,

B.R

Kan

0 Kudos