Skip to content
Merged
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
24 changes: 20 additions & 4 deletions src/runtime/runtime_atsamd51.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,9 @@ func sleepTicks(d timeUnit) {
for d != 0 {
ticks() // update timestamp
ticks := uint32(d)
timerSleep(ticks)
if !timerSleep(ticks) {
return
}
d -= timeUnit(ticks)
}
}
Expand All @@ -266,7 +268,9 @@ func ticks() timeUnit {
}

// ticks are in microseconds
func timerSleep(ticks uint32) {
// Returns true if the timer completed.
// Returns false if another interrupt occured which requires an early return to scheduler.
func timerSleep(ticks uint32) bool {
timerWakeup.Set(0)
if ticks < 8 {
// due to delay waiting for the register value to sync, the minimum sleep value
Expand All @@ -287,8 +291,20 @@ func timerSleep(ticks uint32) {
// enable IRQ for CMP0 compare
sam.RTC_MODE0.INTENSET.SetBits(sam.RTC_MODE0_INTENSET_CMP0)

for timerWakeup.Get() == 0 {
arm.Asm("wfi")
wait:
arm.Asm("wfe")
if timerWakeup.Get() != 0 {
return true
}
if hasScheduler {
// The interurpt may have awoken a goroutine, so bail out early.
// Disable IRQ for CMP0 compare.
sam.RTC_MODE0.INTENCLR.SetBits(sam.RTC_MODE0_INTENSET_CMP0)
return false
} else {
// This is running without a scheduler.
// The application expects this to sleep the whole time.
goto wait
}
}

Expand Down