Low-power delay
The CCS ULP Advisor tool is a great tool because it provides useful hints to squeeze microampers out of an application.
One of the suggestions was to get rid of delay loops. So I investigated how to implement a delay using timers. Implementation was not as difficult as I would expect.
First of all, the counter the timer has to reach is calculated.
uint32_t lcounter = HW_ACLK_FREQUENCY * ms10th;
lcounter = lcounter / 10000;
uint16_t counter = (uint16_t)lcounter - 1;Then, Timer A needs to be initialized
/* Configure TimerA in up mode */
TIMER_A_configureUpMode(TIMER_A1_BASE,
TIMER_A_CLOCKSOURCE_ACLK,
TIMER_A_CLOCKSOURCE_DIVIDER_1,
counter,
TIMER_A_TAIE_INTERRUPT_DISABLE,
TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE,
TIMER_A_SKIP_CLEAR);
/* Start TimerA counter */
TIMER_A_startCounter(TIMER_A1_BASE, TIMER_A_UP_MODE);
Next, the MCU is put in Low power mode 3 (see my previous post for details about different power modes)
/* LPM3, TIMER_A1_ISR will force exit */
__bis_SR_register(LPM3_bits + GIE);
The interrupt routine is even simpler: just stop the timer and exit Low power mode 3
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=TIMER1_A0_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(TIMER1_A0_VECTOR)))
#endif
void TIMER1_A0_ISR_HOOK(void)
{
/* USER CODE START (section: TIMER1_A0_ISR_HOOK) */
TIMER_A_stop(TIMER_A1_BASE);
LPM3_EXIT; // Exit active CPU
/* USER CODE END (section: TIMER1_A0_ISR_HOOK) */
}