aboutsummaryrefslogtreecommitdiff
path: root/estorm/sys_timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'estorm/sys_timer.c')
-rw-r--r--estorm/sys_timer.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/estorm/sys_timer.c b/estorm/sys_timer.c
index 90236d7..2337e3f 100644
--- a/estorm/sys_timer.c
+++ b/estorm/sys_timer.c
@@ -8,10 +8,32 @@
/* The Periodic Interval Timer runs at 3MHz. */
#define PIT_FREQ (CLOCK_FREQ/16)
-void sys_timer_isr(void) {
+/* This counter keeps the system time. It is currently used only for
+ * the sleep code.
+ */
+static volatile unsigned long tick_ms;
+
+static void sys_timer_isr() {
+ unsigned long status;
+
+ /* The PIT requires reading the status register to acknowledge the
+ * interrupt. Let's do that.
+ */
+ status = *AT91C_PITC_PIVR;
+
+ /* Increment the system counter. */
+ tick_ms++;
+
+ /* Manually trigger the low priority kernel interrupt. This low
+ * priority interrupt will do all the slower tasks, that can be
+ * interrupted by hardware needing fast irq handling.
+ *
+ * TODO: Enable this when it has something to do.
+ */
+ //aic_trigger_irq(AT91C_ID_PWMC);
}
-void sys_timer_init(void) {
+void sys_timer_init() {
/* Set the Periodic Interval Timer to a tiny interval, and set it
* disabled. This way, it should wrap around and shut down quickly,
* if it's already running.
@@ -35,3 +57,19 @@ void sys_timer_init(void) {
AT91C_PITC_PITEN |
AT91C_PITC_PITIEN);
}
+
+unsigned long sys_timer_get_ms() {
+ return tick_ms;
+}
+
+void sys_timer_wait_ms(unsigned long ms) {
+ volatile unsigned long final = tick_ms + ms;
+
+ while (tick_ms < final);
+}
+
+void sys_timer_wait_ns(unsigned long ns) {
+ volatile unsigned long i = (ns >> 7) + 1;
+
+ while (i) i--;
+}