alarm
This commit is contained in:
parent
24f1155d76
commit
b654a6f467
@ -35,7 +35,7 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* only controlled resets to 0 are performed, no direct set to counter
|
||||
* working counter region is from 0 to to_end
|
||||
* working counter region is from 0 to TO_END
|
||||
* all public functions are synchronized with disabled irqs
|
||||
*
|
||||
****************************************************************************/
|
||||
@ -71,85 +71,98 @@
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t to_reset = UINT32_MAX / 2;
|
||||
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 TO_RESET = UINT32_MAX / 2;
|
||||
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; /* any alarm should no last more than UINT32_MAX/8 */
|
||||
static struct timespec MAX_TS;
|
||||
|
||||
static uint32_t reset_ticks = 1000; /* ticks to add to force a reset */
|
||||
static uint32_t COMMON_DEV;
|
||||
static uint32_t MIN_TICKS;
|
||||
static uint32_t MIN_NSEC;
|
||||
|
||||
static uint64_t base = 0; /* time base */
|
||||
static uint32_t RESET_TICKS = 1000; /* ticks to add to force a reset */
|
||||
|
||||
static uint64_t alarm_time = 0; /* alarmTime to set on next interrupt, used if not already armed */
|
||||
static struct timespec base_ts; /* time base */
|
||||
static uint32_t base_rest; /* rest of ticks that is < MIN_TICKS*/
|
||||
|
||||
static struct timespec alarm_time_ts; /* alarmTime to set on next interrupt, used if not already armed */
|
||||
|
||||
static bool alarm_time_set = false; /* true if alarm_time set and need to be processed */
|
||||
static bool call = false; /* true if callback should be called on next interrupt */
|
||||
static bool forced_int = false; /* true if interrupt was forced with mask, no reset */
|
||||
static bool armed = false; /* true if alarm is armed for next match */
|
||||
static uint32_t synch = 0; /* synch all calls, recursion is possible */
|
||||
static irqstate_t g_flags;
|
||||
|
||||
static uint32_t ctrl_cache;
|
||||
static uint32_t mask_cache;
|
||||
static uint32_t compare_cache;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/* some timer HW functions */
|
||||
|
||||
static inline void lpc43_tl_set_counter (uint32_t value)
|
||||
static inline void lpc43_tl_set_counter (uint32_t value)
|
||||
{
|
||||
putreg32(value, LPC43_RIT_COUNTER);
|
||||
}
|
||||
|
||||
static inline uint32_t lpc43_tl_get_counter (void)
|
||||
static inline uint32_t lpc43_tl_get_counter (void)
|
||||
{
|
||||
return getreg32(LPC43_RIT_COUNTER);
|
||||
}
|
||||
|
||||
static inline void lpc43_tl_set_compare (uint32_t value)
|
||||
static inline void lpc43_tl_set_compare (uint32_t value)
|
||||
{
|
||||
putreg32(value, LPC43_RIT_COMPVAL);
|
||||
if ( value != compare_cache)
|
||||
{
|
||||
compare_cache = value;
|
||||
putreg32(value, LPC43_RIT_COMPVAL);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t lpc43_tl_get_compare (void)
|
||||
{
|
||||
return getreg32(LPC43_RIT_COMPVAL);
|
||||
return compare_cache;
|
||||
}
|
||||
|
||||
static inline void lpc43_tl_set_mask (uint32_t value)
|
||||
static inline void lpc43_tl_set_mask (uint32_t value)
|
||||
{
|
||||
putreg32(value, LPC43_RIT_MASK);
|
||||
if ( value != mask_cache)
|
||||
{
|
||||
mask_cache = value;
|
||||
putreg32(value, LPC43_RIT_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t lpc43_tl_get_mask (void)
|
||||
{
|
||||
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);
|
||||
if (value)
|
||||
{
|
||||
regval |= bit;
|
||||
}
|
||||
else
|
||||
{
|
||||
regval &= ~bit;
|
||||
}
|
||||
putreg32(regval, LPC43_RIT_CTRL);
|
||||
return mask_cache;
|
||||
}
|
||||
|
||||
static inline bool lpc43_tl_get_ctrl_bit (uint32_t bit)
|
||||
{
|
||||
uint32_t regval;
|
||||
regval = getreg32(LPC43_RIT_CTRL);
|
||||
regval &= bit;
|
||||
if (regval)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return ((ctrl_cache & bit)?true:false);
|
||||
}
|
||||
|
||||
static inline void lpc43_tl_set_ctrl_bit (uint32_t bit, bool value)
|
||||
{
|
||||
|
||||
if ( lpc43_tl_get_ctrl_bit(bit) != value ) {
|
||||
|
||||
if (value)
|
||||
{
|
||||
ctrl_cache |= bit;
|
||||
}
|
||||
else
|
||||
{
|
||||
ctrl_cache &= ~bit;
|
||||
}
|
||||
|
||||
putreg32(ctrl_cache, LPC43_RIT_CTRL);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void lpc43_tl_set_reset_on_match (bool value)
|
||||
@ -172,32 +185,113 @@ static inline bool lpc43_tl_get_enable (void)
|
||||
return lpc43_tl_get_ctrl_bit (RIT_CTRL_EN);
|
||||
}
|
||||
|
||||
static inline void lpc43_tl_clear_interrupt (void)
|
||||
static inline void lpc43_tl_clear_interrupt (void)
|
||||
{
|
||||
lpc43_tl_set_ctrl_bit (RIT_CTRL_INT, true);
|
||||
putreg32(ctrl_cache | RIT_CTRL_INT, LPC43_RIT_CTRL);
|
||||
}
|
||||
|
||||
static inline bool lpc43_tl_get_interrupt (void)
|
||||
static inline bool lpc43_tl_get_interrupt (void)
|
||||
{
|
||||
return lpc43_tl_get_ctrl_bit (RIT_CTRL_INT);
|
||||
return (( getreg32(LPC43_RIT_CTRL) & RIT_CTRL_INT )?true:false);
|
||||
}
|
||||
|
||||
/* converters */
|
||||
static uint32_t commonDev(uint32_t a, uint32_t b)
|
||||
{
|
||||
while(b !=0)
|
||||
{
|
||||
int h = a%b;
|
||||
a = b;
|
||||
b = h;
|
||||
}
|
||||
|
||||
static inline uint64_t lpc43_tl_ts2tick ( FAR const struct timespec *ts)
|
||||
return a;
|
||||
}
|
||||
|
||||
static void lpc43_tl_add(FAR const struct timespec *ts1,
|
||||
FAR const struct timespec *ts2,
|
||||
FAR struct timespec *ts3)
|
||||
{
|
||||
time_t sec = ts1->tv_sec + ts2->tv_sec;
|
||||
long nsec = ts1->tv_nsec + ts2->tv_nsec;
|
||||
|
||||
if (nsec >= NSEC_PER_SEC)
|
||||
{
|
||||
nsec -= NSEC_PER_SEC;
|
||||
sec++;
|
||||
}
|
||||
|
||||
ts3->tv_sec = sec;
|
||||
ts3->tv_nsec = nsec;
|
||||
}
|
||||
|
||||
static void lpc43_tl_sub(FAR const struct timespec *ts1,
|
||||
FAR const struct timespec *ts2,
|
||||
FAR struct timespec *ts3)
|
||||
{
|
||||
time_t sec;
|
||||
long nsec;
|
||||
|
||||
if (ts1->tv_sec < ts2->tv_sec)
|
||||
{
|
||||
sec = 0;
|
||||
nsec = 0;
|
||||
}
|
||||
else if (ts1->tv_sec == ts2->tv_sec && ts1->tv_nsec <= ts2->tv_nsec)
|
||||
{
|
||||
sec = 0;
|
||||
nsec = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sec = ts1->tv_sec - ts2->tv_sec;
|
||||
if (ts1->tv_nsec < ts2->tv_nsec)
|
||||
{
|
||||
nsec = (ts1->tv_nsec + NSEC_PER_SEC) - ts2->tv_nsec;
|
||||
sec--;
|
||||
}
|
||||
else
|
||||
{
|
||||
nsec = ts1->tv_nsec - ts2->tv_nsec;
|
||||
}
|
||||
}
|
||||
|
||||
ts3->tv_sec = sec;
|
||||
ts3->tv_nsec = nsec;
|
||||
}
|
||||
|
||||
static inline uint32_t lpc43_tl_ts2tick ( FAR const struct timespec *ts)
|
||||
{
|
||||
return ( (uint64_t)(ts->tv_sec)*LPC43_CCLK + ( (uint64_t)(ts->tv_nsec)*LPC43_CCLK/NSEC_PER_SEC) );
|
||||
return ( ts->tv_sec*LPC43_CCLK + ( ts->tv_nsec/MIN_NSEC*MIN_TICKS ) );
|
||||
}
|
||||
|
||||
static inline void lpc43_tl_tick2ts (uint64_t tick, FAR struct timespec *ts)
|
||||
static uint32_t lpc43_tl_tick2ts (uint32_t ticks, FAR struct timespec *ts, bool with_rest)
|
||||
{
|
||||
ts->tv_sec = tick/LPC43_CCLK;
|
||||
ts->tv_nsec = (tick%LPC43_CCLK)*NSEC_PER_SEC/LPC43_CCLK;
|
||||
|
||||
uint32_t ticks_whole;
|
||||
uint32_t ticks_rest = 0;
|
||||
|
||||
if (with_rest)
|
||||
{
|
||||
uint32_t ticks_mult = ticks/MIN_TICKS;
|
||||
ticks_whole = ticks_mult*MIN_TICKS;
|
||||
ticks_rest = ticks - ticks_whole;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ticks_whole = ticks;
|
||||
}
|
||||
|
||||
ts->tv_sec = ticks_whole/LPC43_CCLK;
|
||||
ts->tv_nsec = ((ticks_whole%LPC43_CCLK)/MIN_TICKS)*MIN_NSEC;
|
||||
|
||||
return ticks_rest;
|
||||
}
|
||||
|
||||
/* logic functions */
|
||||
|
||||
static void lpc43_tl_sync_up (void) {
|
||||
static inline void lpc43_tl_sync_up (void) {
|
||||
irqstate_t flags;
|
||||
flags = irqsave ();
|
||||
|
||||
@ -209,7 +303,7 @@ static void lpc43_tl_sync_up (void) {
|
||||
synch++;
|
||||
}
|
||||
|
||||
static void lpc43_tl_sync_down (void) {
|
||||
static inline void lpc43_tl_sync_down (void) {
|
||||
synch--;
|
||||
if ( synch == 0 )
|
||||
{
|
||||
@ -219,7 +313,7 @@ static void lpc43_tl_sync_down (void) {
|
||||
|
||||
/* assuming safe timer state, force interrupt, no reset possible */
|
||||
|
||||
static void lpc43_tl_force_int (void)
|
||||
static inline void lpc43_tl_force_int (void)
|
||||
{
|
||||
forced_int = true;
|
||||
lpc43_tl_set_reset_on_match (false);
|
||||
@ -229,22 +323,22 @@ static void lpc43_tl_force_int (void)
|
||||
|
||||
/* init all vars, forced_int should not be cleared */
|
||||
|
||||
static void lpc43_tl_init_timer_vars (void)
|
||||
static inline void lpc43_tl_init_timer_vars (void)
|
||||
{
|
||||
alarm_time = 0;
|
||||
alarm_time_set = false;
|
||||
call = false;
|
||||
armed = false;
|
||||
|
||||
}
|
||||
|
||||
/* calc reset_ticks and set compare to to_reset */
|
||||
/* calc RESET_TICKS and set compare to TO_RESET */
|
||||
|
||||
static void lpc43_tl_calibrate_init (void)
|
||||
{
|
||||
uint32_t counter = lpc43_tl_get_counter ();
|
||||
|
||||
uint32_t counter_after = lpc43_tl_get_counter ();
|
||||
counter_after = to_reset + counter;
|
||||
counter_after = TO_RESET + counter;
|
||||
counter_after = counter_after - counter;
|
||||
|
||||
/*shift to toReset*/
|
||||
@ -253,13 +347,13 @@ static void lpc43_tl_calibrate_init (void)
|
||||
|
||||
counter_after = lpc43_tl_get_counter ();
|
||||
|
||||
reset_ticks = (counter_after - counter) * 2;
|
||||
RESET_TICKS = (counter_after - counter) * 2;
|
||||
|
||||
}
|
||||
|
||||
/* process current and set timer in default safe state */
|
||||
|
||||
static void lpc43_tl_save_timer (void)
|
||||
static void lpc43_tl_save_timer (bool from_isr)
|
||||
{
|
||||
if (forced_int) /* special case of forced interrupt by mask*/
|
||||
{
|
||||
@ -280,12 +374,13 @@ static void lpc43_tl_save_timer (void)
|
||||
lpc43_tl_set_compare (UINT32_MAX);
|
||||
lpc43_tl_set_mask (0);
|
||||
|
||||
if (lpc43_tl_get_interrupt ())
|
||||
if (from_isr || lpc43_tl_get_interrupt ())
|
||||
{
|
||||
if (lpc43_tl_get_reset_on_match ()) /*was reset ?*/
|
||||
{
|
||||
base = base + match;
|
||||
lpc43_tl_set_reset_on_match (false);
|
||||
struct timespec match_ts;
|
||||
base_rest = lpc43_tl_tick2ts(match + base_rest, &match_ts,true);
|
||||
lpc43_tl_add(&base_ts, &match_ts,&base_ts);
|
||||
}
|
||||
lpc43_tl_clear_interrupt ();
|
||||
}
|
||||
@ -296,7 +391,7 @@ static void lpc43_tl_save_timer (void)
|
||||
|
||||
static bool lpc43_tl_set_safe_compare (uint32_t compare_to_set)
|
||||
{
|
||||
if (compare_to_set < to_reset)
|
||||
if (compare_to_set < TO_RESET)
|
||||
{
|
||||
lpc43_tl_set_reset_on_match (false);
|
||||
}
|
||||
@ -324,7 +419,6 @@ static bool lpc43_tl_set_safe_compare (uint32_t compare_to_set)
|
||||
}
|
||||
else
|
||||
{
|
||||
lpc43_tl_set_reset_on_match (false);
|
||||
lpc43_tl_set_compare (UINT32_MAX);
|
||||
|
||||
return false;
|
||||
@ -338,12 +432,12 @@ 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 */
|
||||
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);
|
||||
lpc43_tl_get_counter () + RESET_TICKS * i);
|
||||
};
|
||||
}
|
||||
|
||||
@ -354,15 +448,15 @@ static bool lpc43_tl_set_calc_arm (uint32_t curr, uint32_t to_set, bool arm)
|
||||
|
||||
uint32_t calcTime;
|
||||
|
||||
if (curr < to_reset_next)
|
||||
if (curr < TO_RESET_NEXT)
|
||||
{
|
||||
calcTime = min(to_reset_next, to_set);
|
||||
calcTime = min(TO_RESET_NEXT, to_set);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (curr < to_end)
|
||||
if (curr < TO_END)
|
||||
{
|
||||
calcTime = min(lpc43_tl_get_counter () + reset_ticks, to_set);
|
||||
calcTime = min(curr + RESET_TICKS, to_set);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -383,9 +477,9 @@ static bool lpc43_tl_set_calc_arm (uint32_t curr, uint32_t to_set, bool arm)
|
||||
|
||||
/* assuming safe timer state, try to set compare for normal operation */
|
||||
|
||||
static void lpc43_tl_set_default_compare (void)
|
||||
static void lpc43_tl_set_default_compare (uint32_t curr)
|
||||
{
|
||||
bool result = lpc43_tl_set_calc_arm (lpc43_tl_get_counter (), UINT32_MAX,
|
||||
bool result = lpc43_tl_set_calc_arm (curr, UINT32_MAX,
|
||||
false);
|
||||
if (!result)
|
||||
{
|
||||
@ -399,17 +493,36 @@ static void lpc43_tl_set_default_compare (void)
|
||||
|
||||
}
|
||||
|
||||
/* calculates ticks to set from alarm_time_ts and base_ts/base_rest, UINT32_MAX if overflow */
|
||||
static inline uint32_t lpc43_tl_calc_to_set (void)
|
||||
{
|
||||
struct timespec diff_ts;
|
||||
struct timespec ovf_ts;
|
||||
|
||||
lpc43_tl_sub(&alarm_time_ts,&base_ts,&diff_ts);
|
||||
|
||||
lpc43_tl_sub(&diff_ts,&MAX_TS,&ovf_ts);
|
||||
if ( ovf_ts.tv_sec == 0 && ovf_ts.tv_nsec == 0 ) /* check overflow */
|
||||
{
|
||||
return ( lpc43_tl_ts2tick(&diff_ts) - base_rest );
|
||||
}
|
||||
else
|
||||
{
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* assuming safe timer state, used by isr: sets default compare , calls alarm */
|
||||
static inline void lpc43_tl_alarm (void)
|
||||
static inline void lpc43_tl_alarm (uint32_t curr)
|
||||
{
|
||||
lpc43_tl_init_timer_vars ();
|
||||
lpc43_tl_set_default_compare ();
|
||||
lpc43_tl_set_default_compare (curr);
|
||||
|
||||
struct timespec ts;
|
||||
|
||||
up_timer_gettime (&ts);
|
||||
|
||||
#ifdef CONFIG_SCHED_TICKLESS_ALARM
|
||||
struct timespec ts;
|
||||
up_timer_gettime(&ts);
|
||||
sched_alarm_expiration (&ts);
|
||||
#else
|
||||
sched_timer_expiration();
|
||||
@ -422,48 +535,48 @@ static int lpc43_tl_isr (int irq, FAR void *context)
|
||||
{
|
||||
lpc43_tl_sync_up();
|
||||
|
||||
lpc43_tl_save_timer();
|
||||
lpc43_tl_save_timer(true);
|
||||
|
||||
uint32_t curr = lpc43_tl_get_counter ();
|
||||
if (call)
|
||||
{
|
||||
lpc43_tl_alarm();
|
||||
lpc43_tl_alarm(curr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (armed)
|
||||
{
|
||||
lpc43_tl_alarm(); /* armed - call alarm */
|
||||
lpc43_tl_alarm(curr); /* armed - call alarm */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (alarm_time > 0) /* need to set alarm time */
|
||||
if (alarm_time_set) /* need to set alarm time */
|
||||
{
|
||||
int64_t toSet = alarm_time - base;
|
||||
uint32_t curr = lpc43_tl_get_counter ();
|
||||
uint32_t toSet = lpc43_tl_calc_to_set();
|
||||
|
||||
if (toSet > curr)
|
||||
{
|
||||
if (toSet > to_end)
|
||||
if (toSet > TO_END)
|
||||
{
|
||||
lpc43_tl_set_default_compare ();
|
||||
lpc43_tl_set_default_compare (curr);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool set = lpc43_tl_set_calc_arm (curr, toSet, true);
|
||||
if (!set)
|
||||
{
|
||||
lpc43_tl_alarm();
|
||||
lpc43_tl_alarm(curr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lpc43_tl_alarm();
|
||||
lpc43_tl_alarm(curr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lpc43_tl_set_default_compare ();
|
||||
lpc43_tl_set_default_compare (curr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -473,6 +586,7 @@ static int lpc43_tl_isr (int irq, FAR void *context)
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -482,6 +596,21 @@ void up_timer_initialize (void)
|
||||
irqstate_t flags;
|
||||
flags = irqsave ();
|
||||
|
||||
ctrl_cache = getreg32(LPC43_RIT_CTRL);
|
||||
ctrl_cache &= ~RIT_CTRL_INT; /* set interrupt to 0*/
|
||||
mask_cache = getreg32(LPC43_RIT_MASK);
|
||||
compare_cache = getreg32(LPC43_RIT_COMPVAL);
|
||||
|
||||
COMMON_DEV = commonDev(NSEC_PER_SEC,LPC43_CCLK);
|
||||
MIN_TICKS = LPC43_CCLK/COMMON_DEV;
|
||||
MIN_NSEC = NSEC_PER_SEC/COMMON_DEV;
|
||||
|
||||
base_ts.tv_sec = 0;
|
||||
base_ts.tv_nsec = 0;
|
||||
base_rest = 0;
|
||||
|
||||
lpc43_tl_tick2ts(TO_END,&MAX_TS,false);
|
||||
|
||||
lpc43_tl_set_enable (false);
|
||||
|
||||
lpc43_tl_set_compare (UINT32_MAX);
|
||||
@ -501,15 +630,15 @@ void up_timer_initialize (void)
|
||||
lpc43_tl_calibrate_init ();
|
||||
|
||||
irqrestore (flags);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* no reg changes, only processing */
|
||||
int up_timer_gettime (FAR struct timespec *ts)
|
||||
{
|
||||
lpc43_tl_sync_up();
|
||||
|
||||
uint64_t curr;
|
||||
/* no reg changes, only processing */
|
||||
|
||||
/* order of calls is important, reset can come during processing */
|
||||
|
||||
bool reset = lpc43_tl_get_interrupt ();
|
||||
@ -518,30 +647,28 @@ int up_timer_gettime (FAR struct timespec *ts)
|
||||
/* not processed reset can exist */
|
||||
if (lpc43_tl_get_reset_on_match ())
|
||||
{
|
||||
bool resetAfter = lpc43_tl_get_interrupt ();
|
||||
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 during processing? get new counter */
|
||||
{
|
||||
count = lpc43_tl_get_counter ();
|
||||
}
|
||||
|
||||
if (resetAfter)
|
||||
{
|
||||
curr = base + count + lpc43_tl_get_compare ();
|
||||
}
|
||||
else
|
||||
{
|
||||
curr = base + count;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
curr = base + count;
|
||||
if (resetAfter)
|
||||
{
|
||||
count += lpc43_tl_get_compare (); /* count should be smaller then UINT32_MAX-TO_END -> no overflow */
|
||||
}
|
||||
}
|
||||
|
||||
lpc43_tl_tick2ts (curr, ts);
|
||||
struct timespec count_ts;
|
||||
|
||||
|
||||
lpc43_tl_tick2ts(count + base_rest,&count_ts,false );
|
||||
|
||||
lpc43_tl_add(&base_ts,&count_ts,ts);
|
||||
|
||||
lpc43_tl_sync_down();
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -567,40 +694,40 @@ int up_alarm_start (FAR const struct timespec *ts)
|
||||
{
|
||||
lpc43_tl_sync_up();
|
||||
|
||||
lpc43_tl_save_timer ();
|
||||
lpc43_tl_save_timer (false);
|
||||
|
||||
lpc43_tl_init_timer_vars ();
|
||||
lpc43_tl_init_timer_vars ();
|
||||
|
||||
alarm_time = lpc43_tl_ts2tick (ts);
|
||||
int64_t toSet = alarm_time - base;
|
||||
uint32_t curr = lpc43_tl_get_counter ();
|
||||
alarm_time_set = true;
|
||||
alarm_time_ts.tv_sec = ts->tv_sec;
|
||||
alarm_time_ts.tv_nsec = ts->tv_nsec;
|
||||
|
||||
if (toSet > curr)
|
||||
{
|
||||
if (toSet > to_end) /* future set */
|
||||
{
|
||||
lpc43_tl_set_default_compare ();
|
||||
}
|
||||
else
|
||||
{
|
||||
bool set = lpc43_tl_set_calc_arm (curr, toSet, true);
|
||||
if (!set)
|
||||
{
|
||||
/* signal call, force interrupt handler */
|
||||
uint32_t toSet = lpc43_tl_calc_to_set();
|
||||
|
||||
call = true;
|
||||
lpc43_tl_force_int ();
|
||||
}
|
||||
uint32_t curr = lpc43_tl_get_counter ();
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* signal call, force interrupt handler */
|
||||
if (toSet > curr)
|
||||
{
|
||||
if (toSet > TO_END) /* future set */
|
||||
{
|
||||
lpc43_tl_set_default_compare (curr);
|
||||
}
|
||||
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 */
|
||||
{
|
||||
call = true;
|
||||
lpc43_tl_force_int ();
|
||||
}
|
||||
|
||||
lpc43_tl_sync_down();
|
||||
|
||||
@ -613,27 +740,14 @@ int up_timer_cancel(FAR struct timespec *ts)
|
||||
{
|
||||
lpc43_tl_sync_up();
|
||||
|
||||
if (ts == NULL)
|
||||
if (ts != NULL)
|
||||
{
|
||||
up_alarm_cancel(ts);
|
||||
struct timespec abs_ts;
|
||||
up_timer_gettime(&abs_ts);
|
||||
lpc43_tl_sub( &alarm_time_ts,&abs_ts,ts );
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t saved_alarm_time = alarm_time;
|
||||
up_alarm_cancel(ts);
|
||||
int64_t diff = saved_alarm_time - lpc43_tl_ts2tick(ts);
|
||||
|
||||
if ( diff > 0 )
|
||||
{
|
||||
lpc43_tl_tick2ts(diff, ts);
|
||||
}
|
||||
else
|
||||
{
|
||||
ts->tv_sec = 0;
|
||||
ts->tv_nsec = 0;
|
||||
}
|
||||
|
||||
}
|
||||
lpc43_tl_init_timer_vars ();
|
||||
|
||||
lpc43_tl_sync_down();
|
||||
return OK;
|
||||
@ -644,13 +758,11 @@ int up_timer_start(FAR const struct timespec *ts)
|
||||
|
||||
lpc43_tl_sync_up();
|
||||
|
||||
struct timespec tmp_ts;
|
||||
up_timer_gettime(&tmp_ts);
|
||||
struct timespec abs_ts;
|
||||
up_timer_gettime(&abs_ts);
|
||||
lpc43_tl_add(&abs_ts,ts,&abs_ts);
|
||||
|
||||
tmp_ts.tv_sec += ts->tv_sec;
|
||||
tmp_ts.tv_nsec += ts->tv_nsec;
|
||||
|
||||
up_alarm_start(&tmp_ts);
|
||||
up_alarm_start(&abs_ts);
|
||||
|
||||
lpc43_tl_sync_down();
|
||||
return OK;
|
||||
|
Loading…
x
Reference in New Issue
Block a user