mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-06 12:03:41 +00:00
4ec1e58aa6
We have an optimization for this specific pattern, but it's really just a hack. With the addition of unsafe.Add in Go 1.17 we can directly specify the intent instead and eventually remove this special case. The code is also easier to read.
87 lines
2.2 KiB
Go
87 lines
2.2 KiB
Go
//go:build esp32 || esp32c3
|
|
|
|
package runtime
|
|
|
|
import (
|
|
"device/esp"
|
|
"machine"
|
|
"unsafe"
|
|
)
|
|
|
|
type timeUnit int64
|
|
|
|
func putchar(c byte) {
|
|
machine.Serial.WriteByte(c)
|
|
}
|
|
|
|
func getchar() byte {
|
|
for machine.Serial.Buffered() == 0 {
|
|
Gosched()
|
|
}
|
|
v, _ := machine.Serial.ReadByte()
|
|
return v
|
|
}
|
|
|
|
func buffered() int {
|
|
return machine.Serial.Buffered()
|
|
}
|
|
|
|
// Initialize .bss: zero-initialized global variables.
|
|
// The .data section has already been loaded by the ROM bootloader.
|
|
func clearbss() {
|
|
ptr := unsafe.Pointer(&_sbss)
|
|
for ptr != unsafe.Pointer(&_ebss) {
|
|
*(*uint32)(ptr) = 0
|
|
ptr = unsafe.Add(ptr, 4)
|
|
}
|
|
}
|
|
|
|
func initTimer() {
|
|
// Configure timer 0 in timer group 0, for timekeeping.
|
|
// EN: Enable the timer.
|
|
// INCREASE: Count up every tick (as opposed to counting down).
|
|
// DIVIDER: 16-bit prescaler, set to 2 for dividing the APB clock by two
|
|
// (40MHz).
|
|
// esp.TIMG0.T0CONFIG.Set(0 << esp.TIMG_T0CONFIG_T0_EN_Pos)
|
|
esp.TIMG0.T0CONFIG.Set(esp.TIMG_T0CONFIG_T0_EN | esp.TIMG_T0CONFIG_T0_INCREASE | 2<<esp.TIMG_T0CONFIG_T0_DIVIDER_Pos)
|
|
// esp.TIMG0.T0CONFIG.Set(1 << esp.TIMG_T0CONFIG_T0_DIVCNT_RST_Pos)
|
|
// esp.TIMG0.T0CONFIG.Set(esp.TIMG_T0CONFIG_T0_EN)
|
|
|
|
// Set the timer counter value to 0.
|
|
esp.TIMG0.T0LOADLO.Set(0)
|
|
esp.TIMG0.T0LOADHI.Set(0)
|
|
esp.TIMG0.T0LOAD.Set(0) // value doesn't matter.
|
|
}
|
|
|
|
func ticks() timeUnit {
|
|
// First, update the LO and HI register pair by writing any value to the
|
|
// register. This allows reading the pair atomically.
|
|
esp.TIMG0.T0UPDATE.Set(0)
|
|
// Then read the two 32-bit parts of the timer.
|
|
return timeUnit(uint64(esp.TIMG0.T0LO.Get()) | uint64(esp.TIMG0.T0HI.Get())<<32)
|
|
}
|
|
|
|
func nanosecondsToTicks(ns int64) timeUnit {
|
|
// Calculate the number of ticks from the number of nanoseconds. At a 80MHz
|
|
// APB clock, that's 25 nanoseconds per tick with a timer prescaler of 2:
|
|
// 25 = 1e9 / (80MHz / 2)
|
|
return timeUnit(ns / 25)
|
|
}
|
|
|
|
func ticksToNanoseconds(ticks timeUnit) int64 {
|
|
// See nanosecondsToTicks.
|
|
return int64(ticks) * 25
|
|
}
|
|
|
|
// sleepTicks busy-waits until the given number of ticks have passed.
|
|
func sleepTicks(d timeUnit) {
|
|
sleepUntil := ticks() + d
|
|
for ticks() < sleepUntil {
|
|
// TODO: suspend the CPU to not burn power here unnecessarily.
|
|
}
|
|
}
|
|
|
|
func exit(code int) {
|
|
abort()
|
|
}
|