Repository navigation
runtime/esp32c3, esp32c6, esp32h2: fix timer alarm handler registration - #6052
Conversation
The handler was passed as a closure and the handle was discarded, so the compiler removed it and the alarm interrupt was never cleared. Register a named handler and call Enable, as esp32 and esp32s3 do. Enable no longer uses defer, because the runtime calls it during startup before any goroutine exists.
|
Thanks for tracking this down @gitslav. I tested this PR on a XIAO ESP32-C3 and here are some notes edited from an automated review:
What do you think? |
|
@gitslav alsp plese see test failure https://github.com/tinygo-org/tinygo/actions/runs/40482094802/job/122221078221?pr=6052#step:14:14 thank you. |
Same fix as for esp32c3. The handler was passed as a closure and the handle was discarded, so the alarm interrupt was never cleared. Register a named handler and call Enable, and Enable no longer uses defer. On all three chips, keep only the priority write after Enable, since Enable already clears, sets edge type and enables the line.
|
@deadprogram thanks for testing. Both are done in the second commit. Also the binary size is updated. esp32c6 and esp32h2 now register a named handler and call Enable, their Enable no longer uses defer. initTimerInterrupt on all three chips is now Enable plus the priority write. I kept priority 10 so the timer stays above peripherals. I have no C6 or H2 hardware, so a run on real boards would be welcome for a quick sanity check. |
deadprogram
left a comment
There was a problem hiding this comment.
@gitslav thanks for the update. I tested the second commit on a XIAO ESP32-C6 and a XIAO ESP32-C3.
On both, the timer handler now ends up in the binary with the write to TIMG0.INT_CLR_TIMERS. 100ms sleeps measure about 100.05ms, same as dev. Three goroutines sleeping 30, 70 and 250ms plus a 1s ticker all stay on time. USB serial still works both ways, which also goes through the changed Enable(). The espradio scan example still works on the C3.
I could not test WiFi on the C6, and I have no H2.
This seems good to me. Thank you!
|
Now merging thanks @gitslav |
This registers the esp32c3 TIMG0 alarm handler the way esp32 and esp32s3 already do:
tinygo/src/runtime/runtime_esp32_timer.go
Lines 40 to 41 in 5d0eacb
tinygo/src/runtime/runtime_esp32sx.go
Lines 114 to 115 in 5d0eacb
Currently esp32c3 passes a closure and discards the handle. The compiler removes interrupt handles that are never enabled, so the handler is gone and the alarm interrupt is never cleared.
The esp32c3
Enable()no longer usesdefer, like esp32s3. The runtime calls it during startup before any goroutine exists, and the defer setup panics there on the nil current task.You can see the missing handler in any esp32c3 build. Currently
handleInterruptnever writesTIMG0.INT_CLR_TIMERS. With this PR it does. On hardware this is mostly silent because sleeps still end through theticks()check. Espressif's esp-emulator keeps raising the pending interrupt, so there the espradio WiFi example on esp32c3 runs its WiFi ISR about 1.7 million times and never connects. With this PR it connects.