From 6877099e788222edcf7bded5f99b21e9c3885ac7 Mon Sep 17 00:00:00 2001 From: David Montero Crespo Date: Mon, 3 Aug 2026 05:48:40 +0200 Subject: [PATCH] fix(micropython): the \r poke must not fire once the prompt is already up Stage 1 arms a \r at banner+800ms to flush QEMU's held ">>> " prompt, and stage 2 arms Ctrl-A at prompt+200ms. Nothing kept the first from firing after the second: if the prompt ever arrives on its own within 600ms, the \r lands inside the pasted source, and MicroPython reads a lone \r as a newline - it cuts a source line in half with no diagnostic of its own. Here that is still latent; the in-browser JS engines, which deliver serial per byte, hit it on every single run. --- frontend/src/simulation/Esp32Bridge.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/frontend/src/simulation/Esp32Bridge.ts b/frontend/src/simulation/Esp32Bridge.ts index ccf65c04..a208ac01 100644 --- a/frontend/src/simulation/Esp32Bridge.ts +++ b/frontend/src/simulation/Esp32Bridge.ts @@ -397,10 +397,18 @@ export class Esp32Bridge { // Stage 1: banner "Type help()" → poke UART with \r to flush ">>> " // The >>> prompt has no \n so the backend UART buffer holds it until // we send a byte that causes another write. + // The poke only fires while the prompt is STILL missing. If the + // backend ever delivers ">>>" on its own within 600 ms, stage 2 + // arms Ctrl-A (+200 ms) before this timer (+800 ms) fires, and the + // \r then lands inside the pasted code — MicroPython reads a lone + // \r as a newline, so it silently cuts a source line in half. That + // is exactly what broke the in-browser JS engines, where the prompt + // arrives immediately (see pro microPythonRepl.ts). if (this._replState === 'idle' && this._serialBuffer.includes('Type "help()"')) { this._replState = 'banner_seen'; console.log('[Esp32Bridge] Stage 1: banner seen → poking UART with \\r'); setTimeout(() => { + if (this._replState !== 'banner_seen') return; // prompt already arrived this._send({ type: 'esp32_serial_input', data: { bytes: [0x0d] } }); }, 800); }