Hello all,

We continue to speak about timers, and the next victim is LETIMER0 – low energy timer!

The next example shows how to run this timer and how to move the MCU to EM2 mode (energy save) .

When the MCU receives the LETIMER0 interrupt, it wakes up automatically in active mode (EM0). The waking up takes 2 microseconds (2us) .

So, lets define LETIMER0 to make interrupt every 1 second:

uint8_t GO_TO_SLEEP=1;
int main() {
   uint16_t period=0;
   uint32_t letimer_clock=0;
   LETIMER_Init_TypeDef init_letimer;

   //This function I posted at the previous post: link to function   
   systemClocksInit();
   NVIC_EnableIRQ(LETIMER0_IRQn); //enable interrupts for LETIMER0
   letimer_clock = CMU_ClockFreqGet(cmuClock_LETIMER0);

   /*
   Period calculation: t * (clk/presc)+0.5 (must be less or equal to 16 bit), where:
      t - required time in seconds
      clk - timer clock
      presc - timer clock presceller, 1 - in LETIMER
      0.5 - rounding period to up
   */

   period = (uint16_t) 1 * (letimer_clock/1) +0.5; //we will get 32768
   init_letimer.enable = true; /* Start counting when init completed. */
   init_letimer.debugRun = false; /* Counter shall not keep running during debug halt. */
   init_letimer.rtcComp0Enable = false; /* Don't start counting on RTC COMP0 match. */
   init_letimer.rtcComp1Enable = false; /* Don't start counting on RTC COMP1 match. */
   init_letimer.comp0Top = true; /* Load COMP0 register into CNT when counter underflows. COMP0 is used as TOP */
   init_letimer.bufTop = false; /* Don't load COMP1 into COMP0 when REP0 reaches 0. */
   init_letimer.out0Pol = 0; /* Idle value for output 0. */
   init_letimer.out1Pol = 0; /* Idle value for output 1. */
   init_letimer.ufoa0 = letimerUFOANone; /* PWM output on output 0 */
   init_letimer.ufoa1 = letimerUFOANone; /* Pulse output on output 1*/
   init_letimer.repMode = letimerRepeatFree; /* Count until stopped */
   LETIMER_IntEnable(letim, LETIMER_IF_UF); /* LETIMER counts down, so we set underflow irq*/
   LETIMER_CompareSet(LETIMER0, 0, period); /* Setting up the timer TOP value, to count from it*/
   LETIMER_Init(letim, &init_letimer); /*LETIMER initialization and starting*/

   while(1) {
      if(GO_TO_SLEEP==1){
         EMU_EnterEM2(false); //go to sleep mode
      }
   }
}

/* Here we are defining the LETIMER0 interrupt: */
void LETIMER0_IRQHandler(){
   uint32_t flags;
   flags = LETIMER_IntGet(LETIMER0); //we get all interrupt flags
   if(flags & LETIMER_IF_UF){ //if interrupt is underflow interrupt
      LETIMER_IntClear(LETIMER0, LETIMER_IF_UF); //clear it
      GO_TO_SLEEP=0; //don't go to sleep, and make some work
   }
}

That’s all! 🙂
At the next post, I’ll publish full timer drivers for EFM32 MCU.
Bye, folks! 🙂