6.7 KiB
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/rp2040jsand 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 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.
TL;DR of the prototype
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) —0xFEEDBEADhandshake, 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_etheraddrreturns the STA MAC,gpiooutfires the on-board LED,WLC_SCANproduces a realwl_escan_result_tadvertisingVelxio-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:
- Move
src/{pio_bus_sniffer,cyw43_emulator,sdpcm,virtual_ap,cyw43_constants}.tsintofrontend/src/simulation/cyw43/. - Hook
RP2040Simulator.tsto attach the emulator only whenboardKind === 'pi-pico-w'. - Add a backend WS bridge that turns
onPacketOutEthernet frames into TCP/UDP via slirp (mirrorbackend/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. - It does not implement Tier 1+ (scan, connect, real packet flow).
Those are scoped in
autosearch/04_emulation_design.mdbut 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:
- Promote
src/cyw43_emulator_tier0.tsandsrc/pio_bus_sniffer.tsintofrontend/src/simulation/cyw43/. - Wire the harness into
RP2040Simulator.tsonly whenboardKind === 'pi-pico-w'. - Implement Tier 1 IOCTLs (~600 LOC) — most are 1-line acks.
- Add the backend WS bridge for Tier 2 (mirror
esp32_worker.py).