Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/machine/machine_esp32c3.go
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,10 @@ type Serialer interface {
RTS() bool
}

func initUSB() {
// nothing to do here
}

// USB Serial/JTAG Controller
// See esp32-c3_technical_reference_manual_en.pdf
// pg. 736
Expand Down
1 change: 1 addition & 0 deletions src/machine/serial-usb.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ package machine
var Serial Serialer

func InitSerial() {
initUSB()
Serial = USBCDC
}
11 changes: 11 additions & 0 deletions src/machine/usb.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ var (
USBCDC Serialer
)

func initUSB() {
enableUSBCDC()
USBDev.Configure(UARTConfig{})
}

// Using go:linkname here because there's a circular dependency between the
// machine package and the machine/usb/cdc package.
//
//go:linkname enableUSBCDC machine/usb/cdc.EnableUSBCDC
func enableUSBCDC()

type Serialer interface {
WriteByte(c byte) error
Write(data []byte) (n int, err error)
Expand Down
4 changes: 1 addition & 3 deletions src/runtime/runtime_atsamd21.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"device/arm"
"device/sam"
"machine"
"machine/usb/cdc"
_ "machine/usb/cdc"
"runtime/interrupt"
"runtime/volatile"
"unsafe"
Expand All @@ -26,8 +26,6 @@ func init() {
initUSBClock()
initADCClock()

cdc.EnableUSBCDC()
machine.USBDev.Configure(machine.UARTConfig{})
machine.InitSerial()
}

Expand Down
4 changes: 1 addition & 3 deletions src/runtime/runtime_atsamd51.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"device/arm"
"device/sam"
"machine"
"machine/usb/cdc"
_ "machine/usb/cdc"
"runtime/interrupt"
"runtime/volatile"
)
Expand All @@ -27,8 +27,6 @@ func init() {
initADCClock()
enableCache()

cdc.EnableUSBCDC()
machine.USBDev.Configure(machine.UARTConfig{})
machine.InitSerial()
}

Expand Down
2 changes: 1 addition & 1 deletion src/runtime/runtime_nrf.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build nrf && !nrf52840
//go:build nrf

package runtime

Expand Down
150 changes: 3 additions & 147 deletions src/runtime/runtime_nrf52840.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,150 +2,6 @@

package runtime

import (
"device/arm"
"device/nrf"
"machine"
"machine/usb/cdc"
"runtime/interrupt"
"runtime/volatile"
)

//go:linkname systemInit SystemInit
func systemInit()

//export Reset_Handler
func main() {
if nrf.FPUPresent {
arm.SCB.CPACR.Set(0) // disable FPU if it is enabled
}
systemInit()
preinit()
run()
exit(0)
}

func init() {
cdc.EnableUSBCDC()
machine.USBDev.Configure(machine.UARTConfig{})
machine.InitSerial()
initLFCLK()
initRTC()
}

func initLFCLK() {
if machine.HasLowFrequencyCrystal {
nrf.CLOCK.LFCLKSRC.Set(nrf.CLOCK_LFCLKSTAT_SRC_Xtal)
}
nrf.CLOCK.TASKS_LFCLKSTART.Set(1)
for nrf.CLOCK.EVENTS_LFCLKSTARTED.Get() == 0 {
}
nrf.CLOCK.EVENTS_LFCLKSTARTED.Set(0)
}

func initRTC() {
nrf.RTC1.TASKS_START.Set(1)
intr := interrupt.New(nrf.IRQ_RTC1, func(intr interrupt.Interrupt) {
if nrf.RTC1.EVENTS_COMPARE[0].Get() != 0 {
nrf.RTC1.EVENTS_COMPARE[0].Set(0)
nrf.RTC1.INTENCLR.Set(nrf.RTC_INTENSET_COMPARE0)
nrf.RTC1.EVENTS_COMPARE[0].Set(0)
rtc_wakeup.Set(1)
}
if nrf.RTC1.EVENTS_OVRFLW.Get() != 0 {
nrf.RTC1.EVENTS_OVRFLW.Set(0)
rtcOverflows.Set(rtcOverflows.Get() + 1)
}
})
nrf.RTC1.INTENSET.Set(nrf.RTC_INTENSET_OVRFLW)
intr.SetPriority(0xc0) // low priority
intr.Enable()
}

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()
}

func sleepTicks(d timeUnit) {
for d != 0 {
ticks := uint32(d) & 0x7fffff // 23 bits (to be on the safe side)
if d > 0x7fffff {
ticks = 0x7fffff
}
rtc_sleep(ticks)
d -= timeUnit(ticks)
}
}

var rtcOverflows volatile.Register32 // number of times the RTC wrapped around

// 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 number of ticks since start.
func ticks() timeUnit {
// For some ways of capturing the time atomically, see this thread:
// https://www.eevblog.com/forum/microcontrollers/correct-timing-by-timer-overflow-count/msg749617/#msg749617
// Here, instead of re-reading the counter register if an overflow has been
// detected, we simply try again because that results in (slightly) smaller
// code and is perhaps easier to prove correct.
for {
mask := interrupt.Disable()
counter := uint32(nrf.RTC1.COUNTER.Get())
overflows := rtcOverflows.Get()
hasOverflow := nrf.RTC1.EVENTS_OVRFLW.Get() != 0
interrupt.Restore(mask)

if hasOverflow {
// There was an overflow. Try again.
continue
}

// The counter is 24 bits in size, so the number of overflows form the
// upper 32 bits (together 56 bits, which covers 71493 years at
// 32768kHz: I'd argue good enough for most purposes).
return timeUnit(overflows)<<24 + timeUnit(counter)
}
}

var rtc_wakeup volatile.Register8

func rtc_sleep(ticks uint32) {
nrf.RTC1.INTENSET.Set(nrf.RTC_INTENSET_COMPARE0)
rtc_wakeup.Set(0)
if ticks == 1 {
// Race condition (even in hardware) at ticks == 1.
// TODO: fix this in a better way by detecting it, like the manual
// describes.
ticks = 2
}
nrf.RTC1.CC[0].Set((nrf.RTC1.COUNTER.Get() + ticks) & 0x00ffffff)
for rtc_wakeup.Get() == 0 {
waitForEvents()
}
}
// This package needs to be present so that the machine package can go:linkname
// EnableUSBCDC from it.
import _ "machine/usb/cdc"
4 changes: 1 addition & 3 deletions src/runtime/runtime_rp2.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"device/rp"
"internal/task"
"machine"
"machine/usb/cdc"
_ "machine/usb/cdc"
"runtime/interrupt"
"runtime/volatile"
"unsafe"
Expand Down Expand Up @@ -360,8 +360,6 @@ func machineInit()
func init() {
machineInit()

cdc.EnableUSBCDC()
machine.USBDev.Configure(machine.UARTConfig{})
machine.InitSerial()
}

Expand Down
Loading