AnsweredAssumed Answered

KL03Z32 Stuck in VLLS3 After Programming

Question asked by James Morrison on Mar 18, 2020
Latest reply on Apr 13, 2020 by Diego Charles

I have a very strange problem, hopefully someone can point me in the right direction.

 

I have a device that goes into VLLS3 mode and wakes up via the LLWU_P4 connected to a push button.  In general this works very well.

 

However, there is one case where the device will NOT wake up.  This happens when a battery is connected (it's a battery powered device, and for various reasons it is a possible configuration during production) and the device is programmed by the PE Micro Cyclone.  This is configured to NOT provide power as the battery is doing so.

 

I've done some debugging and say that the problem can easily be repeated.  There are 2 paths in the code that put the device into VLLS3:  one when the button is pressed on power up and released quickly, the other when the button is pressed for a longer period of time.  By adjusting the code, both paths create the same issue.

 

The issue is, that after programming and releasing the reset, the device will boot, pass through one of the 2 paths, go to sleep, and then won't wake up again no matter how many times you push the button, or how long.

 

A short of nRST to GND will cause the micro to reset and then it behaves as expected.  I've also noticed that simply plugging the cable into the Cyclone can also, sometimes, cause the code to start running.  I suspect that it may be causing a glitch on the nRST line and just causing a reset.

 

If I program without the battery and then connect the battery, the device behaves as expected all time time.

 

Any ideas on what could call this.  Below is my code for the function that I call to put the device into VLLS3 as well as the LLWU IRQ handler.  I'm aware of the bug where the chip won't go into VLLS3 if an RTC flag is set (see code below).  But this isn't the problem, I can't get out of deep sleep.

 

Any ideas?

 

void LLWU_IRQHandler(void)
{
    PORT_SetPinInterruptConfig(nUSER_BUTTON_PORT, nUSER_BUTTON_PIN, kPORT_InterruptOrDMADisabled);
    PORT_ClearPinsInterruptFlags(nUSER_BUTTON_PORT, (1U << nUSER_BUTTON_PIN));
    LLWU_ClearExternalWakeupPinFlag(LLWU, LLWU_WAKEUP_PIN_IDX);
    NVIC_ClearPendingIRQ(LLWU_IRQn);
} // LLWU_IRQHandler()

 

 

void go_into_deep_sleep( void )
{
    // disable the 5V EN pin so there is no path to 5V rail during VLLS3
    PORT_SetPinMux( EN_5V_PORT, EN_5V_PIN, kPORT_PinDisabledOrAnalog );

 

    // turn off interrupts that have been enabled so these don't wake device up

    TPM_DisableInterrupts( TICK_TPM, kTPM_TimeOverflowInterruptEnable );
    NVIC_DisableIRQ( TICK_TPM_IRQ_NUM );

 

    // clear flags and configure to wake up from LLWU pin
    NVIC_EnableIRQ( LLWU_IRQn );
    NVIC_ClearPendingIRQ( LLWU_IRQn );
    LLWU_ClearExternalWakeupPinFlag( LLWU, LLWU_WAKEUP_PIN_IDX );
    LLWU_SetExternalWakeupPinMode( LLWU, LLWU_WAKEUP_PIN_IDX, kLLWU_ExternalPinFallingEdge );

 

    // clear RTC invalid time flag as per errata e8068 found in document KL03Z_1N86K

    // on some versions of die this will keep micro from entering power mode
    // RTC must be started and initialized or this call will freak out, which can happen if
    // button debounce kicks in and goes to sleep before RTC initialized
    if( RtcStarted )
    {
      RTC_StopTimer( RTC );
      RTC_ClearStatusFlags( RTC, kRTC_TimeInvalidFlag );
      RtcStarted = 0;
    }

 

    // set power mode to VLLS3
    smc_power_mode_vlls_config_t vlls_config;
    vlls_config.enablePorDetectInVlls0 = false;
    vlls_config.enableLpoClock = false;  // needs to be enabled for digital filtering on pin
    vlls_config.subMode = kSMC_StopSub3;

 

    SMC_PreEnterStopModes();
    SMC_SetPowerModeVlls(SMC, &vlls_config);
    SMC_PostExitStopModes();
} // void go_into_deep_sleep()

Outcomes