github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/runtime/runtime_esp32xx.go (about) 1 //go:build esp32 || esp32c3 2 3 package runtime 4 5 import ( 6 "device/esp" 7 "machine" 8 "unsafe" 9 ) 10 11 type timeUnit int64 12 13 // Initialize .bss: zero-initialized global variables. 14 // The .data section has already been loaded by the ROM bootloader. 15 func clearbss() { 16 ptr := unsafe.Pointer(&_sbss) 17 for ptr != unsafe.Pointer(&_ebss) { 18 *(*uint32)(ptr) = 0 19 ptr = unsafe.Add(ptr, 4) 20 } 21 } 22 23 func initTimer() { 24 // Configure timer 0 in timer group 0, for timekeeping. 25 // EN: Enable the timer. 26 // INCREASE: Count up every tick (as opposed to counting down). 27 // DIVIDER: 16-bit prescaler, set to 2 for dividing the APB clock by two 28 // (40MHz). 29 // esp.TIMG0.T0CONFIG.Set(0 << esp.TIMG_T0CONFIG_T0_EN_Pos) 30 esp.TIMG0.T0CONFIG.Set(esp.TIMG_T0CONFIG_EN | esp.TIMG_T0CONFIG_INCREASE | 2<<esp.TIMG_T0CONFIG_DIVIDER_Pos) 31 // esp.TIMG0.T0CONFIG.Set(1 << esp.TIMG_T0CONFIG_T0_DIVCNT_RST_Pos) 32 // esp.TIMG0.T0CONFIG.Set(esp.TIMG_T0CONFIG_T0_EN) 33 34 // Set the timer counter value to 0. 35 esp.TIMG0.T0LOADLO.Set(0) 36 esp.TIMG0.T0LOADHI.Set(0) 37 esp.TIMG0.T0LOAD.Set(0) // value doesn't matter. 38 } 39 40 func ticks() timeUnit { 41 // First, update the LO and HI register pair by writing any value to the 42 // register. This allows reading the pair atomically. 43 esp.TIMG0.T0UPDATE.Set(0) 44 // Then read the two 32-bit parts of the timer. 45 return timeUnit(uint64(esp.TIMG0.T0LO.Get()) | uint64(esp.TIMG0.T0HI.Get())<<32) 46 } 47 48 func nanosecondsToTicks(ns int64) timeUnit { 49 // Calculate the number of ticks from the number of nanoseconds. At a 80MHz 50 // APB clock, that's 25 nanoseconds per tick with a timer prescaler of 2: 51 // 25 = 1e9 / (80MHz / 2) 52 return timeUnit(ns / 25) 53 } 54 55 func ticksToNanoseconds(ticks timeUnit) int64 { 56 // See nanosecondsToTicks. 57 return int64(ticks) * 25 58 } 59 60 // sleepTicks busy-waits until the given number of ticks have passed. 61 func sleepTicks(d timeUnit) { 62 sleepUntil := ticks() + d 63 for ticks() < sleepUntil { 64 // TODO: suspend the CPU to not burn power here unnecessarily. 65 } 66 } 67 68 func exit(code int) { 69 abort() 70 } 71 72 func putchar(c byte) { 73 machine.Serial.WriteByte(c) 74 } 75 76 func getchar() byte { 77 for machine.Serial.Buffered() == 0 { 78 Gosched() 79 } 80 v, _ := machine.Serial.ReadByte() 81 return v 82 } 83 84 func buffered() int { 85 return machine.Serial.Buffered() 86 }