docs: add ESP32-P4 research and feasibility report

Investigation into adding ESP32-P4 to Velxio via either of the two existing
emulation paths (frontend JS/WASM or backend QEMU/WebSocket). Verified the
arduino-cli toolchain works (RISC-V 32-bit ELF, RVC, single-float ABI), but
both emulation paths are blocked upstream:

- espressif/qemu has no esp32p4 machine yet (issue #127, status: To Do).
- No open-source JS/WASM ESP32 emulator exists; Wokwi's engine is closed.

Includes a smoke-test script ready for the day the Espressif QEMU machine
lands, plus a Phase A/B/C plan in autosearch/06_recommendations.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
David Montero Crespo 2026-05-06 15:48:05 -03:00
parent 694a2f4073
commit 0fdbeffda5
11 changed files with 543 additions and 0 deletions

2
test/test-esp32-p4/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
sketches/*/build/
binaries/

View File

@ -0,0 +1,50 @@
# test-esp32-p4 — investigación de soporte ESP32-P4 en Velxio
Sandbox de investigación para evaluar si el chip Espressif **ESP32-P4** puede sumarse a Velxio como board emulable.
## Contexto
Velxio hoy tiene **dos vías** de emulación:
1. **Frontend (browser)** — JS puro / WASM. Cubre AVR (`avr8js`) y RP2040 (`rp2040js`).
2. **Backend WebSocket → QEMU** — proceso QEMU por cliente, UART y GPIO chardev sobre TCP. Cubre ESP32, ESP32-S3 (Xtensa) y ESP32-C3 (RISC-V).
Ver `backend/app/services/esp_qemu_manager.py` para el pattern actual.
## Estructura
```
test-esp32-p4/
├── README.md # este archivo
├── autosearch/ # hallazgos, qué funciona / qué no
│ ├── 01_findings.md
│ ├── 02_chip_overview.md
│ ├── 03_compilation_test.md
│ ├── 04_qemu_backend_path.md
│ ├── 05_frontend_emulation_path.md
│ └── 06_recommendations.md
├── sketches/blink/blink.ino # sketch mínimo Arduino para esp32:esp32:esp32p4
├── binaries/ # outputs de compilación (gitignore-able)
└── scripts/ # scripts de test (vacío)
```
## TL;DR
- ✅ **Compilación funciona** con `arduino-cli` + core `esp32:esp32 3.3.8`. FQBN `esp32:esp32:esp32p4` produce ELF RISC-V 32-bit (RVC, single-float ABI) y `merged.bin` de 4 MB.
- ❌ **No hay máquina QEMU para ESP32-P4** en `espressif/qemu` (último release `esp-develop-9.2.2-20260417`). Soporte es "To Do" — ver [issue #127](https://github.com/espressif/qemu/issues/127).
- ❌ **No hay emulador JS/WASM open-source** del ESP32-P4. Wokwi tiene simulador beta cerrado (`board-esp32-p4-preview`); su engine no es público.
- ⚠️ La vía realista de hoy es **esperar el merge de la máquina P4 en `espressif/qemu`** y, mientras tanto, dejar la pieza de toolchain (compilación + flashing args) lista en backend y agregar el board element visual (placeholder) en frontend.
Detalles: [`autosearch/06_recommendations.md`](autosearch/06_recommendations.md).
## Reproducir el test de compilación
```bash
cd test/test-esp32-p4/sketches
arduino-cli core install esp32:esp32 # si no está instalado
arduino-cli compile --fqbn esp32:esp32:esp32p4 blink
ls blink/build/esp32.esp32.esp32p4/
# blink.ino.elf, blink.ino.bin, blink.ino.merged.bin (4 MB), bootloader, partitions
file blink/build/esp32.esp32.esp32p4/blink.ino.elf
# → ELF 32-bit LSB executable, UCB RISC-V, RVC, single-float ABI
```

View File

@ -0,0 +1,66 @@
# 01 — Hallazgos sesión 2026-05-06
## Resumen ejecutivo
Sumar ESP32-P4 a Velxio **no es posible hoy con la arquitectura existente** (ni vía backend QEMU ni vía emulador JS frontend), pero **el toolchain de compilación ya funciona** y no hay obstáculo de licencia ni de toolchain. La pieza bloqueante es **la máquina QEMU `esp32p4`**: Espressif aún no la ha implementado en su fork. Wokwi sí simula el chip, pero su engine es propietario.
Recomendación: dejar la rama de **compilación + ELF** lista en backend (cambios mínimos en `arduino_cli.py` y `esp_qemu_manager.py`), y poner el board en estado "compilable, no emulable" hasta que `espressif/qemu` libere la máquina P4. Más detalle en [`06_recommendations.md`](06_recommendations.md).
## Lo que funciona (verificado en esta máquina)
| Pieza | Estado | Evidencia |
|---|---|---|
| Detección de boards ESP32-P4 en `arduino-cli` | ✅ | `arduino-cli board listall` lista 5 variantes (Dev Module, Core Board, FireBeetle 2, 4D Systems MIPI). |
| Core `esp32:esp32 3.3.8` instalado y soporta P4 | ✅ | Ya estaba instalado en el entorno. |
| Compilación de blink mínimo | ✅ | `arduino-cli compile --fqbn esp32:esp32:esp32p4 blink` → exit 0. |
| Output ELF RISC-V 32-bit (RVC, single-float) | ✅ | `file blink.ino.elf``ELF 32-bit LSB executable, UCB RISC-V, RVC, single-float ABI`. |
| Tamaños razonables | ✅ | sketch 312 KB / 1310 KB flash; globals 21 KB / 327 KB SRAM. |
| `merged.bin` 4 MB con bootloader + app + partitions | ✅ | Listo para `qemu -drive if=mtd,format=raw` igual que ESP32/C3. |
| arduino-esp32 v3.1.x soporta P4 | ✅ | Confirmado en [arduino-esp32 #10278](https://github.com/espressif/arduino-esp32/issues/10278): GPIO/I2C/SPI/UART/Wi-Fi (vía co-procesador externo)/USB OK. Faltan ADC calibration, BT Classic, DAC, Hall, MCPWM, PCNT, MIPI, MSPI. |
## Lo que NO funciona (bloqueantes)
| Bloqueante | Estado | Por qué |
|---|---|---|
| **Máquina `esp32p4` en `espressif/qemu`** | ❌ | Último release `esp-develop-9.2.2` (2026-04-17) lista solo `esp32`, `esp32-s3`, `esp32c3`. [Issue #127](https://github.com/espressif/qemu/issues/127) abierto desde 2025-05-17, label `Status: To Do`. La carpeta `hw/riscv` del fork solo tiene `esp32c3.c`. |
| **Forks alternativos QEMU con P4** | ❌ | Revisados: `lcgamboa/qemu` (PICSimLab), `Ebiroll/qemu_esp32`, `epiclabs-uc/qemu-esp32`, `max1220/qemu-esp32`. Ninguno menciona P4. |
| **Emulador JS/WASM open-source** | ❌ | Wokwi tiene `avr8js` y `rp2040js` públicos, pero **no** existe `esp32js` o `esp32p4js` open-source. Wokwi simula P4 en beta dentro de su producto cerrado. |
| **Wokwi-elements board element** | ❌ | `wokwi-libs/wokwi-elements/src/` tiene `esp32-devkit-v1-element.ts` pero no `esp32-p4`. El `board-esp32-p4-preview` que aparece en `diagram.json` de Wokwi vive solo en su build privado. |
| **QEMU instalado localmente para smoke test** | ❌ | `qemu-system-riscv32` no está en PATH en esta máquina. El smoke test contra P4 sería igual fútil porque la máquina ni siquiera existe en el binario. |
## Lo que probé (timeline)
1. Compilación local: **OK**, ELF y `merged.bin` generados (ver `03_compilation_test.md`).
2. Búsqueda en `espressif/qemu`: branches (`esp-develop`, `esp-develop-based-on-9.2.2`, `master`) y carpeta `hw/riscv` → ningún archivo `esp32p4*`. [Issue #127](https://github.com/espressif/qemu/issues/127) es la fuente única de verdad: status "To Do".
3. Búsqueda en wokwi-elements: solo `esp32-devkit-v1-element.ts`, sin variante P4.
4. Búsqueda en organización `wokwi` de GitHub: hay `esp32p4-hello-world` y `esp32p4-mipi-dsi-panel-demo` (solo sketches de ejemplo), no engine.
5. Wokwi docs (`/guides/esp32`): confirma que P4 está "in beta" en Wokwi pero sin detalles del engine.
## Implicaciones para Velxio
1. **Backend (`esp_qemu_manager.py`)**: agregar `'esp32-p4': (QEMU_RISCV32, 'esp32p4')` cuando la máquina exista. Bootloader offset y flash layout ya son los mismos del C3 (offset 0x0000, no 0x1000 — patrón ya implementado en `arduino_cli.py:369`).
2. **Frontend (`types/board.ts`)**: agregar `'esp32-p4'` al `BoardKind`. Es **RISC-V**, igual que C3 → entra en el flujo de WebSocket-QEMU, **no** en el flujo browser-emulado (avr8js / rp2040js).
3. **Cosmético**: dibujar un board element. Sin un SVG de wokwi-elements, hay que crear el componente nuevo (ya hay precedente con `esp32-cam` y `wemos-lolin32-lite` que reutilizan el SVG ESP32 base con pin labels distintos).
4. **MicroPython**: el set `BOARD_SUPPORTS_MICROPYTHON` debería incluir `esp32-p4` cuando QEMU corra (MicroPython oficial ya tiene puerto P4).
## Riesgos
- **Wi-Fi/BLE**: el ESP32-P4 no tiene radio. Las plataformas (FireBeetle 2, ESP32-P4-Module) lo combinan con un **ESP32-C6** externo vía SDIO/UART. Esto rompe el modelo NIC actual (`esp32_wifi`, `esp32c3_wifi`). Cuando llegue el QEMU, hay que decidir: (a) modelar también el C6 companion, (b) marcar Wi-Fi como no-emulado y mostrar warning al usuario.
- **MIPI-DSI / CSI**: el chip los tiene, pero ningún emulador (ni siquiera Wokwi) los simula a fondo. Sería out-of-scope.
- **PSRAM**: hasta 32 MB. QEMU puede hacerlo (-m), no es bloqueante.
## Archivos relacionados
- [`02_chip_overview.md`](02_chip_overview.md) — specs y peripherals
- [`03_compilation_test.md`](03_compilation_test.md) — output exacto de la compilación
- [`04_qemu_backend_path.md`](04_qemu_backend_path.md) — qué hace falta en backend cuando QEMU soporte P4
- [`05_frontend_emulation_path.md`](05_frontend_emulation_path.md) — opciones JS/WASM y por qué descartadas
- [`06_recommendations.md`](06_recommendations.md) — plan accionable
## Fuentes
- [arduino-esp32 — Support of ESP32-P4 (#10278)](https://github.com/espressif/arduino-esp32/issues/10278)
- [espressif/qemu — Is QEMU support planned for esp32p4 and esp32c6? (#127)](https://github.com/espressif/qemu/issues/127)
- [espressif/qemu releases](https://github.com/espressif/qemu/releases)
- [Wokwi ESP32 Simulation guide](https://docs.wokwi.com/guides/esp32)
- [ESP32-P4 product page](https://www.espressif.com/en/products/socs/esp32-p4)

View File

@ -0,0 +1,69 @@
# 02 — ESP32-P4 chip overview
## Procesador
- **HP core**: dual-core RISC-V hasta **400 MHz** (RV32IMAFC + extensiones AI propietarias de Espressif).
- **LP core**: RISC-V single-core hasta **40 MHz** (low-power, similar al ULP coprocessor de otros ESP32).
- ABI: `ilp32f` (single-precision FPU) — confirmado por `file blink.ino.elf` → "RVC, single-float ABI".
- ISA real observada en el ELF: **RV32IMC** (compressed) + soft-float a nivel de Arduino core (el FPU está pero arduino-esp32 aún no lo usa universalmente).
## Memoria
- **768 KB SRAM HP** on-chip (utilizable como cache cuando hay PSRAM).
- **8 KB TCM RAM** zero-wait.
- Soporta **PSRAM externa hasta 32 MB**.
- Flash externa SPI (típicamente QSPI, hasta 16/32 MB en dev kits).
## Sin radio integrado
⚠️ **El P4 NO tiene Wi-Fi ni Bluetooth nativos**. Los dev kits (FireBeetle 2 ESP32-P4, ESP32-P4-Module, ESP32-P4-NANO) llevan un **ESP32-C6 externo** conectado por SDIO/UART para Wi-Fi 6 y BLE.
Implicación para emulación: el modelo NIC `esp32_wifi` / `esp32c3_wifi` que usa el `esp_qemu_manager` actual **no aplica directamente**. Habría que:
- (a) emular el bus SDIO/UART hacia un C6 emulado (complejo, no existe),
- (b) interceptar la API de IDF/Arduino (`WiFi.begin()`, etc.) y devolver mocks (ya hay un patrón parecido en `wifi_status_parser.py`).
## Periféricos relevantes para Velxio
| Periférico | Cantidad | Uso típico Velxio |
|---|---|---|
| GPIO | 55 (vs 22 en ESP32) | LED, botón, sensor digital |
| ADC | 7 ch × 2 unidades, 12-bit | sensores analógicos, potenciómetro |
| I²C | 2 master / 1 slave | sensores BMP280, MPU6050, LCD I²C |
| SPI | 3 (uno dedicado a flash/PSRAM) | display TFT, SD card |
| I²S | 3 | audio |
| UART | 5 | serial monitor + comms externos |
| LEDC PWM | 8 ch | LED brillo, servos |
| MCPWM | 2 | motor control |
| RMT | 4 ch | NeoPixel, IR |
| USB OTG 2.0 HS | 1 | host/device, **480 Mbps** |
| Ethernet | 1 (RMII) | Ethernet en dev kits |
| SDIO Host | 1 (3.0) | SD card / Wi-Fi co-proc |
| **MIPI-CSI** | 1 (1080p) | cámara — **no emulable** |
| **MIPI-DSI** | 1 (1080p) | display — **no emulable hoy** |
## Variantes de board en arduino-cli (verificadas)
```
esp32:esp32:esp32p4 # ESP32P4 Dev Module (genérico)
esp32:esp32:esp32p4_core_board # ESP32P4 Core Board
esp32:esp32:dfrobot_firebeetle2_esp32p4 # DFRobot FireBeetle 2 ESP32-P4
esp32:esp32:esp32p4_4ds_mipi # 4D Systems ESP32-P4 MIPI Displays
esp32:esp32:esp32p4_4ds_mipi_round # 4D Systems redondo
```
Para Velxio, el FQBN canónico debería ser `esp32:esp32:esp32p4` (Dev Module) — paralelo a `esp32:esp32:esp32` para el clásico.
## Comparativa con boards ya soportados en Velxio
| Board | Arch | Dónde corre hoy |
|---|---|---|
| Arduino Uno (atmega328p) | AVR 8-bit | frontend (avr8js) |
| ATtiny85 | AVR 8-bit | frontend (avr8js) |
| Raspberry Pi Pico (RP2040) | ARM Cortex-M0+ dual | frontend (rp2040js) |
| ESP32 | Xtensa LX6 dual | backend QEMU xtensa |
| ESP32-S3 | Xtensa LX7 dual | backend QEMU xtensa |
| ESP32-C3 | RISC-V RV32IMC single | backend QEMU riscv32 |
| Raspberry Pi 3B | ARM64 | backend QEMU aarch64 |
| **ESP32-P4** | **RISC-V RV32IMAFC dual + LP** | **backend QEMU riscv32 (cuando exista)** |
El ESP32-P4 cae en la **misma categoría que el ESP32-C3**: backend, `qemu-system-riscv32`, `-M esp32p4`. Reutiliza casi toda la plomería del C3 (UART por TCP, GPIO chardev, NIC slirp si llega Wi-Fi).

View File

@ -0,0 +1,73 @@
# 03 — Test de compilación: blink ESP32-P4
## Setup
- `arduino-cli 1.4.1` (commit `e39419312`, 2026-01-19) en `C:/Users/000272869/bin/arduino-cli`.
- Core `esp32:esp32 3.3.8` ya instalado (la última disponible al 2026-05-06).
- Sketch: `test/test-esp32-p4/sketches/blink/blink.ino` (toggle GPIO2 + Serial.println, 25 líneas).
## Comando ejecutado
```bash
cd test/test-esp32-p4/sketches
arduino-cli compile --fqbn esp32:esp32:esp32p4 blink \
--output-dir ../../binaries/blink # nota: el flag --output-dir falló, usé el build/ default
```
## Output
```
Sketch uses 312698 bytes (23%) of program storage space. Maximum is 1310720 bytes.
Global variables use 21980 bytes (6%) of dynamic memory, leaving 305700 bytes for local variables. Maximum is 327680 bytes.
```
Exit code: **0**. Tiempo de compilación: ~50 s en frío.
## Artefactos generados
`sketches/blink/build/esp32.esp32.esp32p4/`:
| Archivo | Tamaño | Para qué sirve |
|---|---|---|
| `blink.ino.bin` | 312 880 B | Imagen de la app (sin bootloader). |
| `blink.ino.bootloader.bin` | 21 392 B | Bootloader (offset 0x0000 en flash). |
| `blink.ino.partitions.bin` | 3 072 B | Tabla de particiones (offset 0x8000). |
| `blink.ino.merged.bin` | **4 194 304 B** (4 MB) | Imagen lista para `qemu -drive if=mtd,format=raw`. |
| `blink.ino.elf` | 7 361 896 B | ELF debug; el que abriría GDB. |
| `boot_app0.bin` | 8 192 B | OTA selector. |
| `flash_args` | 172 B | Offsets para `esptool.py write_flash`. |
| `partitions.csv`, `sdkconfig`, `build.options.json`, `blink.ino.map` | misc | metadatos / map de símbolos. |
## Identificación del ELF
```
$ file blink.ino.elf
ELF 32-bit LSB executable, UCB RISC-V, RVC, single-float ABI, version 1 (SYSV),
statically linked, with debug_info, not stripped
```
Confirma:
- **RISC-V 32-bit little-endian**`qemu-system-riscv32`.
- **RVC** (compressed instructions, RV32C extension).
- **single-float ABI** (`ilp32f`) — el chip tiene FPU single-precision.
## flash_args (offsets para flashing)
```
--flash_mode keep --flash_freq keep --flash_size keep
0x0000 blink.ino.bootloader.bin
0x8000 blink.ino.partitions.bin
0xe000 boot_app0.bin
0x10000 blink.ino.bin
```
Notar: bootloader en **0x0000** (igual que ESP32-C3), no 0x1000 (como ESP32 Xtensa). El switch `bootloader_offset` en `arduino_cli.py:369` ya hace `0x0000 if _is_esp32c3_board(...) else 0x1000`. Para P4 hay que extender ese helper a "ES_RISCV_BOARD" y meter ahí también `esp32p4*`.
## Conclusiones
1. La cadena de toolchain para ESP32-P4 está **lista en arduino-cli sin cambios**.
2. El binary final (`merged.bin` 4 MB) es plug-and-play para QEMU vía `-drive if=mtd,format=raw,file=...` — el mismo patrón que ya usa el `esp_qemu_manager`.
3. Lo único que **falta a nivel toolchain** son ajustes menores en el código de Velxio:
- `arduino_cli.py`: extender `_is_esp32c3_board()` a un `_is_riscv_esp32()` que cubra C3, C6, P4 y H2 para el offset 0x0000.
- `compile.py`: aceptar el FQBN `esp32:esp32:esp32p4` como ESP32-family.
4. **No hay forma de probar el ejecutable** hoy — `qemu-system-riscv32 -M esp32p4` no existe.

View File

@ -0,0 +1,80 @@
# 04 — Vía QEMU backend (la realista, pero bloqueada)
Velxio ya tiene la infraestructura para emular ESP32 vía QEMU. Sumar P4 sería trivial **si la máquina existiera**.
## Estado actual del soporte QEMU
| Fork | Última versión revisada | ESP32-P4 |
|---|---|---|
| `espressif/qemu` (oficial) | `esp-develop-9.2.2-20260417` | ❌ no implementado. Carpeta `hw/riscv` solo tiene `esp32c3.c`, `esp32c3_clk.c`, `esp32c3_intmatrix.c`. [Issue #127 abierto desde 2025-05](https://github.com/espressif/qemu/issues/127), label "Status: To Do". |
| `lcgamboa/qemu` (PICSimLab) | `picsimlab-esp32` | ❌ solo ESP32 + C3. README enumera explícitamente esos dos. |
| `Ebiroll/qemu_esp32` | base 9.2 | ❌ ESP32 Xtensa + S2; no menciona P4. |
| `epiclabs-uc/qemu-esp32` | espejo Espressif | ❌ |
| `max1220/qemu-esp32` | base Espressif + patches | ❌ |
**No existe ningún fork público de QEMU que emule ESP32-P4 al 2026-05-06.**
## Cuando exista — cambios necesarios en Velxio
### Backend
`backend/app/services/esp_qemu_manager.py:41`:
```python
_MACHINE: dict[str, tuple[str, str]] = {
'esp32': (QEMU_XTENSA, 'esp32'),
'esp32-s3': (QEMU_XTENSA, 'esp32s3'),
'esp32-c3': (QEMU_RISCV32, 'esp32c3'),
'esp32-p4': (QEMU_RISCV32, 'esp32p4'), # ← nuevo
}
```
`backend/app/services/arduino_cli.py:212`:
```python
def _is_esp32_riscv_board(self, fqbn: str) -> bool:
"""ESP32 RISC-V variants: C3, C6, H2, P4."""
return any(s in fqbn for s in ('esp32c3', 'esp32c6', 'esp32h2', 'esp32p4'))
```
y reemplazar la única call a `_is_esp32c3_board(...)` en línea 369 por `_is_esp32_riscv_board(...)`. (Bootloader offset 0x0000 es el mismo para todas las P-cores RISC-V.)
`backend/app/services/esp32_lib_manager.py:73-76` (mapping a libs PICSimLab):
```python
'esp32-p4': 'esp32p4-picsimlab', # ← cuando el fork lcgamboa lo soporte
```
Hasta que esto exista, el backend tendría que **rutar P4 al binario QEMU oficial Espressif**, no al `lcgamboa` con bibliotecas PICSimLab. Se pierde Wi-Fi/BLE simulado, pero el chip P4 tampoco tiene radio nativa, así que es coherente.
### NIC / Wi-Fi
`esp_qemu_manager.py:213` actualmente hace:
```python
nic_model = 'esp32c3_wifi' if 'c3' in machine else 'esp32_wifi'
```
Para P4 esto **no aplica** porque el chip no tiene radio. Wi-Fi en hardware real viene de un ESP32-C6 externo por SDIO. Opciones cuando llegue QEMU:
1. **Sin Wi-Fi en P4**: forzar `wifi_enabled = False` siempre. Si el sketch llama `WiFi.begin()`, simplemente reportar timeout. Pragmático.
2. **Wi-Fi mock**: interceptar a nivel serial los strings de IDF (`wifi:state: init -> auth`) ya que `wifi_status_parser.py` ya parsea esos. Permitiría UI verde "conectado" sin emular el bus SDIO. Más trabajo, mejor UX.
3. **Bus SDIO emulado al C6**: imposible hoy, complejidad de meses.
Recomendación: opción **1** al inicio, opción **2** después si hay demanda.
### Frontend
`frontend/src/types/board.ts:1`:
```ts
export type BoardKind =
| ...
| 'esp32-p4'; // ← agregar
```
`frontend/src/utils/boardPinMapping.ts`: agregar mapping pin-name → GPIO number para los 55 GPIOs del P4 (ver Espressif datasheet §3.4).
`frontend/src/store/useSimulatorStore.ts`: registrar el board en el factory de boards.
## Roadmap estimado upstream
Sin información oficial de Espressif sobre fechas. Patrón histórico:
- ESP32-C3 fue añadido a `espressif/qemu` ~6-8 meses después del lanzamiento del chip.
- ESP32-S3 ~12 meses después.
- ESP32-P4 lleva ~3 años en el mercado y aún sin QEMU.
**No es razonable esperar una fecha**. Vale la pena suscribirse al [issue #127](https://github.com/espressif/qemu/issues/127) y a las [releases](https://github.com/espressif/qemu/releases).

View File

@ -0,0 +1,61 @@
# 05 — Vía frontend (browser): por qué no es viable hoy
El otro patrón de Velxio es ejecutar el emulador **en el browser** (sin backend, sin WebSocket): así corren AVR (`avr8js`) y RP2040 (`rp2040js`). Para ESP32-P4 esta vía está cerrada por falta de un emulador open-source.
## Opciones evaluadas
### 1. Emulador JS dedicado (estilo `avr8js` / `rp2040js`)
**No existe.** Wokwi mantiene `avr8js` y `rp2040js` open-source en GitHub bajo MIT, pero su engine ESP32 (incluido el P4) es **cerrado** y forma parte del producto Wokwi Cloud / Wokwi VS Code. Verificado:
```
$ # listado de repos públicos org wokwi en github
avr8js # open
rp2040js # open
esp32p4-hello-world # solo sketch ejemplo, NO engine
esp32p4-mipi-dsi-panel-demo # solo sketch ejemplo
esp32-roms # ROMs reverse-engineered
esp32-test-binaries # firmware de prueba
# NO HAY: esp32js, esp32p4js, esp32-emulator, etc.
```
Construir un emulador RV32IMAFC + 55 GPIOs + I²C/SPI/UART/I²S/USB/MIPI-DSI desde cero es **trabajo de años** para una sola persona. Out of scope para este proyecto.
### 2. Emuladores RISC-V genéricos (rvemu, riscv-rust, TinyEMU)
| Proyecto | Lenguaje | ISA | ¿Sirve para ESP32-P4? |
|---|---|---|---|
| `d0iasm/rvemu` | Rust + WASM | RV64GC, Sv39, UART/PLIC/CLINT | ❌ apunta a Linux/xv6, no a ESP32 SoC. |
| `takahirox/riscv-rust` | Rust + WASM | RV64IMAFD, Sv39 | ❌ idem. |
| `TinyEMU` (F. Bellard) | C → wasm | RV32IMA, RV64GC | ❌ idem; emula virtio, no ESP32 mem-map. |
El problema no es el CPU — RV32IMAFC es estándar y cualquiera de estos lo ejecuta — el problema son **los periféricos chip-específicos**: GPIO matrix, IO MUX, RTC, SYSCON, INTERRUPT_CORE, USB OTG, etc. **Sin esos, el firmware se cuelga en el bootloader** intentando configurar reloj y memoria.
### 3. QEMU compilado a WASM
Patrón explorado en `test/esp32-emulator/qemu-wasm/Dockerfile` para Xtensa (vía Emscripten). Aplicaría igual al P4 **si `espressif/qemu` tuviera la máquina**, pero como no la tiene, este path está bloqueado por la misma razón que el backend.
Trade-off: aún cuando esté listo, QEMU-WASM:
- pesa ~30-40 MB (chunk lazy-loaded).
- es ~5-10× más lento que QEMU nativo en backend.
- no tiene WebSocket overhead.
Conclusión: **prefiere backend QEMU** sobre QEMU-WASM para ESP32 boards en general. Coincide con la decisión que ya tomó Velxio para C3/S3.
### 4. Espressif IDF Component Manager + QEMU oficial reutilizado en cliente
Imposible: el QEMU oficial es ELF/EXE para Linux/Mac/Windows, no WASM. Habría que recompilarlo (vuelve a opción 3).
## Por qué AVR y RP2040 sí están en frontend
- **AVR**: ISA chiquita (~131 instrucciones, 8-bit). avr8js son ~5 K líneas TS.
- **RP2040**: ARM Cortex-M0+ con set reducido. rp2040js son ~10 K líneas TS y aprovecha que el RP2040 es bien documentado y open silicon.
- **ESP32-P4**: SoC de **última generación** con dual-core, FPU, AI extensions, MMU, cache, MIPI… al menos un orden de magnitud más complejo. Sin la documentación interna (que Espressif solo da parcialmente), el reverse-engineering completo es prohibitivo.
## Veredicto
La vía frontend para ESP32-P4 está **descartada** salvo dos eventos improbables a corto plazo:
- Wokwi libera su engine ESP32 (no hay señales de eso).
- Espressif publica un emulador WASM oficial.
La única vía realista es **backend QEMU cuando exista la máquina** — ver [`04_qemu_backend_path.md`](04_qemu_backend_path.md).

View File

@ -0,0 +1,61 @@
# 06 — Recomendaciones / plan accionable
## Decisión propuesta
**No agregar ESP32-P4 como board emulable hoy.** Sumarlo en estado "compilable, no emulable" tiene un valor marginal (el usuario ve el ELF generado, pero al pulsar Run no pasa nada útil) y crea expectativa que no se puede cumplir.
Sin embargo, **toda la plomería de toolchain** se puede dejar lista hoy con muy poco esfuerzo, de modo que el día que `espressif/qemu` mergee la máquina P4, sumar el board sea cuestión de un PR de ~50 líneas.
## Plan en 3 fases
### Fase A — Hoy (preparación, sin exponer al usuario)
Esfuerzo: ~2 h. Riesgo: bajo. **No** agrega un board nuevo en el frontend.
1. **Refactor mínimo en `arduino_cli.py`**: renombrar `_is_esp32c3_board``_is_esp32_riscv_board` y extender la lista a `esp32c3, esp32c6, esp32h2, esp32p4`. Misma lógica de `bootloader_offset = 0x0000`. ~10 líneas.
2. **Subscribirse al [issue #127 de espressif/qemu](https://github.com/espressif/qemu/issues/127)** para enterarse cuando aterrice la máquina P4.
3. **Mantener este folder `test/test-esp32-p4/`** como referencia viva — actualizar `01_findings.md` cada vez que haya un release de `espressif/qemu`.
### Fase B — Cuando QEMU soporte ESP32-P4
Esfuerzo: ~1-2 días. Riesgo: medio (depende de qué peripherals emule realmente la máquina).
1. **Backend (`esp_qemu_manager.py`)**:
- Agregar `'esp32-p4': (QEMU_RISCV32, 'esp32p4')` al `_MACHINE` dict.
- Forzar `wifi_enabled = False` para P4 (chip sin radio nativa) — devolver warning explícito si el usuario lo activa.
2. **Frontend (`types/board.ts`)**:
- Agregar `'esp32-p4'` a `BoardKind`.
- Agregar a `BOARD_KIND_LABELS` con label "ESP32-P4 Dev Module".
- Agregar a `BOARD_SUPPORTS_MICROPYTHON` (MicroPython tiene puerto P4 desde mediados 2025).
3. **Pin mapping (`utils/boardPinMapping.ts`)**:
- Mapear los 55 GPIOs según pinout del Dev Module Espressif. Patrón idéntico al ESP32-S3.
4. **Componente visual**:
- SVG nuevo en `components-wokwi/` (no hay element open en `wokwi-elements`). Alternativa de bajo esfuerzo: reutilizar el SVG del ESP32-S3 con renombrado de pines, hasta tener un dibujo propio.
5. **Smoke test**: `test/test-esp32-p4/scripts/smoke.sh` que (a) compila blink, (b) lanza `qemu-system-riscv32 -M esp32p4 -drive ...`, (c) verifica que aparece "ESP32-P4 blink starting" en el TCP serial.
6. **Tests backend**: agregar caso ESP32-P4 a `test/esp32/test_esp32_integration.py`.
### Fase C — Wi-Fi mock (opcional, cuando haya demanda real)
Cuando un usuario reporte que quiere usar `WiFi.h` con ESP32-P4, implementar mock por parsing del UART (mismo patrón que `wifi_status_parser.py` ya usa para C3). El bus SDIO al C6 emulado real es prohibitivo y se puede ignorar.
## Lo que NO hacer
- ❌ No empezar a portar `rp2040js` a "esp32p4js". Es un proyecto de años y duplica esfuerzo de Wokwi/Espressif.
- ❌ No mergear el board en producción sin el QEMU operacional. Da una mala primera impresión.
- ❌ No comprometerse con Wi-Fi/BLE para este chip. La radio externa C6 es una bestia distinta.
- ❌ No usar QEMU-WASM para P4 mientras el backend QEMU funcione bien para los otros ESP32. Costo (~40 MB WASM extra) > beneficio.
## Métrica de éxito
Cuando se ejecute Fase B, el criterio de aceptación es:
- `arduino-cli compile --fqbn esp32:esp32:esp32p4 blink` produce ELF (ya OK).
- En Velxio, seleccionar board "ESP32-P4 Dev Module" + Run reproduce el LED parpadeando + Serial Monitor muestra "HIGH/LOW" cada 500 ms.
- Smoke test CI verde.
## Cómo monitorear el bloqueante
- GitHub: watch [espressif/qemu releases](https://github.com/espressif/qemu/releases).
- Issue principal: [#127](https://github.com/espressif/qemu/issues/127).
- Mirror: [esp-toolchain-docs/qemu](https://github.com/espressif/esp-toolchain-docs/tree/main/qemu).
Cuando aparezca `hw/riscv/esp32p4.c` en `esp-develop`, activar Fase B.

View File

@ -0,0 +1,18 @@
#!/usr/bin/env bash
# Compile the blink sketch for ESP32-P4 with arduino-cli.
# Reproduces the test documented in autosearch/03_compilation_test.md.
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
ROOT="$HERE/.."
SKETCH="$ROOT/sketches/blink"
echo "[+] Compiling $SKETCH for esp32:esp32:esp32p4"
arduino-cli compile --fqbn esp32:esp32:esp32p4 "$SKETCH"
BUILD="$SKETCH/build/esp32.esp32.esp32p4"
echo "[+] Output:"
ls -la "$BUILD"
echo
echo "[+] ELF arch:"
file "$BUILD/blink.ino.elf"

View File

@ -0,0 +1,44 @@
#!/usr/bin/env bash
# Smoke test: run the merged blink binary in qemu-system-riscv32 -M esp32p4.
#
# REQUIREMENTS — none of these is true at 2026-05-06:
# 1. Espressif QEMU fork includes -M esp32p4 (see issue #127, status: To Do).
# 2. qemu-system-riscv32 binary is in PATH.
#
# This script will FAIL today. It exists as a reference for Phase B
# (see autosearch/06_recommendations.md). Re-evaluate when espressif/qemu
# adds hw/riscv/esp32p4.c to esp-develop.
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
ROOT="$HERE/.."
MERGED="$ROOT/sketches/blink/build/esp32.esp32.esp32p4/blink.ino.merged.bin"
if [ ! -f "$MERGED" ]; then
echo "[!] $MERGED not found — run scripts/compile.sh first."
exit 1
fi
QEMU_BIN="${QEMU_RISCV32_BINARY:-qemu-system-riscv32}"
if ! command -v "$QEMU_BIN" >/dev/null; then
echo "[!] $QEMU_BIN not found in PATH."
echo " Install Espressif QEMU fork: https://github.com/espressif/qemu/releases"
exit 1
fi
echo "[+] Available machines:"
"$QEMU_BIN" -M help | grep -i esp || echo " (no ESP32 machines listed)"
echo
if ! "$QEMU_BIN" -M help | grep -q esp32p4; then
echo "[!] -M esp32p4 not supported by this QEMU build."
echo " Track: https://github.com/espressif/qemu/issues/127"
exit 2
fi
echo "[+] Booting $MERGED in QEMU esp32p4 (Ctrl-A X to quit)..."
"$QEMU_BIN" \
-nographic \
-M esp32p4 \
-drive "file=$MERGED,if=mtd,format=raw" \
-serial mon:stdio

View File

@ -0,0 +1,19 @@
// Minimal blink sketch for ESP32-P4
// Toggles GPIO2 every 500 ms.
#define LED_PIN 2
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
Serial.println("ESP32-P4 blink starting");
}
void loop() {
digitalWrite(LED_PIN, HIGH);
Serial.println("HIGH");
delay(500);
digitalWrite(LED_PIN, LOW);
Serial.println("LOW");
delay(500);
}