aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--estorm/aic.c4
-rw-r--r--estorm/aic.h5
-rw-r--r--estorm/sys_timer.c42
-rw-r--r--estorm/sys_timer.h12
4 files changed, 61 insertions, 2 deletions
diff --git a/estorm/aic.c b/estorm/aic.c
index 2fb6fe1..7f78408 100644
--- a/estorm/aic.c
+++ b/estorm/aic.c
@@ -34,3 +34,7 @@ void aic_install_isr(aic_vector_t vector, void *isr) {
/* Install the provided ISR. */
AT91C_AIC_SVR[vector] = (unsigned int)isr;
}
+
+inline void aic_trigger_irq(aic_vector_t vector) {
+ *AT91C_AIC_ISCR = (1 << vector);
+}
diff --git a/estorm/aic.h b/estorm/aic.h
index 954c246..02c1619 100644
--- a/estorm/aic.h
+++ b/estorm/aic.h
@@ -27,4 +27,9 @@ void aic_disable(aic_vector_t vector);
*/
void aic_install_isr(aic_vector_t vector, void *isr);
+/* Manually force the AIC to trigger an irq exception for the given
+ * interrupt VECTOR.
+ */
+inline void aic_trigger_irq(aic_vector_t vector);
+
#endif
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--;
+}
diff --git a/estorm/sys_timer.h b/estorm/sys_timer.h
index e4dccf5..aebca71 100644
--- a/estorm/sys_timer.h
+++ b/estorm/sys_timer.h
@@ -6,6 +6,18 @@
#ifndef __ESTORM_SYS_TIMER_H__
#define __ESTORM_SYS_TIMER_H__
+/* Initialize the system clock that provides sleep support. */
void sys_timer_init();
+/* Return the number of milliseconds elapsed since the system
+ * started.
+ */
+unsigned long sys_timer_get_ms();
+
+/* Busy-wait for MS milliseconds. */
+void sys_timer_wait_ms(unsigned long ms);
+
+/* Busy-wait for approximately NS nanoseconds. */
+void sys_timer_wait_ns(unsigned long ns);
+
#endif