From 4f90d25b7f36663438601f9cd0340429ce7211c8 Mon Sep 17 00:00:00 2001 From: Mikey Sklar Date: Wed, 15 Jul 2026 10:57:10 -0700 Subject: [PATCH] libdvi: halt in RAM instead of flash-resident panic() in DMA IRQ The "TMDS free queue full" error path called panic(), which lives in flash. The DVI IRQ handler runs on a core that may have flash access disabled (CircuitPython locks it out with an MPU region), so the panic would hard fault on the first instruction fetch and never print. Spin in RAM instead, matching the existing hang-on-bug idiom in this code. Co-Authored-By: Claude Fable 5 --- software/libdvi/dvi.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/software/libdvi/dvi.c b/software/libdvi/dvi.c index 3e149c1..7364b04 100644 --- a/software/libdvi/dvi.c +++ b/software/libdvi/dvi.c @@ -186,8 +186,14 @@ static void __dvi_func(dvi_dma_irq_handler)(struct dvi_inst *inst) { // now have until the end of this region to generate DMA blocklist for next // scanline. dvi_timing_state_advance(inst->timing, &inst->timing_state); - if (inst->tmds_buf_release && !queue_try_add_u32(&inst->q_tmds_free, &inst->tmds_buf_release)) - panic("TMDS free queue full in IRQ!"); + if (inst->tmds_buf_release && !queue_try_add_u32(&inst->q_tmds_free, &inst->tmds_buf_release)) { + // Would be a bug ("TMDS free queue full in IRQ"). Hang here rather + // than panic(): panic is flash-resident, and core1 may run with + // flash access disabled (e.g. CircuitPython's MPU lockout), where + // calling into flash hard faults before anything is printed. + while (true) + tight_loop_contents(); + } inst->tmds_buf_release = inst->tmds_buf_release_next; inst->tmds_buf_release_next = NULL;