From b81a7c2bcae2d1371de2b12424c4800d9623ec72 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Thu, 5 Mar 2026 20:31:32 +0100 Subject: [PATCH] fix: ESP32-C3 needs to clear MCAUSE after handling interrupt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MCAUSE was never being cleared after handling an interrupt. On RISC-V, mret does NOT zero MCAUSE — it retains the last trap cause. Every other TinyGo RISC-V target (FE310, K210, QEMU) explicitly does riscv.MCAUSE.Set(0) after handling. The ESP32-C3 was missing this. Signed-off-by: deadprogram --- src/runtime/interrupt/interrupt_esp32c3.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/runtime/interrupt/interrupt_esp32c3.go b/src/runtime/interrupt/interrupt_esp32c3.go index 5725cd352..27b7ae1b2 100644 --- a/src/runtime/interrupt/interrupt_esp32c3.go +++ b/src/runtime/interrupt/interrupt_esp32c3.go @@ -201,6 +201,11 @@ func handleInterrupt() { reg.Set(thresholdSave) riscv.Asm("fence") + // Zero MCAUSE so that interrupt.In() returns false once we + // return to normal (non-interrupt) code. Other RISC-V targets + // (FE310, K210) do the same. + riscv.MCAUSE.Set(0) + // restore MSTATUS & MEPC riscv.MSTATUS.Set(mstatus) riscv.MEPC.Set(mepc)