velxio/test/test_Raspberry_Pi_Pico_W/README.md

151 lines
6.7 KiB
Markdown

# test_Raspberry_Pi_Pico_W
Research + prototype scaffold for **adding CYW43439 WiFi emulation to
Velxio's Raspberry Pi Pico W simulation**.
This folder is the answer to:
> "Velxio emulates ESP32 WiFi but not Raspberry Pi Pico W WiFi. The
> WiFi chip is a CYW43439. Has anyone written an emulator for it?
> Look at `third-party/rp2040js` and figure out what would be needed to
> complete WiFi emulation."
It is **not** a feature drop. The Velxio frontend and backend are
unchanged. Everything here is research, design, and a runnable
prototype harness so that the actual feature work — when it lands — can
land confidently.
## Layout
```
test_Raspberry_Pi_Pico_W/
├── README.md ← this file
├── autosearch/ ← the dossier
│ ├── 00_README.md ← TL;DR + index
│ ├── 01_velxio_current_state.md ← what's broken on Pico W today
│ ├── 02_rp2040js_inventory.md ← what we'd build on top of
│ ├── 03_cyw43_bus_protocol.md ← gSPI command word, registers, magic
│ ├── 04_emulation_design.md ← layered plan: Tier 0 → 3
│ ├── 05_existing_implementations.md ← every CYW43 codebase we found
│ ├── 06_firmware_blob_question.md ← can we ship the 224 KB blob? (no)
│ ├── 07_open_questions.md ← decisions still open
│ └── sources.md ← every URL, dated 2026-04-28
└── test_code/ ← runnable Tier-0 prototype
├── README.md
├── package.json ← local Node deps
├── tsconfig.json
├── src/
│ ├── pio_bus_sniffer.ts ← decodes gSPI cmds off PIO TX FIFO
│ ├── cyw43_emulator_tier0.ts ← stub chip — handshake + LED
│ └── harness.ts ← glue for rp2040js
└── tests/
├── 01_pio_decoder.test.ts ← bit-layout unit tests
├── 02_handshake.test.ts ← 0xFEEDBEAD + HT_AVAIL + LED IOCTL
└── 03_pico_w_blink.test.ts ← end-to-end (skipped without UF2)
```
## TL;DR of the research
| Question | Answer |
|---|---|
| Is there an open-source CYW43439 emulator? | **No.** Open issue [wokwi/rp2040js#134](https://github.com/wokwi/rp2040js/issues/134) confirms upstream hasn't done it; no community fork either. Wokwi simulates Pico W WiFi, but their CYW43 model is closed-source. |
| Is the protocol documented? | **Yes.** Infineon datasheet + three open-source host drivers (pico-sdk, embassy-rs, soypat, picowi) describe every byte the host sends. |
| Do we need the 224 KB firmware blob? | **No.** The driver doesn't read it back — it just streams it and trusts the chip. We ack the writes and lie about HT_AVAIL. |
| Reasonable to add to Velxio? | **Yes**, in 4 tiers — Tier 0 (LED works, ~450 LOC) is achievable in a few days. Tier 2 (real WiFi via slirp through the backend, mirroring the ESP32 path) is comparable in size to the existing ESP32 work. |
Full breakdown in [`autosearch/00_README.md`](./autosearch/00_README.md).
## TL;DR of the prototype
```bash
cd test/test_Raspberry_Pi_Pico_W/test_code
npm install
npm test # 30 unit + integration tests pass — Tier 0/1/2
npm run e2e # 1 e2e test, skipped without a Pico W MicroPython UF2
```
The suite covers the entire chip-side surface:
- **Bus protocol** (`01`, `02`) — `0xFEEDBEAD` handshake, F0/F1
registers, clock CSR, the 224 KB firmware-stream absorb path.
- **SDPCM/CDC framing** (`04`) — encode/decode round-trips for control
frames, IOCTL requests, async event frames.
- **IOCTL responses** (`05`) — `GET_MAGIC`, `UP`/`DOWN`,
`cur_etheraddr` returns the STA MAC, `gpioout` fires the on-board
LED, `WLC_SCAN` produces a real `wl_escan_result_t` advertising
`Velxio-GUEST`.
- **Full WiFi lifecycle** (`06`) — bus init → scan → `SET_SSID
Velxio-GUEST` → link up → `GET_BSSID` → outbound Ethernet frame →
inbound packet injection → `WLC_DOWN` → link down. Plus negative
cases (unknown SSID, mid-firmware-stream IOCTLs).
That is enough to back **production-grade** Pico W WiFi emulation in
Velxio. The remaining work to ship is purely integration:
1. Move `src/{pio_bus_sniffer,cyw43_emulator,sdpcm,virtual_ap,cyw43_constants}.ts`
into `frontend/src/simulation/cyw43/`.
2. Hook `RP2040Simulator.ts` to attach the emulator only when
`boardKind === 'pi-pico-w'`.
3. Add a backend WS bridge that turns `onPacketOut` Ethernet frames
into TCP/UDP via slirp (mirror `backend/app/services/esp32_worker.py`).
## Test results (latest run, 2026-04-29)
```
$ npm test
✓ tests/01_pio_decoder.test.ts (9 tests)
✓ tests/02_handshake.test.ts (6 tests)
✓ tests/04_sdpcm.test.ts (7 tests)
✓ tests/05_ioctl.test.ts (5 tests)
✓ tests/06_full_lifecycle.test.ts (3 tests)
Test Files 5 passed (5)
Tests 30 passed (30)
```
```
$ npm run e2e
↓ tests/03_pico_w_blink.test.ts (1 test | 1 skipped)
[03_pico_w_blink] SKIP: drop a Pico W MicroPython UF2 in fixtures/
to enable this test. Suggested file:
RPI_PICO_W-20230426-v1.20.0.uf2
```
## What "Velxio-GUEST" looks like
The synthetic AP every Pico W simulation joins (single source of
truth in `src/virtual_ap.ts`):
| Field | Value |
|---|---|
| SSID | `Velxio-GUEST` |
| BSSID | `02:42:DA:42:00:01` (locally-administered) |
| Channel | 6 |
| RSSI | -40 dBm |
| Security | open (we accept any password the user sends) |
| STA MAC | `02:42:DA:00:00:42` |
| STA IP (when DHCP gets wired) | `10.13.37.42/24`, gw `10.13.37.1` |
Same naming convention as the existing ESP32 path (`Velxio-GUEST`).
No Wokwi-* identifiers anywhere in the tree.
## What this folder does NOT do
- It does **not** modify the Velxio frontend, backend, or
`third-party/rp2040js`. The repo's Pico W behaviour is unchanged.
- It does **not** ship the closed CYW43 firmware blob — see
[`autosearch/06_firmware_blob_question.md`](./autosearch/06_firmware_blob_question.md).
- It does **not** implement Tier 1+ (scan, connect, real packet flow).
Those are scoped in [`autosearch/04_emulation_design.md`](./autosearch/04_emulation_design.md)
but intentionally not built — the point of the prototype is to
prove the **hardest** layer (bus protocol) works against rp2040js.
When the feature graduates to a real Velxio surface, the right move is:
1. Promote `src/cyw43_emulator_tier0.ts` and `src/pio_bus_sniffer.ts`
into `frontend/src/simulation/cyw43/`.
2. Wire the harness into `RP2040Simulator.ts` only when
`boardKind === 'pi-pico-w'`.
3. Implement Tier 1 IOCTLs (~600 LOC) — most are 1-line acks.
4. Add the backend WS bridge for Tier 2 (mirror `esp32_worker.py`).