From 8bcde2e40fd64df9347344dec1b311994850b0e4 Mon Sep 17 00:00:00 2001 From: Adam Dunkels Date: Wed, 2 Sep 2015 12:05:47 +0200 Subject: [PATCH] Tickless bugfixes: * The clock interrupt must be scheduled relative to the last interrupt, not relative to the current time (which may have progressed significantly) * clock_time() must increase continuously, so that code that may be spinning around clock_time() will make progress, not only after each interrupt --- cpu/cc26xx-cc13xx/clock.c | 36 ++++++++++++++++++--------------- cpu/cc26xx-cc13xx/dev/soc-rtc.c | 10 +++++++++ cpu/cc26xx-cc13xx/dev/soc-rtc.h | 2 ++ cpu/cc26xx-cc13xx/lpm.c | 2 +- 4 files changed, 33 insertions(+), 17 deletions(-) diff --git a/cpu/cc26xx-cc13xx/clock.c b/cpu/cc26xx-cc13xx/clock.c index fd8165d0d..4f6df056f 100644 --- a/cpu/cc26xx-cc13xx/clock.c +++ b/cpu/cc26xx-cc13xx/clock.c @@ -120,31 +120,35 @@ clock_init(void) ((TIMER_CFG_B_ONE_SHOT >> 8) & 0xFF) | GPT_TBMR_TBPWMIE; } /*---------------------------------------------------------------------------*/ +static void +update_clock_variable(void) +{ + uint32_t aon_rtc_secs_now; + uint32_t aon_rtc_secs_now2; + uint16_t aon_rtc_ticks_now; + + do { + aon_rtc_secs_now = HWREG(AON_RTC_BASE + AON_RTC_O_SEC); + aon_rtc_ticks_now = HWREG(AON_RTC_BASE + AON_RTC_O_SUBSEC) >> 16; + aon_rtc_secs_now2 = HWREG(AON_RTC_BASE + AON_RTC_O_SEC); + } while(aon_rtc_secs_now != aon_rtc_secs_now2); + + /* Convert AON RTC ticks to clock tick counter */ + count = (aon_rtc_secs_now * CLOCK_SECOND) + (aon_rtc_ticks_now >> 9); +} +/*---------------------------------------------------------------------------*/ CCIF clock_time_t clock_time(void) { + update_clock_variable(); + return (clock_time_t)(count & 0xFFFFFFFF); } /*---------------------------------------------------------------------------*/ void clock_update(void) { - bool interrupts_disabled; - uint32_t aon_rtc_secs_now; - uint16_t aon_rtc_ticks_now; - - interrupts_disabled = ti_lib_int_master_disable(); - - aon_rtc_secs_now = HWREG(AON_RTC_BASE + AON_RTC_O_SEC); - aon_rtc_ticks_now = HWREG(AON_RTC_BASE + AON_RTC_O_SUBSEC) >> 16; - - /* Convert AON RTC ticks to clock tick counter */ - count = (aon_rtc_secs_now * CLOCK_SECOND) + (aon_rtc_ticks_now >> 9); - - /* Re-enable interrupts */ - if(!interrupts_disabled) { - ti_lib_int_master_enable(); - } + update_clock_variable(); if(etimer_pending()) { etimer_request_poll(); diff --git a/cpu/cc26xx-cc13xx/dev/soc-rtc.c b/cpu/cc26xx-cc13xx/dev/soc-rtc.c index 16a967b9d..fb5394947 100644 --- a/cpu/cc26xx-cc13xx/dev/soc-rtc.c +++ b/cpu/cc26xx-cc13xx/dev/soc-rtc.c @@ -50,6 +50,8 @@ /*---------------------------------------------------------------------------*/ /* Prototype of a function in clock.c. Called every time the handler fires */ void clock_update(void); + +static rtimer_clock_t last_isr_time; /*---------------------------------------------------------------------------*/ #define COMPARE_INCREMENT (RTIMER_SECOND / CLOCK_SECOND) #define MULTIPLE_512_MASK 0xFFFFFE00 @@ -130,6 +132,12 @@ soc_rtc_schedule_one_shot(uint32_t channel, uint32_t ticks) ti_lib_aon_rtc_channel_enable(channel); } /*---------------------------------------------------------------------------*/ +rtimer_clock_t +soc_rtc_last_isr_time(void) +{ + return last_isr_time; +} +/*---------------------------------------------------------------------------*/ /* The AON RTC interrupt handler */ void soc_rtc_isr(void) @@ -138,6 +146,8 @@ soc_rtc_isr(void) ENERGEST_ON(ENERGEST_TYPE_IRQ); + last_isr_time = RTIMER_NOW(); + now = ti_lib_aon_rtc_current_compare_value_get(); /* Adjust the s/w tick counter irrespective of which event trigger this */ diff --git a/cpu/cc26xx-cc13xx/dev/soc-rtc.h b/cpu/cc26xx-cc13xx/dev/soc-rtc.h index ff6a266ff..cedf318c5 100644 --- a/cpu/cc26xx-cc13xx/dev/soc-rtc.h +++ b/cpu/cc26xx-cc13xx/dev/soc-rtc.h @@ -92,6 +92,8 @@ rtimer_clock_t soc_rtc_get_next_trigger(void); * instead use Contiki's timer-related libraries */ void soc_rtc_schedule_one_shot(uint32_t channel, uint32_t t); + +rtimer_clock_t soc_rtc_last_isr_time(void); /*---------------------------------------------------------------------------*/ #endif /* SOC_RTC_H_ */ /*---------------------------------------------------------------------------*/ diff --git a/cpu/cc26xx-cc13xx/lpm.c b/cpu/cc26xx-cc13xx/lpm.c index 2f7b964f8..cc3e49023 100644 --- a/cpu/cc26xx-cc13xx/lpm.c +++ b/cpu/cc26xx-cc13xx/lpm.c @@ -292,7 +292,7 @@ lpm_drop() if(next_event) { next_event = next_event - clock_time(); - soc_rtc_schedule_one_shot(AON_RTC_CH1, RTIMER_NOW() + + soc_rtc_schedule_one_shot(AON_RTC_CH1, soc_rtc_last_isr_time() + (next_event * (RTIMER_SECOND / CLOCK_SECOND))); }