288 lines
12 KiB
Markdown
288 lines
12 KiB
Markdown
# Findings — log corrido
|
|
|
|
Formato: por sesión + fecha. Lo más reciente arriba.
|
|
|
|
---
|
|
|
|
## 2026-04-28 (sesión 4) — SPI + 5 chips nuevos + gaps cubiertos
|
|
|
|
### Resultado
|
|
|
|
```
|
|
Test Files 26 passed | 0 skipped (26)
|
|
Tests 70 passed | 0 skipped (70)
|
|
```
|
|
|
|
### Gaps de wokwi-api.h ahora cubiertos
|
|
|
|
✅ **SPI slave**: nuevo `SPIBus` + `SPIDevice` + `vx_spi_attach`/`start`/`stop`. Modelo
|
|
buffer-bidireccional como Wokwi: chip pre-llena con MISO, master clockea bytes,
|
|
buffer queda con MOSI recibido, fires `on_done(buffer, count)`.
|
|
✅ **`VX_OUTPUT_LOW` / `VX_OUTPUT_HIGH`**: modos 16/17 que inicializan el pin a un
|
|
nivel concreto al registrar — elimina la ventana glitch entre register+write.
|
|
✅ **`vx_pin_watch_stop`**: por-handle, libera todos los watches del pin.
|
|
✅ **`vx_pin_dac_write`**: dispara analog listeners en PinManager (DAC).
|
|
✅ **`vx_pin_set_mode`**: cambiar modo después del init (renombrado de pin_mode
|
|
por colisión con el nombre del enum en C).
|
|
✅ **`reserved[8]` en configs**: i2c_config = 64 bytes, uart_config = 56 bytes,
|
|
spi_config = 60 bytes. ABI estable hacia adelante.
|
|
|
|
### Chips nuevos compilados (5)
|
|
|
|
| Chip | Tamaño | Protocolos | Notas |
|
|
|---|---|---|---|
|
|
| `sn74hc595.wasm` | 64 KB | SPI + GPIO + RCLK latch | Shift register 8-bit, latch en RCLK rising |
|
|
| `mcp3008.wasm` | 64 KB | SPI + ANALOG | ADC 8-canales 10-bit |
|
|
| `pcf8574.wasm` | 64 KB | I2C + GPIO bidireccional | I/O expander 8-bit, base 0x20 |
|
|
| `ds3231.wasm` | 64 KB | I2C + estado interno | RTC con 19 registros, BCD encoding |
|
|
| `pulse-counter.wasm` | 64 KB | GPIO + atributos | Cuenta flancos, OVF cada N pulsos |
|
|
|
|
### Tests nuevos (21 más, total 70)
|
|
|
|
- `14_sn74hc595` — 4 tests: SPI byte transfer, RCLK latching, SRCLR clear, byte override.
|
|
- `15_mcp3008` — 3 tests: 0V/2.5V/5V analog readings via SPI command protocol.
|
|
- `16_pcf8574` — 4 tests: I2C write→pin pattern, read line state, A0..A2 addressing, latched persistence.
|
|
- `17_ds3231` — 3 tests: read default time, set+read time round-trip BCD, register pointer.
|
|
- `18_pulse_counter` — 3 tests: default threshold (4), custom threshold attr, RST clear.
|
|
- `19_api_extras` — 4 tests: import surface, OUTPUT_HIGH init, OUTPUT_LOW init, DAC dispatch.
|
|
|
|
### Lo que se aprendió
|
|
|
|
1. **Re-arm SPI**: chips como 74HC595 que no usan CS deben llamar `vx_spi_start` de
|
|
nuevo dentro del `on_done` callback. Si no, solo el primer byte llega.
|
|
2. **Naming collision en C**: `vx_pin_mode` no podía ser tipo Y función. Renombrado a
|
|
`vx_pin_set_mode`. Lección: prefijar funciones distinto del enum/typedef.
|
|
3. **Struct ABI con reserved[8]**: agregar campos al final no rompe los chips ya
|
|
compilados solo si las posiciones existentes no se mueven. El `_Static_assert`
|
|
en el header detecta cualquier movimiento accidental.
|
|
4. **PinManager.setAnalogVoltage** ya existía y permitió implementar `pin_dac_write`
|
|
sin agregar infraestructura nueva.
|
|
|
|
### Aún pendiente (deferido)
|
|
|
|
- Framebuffer para displays (LCD/OLED custom). El IL9163 que pasaste sería el caso
|
|
de uso. Implementarlo cuando sea necesario; SSD1306 / ILI9341 ya están en
|
|
wokwi-elements y no necesitan custom chip.
|
|
- `attr_string_init` (atributos texto/select). Caso raro.
|
|
- Experimental `_mcu_*` (memoria del CPU emulado). Solo para debug.
|
|
|
|
---
|
|
|
|
## 2026-04-28 (sesión 3) — AVR Wire + chip I2C: full E2E
|
|
|
|
### Resultado
|
|
|
|
```
|
|
Test Files 20 passed | 0 skipped (20)
|
|
Tests 49 passed | 0 skipped (49)
|
|
```
|
|
|
|
**Cero tests skipped.** Toda la suite corre verde sin excepción.
|
|
|
|
### Lo que se completó
|
|
|
|
- Sketch Arduino real (`sketches/i2c_eeprom_demo/i2c_eeprom_demo.ino`) que usa
|
|
`Wire.h` para hablar con el chip 24C01.
|
|
- Compilado con `arduino-cli compile --fqbn arduino:avr:uno`. Salida en
|
|
`fixtures/i2c_eeprom_demo.hex` (11 KB, ATmega328P).
|
|
- Test `07_chip_eeprom_avr_e2e` pasa: el sketch escribe 4 bytes (0xAA..0xDD),
|
|
resetea el pointer, lee de vuelta, y los emite por Serial. La suite verifica
|
|
que los 4 bytes aparecen en `getSerialOutput()` en el orden correcto.
|
|
|
|
### Cadena verificada end-to-end
|
|
|
|
```
|
|
i2c_eeprom_demo.ino (C++)
|
|
→ arduino-cli + arduino:avr:1.8.7
|
|
→ ATmega328P .hex
|
|
→ avr8js CPU (real instrucciones)
|
|
→ AVRTWI peripheral (real I2C bit-banging)
|
|
→ I2CBus (TWIEventHandler)
|
|
→ ChipInstance (WASM)
|
|
→ eeprom-24c01.wasm
|
|
→ callbacks I2C (connect/read/write/stop)
|
|
→ respuestas del bus
|
|
→ AVR USART transmit
|
|
→ serialOut buffer
|
|
→ assertion en el test ✅
|
|
```
|
|
|
|
### API gap vs wokwi-api.h
|
|
|
|
Documentado en `06_wokwi_api_gap_analysis.md`. Lo importante que falta:
|
|
- SPI slave (alta prioridad)
|
|
- `OUTPUT_LOW`/`OUTPUT_HIGH` modes
|
|
- `pin_watch_stop`
|
|
- `reserved[8]` en configs (forward-compat)
|
|
- `pin_dac_write`, `pin_mode`
|
|
|
|
Total estimado: ~1 día para cubrir esos gaps.
|
|
|
|
---
|
|
|
|
## 2026-04-28 (sesión 2) — Suite completa: GPIO + I2C + UART + multi-chip + AVR
|
|
|
|
### Resultado
|
|
|
|
```
|
|
Test Files 19 passed | 1 skipped (20)
|
|
Tests 48 passed | 1 skipped (49)
|
|
```
|
|
|
|
### Chips compilados y validados
|
|
|
|
| Chip | Tamaño | Protocolos ejercitados |
|
|
|---|---|---|
|
|
| `inverter.wasm` | 63 KB | GPIO + pin_watch |
|
|
| `xor.wasm` | 63 KB | GPIO + pin_watch (2 inputs) |
|
|
| `cd4094.wasm` | 64 KB | GPIO + pin_watch BOTH/RISING + state machine 8-bit |
|
|
| `eeprom-24c01.wasm` | 64 KB | I2C slave + addressing + 128-byte memory |
|
|
| `eeprom-24lc256.wasm` | 64 KB | I2C slave + 16-bit addressing + 32 KB memory |
|
|
| `uart-rot13.wasm` | 63 KB | UART RX/TX + struct passing + uart_write |
|
|
|
|
### Tests por categoría
|
|
|
|
**Tier 1 — single chip (10 tests):** inicialización, edges, truth table XOR, shift register
|
|
8-bit, power gate, strobe latching.
|
|
|
|
**Tier 2 — protocols (13 tests):**
|
|
- I2C 24C01: write/read básico, auto-increment, wrap @ 0x80, A0/A1/A2 pin selection.
|
|
- I2C 24LC256: 16-bit addressing, high addresses (>0xff), page write 8 bytes, cross-page read.
|
|
- UART ROT13: A↔N, Z↔M wrap, lowercase, non-alpha passthrough, round-trip todos los printables.
|
|
|
|
**Tier 3 — multi-chip (4 tests):**
|
|
- Dos 24C01 con A0 distinto → 0x50 y 0x51 independientes en el mismo bus.
|
|
- NACK a direcciones no usadas (0x52..0x77).
|
|
- Dos CD4094 cascadeados (A.QS → B.DATA) con CLK/STR compartidos.
|
|
- XOR.OUT → Inverter.IN → XNOR truth table (logic chaining).
|
|
- EEPROM I2C + UART chip operando en paralelo sin interferencia.
|
|
|
|
**Tier 4 — AVR + chips (3 tests):**
|
|
- avr8js con `blink.hex` real → pin 13 toggle → Inverter chip OUT toggle inverso.
|
|
- avr8js → XOR.A (B held LOW) → OUT mirrors A.
|
|
- avr8js → CD4094.CLK + DATA HIGH + strobe → register latches non-zero.
|
|
|
|
### Protocolos validados end-to-end
|
|
|
|
✅ **GPIO**: pin_register, pin_read, pin_write, pin_watch (RISING/FALLING/BOTH).
|
|
✅ **I2C slave**: connect/read/write/stop callbacks via function table indirect.
|
|
✅ **UART**: rx_byte callback, write_done callback, vx_uart_write con buffer.
|
|
✅ **Multi-instance**: dos `.wasm` idénticos con state independiente (memorias separadas).
|
|
✅ **Multi-chip**: chips de protocolos distintos en el mismo `PinManager` + `I2CBus`.
|
|
✅ **Chip → chip**: la salida de un chip dispara el `pin_watch` de otro chip.
|
|
✅ **AVR → chip**: el AVR drivea pines y los chips reaccionan correctamente.
|
|
|
|
### Lo que NO hicimos (todavía)
|
|
|
|
- Test #07 `chip_eeprom_avr_e2e` requiere `.hex` de un sketch con `Wire.h` hablando con
|
|
el chip 24C01. Si bien todos los componentes están validados por separado, falta
|
|
ese caso "AVR Wire master + chip I2C slave" como prueba final.
|
|
|
|
---
|
|
|
|
## 2026-04-28 — wasi-sdk + compilación real + E2E pasando
|
|
|
|
### Hito alcanzado: VIABILIDAD CONFIRMADA
|
|
|
|
**El sistema completo funciona end-to-end.** Un `.c` escrito contra `velxio-chip.h`
|
|
compila a `.wasm` con clang+wasi-sdk, se carga en el `ChipRuntime`, y la lógica
|
|
del chip (incluyendo I2C slave con callbacks via function table) ejecuta correctamente.
|
|
|
|
### Resultados
|
|
|
|
```
|
|
Test Files 6 passed | 1 skipped (7)
|
|
Tests 17 passed | 1 skipped (18)
|
|
```
|
|
|
|
- ✅ `inverter.c` compilado (~63 KB) — `vx_pin_register`/`vx_pin_write`/`vx_pin_watch`
|
|
con callback indirect-call funcionan en WASM real.
|
|
- ✅ `eeprom-24c01.c` compilado (~63 KB) — protocolo I2C completo: addressing,
|
|
write pointer + bytes, read sequential, pointer auto-increment.
|
|
- ✅ Dos instancias del mismo `.wasm` (24C01 con A0 distintos → direcciones
|
|
0x50 y 0x51) operan en paralelo en el mismo `I2CBus` sin interferencia.
|
|
- ⏭ Skipped: test #07 que requiere un `.hex` de Arduino real con `Wire.h`
|
|
hablándole al chip. Falta compilarlo con `arduino-cli`.
|
|
|
|
### Setup que funcionó
|
|
|
|
- **WASI-SDK 32.0** instalado en `C:\wasi-sdk` (Windows). Apache 2.0.
|
|
- **clang 22.1.0** con target `wasm32-unknown-wasip1`.
|
|
- Comando final:
|
|
```
|
|
clang --target=wasm32-unknown-wasip1 -O2 -nostartfiles \
|
|
-Wl,--import-memory -Wl,--export-table -Wl,--no-entry \
|
|
-Wl,--export=chip_setup -Wl,--allow-undefined \
|
|
-I sdk/include chip.c -o chip.wasm
|
|
```
|
|
|
|
### Lo que NO funcionó al primer intento
|
|
|
|
1. **Target deprecado**: `--target=wasm32-unknown-wasi` daba warning. Se cambió
|
|
a `wasm32-unknown-wasip1`.
|
|
2. **Linker fallaba** con "undefined symbol: vx_pin_register …": faltaba
|
|
`-Wl,--allow-undefined`. Sin ese flag, las funciones extern del header
|
|
se trataban como link errors. Con el flag, el linker las convierte en
|
|
imports WASM (que es exactamente lo que queremos).
|
|
3. **Doble prefijo `[chip] [chip] inverter ready`** en stdout: el `WasiShim`
|
|
prefijaba el output de printf y el `ChipRuntime` también prefijaba en
|
|
`vx_log`. Se removió el prefijo del runtime (lo deja al WasiShim).
|
|
|
|
### Tamaño del WASM
|
|
|
|
~63 KB tanto para inverter como para 24C01. Más de lo estimado (~10 KB)
|
|
porque wasi-libc trae `malloc`+`printf`+familia. Aceptable para el caso
|
|
de uso (almacenar por proyecto en SQLite).
|
|
|
|
### Próximos pasos
|
|
|
|
- Compilar un sketch Arduino real (`Wire.h`) con `arduino-cli` y dropearlo
|
|
en `fixtures/i2c_eeprom_demo.hex` para activar el test #07. Eso valida
|
|
el flujo completo: AVR sketch → I2C bus virtual → chip WASM → respuesta.
|
|
- Implementar `vx_uart_attach` (hoy stub).
|
|
- Validar el `_Static_assert(sizeof(vx_i2c_config) == 32)` realmente se
|
|
honra: el header lo declara, pero confirmarlo en runtime con un script
|
|
de compilación que falle si cambia.
|
|
- Decidir cómo reducir el tamaño del .wasm (¿compilar sin printf? ¿stripping
|
|
agresivo?). No urgente.
|
|
|
|
---
|
|
|
|
## 2026-04-27 — Sesión inicial: scaffold + diseño
|
|
|
|
### Lo que se hizo
|
|
|
|
- Se creó la estructura `test/autosearch/` y `test/test_custom_chips/`.
|
|
- Se documentó la API de Wokwi como referencia (no como código a usar).
|
|
- Se diseñó `velxio-chip.h` desde cero, naming propio (`vx_*`).
|
|
- Se decidió: cero código de Wokwi en el proyecto. Toolchain solo LLVM/WASI.
|
|
- Se implementaron los siguientes módulos JS en el sandbox:
|
|
- `src/PinManager.js` — espejo 1:1 de `frontend/src/simulation/PinManager.ts`.
|
|
- `src/I2CBus.js` — espejo de `I2CBusManager.ts`.
|
|
- `src/AVRHarness.js` — copiado desde `test_circuit/src/avr/AVRHarness.js` (mismo pattern que Velxio).
|
|
- `src/ChipRuntime.js` — loader WASM + tabla de host imports.
|
|
- `src/WasiShim.js` — `fd_write`, `proc_exit`, `clock_time_get`.
|
|
|
|
### Qué probamos
|
|
|
|
- Tests JS-only (no requieren clang) corren con `pnpm test`.
|
|
- Validan el shape de PinManager, I2CBus, host imports, AVRHarness con `.hex` real.
|
|
|
|
### Qué falta (próxima sesión)
|
|
|
|
- Compilar `inverter.c` y `eeprom-24c01.c` con `compile-chip.sh` para generar fixtures `.wasm`.
|
|
- Test E2E: AVR sketch + 24C01 chip vía I2C bus virtual. Validar lectura/escritura.
|
|
- Implementar `vx_pin_watch` con indirect call al function table.
|
|
- Decidir layout exacto del struct `vx_i2c_config` (ABI estable entre clang y host JS).
|
|
|
|
### Lo que NO funcionó (todavía)
|
|
|
|
- N/A — primera sesión.
|
|
|
|
### Lo que funcionó
|
|
|
|
- Reusar `AVRHarness.js` de `test_circuit` sin modificaciones — buena señal de que la
|
|
abstracción está bien hecha en Velxio.
|
|
- `I2CBusManager` de Velxio ya tiene la interface que necesita el chip (`writeByte`/`readByte`/`stop`)
|
|
→ mapeo casi directo.
|