ESR-2025/src/timer.c
2025-07-03 08:37:46 +02:00

71 lines
2.2 KiB
C

/**
* \file timer.c
* \brief MSP430 Timer B driver and blocking delay implementation.
*
* This module provides a millisecond-level blocking delay function using
* low-power mode and global interrupts, as well as initialization for Timer B
* in up mode to generate periodic 1ms interrupts.
*/
#include <stdint.h>
#include <msp430.h>
#include <driverlib.h>
#include "timer.h"
/**
* \brief Block execution for a given number of milliseconds.
*
* Implements a blocking delay by entering LPM0 and waking up via the
* Timer interrupt on each millisecond tick.
*
* \param ms Number of milliseconds to delay.
*/
void sleep(uint16_t ms) {
while (ms--) {
/* Enter low-power mode 0 with interrupts enabled */
__bis_SR_register(LPM0_bits + GIE);
/* No operation, wait for interrupt */
__no_operation();
}
}
/**
* \brief Initialize Timer B0 in up mode to generate 1ms period interrupts.
*
* Configures Timer B0 to use SMCLK, no divider, and a period of 999 ticks
* to achieve a 1ms overflow (assuming 1MHz SMCLK). Enables CCR0 interrupt
* to exit low-power mode on each tick.
*/
void init_timer(void) {
static Timer_B_initUpModeParam param = {0};
/* Select SMCLK as clock source */
param.clockSource = TIMER_B_CLOCKSOURCE_SMCLK;
/* No division: tick = 1MHz / 1 = 1MHz */
param.clockSourceDivider = TIMER_B_CLOCKSOURCE_DIVIDER_1;
/* Period = 999 -> interrupt every 1000 ticks => 1ms */
param.timerPeriod = 999;
/* Disable interrupt on timer rollover (TBIE) */
param.timerInterruptEnable_TBIE = TIMER_B_TBIE_INTERRUPT_DISABLE;
/* Enable CCR0 interrupt on timer compare match */
param.captureCompareInterruptEnable_CCR0_CCIE =
TIMER_B_CAPTURECOMPARE_INTERRUPT_ENABLE;
/* Clear timer and start immediately */
param.timerClear = TIMER_B_DO_CLEAR;
param.startTimer = true;
/* Initialize and start Timer B0 in up mode */
Timer_B_initUpMode(TB0_BASE, &param);
}
/**
* \brief ISR for Timer0_B0 (CCR0) comparison event.
*
* Exits low-power mode 0 to resume the sleeping function.
*/
#pragma vector=TIMER0_B0_VECTOR
__interrupt void TIMER0_B0_ISR(void) {
/* Clear LPM0 bits on exit to wake up CPU */
__bic_SR_register_on_exit(LPM0_bits);
}