Repository navigation
Tracking: Pico W / Pico 2 W Bluetooth + Soft_AP DHCP + SSL/TLS HTTP Server via the CYW43439 shared gSPI bus #15
Description
Umbrella for the CYW43439 shared-bus Bluetooth work, so nothing here is untracked. Both boards are verified working on hardware: patchram loads over the shared gSPI bus, the controller reports the expected OTP-derived BD_ADDR, and a legacy LE scan returns real advertisers.
Based on the reference implementation in beriberikix/zephyr-cyw43-driver, proposed upstream as zephyrproject-rtos/zephyr#111811 (closed not_planned by the stale bot, not on merit).
State as of 2026-09-09 (rebased onto main 121489fe70)
main moved between the first PRs and now, and two things it did changed this stack:
- Board files moved from
boards/<board>.overlay|conftoboards/<vendor>/<board>/board.overlay|conf(d0f27bfc97). All three branches were rebased and their board-file changes relocated. mainfixed the RP2040ranges;boot bug itself (ffd62e1c59), so zephyr-cp: restore "ranges" on RP2040 partitions, fixing unbootable images #13 was closed as redundant and zephyr-cp: RP2040 boards are unbootable — overlays drop "ranges" from the partitions node #6/zephyr-cp: stm32wba65i_dk1 overlay has the same missing "ranges" defect as the RP2040 boards #7 closed as fixed upstream. It also resized the settings partition to one aligned 4K sector and pinnednvm/circuitpyto matchports/raspberrypivia a newcheck_partitions.pyparity check. One sector is still one short for NVS (nvs_mount()needs two), so zephyr-cp: enable BLE on the Raspberry Pi Pico 2 W #4/zephyr-cp: enable BLE on the Raspberry Pi Pico W #14 now growstorageto 8K at0x17e000out of the code partition and leavecircuitpyalone — CIRCUITPY is no longer reformatted by these branches. That placement is build-tested; the hardware runs used the earlier0x181000layout.
Link to Upstream Escalation list:
Pull requests
This repo — stack: main → #5 → #4 → #14
| PR | Base | Head | Contents |
|---|---|---|---|
| #5 | main |
5f0ea1254a |
debug UDC thread stack (independent) |
| #4 | #5 | bb410ab164 |
Pico 2 W BLE enablement + settings partition fix |
| #14 | #4 | 8d2023c6b5 |
Pico W BLE enablement + settings partition fix |
| #17 | main |
74e414d323 |
README "Board overlay pitfalls" (rework of #13's second commit) |
main |
closed — ranges; fix landed upstream as ffd62e1c59 |
Module forks
| PR | Contents |
|---|---|
| tyeth/zephyr#2 | USB DPRAM unaligned-access fix (independent) |
| tyeth/zephyr#1 | CYW43 shared-bus HCI driver (stacked on #2) |
| tyeth/hal_rpi_pico#1 | cybt ring-index re-read hardening |
| tyeth/hal_rpi_pico#2 | flash helper RAM placement (independent) |
| tyeth/hal_infineon#1 | Murata-1YN BT coex NVRAM |
hal_rpi_pico branch builds working firmware — both its commits must be combined (currently integration-pico2w-ble, see #12).
Build (post-rebase heads, local zephyr tree with the driver)
| Pico 2 W | Pico W | |
|---|---|---|
| FLASH | 1,146,096 B / 1528 KB = 73.25% | 1,181,372 B / 1,564,416 B = 75.52% |
| RAM | 229,144 B / 520 KB = 43.03% | 228,044 B / 264 KB = 84.36% |
CONFIG_BT / CONFIG_BT_CYW43_SHARED_BUS |
y / y | y / y |
check_partitions.py |
matches raspberry_pi_pico2_w |
matches raspberry_pi_pico_w |
CI verification
The reviewable PRs still cannot link — #16 — but the build is now verified green in CI for both
boards on ci/pico2w-ble-assets (94bfd47b5f), which sits on top of this stack and adds one
CI-only commit overriding zephyr/hal_rpi_pico/hal_infineon in zephyr-config/west.yml to the
fork branches. That override needs tyeth/zephyr#1 to exist, not to merge, so CI verification is
decoupled from upstream review. The branch is now 0 commits behind main (was 229) and therefore
exercises the current boards/<vendor>/<board>/ layout.
| Pico 2 W | Pico W | |
|---|---|---|
| run | 34287512362 ✅ | 34287514167 ✅ |
| FLASH | 1,146,092 B = 73.25% | 1,181,368 B = 75.51% |
| RAM | 229,144 B = 43.03% | 228,044 B = 84.36% |
| artifact (expires 2026-12-07) | 8,852,015 B | 8,912,451 B |
CI matched the local builds to within 4 bytes of flash and exactly on RAM. The Pico W run reports
BOOT_FLASH 256 B 100.00% — a positive check that .boot2 is linked, i.e. the #6 failure mode
tested rather than inferred. This is also the first CI build of the Pico W BLE firmware; previously
only the Pico 2 W had an asset.
--ref and -f branch= — --ref only
selects the workflow file, while the checkout uses the branch input (default main), so a
--ref-only dispatch silently builds main and yields an artifact with no Bluetooth in it.
Issues
| Issue | State | Summary |
|---|---|---|
| #6 | closed | RP2040 boards unbootable — missing ranges (fixed upstream, ffd62e1c59) |
| #7 | closed | Same defect in the STM32WBA overlay (fixed upstream, same commit) |
| #8 | open | BT_EXT_ADV defaults on port-wide, asserting a capability not all controllers have |
| #9 | open | start_scan(extended=) silently ignored |
| #10 | open | boot_out.txt stale version on incremental builds |
| #11 | open | tests / zephyr CI job red — cause not established; being re-evidenced post-rebase on #5's run |
| #12 | open | CI-only west.yml override must not merge; depends on an unreviewed branch |
| #16 | open | BLE branches cannot link in CI: HCI driver absent from pinned zephyr revision (also root-causes #13's missing Build CI run: stale base → no merge commit → no pull_request run). Path now verified green via the override branch — see above |
| #18 | open | release builds lose USB during BLE activity — the #5 UDC stack fix is debug.conf-only (verified on hardware; +unexplained post-scan stall) |
| #25 | open | warm-reset BLE bring-up failure not reproducible (45/45 on the unfixed image); mechanism real, trigger unexplained |
| #24 | open | make DEBUG=1 was broken by an unquoted EXTRA_CONF_FILE (validated) |
| tyeth/zephyr#3 | open | settings_nvs reads an uninitialized struct when a partition holds zero sectors |
| tyeth/hal_rpi_pico#3 | open | cybt HOST_CTRL cache makes a corruption check vacuous |
Seven defects were fixed to get here — only one was mine
| Defect | Mine? |
|---|---|
Unaligned memcpy into USB DPRAM (M33 widens transfers; M0+ didn't) |
no |
UDC_RPI_PICO_STACK_SIZE 512 B under immediate logging |
no |
storage_partition 2 KB & misaligned → NVS -EDOM (now: 4 KB upstream → NVS -EINVAL, still needs two sectors) |
no |
Stale settings sectors → NVS -EDEADLK |
no |
flash_enable_write emitted to XIP, called with XIP off → silent core hang |
no |
cyw43_btbus_init(NULL) — cybt NULL-checks the handle as a sentinel |
yes |
BT_EXT_ADV on a controller lacking extended advertising |
no |
Known limits
- Extended advertising is not available on this controller and cannot be made so host-side: the CYW43439 reports the feature bit clear and rejects the commands. The in-tree
hal_infineon.hcdis not an alternative — it is the sameCYW4343A2firmware family at an older patch level (...0031vs pico-sdk's...0065) and built for UART transport, not the shared bus. - The georgerobotics
cyw43-driversubmodule supplies the controller patchram and is underLICENSE.RP, which permits use only alongside Raspberry Pi silicon. Fine for these boards; a blocker for upstreaming to Zephyr proper. - Measuring anything timing-sensitive on a
debug.confbuild is unsafe:LOG_MODE_IMMEDIATEformats and transmits in-thread over a 115200 UART and manufactured an apparent 12.5 s HCI stall that does not exist in release builds (first-detection latency ~9,700 ms debug vs 22 ms release).
Activity
tyeth commentedon Sep 8, 2026
Worked from stale upstream, partition range should be fixed, but not settings partition necessarily.
tyeth commentedon Sep 8, 2026
Body updated with the CI evidence now that both boards build green in CI.
ci/pico2w-ble-assetsrebased to94bfd47b5f(0 commits behindmain, was 229) so the override branch exercises the currentboards/<vendor>/<board>/layout; both boards green (pico2w, picow) with artifacts and per-board flash/RAM. CI matched the local builds to within 4 bytes.-f branch=dispatch gotcha that otherwise yields a Bluetooth-free artifact.BOOT_FLASH 256 B 100.00%on the Pico W as a positive CI check for.boot2, i.e. zephyr-cp: RP2040 boards are unbootable — overlays drop "ranges" from the partitions node #6's failure mode now tested rather than inferred.Still in flight, not yet reflected: Build CI re-runs on #5 (34282151673) and #17 (34281847143) — these carry the
tests / zephyrjob that #11 is about, so #11 will be re-evidenced from #5's result rather than the pre-rebase run.🤖 Generated with Claude Code
tyeth commentedon Sep 8, 2026
Firmware binaries parked for easy access —
v-zephyr-cp-ble-ci-20260909(marked prerelease).GitHub issues can't take file attachments through the API, and the Actions artifacts expire 2026-12-07, so the binaries are on a prerelease instead. Direct links, no login or Actions access needed:
…pico2_w…94bfd47.uf2· 2,292,224 B.elf· 22,214,004 B…pico_w…94bfd47.uf2· 2,363,392 B.elf· 22,310,200 BBuilt from
ci/pico2w-ble-assets@94bfd47b5f. Both UF2s load from0x10000000with the correct family IDs (0xe48bff56RP2040,0xe48bff57RP2350) — independent confirmation.boot2is linked, versus the0x00000100start the pre-fix images had (#6).gh release delete v-zephyr-cp-ble-ci-20260909whenever it has served its purpose.🤖 Generated with Claude Code
Edit: the release tag was renamed to
v-zephyr-cp-ble-ci-20260909and the links above updated. A tag not starting withvis picked up bypy/version.py(git describe --first-parent --match "[!v]*"), which broke every pristine build and both CI asset builds onci/pico2w-ble-assetswith "Cannot determine version". Thev-prefix makes it invisible to that matcher.tyeth commentedon Sep 9, 2026
First on-hardware results for the rebased firmware (Pico 2 W,
10.3.0-51-g8031983fc9, flashed over SWD;NET_MAX_CONTEXTS=12,UDC_RPI_PICO_STACK_SIZE=2048,BT_MAX_CONN=4; RAM 236,864 B / 44.48%).BLE reception confirmed. A 12 s active scan returned 925 advertisement reports from 20 distinct devices, with names resolving (
TUYA_,Sinilink-APP,LE-Ninja) — so scan RX and active-scan TX both work.HUB-D754was not among them on this run, unlike the original bring-up.Heap: the ELF arithmetic in the port docs is wrong in both directions.
gc.mem_free()at a bare REPLbytearray(8192)toMemoryErrorThe GC grows on demand (
gc.mem_free()rose to 103,808 B mid-allocation), andport_heap_init()skips its TLSF pool when picolibc'sARENA_SIZE=-1arena covers the same region, routing allocations through Zephyrmalloc. So capacity is chunked: object count is fine, single large buffers are not. Budget against ~208 KB with no object over ~50 KB.Capability claims verified at the REPL:
time.time()→RuntimeError('RTC is not supported on this board');wifi.radio.start_ap("x")returns without error butap_activestaysFalse;busio.I2C(scl, sda)→NotImplementedError('Use device tree to define I2C devices');board.I2C0/I2C1/SPI/UARTexist as callables.Two corrections to what this issue and the port doc imply:
CONFIG_BT_MAX_CONN=1is Zephyr's own default, not a controller limit — nothing in this port set it. A connectionless advertisement-only node protocol is therefore a workaround for a default, not a hardware constraint. Raised to 4 on the Pico 2 W.start_apbeing a stub is not a missing driver:airoc_mgmt_ap_enable/ap_disableexist indrivers/wifi/infineon/airoc_wifi.cand are registered inwifi_mgmt_ops. zephyr-cp just never issuesNET_REQUEST_WIFI_AP_ENABLE. Zephyr also shipsdhcpv4_server.c(CONFIG_NET_DHCPV4_SERVER), so softAP + DHCP + captive portal are hook-up work rather than porting work.New: #18 (release builds lose USB during BLE activity; the #5 stack fix is debug-only, plus an unexplained post-scan stall).
🤖 Generated with Claude Code
tyeth commentedon Sep 9, 2026
2026-09-09 (later): softAP, DHCP, TLS, frozen modules, and the scan "stall" — new stack on top of #19
New PRs (stack: #19 → #20 → #21 → #22 → #23)
zephyr-cp-ble-scan-timeout3c6020d4d8scan_param.timeouton the legacy path; deadline enforced from the main thread; console RX wakes the main threadzephyr-cp-pico2w-sockets-tls04a55c99dazsock_shutdown(0)→ jump intocdc_acm_1), errno reporting, accept inherits timeout;sslserver contexts stop demanding a client cert (shared-module, all ports); PEM parsing; p256-m off (mbedTLS sizes the TLS 1.2 premaster from a dummyECP_MAX_BITS 1→PSA_ERROR_BUFFER_TOO_SMALLon every ECDHE)zephyr-cp-pico2w-softap8ea8f3f75cstart_ap/stop_ap/ap_active/stations_ap/ipv4_address_ap/DHCPv4 server with RFC 8910 option 114zephyr-cp-frozen-modulesfb700f76bcFROZEN_MPY_DIRSincircuitpython.toml; Pico W freezesadafruit_bleModule forks
airoc-softap-fixes(3943b1cd7, on top ofcyw43-shared-bus-ble)ap_enablechanspec bug (every 2.4 GHz channel became 0xd001 →WLAN_BADCHAN, so the AP could never start); AP station events raised without wpa_supplicant; a station's DEAUTH no longer takes the AP interface dormantcybt-ring-index-failure-paths(cc2ea478, merged intointegration-pico2w-ble)cybt_hci_write_buf/cybt_hci_readhonourcybt_get_bt_buf_index()failure — a garbagehost2bt_in_valmadememcpyread off the end of SRAM (bus fault, BFAR 0x20082000, threadbt_tx_processor) after "index still corrupt after 8 reads"Hardware verification (Pico 2 W AP, ESP32-C6 station): AP up in 0.15 s; C6 gets 192.168.4.2 via DHCP, pings in 5–8 ms;
stations_aptracks join/leave/rejoin; AP survivesstop_ap/start_apand a soft reboot with a station attached; HTTPS served from a PEM RSA-2048 cert over the AP, C6 client receivesHTTP/1.0 200 OKin 2.0 s.import adafruit_ble(+2 submodules): 10,384 B heap frozen vs 21,792 B from.mpy.Sizes
10.3.0-52, this stack)Of the RAM growth, TCP is ~9.8 KB and the DHCPv4 server + socket service ~3.6 KB. The Pico W at 88 % static RAM is the number to watch.
BT bring-up reliability — worth its own issue. Warm-resetting the RP2350 over SWD (
reset run) 12 times on the final image, then_bleio.adapter.enabled = True~15 s after boot: every boot that did not re-download the patchram (controller still had it) came up instantly; of the boots that did download, 2 of 3 (and 2 of 3 in an earlier run) produced a flood of HCIHardware error, hardware code: 0events (~74 at 7 ms intervals) andcybt_get_bt_buf_index: out-of-range indexretries, andbt_enable()did not complete within 8 s — withCONFIG_BT_ASSERT=ythat ends inController unresponsive, command opcode 0x1009 timeoutand a halt. The old image (fw-51) showed 0/7 in the same loop; with only 6–7 boots per arm this is suggestive, not proof, that the new image shifts timing. The cybt fix above stops the crash but not the failed bring-up. Suspect: the first HCI traffic right aftercybt_fw_download/cybt_wait_bt_readyreading a ring whose indices are not yet valid. Not fixed here.Open items
make DEBUG=1is broken by shell;in-Dzephyr-cp_EXTRA_CONF_FILE=a.conf;b.conf(runsb.confas a command, "Permission denied"); the debug fragment is silently dropped.mpversion.his stale in an incremental build dir (zephyr-cp: boot_out.txt reports a stale version on incremental builds #10) — the board reports-51while running-52code.ci/pico2w-ble-assetsneeds itszephyrrevision moved toairoc-softap-fixesand rebasing onto zephyr-cp: freeze .mpy modules named in circuitpython.toml #23 to CI-verify this stack.🤖 Generated with Claude Code
tyeth commentedon Sep 9, 2026
Correction to my earlier evidence in this thread.
I described the USB verification as "a 12 s active scan producing 925 advertisement reports". The scan duration was wrong:
timeout=was being silently ignored on the legacy scan path, so that run was ~33 s at ~28 reports/s, not 12 s (#18, now fixed by #20). I also characterised the behaviour afterwards as a "post-scan stall" — nothing was stalled; the scan had never ended, and theKeyboardInterruptsimply landed on the statement after the loop.What still holds: USB stayed enumerated for the whole run with
UDC_RPI_PICO_STACK_SIZE=2048, where the same workload previously took the board off the bus. That was the claim being tested, and a longer scan makes it a stronger result, not a weaker one. The report count and distinct-device count were accurate.Two of my other framings in this thread were also wrong, per the bench work in #21/#22:
start_apwas "a hook-up job, not a driver port" becauseairoc_mgmt_ap_enableexists. The driver was in fact broken: it composed band/bandwidth bits into a chanspec that WHD'swhd_wifi_init_ap()re-wraps withCH20MHZ_CHSPEC(), turning channel 1 into0xd001(5 GHz) and failing every AP start withWLAN_BADCHAN. Fixed on the zephyr fork, not in CircuitPython.ssl/socketpoolare already enabled" as though TLS would work.CONFIG_NET_TCPhad never been enabled for these boards, so noSOCK_STREAMsocket had ever succeeded — it failed withEPROTOTYPE, misreported as "Out of sockets". Three further defects had to be fixed before a handshake completed.🤖 Generated with Claude Code
[-]Tracking: Pico W / Pico 2 W Bluetooth via the CYW43439 shared gSPI bus[/-][+]Tracking: Pico W / Pico 2 W Bluetooth + Soft_AP DHCP + SSL/TLS HTTP Server via the CYW43439 shared gSPI bus[/+]tyeth commentedon Sep 10, 2026
Warm-reset BLE bring-up: measured, and the previous conclusion retracted. Full evidence in #25.
The failure mechanism is real and gdb-evidenced (BT shared-memory base reads 0 → HCI command to backplane address 0 → 10 s timeout →
BT_ASSERThalts the kernel → USB drops). But the reported 19% → 50% → 100% warm-reset failure rate, and its attribution to cumulative controller degradation needing a physical power cycle, do not hold. On the unfixed image, probe pinned, no power cycle performed: 45/45 successful bring-ups — 16/16 software warm resets with no debugger, 16/16 one-shot SWD resets, 13/13 with a persistent debugger and deliberate mid-boot halts. p ≈ 1e-4 against a 19% rate.My own follow-up hypothesis — that a persistent debugger desynchronised the shared bus — was also tested and rejected by that third arm. The original numbers are unexplained; the leading untested candidate is an unpinned
cmsis-dap.cfgwith two probes attached, so resets may have been driven into the other board.Landing anyway as safety hardening, explicitly not as a reliability fix: tyeth/zephyr#4 and tyeth/hal_rpi_pico#4 (validate the base, source it via WHD, bounded retry, return a retryable
OSErrorinstead of halting — 8 halts → 0). #24 (make DEBUG=1) is unrelated and validated.Bench practice worth adopting: never measure hardware reliability with a debugger attached, and always pin
adapter serialwhen more than one CMSIS-DAP probe is present.🤖 Generated with Claude Code
tyeth commentedon Sep 10, 2026
Upstream escalation index
Every defect found in this work that belongs to an upstream project now has an issue on the corresponding fork, so upstreaming later is a matter of copying the issue and pointing at the branch. Only the esp-idf one has been submitted upstream so far — the rest say so explicitly on the issue.
Index current to 2026-10-03; covers tyeth/circuitpython #4–#30 and all fork issues. Updated after the stack was rebased onto upstream
main@35210c2e31(after 11.0.0-alpha.1). Each CircuitPython defect below was re-checked against thatmainand is still present upstream. Fork fix SHAs are the post-rebase ones. Firmware: v-zephyr-cp-ble-ci-20261003.Fixed upstream since the last update
make DEBUG=1(unquotedEXTRA_CONF_FILE)d9682758b5)2b8a218385)CONFIG_BT_MAX_CONN=4prj.confnow setsCONFIG_BT_MAX_CONN=5for every boardboard.confto give the heap back (#14,b610e43da2)zephyrproject-rtos/zephyr
settings_nvs:sector_cnt==0withrc==0treated as success, then an uninitialisedhw_flash_sectoris read (sawfs_size=537016640)0x17e000on top of upstream's Adaboot layout, #4/#14)udc_rpi_pico: unalignedmemcpyto/from USB DPRAM faults on Cortex-M33 (M0+ escapes it by byte-copying)udc_rpi_pico: default thread stack of 512 B overflows under concurrent USB + radio load; board leaves the USB busprj.conf)udc_rpi_pico:Endpoint busylogged as an error during normal CDC transmission (1400+ line bursts)LOG_MODE_IMMEDIATEairoc:ap_enablebuilds a chanspec thatwhd_wifi_init_ap()re-wraps, so every softAP start failsWLAN_BADCHAN; plus a station DEAUTH taking the AP interface dormantairoc-softap-fixesbt_le_scan_param.timeout, so scans never endECP_MAX_BITSwhen p256-m serves P-256 →PSA_ERROR_BUFFER_TOO_SMALLThe
tyeth/zephyroverride branches (cyw43-shared-bus-ble,airoc-softap-fixes) are still based on62e7a3764b, 9 commits behind upstream CircuitPython's Zephyr pin70f1a63cc8. Those 9 commits touch none of the same files, so a rebase should be clean. It hasn't been done yet.zephyrproject-rtos/hal_rpi_pico (ultimately raspberrypi/pico-sdk)
HOST_CTRLreads come from a software cache, making the corruption check incybt_toggle_bt_intr()vacuousassert()is live in the Zephyr build and panics the kernel on bring-up failure, pre-empting the error return already behind ithardware_flash:static inlinehelpers can be emitted to flash and called with XIP disabled → silent hang, unrecoverable over SWDThe
hal_rpi_picoandhal_infineonoverride branches still sit directly on the revisions upstream pins (266394b0f2,13e4b3cd70), so they match without a rebase.adafruit/circuitpython
main@35210c2e31shared-module/ssl: a server-sideSSLContextwrongly requires a client certificate (-0x7480), unlike CPython. Affects all portsba0232c35aon #21's branch (wascbcfeec077)SSLSocket.csetsMBEDTLS_SSL_VERIFY_REQUIREDfor a server side tooports/zephyr-cp_bleio: afterbt_enable()fails inbt_hci_open(), nothing clearsBT_DEV_ENABLE, so the retry takes-EALREADYas success —settings_load()then runs on an uninitialised host, yielding a random static BD_ADDR and, when the GATT db hash differs, ak_workNULL handler → UsageFault → kernel halt (USB drops)BT_DEV_ENABLEon failure; accept-EALREADYonly whenbt_is_ready(); never fall back to a random identity)bleio_adapter_ensure_stack_ready()accepts-EALREADY, then callssettings_load()py/version.pytests"CP_VERSION" in os.environ(presence, not truth), so an emptyCP_VERSIONexported by.github/actions/mpy_crossaborts "Set up mpy-cross" with Cannot determine version. Bites any board with frozen modules whose caller passes an emptycp-version393be068abonci/pico2w-ble-assets(was7ba84d8936) — one line,os.environ.get("CP_VERSION"). Both boards green with it on the rebased stack (37126091753, 37127295820)if "CP_VERSION" in os.environ:#26 is still the best standalone upstream candidate — port-independent, small, and it makes
socketpool+sslunusable as a TLS server on any board. #28 is the next easiest: one line, no port knowledge needed, already proven in CI here. #27 is zephyr-cp-only and larger, but it is a hard kernel halt and a silently wrong BLE identity, so it should not sit on the fork indefinitely.Bench note, deliberately not upstreamed: #29 — ESP32-C6 Nordic UART service invisible to Windows clients. Filed against the fork because it presents as a CircuitPython bug and is not one: Windows serves a cached GAP+GATT-only attribute table keyed on the BLE address, and changing the address makes the service appear on unchanged firmware. There is a possible upstream angle — the peripheral advertises robust caching (
0x2B3A/0x2B29), so if_bleiochanges its service set between boots (e.g. theCIRCUITPY{mac}BLE workflow on one boot, the app's services on the next) without a Service Changed indication or a database-hash bump, the board is arguably at fault. Not upstreamable until that is confirmed on a C3/S3, so it stays here for now.zephyrproject-rtos/hal_infineon
.hcdis not a usable patchram alternative)espressif/esp-idf
lwip/dhcpserver.cfails to build withDHCPS_DEBUG=1(%xvsu32_t)Not upstream — ours to keep
#8 (
BT_EXT_ADVdefault), #9 (start_scan(extended=)ignored), #10 (staleboot_out.txt), #12 (CI-onlywest.ymloverride), #16 (CI cannot link until tyeth/zephyr#1 merges), #25 (warm-reset bring-up: mechanism real, trigger unexplained). #30 is the env-collector's frozen-library PR against the ESP32 bench firmware, not an upstream candidate.Closed since: #6, #7 (
ranges;fixed upstream byffd62e1c59), #11 (tests / zephyrgreen again, likely an upstream fix), #13 (redundant), #18 (USB loss fixed by #19; its "residual stall" explained by #20), #24 (landed upstream as adafruit#11423).🤖 Generated with Claude Code
tyeth commentedon Sep 10, 2026
https://github.com/tyeth/circuitpython/tree/zephyr-cp-rtt-console for RTT mode, both Pico+Pico2w
tyeth-ai-assisted commentedon Oct 24, 2026
Upstream escalation index and alpha.2 refresh
This updates the 3 October index. Fork fixes, upstream resolutions and hardware evidence are distinguished below. A fork PR is not an upstream submission, and a successful build is not a physical-board pass.
As checked on 24 October 2026, the newest published prerelease is 11.0.0-alpha.2 (21 October); stable is 10.3.1. There is no published alpha.3 (official releases). The current work is rebased on alpha.2, with exact dependency pins recorded below.
Integration branches and qualification
Current open draft heads: ESP CP
e46718f34b32, Pico CP3254e272628e, Zephyr5bf4230db7fe, HAL Infineon7f93dc606751, and HAL Pico #8de12fc2a0f75. Collector source and evidence are atb62ba7c2a4f5.The ESP32 V2, bare C6 and Metro S3 have bounded physical checks on the ESP-NOW fix; C5/C61 now run the later
e467board-specific images, with separate post-reset radio checks and C5 trusted HTTPS/asset verification. Feather S3 was removed: its newer image is built but not physically requalified. Both Picos remain on original9e153production images after temporary candidate tests and verified restoration. Normal startup/radio, forced retry and targeted MSC-error checks now have evidence on both Picos; general USB reliability is still unresolved.Three completed eight-hour runs cover earlier pinned builds: C5/C61 application delivery (236 true wakes), ESP32 V2 radio (960 cycles), and HTTPS (240 checks). Later firmware does not inherit these passes. The original Pico W 140-cycle failure remains failed. Actual Pico W node startup passes two MCU resets, stable identity and repeated simulated-sensor advertisements; bounded receiver delivery now passes as described below; real SCD41 sampling remains unverified.
Pico 2 hub testing found two distinct defects: a positional
start_scanargument (fixed withprefixes=, three host regressions) and first-use advertising/scanning identity mismatch (Zephyr #12, fixed by #11). The earlier revised diagnostic passes 44-file readback, MCU startup, twelve scan starts and twelve HTTP JSON checks, followed by byte-exact original 4 MiB restoration and independent postflight. Those diagnostic scanner samples contain no error but zero received packets; the subsequent normal-image paired result follows. Earlier application failures, the separate recovery after USB loss and the minimal diagnostic missing its BEGIN marker remain recorded failures. This is bounded hub startup/scan/HTTP qualification, not end-to-end delivery, real sensors or a long soak. Evidence.Both normal Pico builds pass at CP
3254e272628e/ Zephyr5bf4230db7fe, with clean dependencies and no firmware diagnostic hooks. The normal Pico 2 image now passes actual Pico W node advertisement reception: three changing synthetic readings match captured node UART values, with RSSI, receive counts 4/5/6 and twelve HTTP checks. Both original storage images restore byte-exact; original board/version/files and independent postflight pass. Original Pico 2 radio health is explicitly not certified: its earlierimport wifitimeout also reproduces without the sender. Earlier failed attempts remain failed. The new normal Pico W image remains build-only here, and production retains restored9e153. Paired evidence and limits.All nine ESP board variants and both Pico variants have build evidence. Physical qualification must be read from the results above, not inferred from the eleven-build total. Earlier failed/interrupted runs remain preserved. In particular, the
a0c1485cf5Pico W run failed after 140 cycles / 4,236.05 seconds; the later RX lock fix proves a source defect but does not, without a live thread capture, prove the cause of that particular physical stall. Earlier binaries built from stale dependency checkouts retain their actual-source attribution.Confirmed upstream resolutions
c2d5de2a0ac62f0bc11264a8XFER_NEWqueue-path log; a different completion-path log remains.74cc3dfda63eThe historical sleep-memory reload report is already resolved by Adafruit #11274; its merge is an ancestor of alpha.2. No duplicate patch is needed. A current C5 physical control now preserves all 4,096 bytes across three verified VM reloads with POWER_ON reset reason and restores the original contents. Its final combined cleanup assertion fails; separate read-only checks confirm original port/inventory/import state without recovery mutation. This is not fake/true-deep-sleep or battery-retention qualification. See Collector
docs/c5-sleep-memory-reload-2026-10-23.mdatffe24af5c051911310b940239fe85a359ad7149b.The global
BT_MAX_CONN=4override was also dropped because upstream sets 5. Pico W's board-specific limit of 2 remains a separate memory choice. The three newly closed trackers above were checked against upstream source and commit ancestry, not merely matching issue titles.Reproduced candidates and minimal tests
These are still fork candidates unless an upstream PR is explicitly named. Commands assume the configured checkout and its dependencies; use fresh test output directories.
5bf4230db7fein #11, pinned by CP #32west twister -T tests/bluetooth/host/id/bt_id_set_scan_own_addr -p unit_testing.5f73172d462a000000000000000800using the existing first 4096 bytes. Inspect SCSI status/sense, then verify the complete disk. Use LBA 1 as a valid same-data control.9e153and CHECK CONDITION / WRITE ERROR (03/0c/00) on the candidate. Valid writes and three free-sector spans restore exactly. Native bounds/media/cache/error checks pass 56/56 versus 34 baseline failures. Synthetic-MBR multi-sector rejection remains intentional. Pico 2's job failed later at a ROM identity guard before firmware restoration writes; the MSC disk had already been restored exactly. Separate recovery verified original code/full expected flash and radios. Preserve both records. Exact evidence and limits.9e153ad624in #32wifi.radio.stop_station(), inspect connection/IP and independently check AP departure. Repeat stop and reconnect; then repeat while the board also hosts an AP.ea06dcb44ein #31python3 tools/check_espnow_rx_lock.pyagainst the pinned baseline/candidate. Interleave the reader after header publication, before payload completion; then exercise two real threads. Physically send numbered, checksummed packets from an S3 to an ESP32 V2.6b117bdce5in #32CP_VERSION= python3 py/makeversionhdr.py /tmp/version.hwithenv -u CP_VERSION python3 py/makeversionhdr.py /tmp/version.h. Empty must fall back to Git.-0x7480; the carried fix accepts the client. Explicitload_verify_locations()still requires a trusted client certificate. Clients still reject untrusted servers and wrong hostnames. This exercises actual shared-module policy with real cryptography over memory transport, not every port's interpreter/network stack.start_scan(extended=True), consume the original scan, then start another ordinary scan.NotImplementedErrorbefore replacing the scan; extended advertising is not implemented.CP_VERSION, and rebuild without cleaning. The version must refresh; unchanged output must retain its timestamp.west twister -T tests/subsys/settings/sector_geometry -p native_sim/native/64. Initialization must reject zero sectors before reading geometry or mounting.python3 tests/drivers/bluetooth/cyw43_rx_bus_contention.py --root . --baseline 353bcd30f76e1fa140291540dde20334e952e0e6, then omit--baseline. A consumer requiring the bus must progress while host RX allocation waits.python3 tests/test_whd_backplane_lock.pyandpython3 tests/test_whd_bus_power_lock.py. Inject competing owners between window selection/access and during sleep/wake transitions.MBEDTLS_PREMASTER_SIZEwith an explicit 32-byte control.PSA_ERROR_BUFFER_TOO_SMALL(-138); its 32-byte control passes. Disabling p256-m gives 32 bytes and both cases pass. Relevant tested TLS/ECP header blobs match current upstream. This is component evidence, not a new network handshake.The earlier
7d4ef1aac7/7379648278integration passed all ten BLE scan tests across nRF5340/nRF54LM20 and all 85 build-tool tests, with actual clean pins checked before and after. Nordic simulator tests do not exercise the CYW43 hardware driver. The audit links exact manifests, source blobs, output hashes and reproduction boundaries.Carried reports needing additional targeted evidence
whd_wifi_init_ap, then associate/deauthenticate a station. The fork passes the bare channel and handles AP events; upstream source still constructs the problematic chanspec. Physical results must be read separately above..timeout=300(3 s) scans still receiving at 6 s, with 23/26 reports after 3.5 s and no callback. Unlimited control and explicit-stop checks pass. Current upstream 76280bce still omits the field, but differs in filter-policy code; it was source-audited, not flashed. Production restored exactly after a separately recorded ROM-handshake recovery. Minimal app: Collector tools/repro_legacy_scan_timeout; evidence docs/legacy-ble-scan-timeout-2026-10-23.md. The CP host deadline remains the workaround; no Zephyr fix implemented.btc_mode=0; HAL #1 supplies the carried resource changes, extended by #3.DHCPS_DEBUG=1on ESP32-C6/S3:%xreceivesu32_tand trips-Werror=format. The submitted fix usesPRIx32. Refreshed 24 October: still OPEN/unmerged at60bf48d497c086d5b26f123f49df1401c523b727.Project choices and corrected claims
Frozen application libraries (#30, integrated through ESP #31), board flash layouts, CI override plumbing (#12/#16), default extended-advertising configuration (#8), and memory limits remain project integration work. The unsupported
extended=TrueAPI-contract bug is now explicitly handled as described above; this does not provide extended advertising.The old warm-reset failure-rate claim for #25 was retracted after 45/45 warm resets succeeded; its trigger remains unproven. #29's possible GATT-cache/Service Changed angle remains unconfirmed, so it is not presented as an established upstream defect.
Chrome WebMCP and the mobile Prompt API fallback are separate paths. Android emulator testing retained the 512,096,557-byte model across reload, Chrome restart and emulator restart, then ran inference without fetching weights again. This validates the JavaScript/OPFS fallback; it does not claim native Android ML Kit/AICore support or measured physical-phone performance. Storage clearing or browser eviction can require another download.
Bench fixes and remaining USB failures
restore_port_power=falsemeans other ports returning on is not itself a proven restoration defect.Two distinct unresolved USB workloads must remain separate:
Mixed USB tests also directly captured HCD channel exhaustion with three leaves and three hubs. With the unused C6 off, both attachment orders pass with zero exhaustion messages. Exact live channel accounting and scheduling remain open. No failure was relabelled a success merely because a separate recovery passed.
Other application/library findings and verification limits
Application #38 reproduces non-atomic certificate/key promotion: failing the second rename can leave a new chain with an old key. Run
python3 tools/repro_cert_install_failures.py .; evidence and fixture limits. A pair-recovery design is still needed; no physical power-loss guarantee is claimed. Full certificate-chain handling is a separate completed fix. Closed application #25 concerns oversized BLE writes, distinct from CP #25: twenty JS protocol groups (node webapp/tests/cert_sync.test.mjs) pluspython3 tools/test_cert_ble.pycover bounded chunks, reassembly and disconnect cleanup. This is not fresh alpha.2 certificate installation or key/certificate-match qualification.The mpremote ENOENT conversion issue matches existing MicroPython #17752; fork draft PR #1 carries the candidate. Reproduce by copying a small file to a missing path with the stock CLI, compare direct
open(path, 'wb'), then verify overwrite/readback/cleanup. The ESP32 V2 baseline fails and candidate passes. Matching MicroPython hardware and upstream review remain outstanding. JD79667 constructor logging/defaults have exact-source host controls and a retained minimal print-removal patch; it has not been deployed or submitted as a library PR. Actual panel timing and stray AttributeError require the absent rig. Library/tool evidence.Fresh bare-C6 checks cover five startup orderings, DHCP/HTTP, absent-card SPI unlock, exact 10,240-byte NUS transfer, disconnect/reconnect and bounded ESP-NOW with BLE. Seven of 100 sends fail; all 93 received echoes are exact. This does not qualify low negotiated MTU, sustained multi-sender traffic, shared display/SD wiring or real SCD41/RTC operation. Windows GATT-cache mechanism, battery events, real calibration/outage replay and several full-application scenarios remain explicitly unverified.
For the original numbered bug document (these numbers are not GitHub issue IDs), the disposition is:
The old request in that document to file reports 1–4/#5 is not evidence that separate upstream issues were filed. No new filing or closure is claimed for unreproduced causes. The coverage ledger maps every original report and application TODO to evidence and remaining checks, including actual-drive relabel/interruption with concurrent HTTP/ESP-NOW, router-channel/autoconnect variants, outage replay, calibration and battery events. GitHub Pages/Adafruit IO and new rig assembly remain future product work. Missing hardware and source-only coverage are not passes or automatic closures.
The new-issue tally is eight: CP #40/#42/#43, application #38, bridge #23/#26, controller #1 and Zephyr #12. Fix groups, upstream resolutions, workarounds and bench findings overlap; they must not be summed into a single issue total. The three newly closed trackers are Zephyr #5/#7 and HAL Pico #7; other existing upstream resolutions are listed above.
jakobi commentedon Oct 24, 2026
@tyeth #1 "known limits" mention of georgerobotics cyw43-driver and its RP-license:
I got curious about this driver and saw that Damien change the license of the driver to MIT in the meantime: https://github.com/georgerobotics/cyw43-driver/commits/main/LICENSE
Given the date of change, I'd bet that you already know about this change, and forgot to add a footnote about the change in #1 :-).
Thx for your work,
P.