diff --git a/cpu/msp430-common/hwtimer_cpu.c b/cpu/msp430-common/hwtimer_cpu.c index 06f4f5cf71..511d341810 100644 --- a/cpu/msp430-common/hwtimer_cpu.c +++ b/cpu/msp430-common/hwtimer_cpu.c @@ -34,6 +34,9 @@ void (*int_handler)(int); extern void timerA_init(void); +#ifndef CC430 +extern void timerB_init(void); +#endif extern volatile msp430_timer_t msp430_timer[HWTIMER_MAXTIMERS]; @@ -90,7 +93,7 @@ static volatile unsigned int *get_comparator_reg_for_msp430_timer(int index) #else /* ... while other MSP430 MCUs have "TimerA", "TimerB". Cheers for TI and its consistency! */ - #define TIMER_VAL_REG (TAR) + #define TIMER_VAL_REG (TBR) #endif /* hardware-dependent functions */ @@ -141,6 +144,9 @@ unsigned long hwtimer_arch_now(void) void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu) { (void) fcpu; +#ifndef CC430 + timerB_init(); +#endif timerA_init(); int_handler = handler; } diff --git a/cpu/msp430-common/include/hwtimer_cpu.h b/cpu/msp430-common/include/hwtimer_cpu.h index afefc05b2c..167471c7f5 100644 --- a/cpu/msp430-common/include/hwtimer_cpu.h +++ b/cpu/msp430-common/include/hwtimer_cpu.h @@ -42,7 +42,15 @@ extern "C" { #define TIMER_A_MAXCOMP 0 #endif -#define HWTIMER_MAXTIMERS (TIMER_A_MAXCOMP) +#if defined (__MSP430_HAS_TB3__) +#define TIMER_B_MAXCOMP 3 +#elif defined (__MSP430_HAS_TB7__) +#define TIMER_B_MAXCOMP 7 +#else +#define TIMER_B_MAXCOMP 0 +#endif + +#define HWTIMER_MAXTIMERS (TIMER_A_MAXCOMP + TIMER_B_MAXCOMP) #ifndef HWTIMER_MAXTIMERS #warning "HWTIMER_MAXTIMERS UNSET!" diff --git a/cpu/msp430fxyz/hwtimer_msp430.c b/cpu/msp430fxyz/hwtimer_msp430.c index 954c3940c1..ad4d3f78fd 100644 --- a/cpu/msp430fxyz/hwtimer_msp430.c +++ b/cpu/msp430fxyz/hwtimer_msp430.c @@ -24,7 +24,7 @@ #include "hwtimer.h" #include "arch/hwtimer_arch.h" -#define ENABLE_DEBUG (1) +#define ENABLE_DEBUG (0) #include "debug.h" extern void (*int_handler)(int); @@ -33,6 +33,7 @@ extern void timer_unset(short timer); msp430_timer_t msp430_timer[HWTIMER_MAXTIMERS]; #define CCRA_NUM_TO_INDEX(ccr) (ccr) +#define CCRB_NUM_TO_INDEX(ccr) ((ccr) + TIMER_A_MAXCOMP) void timerA_init(void) { @@ -56,6 +57,29 @@ void timerA_init(void) TACTL |= MC_2; } +void timerB_init(void) +{ + + TBCTL = TBSSEL_1 + TBCLR; /* Clear the timer counter, set ACLK */ + TBCTL &= ~(TBIFG); /* Clear the IFG */ + TBCTL &= ~(TBIE); /* Disable TBIE (overflow IRQ) */ + + for (uint8_t i = 0; i < TIMER_B_MAXCOMP; i++) { + volatile unsigned int *ccr = &TBCCR0 + (i); + volatile unsigned int *ctl = &TBCCTL0 + (i); + *ccr = 0; + *ctl &= ~(CCIFG); + *ctl &= ~(CCIE); + + /* intialize the corresponding msp430_timer struct */ + short index = CCRB_NUM_TO_INDEX(i); + msp430_timer[index].base_timer = TIMER_B; + msp430_timer[index].ccr_num = i; + } + + TBCTL |= MC_2; +} + interrupt(TIMERA0_VECTOR) __attribute__((naked)) timerA_isr_ccr0(void) { __enter_isr(); @@ -78,3 +102,26 @@ interrupt(TIMERA1_VECTOR) __attribute__((naked)) timerA_isr(void) __exit_isr(); } + +interrupt(TIMERB0_VECTOR) __attribute__((naked)) timerB_isr_ccr0(void) +{ + __enter_isr(); + + short timer = CCRB_NUM_TO_INDEX(0); + timer_unset(timer); + int_handler(timer); + + __exit_isr(); +} + +interrupt(TIMERB1_VECTOR) __attribute__((naked)) timerB_isr(void) +{ + __enter_isr(); + + /* determine which CCR has been hit, and fire the appropriate callback */ + short timer = CCRB_NUM_TO_INDEX(TBIV >> 1); + timer_unset(timer); + int_handler(timer); + + __exit_isr(); +}