mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-13 07:23:39 +00:00
runtime: refactor time handling
This commit refactors both determining the current time and sleeping for
a given time. It also improves precision for many chips.
* The nrf chips had a long-standing TODO comment about a slightly
inaccurate clock. This should now be fixed.
* The SAM D2x/D5x chips may have a slightly more accurate clock,
although probably within the error margin of the RTC. Also, by
working with RTC ticks and converting in the least number of places,
code size is often slightly reduced (usually just a few bytes, up to
around 1kB in some cases).
* I believe the HiFive1 rev B timer was slightly wrong (32768Hz vs
30517.6Hz). Because the datasheet says the clock runs at 32768Hz,
I've used the same conversion code here as in the nrf and sam cases.
* I couldn't test both stm32 timers, so I kept them as they currently
are. It may be possible to make them more efficient by using the
native tick frequency instead of using microseconds everywhere.
This commit is contained in:
committed by
Ron Evans
parent
95f509b109
commit
3c55689566
@@ -12,8 +12,6 @@ import (
|
||||
|
||||
type timeUnit int64
|
||||
|
||||
const tickMicros = 1024 * 32
|
||||
|
||||
//go:linkname systemInit SystemInit
|
||||
func systemInit()
|
||||
|
||||
@@ -64,7 +62,7 @@ func sleepTicks(d timeUnit) {
|
||||
for d != 0 {
|
||||
ticks() // update timestamp
|
||||
ticks := uint32(d) & 0x7fffff // 23 bits (to be on the safe side)
|
||||
rtc_sleep(ticks) // TODO: not accurate (must be d / 30.5175...)
|
||||
rtc_sleep(ticks)
|
||||
d -= timeUnit(ticks)
|
||||
}
|
||||
}
|
||||
@@ -74,6 +72,22 @@ var (
|
||||
rtcLastCounter uint32 // 24 bits ticks
|
||||
)
|
||||
|
||||
// ticksToNanoseconds converts RTC ticks (at 32768Hz) to nanoseconds.
|
||||
func ticksToNanoseconds(ticks timeUnit) int64 {
|
||||
// The following calculation is actually the following, but with both sides
|
||||
// reduced to reduce the risk of overflow:
|
||||
// ticks * 1e9 / 32768
|
||||
return int64(ticks) * 1953125 / 64
|
||||
}
|
||||
|
||||
// nanosecondsToTicks converts nanoseconds to RTC ticks (running at 32768Hz).
|
||||
func nanosecondsToTicks(ns int64) timeUnit {
|
||||
// The following calculation is actually the following, but with both sides
|
||||
// reduced to reduce the risk of overflow:
|
||||
// ns * 32768 / 1e9
|
||||
return timeUnit(ns * 64 / 1953125)
|
||||
}
|
||||
|
||||
// Monotonically increasing numer of ticks since start.
|
||||
//
|
||||
// Note: very long pauses between measurements (more than 8 minutes) may
|
||||
@@ -83,7 +97,7 @@ func ticks() timeUnit {
|
||||
rtcCounter := uint32(nrf.RTC1.COUNTER.Get())
|
||||
offset := (rtcCounter - rtcLastCounter) & 0xffffff // change since last measurement
|
||||
rtcLastCounter = rtcCounter
|
||||
timestamp += timeUnit(offset) // TODO: not precise
|
||||
timestamp += timeUnit(offset)
|
||||
return timestamp
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user