From 5acf3fb770d7ea3c01d7532fa1d185729a5b2551 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Thu, 21 Aug 2014 18:09:54 +0200 Subject: [PATCH 1/2] Fix time accounting on msp430 Series 5 MCU based platforms (wismote) See https://github.com/contiki-os/contiki/pull/727 for explanation --- cpu/msp430/f5xxx/clock.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/cpu/msp430/f5xxx/clock.c b/cpu/msp430/f5xxx/clock.c index 3cda89232..b0047a9e6 100644 --- a/cpu/msp430/f5xxx/clock.c +++ b/cpu/msp430/f5xxx/clock.c @@ -41,12 +41,26 @@ #define MAX_TICKS (~((clock_time_t)0) / 2) +#define CLOCK_LT(a, b) ((int16_t)((a)-(b)) < 0) + static volatile unsigned long seconds; static volatile clock_time_t count = 0; /* last_tar is used for calculating clock_fine, last_ccr might be better? */ static volatile uint16_t last_tar = 0; /*---------------------------------------------------------------------------*/ +static inline uint16_t +read_tar(void) +{ + /* Same as clock_counter(), but can be inlined */ + uint16_t t1, t2; + do { + t1 = TA1R; + t2 = TA1R; + } while(t1 != t2); + return t1; +} +/*---------------------------------------------------------------------------*/ ISR(TIMER1_A1, timera1) { ENERGEST_ON(ENERGEST_TYPE_IRQ); @@ -59,8 +73,9 @@ ISR(TIMER1_A1, timera1) * Occurs when timer state is toggled between STOP and CONT. */ while(TA1CTL & MC1 && TA1CCR1 - TA1R == 1); + last_tar = read_tar(); /* Make sure interrupt time is future */ - do { + while(!CLOCK_LT(last_tar, TA1CCR1)) { TA1CCR1 += INTERVAL; ++count; @@ -76,9 +91,8 @@ ISR(TIMER1_A1, timera1) ++seconds; energest_flush(); } - } while((TA1CCR1 - TA1R) > INTERVAL); - - last_tar = TA1R; + last_tar = read_tar(); + } if(etimer_pending() && (etimer_next_expiration_time() - count - 1) > MAX_TICKS) { From 0e9c0514851d800f7b91f15484d39571280bb334 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Thu, 21 Aug 2014 18:10:53 +0200 Subject: [PATCH 2/2] Fix time accounting on TI EXP5438 MSP430x5438a experimenters board --- platform/exp5438/clock.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/platform/exp5438/clock.c b/platform/exp5438/clock.c index 7a0dcaf72..be8fcca47 100644 --- a/platform/exp5438/clock.c +++ b/platform/exp5438/clock.c @@ -43,12 +43,26 @@ #define MAX_TICKS (~((clock_time_t)0) / 2) +#define CLOCK_LT(a, b) ((int16_t)((a)-(b)) < 0) + static volatile unsigned long seconds; static volatile clock_time_t count = 0; /* last_tar is used for calculating clock_fine, last_ccr might be better? */ static unsigned short last_tar = 0; /*---------------------------------------------------------------------------*/ +static inline uint16_t +read_tar(void) +{ + /* Same as clock_counter(), but can be inlined */ + uint16_t t1, t2; + do { + t1 = TA1R; + t2 = TA1R; + } while(t1 != t2); + return t1; +} +/*---------------------------------------------------------------------------*/ ISR(TIMER1_A1, timera1) { ENERGEST_ON(ENERGEST_TYPE_IRQ); @@ -59,8 +73,9 @@ ISR(TIMER1_A1, timera1) * Occurrs when timer state is toggled between STOP and CONT. */ while(TA1CTL & MC1 && TA1CCR1 - TA1R == 1); + last_tar = read_tar(); /* Make sure interrupt time is future */ - do { + while(!CLOCK_LT(last_tar, TA1CCR1)) { /* TACTL &= ~MC1;*/ TA1CCR1 += INTERVAL; /* TACTL |= MC1;*/ @@ -78,9 +93,8 @@ ISR(TIMER1_A1, timera1) ++seconds; energest_flush(); } - } while((TA1CCR1 - TA1R) > INTERVAL); - - last_tar = TA1R; + last_tar = read_tar(); + } if(etimer_pending() && (etimer_next_expiration_time() - count - 1) > MAX_TICKS) {