AnsweredAssumed Answered

Waking up from VLLS0 with a push button - Kinetis K22

Question asked by Felipe Vera on Mar 2, 2017

I'm having an issue with waking up a Kinetis K22 microcontroller from Very Low Leakage mode with LLWU tied to the E.1 port signal (LLWU0)

Interrupt for the button effectively puts the microcontroller to sleep and LLWU seemingly wakes up the microcontroller, as the current for the microcontroller goes up a bit, but it doesn't effectively reset the microcontroller to the Main function.

I made a little work bench with Processor Expert to make it run in a custom K22 board I made for a project.

 

Here's the code.

 

-- Called before putting the MCU in Deep Sleep mode --

void method_PowerOffDevice()
{
    uint32_t llwu_temp, dummyread;

    // Set LLWU to Button E.1 (LLWU unit 0, external pin)
    llwu_temp =     LLWU_PE1;
    llwu_temp &=     ~LLWU_PE1_WUPE0_MASK;
    llwu_temp |=     LLWU_PE1_WUPE0(0b11);
    LLWU_PE1 =        llwu_temp;

    LLWU_F1 =        LLWU_F1_WUF0_MASK;

    // Setup Sleep mode.
    PMC_REGSC |= PMC_REGSC_ACKISO_MASK;

    SMC_PMCTRL =     SMC_PMCTRL_STOPM(0x04);
    PORTD_PCR5 =    PORT_PCR_ISF_MASK;

    // Application note recommended me this after writing PMCTRL
    dummyread =     SMC_PMCTRL;
    dummyread++;

    // Activating VLLS3
    SMC_STOPCTRL =    SMC_STOPCTRL_LLSM(0x00);
    SCB_SCR =        SCB_SCR | 0x04;                    // Sleep deep mode set in the ARM core. Puts even the JTAG to sleep!

    __asm("WFI");
}

 

-- E.1 GPIO interrupt manager, tied from a GPIO_LDD component in Processor Expert. btnflag activates the method_PowerOffDevice routine to be called from the Main loop --

void BTN1_OnPortEvent(LDD_TUserData *UserDataPtr)
{
  /* Write your code here ... */
    btnflag = 1;
    PORTD_PCR5 =    PORT_PCR_ISF_MASK;
}

-- LLWU interrupt service, tied to a Init_LLWU component, with priority zero --

PE_ISR(LLWU_Button1)
{
    uint32_t    ct;

    PORTD_PCR5 = PORTD_PCR5 & ~(PORT_PCR_MUX_MASK | PORT_PCR_DSE_MASK) |
                                    (PORT_PCR_MUX(1) | PORT_PCR_DSE_MASK);
    GPIOD_PDDR = GPIOD_PDDR | (1 << 7);
    GPIOD_PSOR |= (1 << 7);

    LLWU_F1 =        LLWU_F1_WUF0_MASK;
    PORTE_PCR1 =    PORTE_PCR1 & ~PORT_PCR_IRQC_MASK | PORT_PCR_IRQC(0x0);
    PORTE_ISFR =    (1 << 1);

    // Button ISR clear
    PORTD_PCR5 =    PORT_PCR_ISF_MASK;
}

 

Here I include the test bench I'm using. I'm using Kinetis Studio 3.2.0 with GCC and Olimex JTAG. I'd prefer to keep solutions open source.

 

Thanks in advance.

Original Attachment has been moved to: Test_bench.zip

Outcomes