From 14bb2f6fbeff23160a4bed40bd074a6de007cea1 Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Fri, 21 Oct 2022 05:12:36 -0300 Subject: [PATCH] chore: improve timer behaviour --- src/bus/io.zig | 8 ++++---- src/bus/timer.zig | 28 ++++++++++++++++------------ 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/bus/io.zig b/src/bus/io.zig index 73a3d83..35e4508 100644 --- a/src/bus/io.zig +++ b/src/bus/io.zig @@ -268,13 +268,13 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void { 0x0400_00DE => bus.dma._3.writeCntHigh(value), // Timers - 0x0400_0100 => bus.tim._0.writeCntLow(value), + 0x0400_0100 => bus.tim._0.setReload(value), 0x0400_0102 => bus.tim._0.writeCntHigh(value), - 0x0400_0104 => bus.tim._1.writeCntLow(value), + 0x0400_0104 => bus.tim._1.setReload(value), 0x0400_0106 => bus.tim._1.writeCntHigh(value), - 0x0400_0108 => bus.tim._2.writeCntLow(value), + 0x0400_0108 => bus.tim._2.setReload(value), 0x0400_010A => bus.tim._2.writeCntHigh(value), - 0x0400_010C => bus.tim._3.writeCntLow(value), + 0x0400_010C => bus.tim._3.setReload(value), 0x0400_010E => bus.tim._3.writeCntHigh(value), 0x0400_0110 => {}, // Not Used diff --git a/src/bus/timer.zig b/src/bus/timer.zig index 012e469..d68f9fe 100644 --- a/src/bus/timer.zig +++ b/src/bus/timer.zig @@ -33,7 +33,7 @@ fn Timer(comptime id: u2) type { /// Read Only, Internal. Please use self.counter() _counter: u16, - /// Write Only, Internal. Please use self.writeCntLow() + /// Write Only, Internal. Please use self.setReload() _reload: u16, /// Write Only, Internal. Please use self.WriteCntHigh() @@ -56,18 +56,17 @@ fn Timer(comptime id: u2) type { } pub fn counter(self: *const Self) u16 { - if (self.cnt.cascade.read()) - return self._counter - else - return self._counter +% @truncate(u16, (self.sched.now() - self._start_timestamp) / self.frequency()); + if (self.cnt.cascade.read() or !self.cnt.enabled.read()) return self._counter; + + return self._counter +% @truncate(u16, (self.sched.now() - self._start_timestamp) / self.frequency()); } pub fn writeCnt(self: *Self, word: u32) void { - self.writeCntLow(@truncate(u16, word)); + self.setReload(@truncate(u16, word)); self.writeCntHigh(@truncate(u16, word >> 16)); } - pub fn writeCntLow(self: *Self, halfword: u16) void { + pub fn setReload(self: *Self, halfword: u16) void { self._reload = halfword; } @@ -77,13 +76,18 @@ fn Timer(comptime id: u2) type { // If Timer happens to be enabled, It will either be resheduled or disabled self.sched.removeScheduledEvent(.{ .TimerOverflow = id }); - if (!self.cnt.enabled.read() and new.enabled.read()) { - // Reload on Rising edge - self._counter = self._reload; - - if (!new.cascade.read()) self.scheduleOverflow(0); + if (self.cnt.enabled.read() and (new.cascade.read() or !new.enabled.read())) { + // Either through the cascade bit or the enable bit, the timer has effectively been disabled + // The Counter should hold whatever value it should have been at when it was disabled + self._counter +%= @truncate(u16, (self.sched.now() - self._start_timestamp) / self.frequency()); } + // The counter is only reloaded on the rising edge of the enable bit + if (!self.cnt.enabled.read() and new.enabled.read()) self._counter = self._reload; + + // If Timer is enabled and we're not cascading, we need to schedule an overflow event + if (new.enabled.read() and !new.cascade.read()) self.scheduleOverflow(0); + self.cnt.raw = halfword; }