runtime (atsamd51): allow interrupts to wake the scheduler

Этот коммит содержится в:
Jaden Weiss 2020-06-27 14:03:15 -04:00 коммит произвёл Ayke
родитель 1451eeaf41
коммит 89a9c09af5

Просмотреть файл

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