From 08224b8606fa3aaaf3b66c931836976a29fd669b Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Sun, 1 Nov 2015 23:11:37 +0100 Subject: [PATCH] after debug --- arch/arm/src/lpc43xx/chip/lpc43_rit.h | 1 - arch/arm/src/lpc43xx/lpc43_tickless_rit.c | 408 ++++++++++++---------- 2 files changed, 222 insertions(+), 187 deletions(-) diff --git a/arch/arm/src/lpc43xx/chip/lpc43_rit.h b/arch/arm/src/lpc43xx/chip/lpc43_rit.h index 90c911e4ddb..71671cd3ab0 100644 --- a/arch/arm/src/lpc43xx/chip/lpc43_rit.h +++ b/arch/arm/src/lpc43xx/chip/lpc43_rit.h @@ -42,7 +42,6 @@ ************************************************************************************/ #include -#include "chip/lpc4310203050_memorymap.h" /************************************************************************************ * Pre-processor Definitions diff --git a/arch/arm/src/lpc43xx/lpc43_tickless_rit.c b/arch/arm/src/lpc43xx/lpc43_tickless_rit.c index e0f6cfb60bb..59a7979a3ef 100644 --- a/arch/arm/src/lpc43xx/lpc43_tickless_rit.c +++ b/arch/arm/src/lpc43xx/lpc43_tickless_rit.c @@ -41,9 +41,10 @@ #include #include +#include -#include "arch.h" -#include "time.h" +#include "up_arch.h" +#include "chip.h" #include "chip/lpc43_rit.h" #ifdef CONFIG_SCHED_TICKLESS @@ -52,17 +53,19 @@ * Pre-processor Definitions ****************************************************************************/ -#define LPC43_TL_NANOS_IN_SEC 1000000000 +#define LPC43_TL_NANOS_IN_SEC (1000000000) -#define LPC43_TL_NANOS_IN_TICK LPC43_TL_NANOS_IN_SEC/LPC43_CCLK +#ifndef min +# define min(a,b) a < b ? a : b +#endif /**************************************************************************** * Private Data ****************************************************************************/ static uint32_t to_reset = UINT32_MAX / 2; -static uint32_t to_reset_next = to_reset + UINT32_MAX / 4; -static uint32_t to_end = to_reset_next + UINT32_MAX / 8; +static uint32_t to_reset_next = UINT32_MAX / 2 + UINT32_MAX / 4; +static uint32_t to_end = UINT32_MAX / 2 + UINT32_MAX / 4 + UINT32_MAX / 8; static uint32_t reset_ticks = 1000; /* ticks to add to force a reset */ @@ -71,6 +74,9 @@ static uint64_t base = 0; /* time base */ static uint64_t alarm_time = 0; /* alarmTime to set on next interrupt, used if not already armed */ static bool call = false; /* true if callback should be called on next interrupt */ static bool armed = false; /* true if alarm is armed for next match */ +static bool in_isr = false; /* true if inside isr */ +static uint32_t synch = 0; +static irqstate_t g_flags; /**************************************************************************** * Private Functions @@ -80,38 +86,38 @@ static bool armed = false; /* true if alarm is armed for next match */ static inline void lpc43_tl_set_counter (uint32_t value) { - putreg32 (value, LPC43_RIT_COUNTER); + putreg32(value, LPC43_RIT_COUNTER); } static inline uint32_t lpc43_tl_get_counter (void) { - return getreg32 (LPC43_RIT_COUNTER); + return getreg32(LPC43_RIT_COUNTER); } static inline void lpc43_tl_set_compare (uint32_t value) { - putreg32 (value, LPC43_RIT_COMPVAL); + putreg32(value, LPC43_RIT_COMPVAL); } static inline uint32_t lpc43_tl_get_compare (void) { - return getreg32 (LPC43_RIT_COMPVAL); + return getreg32(LPC43_RIT_COMPVAL); } static inline void lpc43_tl_set_mask (uint32_t value) { - putreg32 (value, LPC43_RIT_MASK); + putreg32(value, LPC43_RIT_MASK); } static inline uint32_t lpc43_tl_get_mask (void) { - return getreg32 (LPC43_RIT_MASK); + return getreg32(LPC43_RIT_MASK); } static inline void lpc43_tl_set_ctrl_bit (uint32_t bit, bool value) { uint32_t regval; - regval = getreg32 (LPC43_RIT_CTRL); + regval = getreg32(LPC43_RIT_CTRL); if (value) { regval |= bit; @@ -120,21 +126,21 @@ static inline void lpc43_tl_set_ctrl_bit (uint32_t bit, bool value) { regval &= ~bit; } - putreg32 (regval, LPC43_RIT_CTRL); + putreg32(regval, LPC43_RIT_CTRL); } static inline bool lpc43_tl_get_ctrl_bit (uint32_t bit) { uint32_t regval; - regval = getreg32 (LPC43_RIT_CTRL); - regval |= bit; + regval = getreg32(LPC43_RIT_CTRL); + regval &= bit; if (regval) { - return true ; + return true; } else { - return false ; + return false; } } @@ -158,9 +164,9 @@ static inline bool lpc43_tl_get_enable (void) return lpc43_tl_get_ctrl_bit (RIT_CTRL_EN); } -static inline void lpc43_tl_clear_interrupt () +static inline void lpc43_tl_clear_interrupt (void) { - lpc43_tl_set_ctrl_bit (RIT_CTRL_EN, true); + lpc43_tl_set_ctrl_bit (RIT_CTRL_INT, true); } static inline bool lpc43_tl_get_interrupt (void) @@ -170,24 +176,42 @@ static inline bool lpc43_tl_get_interrupt (void) /* converters */ -static inline uint64_t lpc43_tl_ts2tick ( FAR struct timespec *ts) -{ - return ((ts->tv_nsec + ts->tv_sec * LPC43_TL_NANOS_IN_SEC) / LPC43_TL_NANOS_IN_TICK); -} +static inline uint64_t lpc43_tl_ts2tick ( FAR const struct timespec *ts) + { + return ( (uint64_t)(ts->tv_sec)*LPC43_CCLK + ( (uint64_t)(ts->tv_nsec)*LPC43_CCLK/LPC43_TL_NANOS_IN_SEC) ); + } static inline void lpc43_tl_tick2ts (uint64_t tick, FAR struct timespec *ts) -{ - uint64_t nanos = tick * LPC43_TL_NANOS_IN_TICK; - - ts->tv_sec = nanos / LPC43_TL_NANOS_IN_SEC; - ts->tv_nsec = nanos % LPC43_TL_NANOS_IN_SEC; -} + { + ts->tv_sec = tick/LPC43_CCLK; + ts->tv_nsec = (tick%LPC43_CCLK)*LPC43_TL_NANOS_IN_SEC/LPC43_CCLK; + } /* logic functions */ +static void lpc43_tl_sync_up (void) { + irqstate_t flags; + flags = irqsave (); + + if ( synch == 0 ) + { + g_flags = flags; + + } + synch++; +} + +static void lpc43_tl_sync_down (void) { + synch--; + if ( synch == 0 ) + { + irqrestore (g_flags); + } +} + /* force interrupt, no reset possible */ -static void lpc43_tl_force_int () +static void lpc43_tl_force_int (void) { lpc43_tl_set_reset_on_match (false); lpc43_tl_set_mask (UINT32_MAX); @@ -195,7 +219,7 @@ static void lpc43_tl_force_int () /* init all vars */ -static void lpc43_tl_init_timer_vars () +static void lpc43_tl_init_timer_vars (void) { alarm_time = 0; call = false; @@ -204,7 +228,7 @@ static void lpc43_tl_init_timer_vars () /* calc reset_ticks and set compare to to_reset */ -static void lpc43_tl_calibrate_init () +static void lpc43_tl_calibrate_init (void) { uint32_t counter = lpc43_tl_get_counter (); @@ -224,7 +248,7 @@ static void lpc43_tl_calibrate_init () /* process current and set timer in default state */ -static void lpc43_tl_save_timer () +static void lpc43_tl_save_timer (void) { /*process reset if any*/ @@ -244,14 +268,20 @@ static void lpc43_tl_save_timer () lpc43_tl_set_reset_on_match (false); } lpc43_tl_clear_interrupt (); + + int i=0; + while( lpc43_tl_get_interrupt () ) { + i++; + } + } } /* assuming safe state, true if set, false - time is in the past */ -static bool lpc43_tl_set_safe_compare (uint32_t time) +static bool lpc43_tl_set_safe_compare (uint32_t compare_to_set) { - if (time < to_reset) + if (compare_to_set < to_reset) { lpc43_tl_set_reset_on_match (false); } @@ -260,7 +290,7 @@ static bool lpc43_tl_set_safe_compare (uint32_t time) lpc43_tl_set_reset_on_match (true); } - lpc43_tl_set_compare (time); + lpc43_tl_set_compare (compare_to_set); //check if ok bool reset = lpc43_tl_get_interrupt (); @@ -273,27 +303,29 @@ static bool lpc43_tl_set_safe_compare (uint32_t time) counter = lpc43_tl_get_counter (); } - if (reset_after || (!reset_after && time > counter)) + if (reset_after || (!reset_after && compare_to_set > counter)) { - return true ; + return true; } else { - return false ; + return false; } } /* set_safe_compare in loop */ -static void lpc43_tl_looped_forced_set_compare () +static void lpc43_tl_looped_forced_set_compare (void) { uint32_t i = 1; - bool result = lpc43_tl_set_safe_compare (lpc43_tl_get_counter () + reset_ticks); /* like in calibrateInit */ + bool result = lpc43_tl_set_safe_compare ( + lpc43_tl_get_counter () + reset_ticks); /* like in calibrateInit */ while (!result) { i++; - result = lpc43_tl_set_safe_compare (lpc43_tl_get_counter () + reset_ticks * i); + result = lpc43_tl_set_safe_compare ( + lpc43_tl_get_counter () + reset_ticks * i); }; } @@ -306,18 +338,18 @@ static bool lpc43_tl_set_calc_arm (uint32_t curr, uint32_t to_set, bool arm) if (curr < to_reset_next) { - calcTime = min (to_reset_next, to_set); + calcTime = min(to_reset_next, to_set); } else { if (curr < to_end) { - calcTime = min (lpc43_tl_get_counter () + reset_ticks, to_set); + calcTime = min(lpc43_tl_get_counter () + reset_ticks, to_set); } else { lpc43_tl_looped_forced_set_compare (); - return true ; + return true; } } @@ -333,12 +365,14 @@ static bool lpc43_tl_set_calc_arm (uint32_t curr, uint32_t to_set, bool arm) /* try to set compare for normal operation */ -static void lpc43_tl_set_default_compare () +static void lpc43_tl_set_default_compare (void) { - bool result = lpc43_tl_set_calc_arm (lpc43_tl_get_counter (), UINT32_MAX, false); + bool result = lpc43_tl_set_calc_arm (lpc43_tl_get_counter (), UINT32_MAX, + false); if (!result) { - result = lpc43_tl_set_calc_arm (lpc43_tl_get_counter (), UINT32_MAX, false); + result = lpc43_tl_set_calc_arm (lpc43_tl_get_counter (), UINT32_MAX, + false); if (!result) { lpc43_tl_looped_forced_set_compare (); @@ -347,80 +381,83 @@ static void lpc43_tl_set_default_compare () } -static inline void lpc43_tl_alarm() +static inline void lpc43_tl_alarm (void) { lpc43_tl_init_timer_vars (); lpc43_tl_set_default_compare (); struct timespec ts; - up_timer_gettime(&ts); + up_timer_gettime (&ts); - sched_alarm_expiration(&ts); + sched_alarm_expiration (&ts); } /* interrupt handler */ static int lpc43_tl_isr (int irq, FAR void *context) -{ - irqstate_t flags; - flags = irqsave (); + { + lpc43_tl_sync_up(); - if (call) - { - /* forced call case */ - lpc43_tl_set_mask (false); + in_isr = true; - lpc43_tl_clear_interrupt (); + if (call) + { + /* forced call case */ + lpc43_tl_set_mask (false); - lpc43_tl_alarm(); + lpc43_tl_clear_interrupt (); - } - else - { - lpc43_tl_save_timer (); + lpc43_tl_alarm(); - if (armed) - { - lpc43_tl_alarm(); - } - else - { - if (alarm_time > 0) - { - uint64_t toSet = alarm_time - base; - uint32_t curr = lpc43_tl_get_counter (); + } + else + { + lpc43_tl_save_timer (); - if (toSet > curr) - { - if (toSet > to_end) - { - lpc43_tl_set_default_compare (); - } - else - { - bool set = lpc43_tl_set_calc_arm (curr, toSet, true); - if (!set) - { - lpc43_tl_alarm(); - } - } - } - else - { - lpc43_tl_alarm(); - } - } - else - { - lpc43_tl_set_default_compare (); - } - } - } + if (armed) + { + lpc43_tl_alarm(); + } + else + { + if (alarm_time > 0) + { + int64_t toSet = alarm_time - base; + uint32_t curr = lpc43_tl_get_counter (); - irqrestore (flags); - return OK; -} + if (toSet > curr) + { + if (toSet > to_end) + { + lpc43_tl_set_default_compare (); + } + else + { + bool set = lpc43_tl_set_calc_arm (curr, toSet, true); + if (!set) + { + lpc43_tl_alarm(); + } + } + } + else + { + lpc43_tl_alarm(); + } + } + else + { + lpc43_tl_set_default_compare (); + } + } + } + + in_isr = false; + lpc43_tl_sync_down(); + + return OK; + } /**************************************************************************** * Public Functions @@ -453,134 +490,133 @@ void up_timer_initialize (void) } int up_timer_gettime (FAR struct timespec *ts) -{ - irqstate_t flags; - flags = irqsave (); + { + lpc43_tl_sync_up(); - uint32_t time; - /* no reg changes, only processing */ + uint64_t curr; + /* no reg changes, only processing */ - /* order of calls is important, reset can come during processing */ + /* order of calls is important, reset can come during processing */ - bool reset = lpc43_tl_get_interrupt (); - uint32_t count = lpc43_tl_get_counter (); + bool reset = lpc43_tl_get_interrupt (); + uint32_t count = lpc43_tl_get_counter (); - /* not processed reset can exist */ - if (lpc43_tl_get_reset_on_match ()) - { - bool resetAfter = lpc43_tl_get_interrupt (); + /* not processed reset can exist */ + if (lpc43_tl_get_reset_on_match ()) + { + bool resetAfter = lpc43_tl_get_interrupt (); - if (reset != resetAfter) /* was a reset get new counter */ - { - count = lpc43_tl_get_counter (); - } + if (reset != resetAfter) /* was a reset get new counter */ + { + count = lpc43_tl_get_counter (); + } - if (resetAfter) - { - time = base + count + lpc43_tl_get_compare (); - } - else - { - time = base + count; - } - } - else - { - time = base + count; - } + if (resetAfter) + { + curr = base + count + lpc43_tl_get_compare (); + } + else + { + curr = base + count; + } + } + else + { + curr = base + count; + } - lpc43_tl_tick2ts (time, ts); + lpc43_tl_tick2ts (curr, ts); - irqrestore (flags); - return OK; -} + lpc43_tl_sync_down(); + return OK; + } # ifdef CONFIG_SCHED_TICKLESS_ALARM int up_alarm_cancel (FAR struct timespec *ts) -{ - irqstate_t flags; - flags = irqsave (); + { + lpc43_tl_sync_up(); - /*no reg changes, only variables logic*/ + /*no reg changes, only variables logic*/ - up_timer_gettime (ts); + up_timer_gettime (ts); - /* let default setup will be done in interrupt handler or setAlarm */ - lpc43_tl_init_timer_vars (); + /* let default setup will be done in interrupt handler or setAlarm */ + lpc43_tl_init_timer_vars (); - irqrestore (flags); - return OK; -} + lpc43_tl_sync_down(); + return OK; + } int up_alarm_start (FAR const struct timespec *ts) -{ - irqstate_t flags; - flags = irqsave (); + { + lpc43_tl_sync_up(); - lpc43_tl_init_timer_vars (); + lpc43_tl_init_timer_vars (); - lpc43_tl_save_timer (); + if (in_isr) { + alarm_time = lpc43_tl_ts2tick (ts); + } else { + lpc43_tl_save_timer (); - //----calc time to set + //----calc time to set - uint64_t time = lpc43_tl_ts2tick (ts); - uint64_t toSet = time - base; - uint32_t curr = lpc43_tl_get_counter (); + uint64_t time = lpc43_tl_ts2tick (ts); + int64_t toSet = time - base; + uint32_t curr = lpc43_tl_get_counter (); - if (toSet > curr) - { - alarm_time = time; - - if (toSet > to_end) /* future set */ + if (toSet > curr) { - lpc43_tl_set_default_compare (); - } - else - { - bool set = lpc43_tl_set_calc_arm (curr, toSet, true); - if (!set) + alarm_time = time; + + if (toSet > to_end) /* future set */ { - /* signal call, force interrupt handler */ + lpc43_tl_set_default_compare (); + } + else + { + bool set = lpc43_tl_set_calc_arm (curr, toSet, true); + if (!set) + { + /* signal call, force interrupt handler */ + + call = true; + lpc43_tl_force_int (); + } - call = true; - lpc43_tl_force_int (); } } + else + { + /* signal call, force interrupt handler */ - } - else - { - /* signal call, force interrupt handler */ - - call = true; - lpc43_tl_force_int (); + call = true; + lpc43_tl_force_int (); + } } - irqrestore (flags); + lpc43_tl_sync_down(); - return OK; -} + return OK; + } # else int up_timer_cancel(FAR struct timespec *ts) { /*TODO*/ - irqstate_t flags; - flags = irqsave (); + lpc43_tl_sync_up(); - irqrestore (flags); + lpc43_tl_sync_down(); return OK; } int up_timer_start(FAR const struct timespec *ts) { /*TODO*/ - irqstate_t flags; - flags = irqsave (); + lpc43_tl_sync_up(); - irqrestore (flags); + lpc43_tl_sync_down(); return OK; }