aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/machine/machine_rp2040_timer.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/machine/machine_rp2040_timer.go')
-rw-r--r--src/machine/machine_rp2040_timer.go51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/machine/machine_rp2040_timer.go b/src/machine/machine_rp2040_timer.go
new file mode 100644
index 000000000..e714a1915
--- /dev/null
+++ b/src/machine/machine_rp2040_timer.go
@@ -0,0 +1,51 @@
+// +build rp2040
+
+package machine
+
+import (
+ "device/rp"
+ "runtime/volatile"
+ "unsafe"
+)
+
+const numTimers = 4
+
+type timerType struct {
+ timeHW volatile.Register32
+ timeLW volatile.Register32
+ timeHR volatile.Register32
+ timeLR volatile.Register32
+ alarm [numTimers]volatile.Register32
+ armed volatile.Register32
+ timeRawH volatile.Register32
+ timeRawL volatile.Register32
+ dbgPause volatile.Register32
+ pause volatile.Register32
+ intR volatile.Register32
+ intE volatile.Register32
+ intF volatile.Register32
+ intS volatile.Register32
+}
+
+var timer = (*timerType)(unsafe.Pointer(rp.TIMER))
+
+// TimeElapsed returns time elapsed since power up, in microseconds.
+func (tmr *timerType) timeElapsed() (us uint64) {
+ // Need to make sure that the upper 32 bits of the timer
+ // don't change, so read that first
+ hi := tmr.timeRawH.Get()
+ var lo, nextHi uint32
+ for {
+ // Read the lower 32 bits
+ lo = tmr.timeRawL.Get()
+ // Now read the upper 32 bits again and
+ // check that it hasn't incremented. If it has, loop around
+ // and read the lower 32 bits again to get an accurate value
+ nextHi = tmr.timeRawH.Get()
+ if hi == nextHi {
+ break
+ }
+ hi = nextHi
+ }
+ return uint64(hi)<<32 | uint64(lo)
+}