From 07fdd6c1dd26fae3a1e0b93b3877483c87d81f2a Mon Sep 17 00:00:00 2001
From: Clyne Sullivan <clyne@bitgloo.com>
Date: Sun, 6 Oct 2024 15:00:11 -0400
Subject: abstract timer driver

---
 src/main.zig  |  7 ++++---
 src/timer.zig | 38 +++++++++++++++++++++++++-------------
 2 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/src/main.zig b/src/main.zig
index deac169..d6a1aa4 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -6,12 +6,13 @@ const timer = @import("timer.zig");
 const rcc: *[39]u32 = @ptrFromInt(0x40021000);
 const gpioa = gpio.gpioa;
 const gpioc = gpio.gpioc;
+const tick = timer.systick;
 
 export fn _start() callconv(.C) noreturn {
     cpu.interrupt_disable();
     interrupt.initialize();
     interrupt.register(.SVCall, svcall);
-    timer.initialize(1000);
+    tick.initialize(1000);
     cpu.interrupt_enable();
 
     rcc[19] |= 5; // gpio a and c
@@ -21,8 +22,8 @@ export fn _start() callconv(.C) noreturn {
     while (true) {
         //asm volatile("svc 0");
         gpioa.toggle(5);
-        const next = timer.ticks() + 1000;
-        while (timer.ticks() < next) {
+        const next = tick.ticks() + 1000;
+        while (tick.ticks() < next) {
             asm volatile("nop");
         }
     }
diff --git a/src/timer.zig b/src/timer.zig
index 21151c7..b30cfcf 100644
--- a/src/timer.zig
+++ b/src/timer.zig
@@ -1,6 +1,6 @@
 const interrupt = @import("interrupt.zig");
 
-const sys_tick_type = packed struct {
+const driver_armcortex = packed struct {
     enable: u1,
     tickint: u1,
     unused: u30,
@@ -8,24 +8,36 @@ const sys_tick_type = packed struct {
     rvr: u32,
     cvr: u32,
     calib: u32,
-};
 
-var sys_tick: *volatile sys_tick_type = @ptrFromInt(0xE000E010);
+    pub fn initialize(self: *driver_armcortex, freq: u32) void {
+        self.rvr = 4000000 / 8 / freq;
+        self.tickint = 1;
+        self.enable = 1;
+    }
 
-pub var ticks_raw: u32 = 0;
+};
 
-pub fn initialize(freq: u32) void {
-    interrupt.register(.SysTick, tick);
-    sys_tick.rvr = 4000000 / 8 / freq;
-    sys_tick.tickint = 1;
-    sys_tick.enable = 1;
-}
+var ticks_raw: u32 = 0;
 
 fn tick() void {
     ticks_raw += 1;
 }
 
-pub fn ticks() u32 {
-    return @atomicLoad(u32, &ticks_raw, .acquire);
-}
+const driver = struct {
+    const lld_type = driver_armcortex;
+
+    lld: *driver_armcortex,
+
+    pub fn initialize(self: driver, freq: u32) void {
+        interrupt.register(.SysTick, tick);
+        self.lld.initialize(freq);
+    }
+
+    pub fn ticks(self: driver) u32 {
+        _ = self;
+        return @atomicLoad(u32, &ticks_raw, .acquire);
+    }
+};
+
+pub const systick = driver { .lld = @ptrFromInt(0xE000E010) };
 
-- 
cgit v1.2.3