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! 🙂