Commit 9b6b9b98 authored by Alessandro Rubini's avatar Alessandro Rubini

timer: fix overflow related bugs using time_after()

Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent 9f94bb86
...@@ -35,12 +35,11 @@ uint32_t timer_get_tics(void) ...@@ -35,12 +35,11 @@ uint32_t timer_get_tics(void)
void timer_delay(uint32_t tics) void timer_delay(uint32_t tics)
{ {
uint32_t t_start; uint32_t t_end;
// timer_init(1); // timer_init(1);
do {
t_start = timer_get_tics();
} while (t_start > UINT32_MAX - tics); //in case of overflow
while (t_start + tics > timer_get_tics()) ; t_end = timer_get_tics() + tics;
while (time_before(timer_get_tics(), t_end))
;
} }
...@@ -9,12 +9,8 @@ uint32_t timer_get_tics(void) ...@@ -9,12 +9,8 @@ uint32_t timer_get_tics(void)
void timer_delay(uint32_t tics) void timer_delay(uint32_t tics)
{ {
uint32_t t_start; uint32_t t_end = timer_get_tics() + tics;
t_start = timer_get_tics(); while (time_before(timer_get_tics(), t_end))
;
if(t_start + tics < t_start)
while(t_start + tics < timer_get_tics());
while(t_start + tics > timer_get_tics());
} }
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
uint64_t ptpd_netif_get_msec_tics(void) uint64_t ptpd_netif_get_msec_tics(void)
{ {
#if TICS_PER_SECOND != 1000
#error "This code assumes 1kHz timer"
#endif
return timer_get_tics(); return timer_get_tics();
} }
......
...@@ -44,7 +44,7 @@ extern int wrc_man_phase; ...@@ -44,7 +44,7 @@ extern int wrc_man_phase;
void wrc_mon_gui(void) void wrc_mon_gui(void)
{ {
static uint32_t last = 0; static uint32_t last;
hexp_port_state_t ps; hexp_port_state_t ps;
int tx, rx; int tx, rx;
uint64_t sec; uint64_t sec;
...@@ -53,7 +53,9 @@ void wrc_mon_gui(void) ...@@ -53,7 +53,9 @@ void wrc_mon_gui(void)
uint8_t ip[4]; uint8_t ip[4];
#endif #endif
if (timer_get_tics() - last < wrc_ui_refperiod) if (!last)
last = timer_get_tics();
if (time_before(timer_get_tics(), last + wrc_ui_refperiod))
return; return;
last = timer_get_tics(); last = timer_get_tics();
...@@ -191,14 +193,16 @@ void wrc_mon_gui(void) ...@@ -191,14 +193,16 @@ void wrc_mon_gui(void)
int wrc_log_stats(uint8_t onetime) int wrc_log_stats(uint8_t onetime)
{ {
static uint32_t last = 0; static uint32_t last;
hexp_port_state_t ps; hexp_port_state_t ps;
int tx, rx; int tx, rx;
int aux_stat; int aux_stat;
uint64_t sec; uint64_t sec;
uint32_t nsec; uint32_t nsec;
if (!onetime && timer_get_tics() - last < wrc_ui_refperiod) if (!last)
last = timer_get_tics();
if (!onetime && time_before(timer_get_tics(), last + wrc_ui_refperiod))
return 0; return 0;
last = timer_get_tics(); last = timer_get_tics();
......
...@@ -74,7 +74,7 @@ int wrc_mon_status() ...@@ -74,7 +74,7 @@ int wrc_mon_status()
void wrc_mon_gui(void) void wrc_mon_gui(void)
{ {
static uint32_t last = 0; static uint32_t last;
hexp_port_state_t ps; hexp_port_state_t ps;
int tx, rx; int tx, rx;
int aux_stat; int aux_stat;
...@@ -84,7 +84,9 @@ void wrc_mon_gui(void) ...@@ -84,7 +84,9 @@ void wrc_mon_gui(void)
uint8_t ip[4]; uint8_t ip[4];
#endif #endif
if (timer_get_tics() - last < wrc_ui_refperiod) if (!last)
last = timer_get_tics();
if (time_before(timer_get_tics(), last + wrc_ui_refperiod))
return; return;
last = timer_get_tics(); last = timer_get_tics();
...@@ -256,14 +258,16 @@ static void wrc_mon_std_servo(void) ...@@ -256,14 +258,16 @@ static void wrc_mon_std_servo(void)
int wrc_log_stats(uint8_t onetime) int wrc_log_stats(uint8_t onetime)
{ {
static uint32_t last = 0; static uint32_t last;
hexp_port_state_t ps; hexp_port_state_t ps;
int tx, rx; int tx, rx;
int aux_stat; int aux_stat;
uint64_t sec; uint64_t sec;
uint32_t nsec; uint32_t nsec;
if (!onetime && timer_get_tics() - last < wrc_ui_refperiod) if (!last)
last = timer_get_tics();
if (!onetime && time_before(timer_get_tics(), wrc_ui_refperiod + last))
return 0; return 0;
last = timer_get_tics(); last = timer_get_tics();
......
...@@ -114,8 +114,9 @@ static inline void sequencing_fsm(struct softpll_state *s, int tag_value, int ta ...@@ -114,8 +114,9 @@ static inline void sequencing_fsm(struct softpll_state *s, int tag_value, int ta
/* we need tags from at least one channel, so that the IRQ that calls this function /* we need tags from at least one channel, so that the IRQ that calls this function
gets called again */ gets called again */
spll_enable_tagger(MAIN_CHANNEL, 1); spll_enable_tagger(MAIN_CHANNEL, 1);
softpll.dac_timeout = timer_get_tics(); softpll.dac_timeout = timer_get_tics()
+ TICS_PER_SECOND / 20;
softpll.seq_state = SEQ_WAIT_CLEAR_DACS; softpll.seq_state = SEQ_WAIT_CLEAR_DACS;
break; break;
...@@ -124,8 +125,7 @@ static inline void sequencing_fsm(struct softpll_state *s, int tag_value, int ta ...@@ -124,8 +125,7 @@ static inline void sequencing_fsm(struct softpll_state *s, int tag_value, int ta
/* State "Wait until DACs have been cleared". Makes sure the VCO control inputs have stabilized before starting the PLL. */ /* State "Wait until DACs have been cleared". Makes sure the VCO control inputs have stabilized before starting the PLL. */
case SEQ_WAIT_CLEAR_DACS: case SEQ_WAIT_CLEAR_DACS:
{ {
if (timer_get_tics() - softpll.dac_timeout > if (time_after(timer_get_tics(), softpll.dac_timeout))
TICS_PER_SECOND / 20)
{ {
if(s->mode == SPLL_MODE_GRAND_MASTER) if(s->mode == SPLL_MODE_GRAND_MASTER)
s->seq_state = SEQ_START_EXT; s->seq_state = SEQ_START_EXT;
......
...@@ -52,15 +52,14 @@ static inline void realign_fsm(struct spll_external_state *s) ...@@ -52,15 +52,14 @@ static inline void realign_fsm(struct spll_external_state *s)
SPLL->ECCR |= SPLL_ECCR_ALIGN_EN; SPLL->ECCR |= SPLL_ECCR_ALIGN_EN;
s->realign_state = REALIGN_STAGE1_WAIT; s->realign_state = REALIGN_STAGE1_WAIT;
s->realign_timer = timer_get_tics(); s->realign_timer = timer_get_tics() + 2 * TICS_PER_SECOND;
break; break;
case REALIGN_STAGE1_WAIT: case REALIGN_STAGE1_WAIT:
if (SPLL->ECCR & SPLL_ECCR_ALIGN_DONE) if (SPLL->ECCR & SPLL_ECCR_ALIGN_DONE)
s->realign_state = REALIGN_STAGE2; s->realign_state = REALIGN_STAGE2;
else if (timer_get_tics() - s->realign_timer > else if (time_after(timer_get_tics(), s->realign_timer)) {
2 * TICS_PER_SECOND) {
SPLL->ECCR &= ~SPLL_ECCR_ALIGN_EN; SPLL->ECCR &= ~SPLL_ECCR_ALIGN_EN;
s->realign_state = REALIGN_PPS_INVALID; s->realign_state = REALIGN_PPS_INVALID;
} }
...@@ -75,7 +74,8 @@ static inline void realign_fsm(struct spll_external_state *s) ...@@ -75,7 +74,8 @@ static inline void realign_fsm(struct spll_external_state *s)
PPSG->ESCR = PPSG_ESCR_SYNC; PPSG->ESCR = PPSG_ESCR_SYNC;
s->realign_state = REALIGN_STAGE2_WAIT; s->realign_state = REALIGN_STAGE2_WAIT;
s->realign_timer = timer_get_tics(); s->realign_timer = timer_get_tics()
+ 2 * TICS_PER_SECOND;
} }
break; break;
...@@ -83,8 +83,7 @@ static inline void realign_fsm(struct spll_external_state *s) ...@@ -83,8 +83,7 @@ static inline void realign_fsm(struct spll_external_state *s)
if (PPSG->ESCR & PPSG_ESCR_SYNC) { if (PPSG->ESCR & PPSG_ESCR_SYNC) {
PPSG->ESCR = PPSG_ESCR_PPS_VALID | PPSG_ESCR_TM_VALID; PPSG->ESCR = PPSG_ESCR_PPS_VALID | PPSG_ESCR_TM_VALID;
s->realign_state = REALIGN_DONE; s->realign_state = REALIGN_DONE;
} else if (timer_get_tics() - s->realign_timer > } else if (time_after(timer_get_tics(), s->realign_timer)) {
2 * TICS_PER_SECOND) {
PPSG->ESCR = 0; PPSG->ESCR = 0;
s->realign_state = REALIGN_PPS_INVALID; s->realign_state = REALIGN_PPS_INVALID;
} }
......
...@@ -128,7 +128,7 @@ int wrc_ptp_set_mode(int mode) ...@@ -128,7 +128,7 @@ int wrc_ptp_set_mode(int mode)
while (!spll_check_lock(0) && lock_timeout) { while (!spll_check_lock(0) && lock_timeout) {
timer_delay_ms(1000); timer_delay_ms(1000);
mprintf("."); mprintf(".");
if (timer_get_tics() - start_tics > lock_timeout) { if (time_after(timer_get_tics(), start_tics + lock_timeout)) {
mprintf("\nLock timeout.\n"); mprintf("\nLock timeout.\n");
return -ETIMEDOUT; return -ETIMEDOUT;
} else if (uart_read_byte() == 27) { } else if (uart_read_byte() == 27) {
......
...@@ -10,7 +10,7 @@ const char *build_date; ...@@ -10,7 +10,7 @@ const char *build_date;
int main(void) int main(void)
{ {
uint32_t start_tics = 0; uint32_t start_tics = timer_get_tics();
uart_init_hw(); uart_init_hw();
...@@ -25,8 +25,8 @@ int main(void) ...@@ -25,8 +25,8 @@ int main(void)
for(;;) for(;;)
{ {
uint32_t tics = timer_get_tics(); uint32_t tics = timer_get_tics();
if(tics - start_tics > TICS_PER_SECOND/5) if(time_after(tics, start_tics + TICS_PER_SECOND/5))
{ {
// TRACE("tick!\n"); // TRACE("tick!\n");
spll_show_stats(); spll_show_stats();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment