KL82 low power mode in RTX

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

KL82 low power mode in RTX

2,625 Views
diandizhu
Contributor II

Hi there,

I tried to write some code to make kl82 enter to lls3 in RTX. Here is my code:

volatile uint32_t tc;
volatile uint32_t tc_weakup;
volatile uint8_t lp_sleep = 0;
void LPTMR1_IRQHandler()
{
        if (kLPTMR_TimerInterruptEnable & LPTMR_GetEnabledInterrupts(LPTMR1))
        {
                LPTMR_DisableInterrupts(LPTMR1, kLPTMR_TimerInterruptEnable);
                LPTMR_ClearStatusFlags(LPTMR1, kLPTMR_TimerCompareFlag);
                LPTMR_StopTimer(LPTMR1);
        }
}

void LLWU_IRQHandler(void)
{
    /* If wakeup by LPTMR. */

        tc = 0;
        //LPTMR_DisableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable);
        if (LPTMR1->CSR >> 7 )
        {
                INTMUX_DisableInterrupt(INTMUX0, 0, LPTMR1_IRQn);
                LPTMR_ClearStatusFlags(LPTMR1, kLPTMR_TimerCompareFlag);
                LPTMR_StopTimer(LPTMR1);
                NVIC_EnableIRQ(LPTMR0_IRQn);
        }



}



/// \brief The idle demon is running when no other thread is ready to run
void os_idle_demon (void) {

  for (;;) {
//        __WFI();
          tc_weakup = os_suspend();
          if (tc_weakup > 0)
          {
                  lptmr_config_t lptmrConfig;
                  /* Setup LPTMR. */
                  LPTMR_GetDefaultConfig(&lptmrConfig);
                  /* Use LPO as clock source. */
                  lptmrConfig.prescalerClockSource = kLPTMR_PrescalerClock_1;
                  lptmrConfig.bypassPrescaler = true;
                  LPTMR_Init(LPTMR1, &lptmrConfig);
                  INTMUX_Init(INTMUX0);
                  INTMUX_SetChannelMode(INTMUX0, 0, kINTMUX_ChannelLogicOR);
                  INTMUX_EnableInterrupt(INTMUX0, 0, LPTMR1_IRQn);

                  LPTMR_SetTimerPeriod(LPTMR1, tc_weakup - 1U);
                  LPTMR_StartTimer(LPTMR1);
                  LPTMR_EnableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable);     

                  LLWU_EnableInternalModuleInterruptWakup(LLWU, 0, true);//Module 0 for lptmr0 and lptmr1
                  NVIC_EnableIRQ(LLWU_IRQn);

                  SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeLls);//dont forget to allow lls mode
                  
                  smc_power_mode_lls_config_t lls_config;
                  lls_config.subMode = kSMC_StopSub3;
                  lls_config.enableLpoClock =1;

                  SMC_SetPowerModeLls(SMC, &lls_config);
                  tc = 0;


          }

          os_resume(tc_weakup);

  }
}

any comments?

 

Thank you very much in advance.

Best Regards,

Labels (1)
10 Replies

2,076 Views
diandizhu
Contributor II

Here is my latest code for LLWU handler, LPTMR handler and os_idle_deamon thread. I set the OS_SYSTICK to 1, so instead of running RTX systick on LPTMR0, now the kernel is running systick on the ARM Cortex-M processors SysTick timer. It seems use a bit more current than the LPTMR while runing. But my idle is 3ma now instead of 13ma before. I am wondering now, is it possible to setup LLWU to only wakeup when a LPTMR1 interrupt is generated, but ignore LPTMR0 interrupt. I saw the manual says both LPTMR0/1 both belongs to LLWU module 0. But still want to confirm if it is possible.

void LLWU_IRQHandler(void)
{
    /* If wakeup by LPTMR. */
     if (LLWU_GetInternalWakeupModuleFlag(LLWU, 0U))
     {
          LPTMR_DisableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable);
          LPTMR_ClearStatusFlags(LPTMR0, kLPTMR_TimerCompareFlag);
          LPTMR_StopTimer(LPTMR0);
     }

}

/*!
 * @brief LPTMR0 interrupt handler.
 */
void LPTMR0_IRQHandler(void)
{
     if (kLPTMR_TimerInterruptEnable & LPTMR_GetEnabledInterrupts(LPTMR0))
     {
          LPTMR_DisableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable);
          LPTMR_ClearStatusFlags(LPTMR0, kLPTMR_TimerCompareFlag);
          LPTMR_StopTimer(LPTMR0);
     }
}


void os_idle_demon (void) {

  for (;;) {
       __WFE();
       
       tc_weakup = os_suspend();
       if (tc_weakup > 0)
       {
            
            tc = 0;
            lp_sleep = 1;

            lptmr_config_t lptmrConfig;
            /* Setup LPTMR. */
            LPTMR_GetDefaultConfig(&lptmrConfig);
            /* Use LPO as clock source. */
            lptmrConfig.prescalerClockSource = kLPTMR_PrescalerClock_1;
            lptmrConfig.bypassPrescaler = true;
            LPTMR_Init(LPTMR0, &lptmrConfig);
          
            
            NVIC_EnableIRQ(LLWU_IRQn);
            NVIC_EnableIRQ(LPTMR0_IRQn);

            LPTMR_SetTimerPeriod(LPTMR0, tc_weakup);
            LPTMR_StartTimer(LPTMR0);
            LPTMR_EnableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable);       
            
            LLWU_EnableInternalModuleInterruptWakup(LLWU, 0U, true);//Module 0 for lptmr0 and lptmr1
            NVIC_EnableIRQ(LLWU_IRQn);
     
     
     
            SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeLls);
            smc_power_mode_lls_config_t lls_config;
            lls_config.subMode = kSMC_StopSub3;
            lls_config.enableLpoClock = 1;
           
            SMC_SetPowerModeLls(SMC, &lls_config);
            tc = 0;

            
       }
       
       os_resume(tc_weakup);
       
  }
}
0 Kudos
Reply

2,076 Views
knishi
Contributor I

It might be too late but best example for tickless operation could be found on SiLab

0 Kudos
Reply

2,076 Views
diandizhu
Contributor II

do not forget enable lptmr interrupt “LPTMR_EnableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable);”

0 Kudos
Reply

2,076 Views
diandizhu
Contributor II

I forgot to write "SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeLls);" to enable lls mode. And seems you cannot stop while debugging? the PMSTAT is always 1 no matter how I se PMPROT, PMCTRL and STOPCTRL. 

微信截图_20161205174047.png

But it entered into sleep mode, if I just reset my board. The current reading from my power supplier is 0ma.

Have to see if my os_deamon_idlea implementation work tomorrow.

0 Kudos
Reply

2,076 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Diandi,

You can not debug in LLS mode, the chip will reset after waking up.

BR

Xiangjun Rong

0 Kudos
Reply

2,076 Views
diandizhu
Contributor II

if I have to run lptmr0 and lptmr1 at same time, is there a way make LLWU only wake up by lptmr1?

0 Kudos
Reply

2,076 Views
diandizhu
Contributor II

16.4.5.3 Low-Leakage Stop (LLSx) modes This device contains two Low-Leakage Stop modes: LLS3 and LLS2. LLS or LLSx is often used in this document to refer to both modes. All LLS modes can be entered from normal RUN or VLPR modes. The MCU enters LLS mode if: • In Sleep-Now or Sleep-On-Exit mode, SLEEPDEEP is set in the System Control Register in the ARM core, and • The device is configured as shown in Table 16-2. In LLS, the on-chip voltage regulator is in stop regulation. Most of the peripherals are put in a state-retention mode that does not allow them to operate while in LLS. Before entering LLS mode, the user should configure the Low-Leakage Wake-up (LLWU) module to enable the desired wake-up sources. The available wake-up sources in LLS are detailed in the chip configuration details for this device. After wakeup from LLS, the device returns to the run mode from which LLS was entered (either normal RUN or VLPR) with a pending LLWU module interrupt. If LLS was entered from VLPR mode, then the MCU will begin VLPR entry shortly after wake-up. In the LLWU interrupt service routine (ISR), the user can poll the LLWU module wakeup flags to determine the source of the wakeup.

It should go back the RUN mode from which LLS was entered?

0 Kudos
Reply

2,076 Views
diandizhu
Contributor II

And If I setup llwu and lptmr correctly, what do I expect to see in llwu and lptmr handler? Should see the lptmr triggered first, and stopped at the breakpoint I set in the lptmr handler and then if hit run I would see llwu handler triggered by lptmr? and the cpu wake up?

Now I haven't see llwu handler be trrigered. The lptmr seems working.

0 Kudos
Reply

2,076 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Diandi,

Sorry, although I am not familiar with RTX os from keil, can the mcu enter lls3 after you executing the code?

SMC_SetPowerModeLls(SMC, &lls_config);

what is your issue?

BR

Xiangjun Rong

2,076 Views
diandizhu
Contributor II

Hi Xiangjun,

I am new to rtos and not quite familiar with low power mode on NXP mcus. I feel it's not entering the low power mode, cause the current was still same(about 13ma) after I stepped over "SMC_SetPowerModeLls(SMC, &lls_config);".  I wrote the code based on KDS2.0 example "power_manager_frdmkl82z". Did I missing something so it didnt enter to lls mode? How can I test if its in lls mode?

Thank you very much for your reply.

Best,

Diandi

0 Kudos
Reply