diff options
author | danh-arm <dan.handley@arm.com> | 2016-05-24 16:12:08 +0100 |
---|---|---|
committer | danh-arm <dan.handley@arm.com> | 2016-05-24 16:12:08 +0100 |
commit | e141aa0357fd4977ba874f4f86874e2cadc73498 (patch) | |
tree | cc01a644b84f7e07215a4920c3053ce4ddfb3f50 /drivers/delay_timer/delay_timer.c | |
parent | d1d716531db8d52101d9168a79d4b6acaef976fe (diff) | |
parent | 6704f425ddb2772bd9a2b9dacacbefcbb00dcf28 (diff) |
Merge pull request #625 from antonio-nino-diaz-arm/an/delay-timer-v2
Implement generic delay timer and use it on platforms
Diffstat (limited to 'drivers/delay_timer/delay_timer.c')
-rw-r--r-- | drivers/delay_timer/delay_timer.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/drivers/delay_timer/delay_timer.c b/drivers/delay_timer/delay_timer.c index 0bee876f..ed7ed52e 100644 --- a/drivers/delay_timer/delay_timer.c +++ b/drivers/delay_timer/delay_timer.c @@ -48,19 +48,22 @@ void udelay(uint32_t usec) (ops->clk_div != 0) && (ops->get_timer_value != 0)); - uint32_t start, cnt, delta, delta_us; + uint32_t start, delta, total_delta; + + assert(usec < UINT32_MAX / ops->clk_div); - /* counter is decreasing */ start = ops->get_timer_value(); + + total_delta = (usec * ops->clk_div) / ops->clk_mult; + do { - cnt = ops->get_timer_value(); - if (cnt > start) { - delta = UINT32_MAX - cnt; - delta += start; - } else - delta = start - cnt; - delta_us = (delta * ops->clk_mult) / ops->clk_div; - } while (delta_us < usec); + /* + * If the timer value wraps around, the subtraction will + * overflow and it will still give the correct result. + */ + delta = start - ops->get_timer_value(); /* Decreasing counter */ + + } while (delta < total_delta); } /*********************************************************** |