diff --git a/cpu/cc430/hwtimer_cc430.c b/cpu/cc430/hwtimer_cc430.c index 6c8ac8c19f..3423aaee0b 100644 --- a/cpu/cc430/hwtimer_cc430.c +++ b/cpu/cc430/hwtimer_cc430.c @@ -31,17 +31,15 @@ extern void (*int_handler)(int); extern void timer_unset(short timer); -extern volatile uint16_t overflow_interrupt[HWTIMER_MAXTIMERS+1]; -extern volatile uint16_t timer_round; void timerA_init(void) { volatile unsigned int *ccr = &TA0CCR0; volatile unsigned int *ctl = &TA0CCTL0; - timer_round = 0; /* Set to round 0 */ + TA0CTL = TASSEL_1 + TACLR; /* Clear the timer counter, set ACLK */ TA0CTL &= ~TAIFG; /* Clear the IFG */ - TA0CTL |= TAIE; /* Enable TAIE (overflow IRQ) */ + TA0CTL &= ~TAIE; /* Disable TAIE (overflow IRQ) */ for (int i = 0; i < HWTIMER_MAXTIMERS; i++) { *(ccr + i) = 0; @@ -56,10 +54,8 @@ interrupt(TIMER0_A0_VECTOR) __attribute__((naked)) timer0_a0_isr(void) { __enter_isr(); - if (overflow_interrupt[0] == timer_round) { - timer_unset(0); - int_handler(0); - } + timer_unset(0); + int_handler(0); __exit_isr(); } @@ -68,35 +64,10 @@ interrupt(TIMER0_A1_VECTOR) __attribute__((naked)) timer0_a1_5_isr(void) { __enter_isr(); - short taiv_reg = TA0IV; - if (taiv_reg == 0x0E) { - /* TAIV = 0x0E means overflow */ - DEBUG("Overflow\n"); - timer_round++; - } - else { - short timer = taiv_reg >> 1; - /* check which CCR has been hit and if the overflow counter - for this timer has been reached (or exceeded); - there is indeed a race condition where an hwtimer - due to fire in the next round can be set after - the timer's counter has overflowed but *before* - timer_round incrementation has occured (when - interrupts are disabled for any reason), thus - effectively setting the timer one round in the past! */ - int16_t round_delta = overflow_interrupt[timer] - timer_round; - /* in order to correctly handle timer_round overflow, - we must fire the timer when, for example, - timer_round == 0 and overflow_interrupt[timer] == 65535; - to that end, we compute the difference between the two - on a 16-bit signed integer: any difference >= +32768 will - thus overload to a negative number; we should then - correctly fire "overdue" timers whenever the case */ - if (round_delta <= 0) { - timer_unset(timer); - int_handler(timer); - } - } + /* determine which CCR has been hit, and fire the appropriate callback */ + short timer = TA0IV >> 1; + timer_unset(timer); + int_handler(timer); __exit_isr(); } diff --git a/cpu/msp430-common/hwtimer_cpu.c b/cpu/msp430-common/hwtimer_cpu.c index ff1a1cfad3..195ba1eee3 100644 --- a/cpu/msp430-common/hwtimer_cpu.c +++ b/cpu/msp430-common/hwtimer_cpu.c @@ -18,8 +18,6 @@ void (*int_handler)(int); extern void timerA_init(void); -volatile uint16_t overflow_interrupt[HWTIMER_MAXTIMERS+1]; -volatile uint16_t timer_round; #ifdef CC430 /* CC430 have "TimerA0", "TimerA1" and so on... */ @@ -55,7 +53,6 @@ static void timer_set_nostart(uint32_t value, short timer) if (value <= hwtimer_arch_now()) { value = hwtimer_arch_now() + 2; } - overflow_interrupt[timer] = (uint16_t)(value >> 16); *ptr = (value & 0xFFFF); } @@ -75,7 +72,7 @@ void timer_unset(short timer) unsigned long hwtimer_arch_now(void) { - return ((uint32_t)timer_round << 16) + TIMER_VAL_REG; + return (TIMER_VAL_REG & 0xffff); } void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu) diff --git a/cpu/msp430-common/include/hwtimer_cpu.h b/cpu/msp430-common/include/hwtimer_cpu.h index 0aed689a2d..0bcd9b9490 100644 --- a/cpu/msp430-common/include/hwtimer_cpu.h +++ b/cpu/msp430-common/include/hwtimer_cpu.h @@ -34,7 +34,7 @@ extern "C" { #endif #define HWTIMER_SPEED (F_RC_OSCILLATOR) -#define HWTIMER_MAXTICKS (0xFFFFFFFF) +#define HWTIMER_MAXTICKS (0x0000FFFF) #ifdef __cplusplus } diff --git a/cpu/msp430fxyz/hwtimer_msp430.c b/cpu/msp430fxyz/hwtimer_msp430.c index 941f1800b9..7e3f0551eb 100644 --- a/cpu/msp430fxyz/hwtimer_msp430.c +++ b/cpu/msp430fxyz/hwtimer_msp430.c @@ -29,19 +29,19 @@ extern void (*int_handler)(int); extern void timer_unset(short timer); -extern volatile uint16_t overflow_interrupt[HWTIMER_MAXTIMERS+1]; -extern volatile uint16_t timer_round; void timerA_init(void) { - timer_round = 0; /* Set to round 0 */ + volatile unsigned int *ccr; + volatile unsigned int *ctl; + TACTL = TASSEL_1 + TACLR; /* Clear the timer counter, set ACLK */ TACTL &= ~TAIFG; /* Clear the IFG */ - TACTL |= TAIE; /* Enable TAIE (overflow IRQ) */ + TACTL &= ~TAIE; /* Disable TAIE (overflow IRQ) */ for (int i = 0; i < HWTIMER_MAXTIMERS; i++) { - volatile unsigned int *ccr = &TACCR0 + (i); - volatile unsigned int *ctl = &TACCTL0 + (i); + ccr = &TACCR0 + (i); + ctl = &TACCTL0 + (i); *ccr = 0; *ctl &= ~(CCIFG); *ctl &= ~(CCIE); @@ -54,10 +54,8 @@ interrupt(TIMERA0_VECTOR) __attribute__((naked)) timer_isr_ccr0(void) { __enter_isr(); - if (overflow_interrupt[0] == timer_round) { - timer_unset(0); - int_handler(0); - } + timer_unset(0); + int_handler(0); __exit_isr(); } @@ -66,35 +64,10 @@ interrupt(TIMERA1_VECTOR) __attribute__((naked)) timer_isr(void) { __enter_isr(); - short taiv_reg = TAIV; - if (taiv_reg == 0x0A) { - /* TAIV = 0x0A means overflow */ - DEBUG("Overflow\n"); - timer_round++; - } - else { - short timer = taiv_reg >> 1; - /* check which CCR has been hit and if the overflow counter - for this timer has been reached (or exceeded); - there is indeed a race condition where an hwtimer - due to fire in the next round can be set after - the timer's counter has overflowed but *before* - timer_round incrementation has occured (when - interrupts are disabled for any reason), thus - effectively setting the timer one round in the past! */ - int16_t round_delta = overflow_interrupt[timer] - timer_round; - /* in order to correctly handle timer_round overflow, - we must fire the timer when, for example, - timer_round == 0 and overflow_interrupt[timer] == 65535; - to that end, we compute the difference between the two - on a 16-bit signed integer: any difference >= +32768 will - thus overload to a negative number; we should then - correctly fire "overdue" timers whenever the case */ - if (round_delta <= 0) { - timer_unset(timer); - int_handler(timer); - } - } + /* determine which CCR has been hit, and fire the appropriate callback */ + short timer = TAIV >> 1; + timer_unset(timer); + int_handler(timer); __exit_isr(); }