summaryrefslogtreecommitdiff
path: root/drivers/delay_timer/delay_timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/delay_timer/delay_timer.c')
-rw-r--r--drivers/delay_timer/delay_timer.c23
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);
}
/***********************************************************