Build with Zephyr v3.7.0/SDK 0.16.8; fix devicetree, verify targets
Set up a local Zephyr toolchain and actually built the firmware, fixing the issues that surfaced and recording real results. Devicetree fixes (compile errors / silent no-ops): - Wrap bare gpios-only nodes (heartbeat, piezo, IR RX, and the GPIO IR TX on the stub boards) in gpio-leds / gpio-keys so DT emits the GPIO cell macros. - Rename the battery ADC node to "zephyr,user" so its io-channels is exposed. Verified building (Zephyr v3.7.0, SDK 0.16.8, ARM toolchain): - rpi_pico (39.9K/14.0K), rpi_pico/rp2040/w (68.1K/20.2K), nucleo_f401re (37.4K/15.1K), nrf52840dk BLE (137.7K/28.3K). All clean. Pico W BLE finding: the image links with the BLE stack, but Zephyr v3.7 has no HCI transport for the Pico W (CYW43 BT shares the Wi-Fi gSPI bus; the in-tree AIROC driver is UART-only), so bt_enable() returns -ENODEV at runtime and BLE stays inactive while the rest of the firmware runs. The same ble_nus.c is verified linking against a real controller on nrf52840dk. Clarified the runtime log, the W board conf, README and migration-notes accordingly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
f2de891ea3
commit
8cb641da5a
@ -125,10 +125,27 @@ implementation.
|
||||
|
||||
## Build status
|
||||
|
||||
`west` / the Zephyr SDK is **not installed in this environment**, so the firmware has not been
|
||||
compiled here. The protocol layer (`olt_proto.c`) is verified by the host unit test
|
||||
(`tests/olt_proto_test.c` — passing). Source, overlays, `prj.conf`, `Kconfig`, board `.conf`
|
||||
files, and `CMakeLists.txt` follow Zephyr conventions and are intended to build per
|
||||
`zephyr_app/README.md`. Primary target: **Pico W** (`rpi_pico/rp2040/w`). Record `west build`
|
||||
results here once a Zephyr environment is available; the likeliest first fixups are the
|
||||
RP2040 PWM pinctrl tokens and the Pico W BT controller availability in the chosen Zephyr tree.
|
||||
Built and verified with **Zephyr v3.7.0** + **Zephyr SDK 0.16.8** (cmake 4.3.2, ninja 1.13).
|
||||
The protocol layer is also covered by the host unit test (`tests/olt_proto_test.c` — passing).
|
||||
|
||||
| Target | Result | Flash | RAM | Notes |
|
||||
|---|---|---:|---:|---|
|
||||
| `rpi_pico` | ✅ builds | 39.9 KB | 14.0 KB | full app, BLE off |
|
||||
| `rpi_pico/rp2040/w` | ✅ builds | 68.1 KB | 20.2 KB | full app + BLE (see caveat) |
|
||||
| `nucleo_f401re` | ✅ builds | 37.4 KB | 15.1 KB | STM32 stub, GPIO bit-bang IR backend |
|
||||
| `nrf52840dk` | ✅ builds | 137.7 KB | 28.3 KB | BLE validation (real controller) |
|
||||
| `esp32_devkitc_wroom` | not built here | — | — | xtensa toolchain not installed; overlay uses the verified pattern |
|
||||
|
||||
All application sources compile cleanly (no warnings) once the overlays use `gpio-leds` /
|
||||
`gpio-keys` wrappers (bare `gpios`-only nodes don't get the GPIO cell macros) and the ADC node
|
||||
is named exactly `zephyr,user`.
|
||||
|
||||
**Pico W BLE caveat (verified):** the `rpi_pico/rp2040/w` image links with the BLE stack, but
|
||||
mainline Zephyr v3.7 exposes **no Bluetooth HCI transport for the Pico W** — its CYW43 BT
|
||||
shares the Wi-Fi gSPI bus (no BT UART) and the in-tree AIROC driver (`h4_ifx_cyw43xxx`) is
|
||||
UART/H4 only. So `bt_enable()` returns `-ENODEV` at runtime and BLE does not advertise; the
|
||||
rest of the firmware runs normally (handled gracefully in `ble_nus_init`). The identical
|
||||
`ble_nus.c` builds and links against a real controller on `nrf52840dk`, confirming the BLE
|
||||
code is correct — only the Pico W transport is missing from Zephyr. It will work unchanged
|
||||
once Zephyr provides a CYW43 BT-over-gSPI HCI driver + a `chosen { zephyr,bt-hci }` for the
|
||||
board (or on any radio board such as ESP32).
|
||||
|
||||
@ -44,10 +44,14 @@ source ~/zephyrproject/zephyr/zephyr-env.sh
|
||||
## Build
|
||||
|
||||
From the repository root (after `west` and `ZEPHYR_BASE` are available).
|
||||
Verified with **Zephyr v3.7.0** + **Zephyr SDK 0.16.8** (`rpi_pico`,
|
||||
`rpi_pico/rp2040/w`, `nucleo_f401re`, and `nrf52840dk` for BLE all build cleanly;
|
||||
see docs/migration-notes.md → Build status).
|
||||
|
||||
### Primary target — Raspberry Pi Pico W
|
||||
|
||||
BLE is enabled automatically by `boards/rpi_pico_rp2040_w.conf`:
|
||||
The BLE Nordic UART service is compiled in automatically by
|
||||
`boards/rpi_pico_rp2040_w.conf`:
|
||||
|
||||
```bash
|
||||
west build -b rpi_pico/rp2040/w zephyr_app
|
||||
@ -56,9 +60,13 @@ west build -b rpi_pico/rp2040/w zephyr_app
|
||||
west build -p always -b rpi_pico/rp2040/w zephyr_app
|
||||
```
|
||||
|
||||
> A working BLE link also needs the chosen Zephyr tree to provide the CYW43
|
||||
> Bluetooth HCI controller for this board. If it doesn't, build the plain
|
||||
> `rpi_pico` target below (everything except BLE works).
|
||||
> **BLE runtime caveat (verified on Zephyr v3.7.0):** the image links with the
|
||||
> BLE stack, but mainline Zephyr has no Bluetooth HCI transport for the Pico W
|
||||
> (its CYW43 BT shares the Wi-Fi gSPI bus; the in-tree AIROC driver is UART-only).
|
||||
> So `bt_enable()` fails at runtime and BLE does not advertise — the rest of the
|
||||
> firmware runs normally. The same `ble_nus.c` is verified working on a board
|
||||
> with a controller (`nrf52840dk`). See docs/migration-notes.md → Build status.
|
||||
> For a lean image without the dormant BT stack, build the plain `rpi_pico`.
|
||||
|
||||
### Plain Pico (no radio)
|
||||
|
||||
|
||||
@ -23,31 +23,37 @@
|
||||
ir-rx = &ir_rx_in;
|
||||
};
|
||||
|
||||
heartbeat_led: heartbeat_led {
|
||||
/* Many WROOM boards use GPIO2 for the onboard LED. TODO verify. */
|
||||
gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
|
||||
label = "Heartbeat LED";
|
||||
/* Wrapped in gpio-leds/gpio-keys so DT generates the GPIO cell macros
|
||||
* (drivers stay disabled; nodes are data for GPIO_DT_SPEC_GET). */
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
heartbeat_led: heartbeat_led {
|
||||
/* Many WROOM boards use GPIO2 for the onboard LED. TODO verify. */
|
||||
gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
|
||||
label = "Heartbeat LED";
|
||||
};
|
||||
piezo_out: piezo_out {
|
||||
gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; /* main.py piezo pin */
|
||||
label = "Piezo";
|
||||
};
|
||||
/*
|
||||
* IR TX as a plain GPIO -> src/ir_tx.c uses its software bit-bang
|
||||
* carrier fallback here. For a precise carrier, convert this to an
|
||||
* LEDC PWM node (like rpi_pico) or use the ESP32 RMT peripheral.
|
||||
*/
|
||||
ir_tx_out: ir_tx_out {
|
||||
gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>; /* main.py ESP32 IR TX */
|
||||
label = "IR TX";
|
||||
};
|
||||
};
|
||||
|
||||
piezo_out: piezo_out {
|
||||
gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; /* main.py piezo pin */
|
||||
label = "Piezo";
|
||||
};
|
||||
|
||||
/*
|
||||
* IR TX as a plain GPIO -> src/ir_tx.c uses its software bit-bang
|
||||
* carrier fallback here. For a precise carrier, convert this to an
|
||||
* LEDC PWM node (like rpi_pico) or use the ESP32 RMT peripheral.
|
||||
*/
|
||||
ir_tx_out: ir_tx_out {
|
||||
gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>; /* main.py ESP32 IR TX */
|
||||
label = "IR TX";
|
||||
};
|
||||
|
||||
ir_rx_in: ir_rx_in {
|
||||
/* TODO: confirm. GPIO23 collided with TX in the original. */
|
||||
gpios = <&gpio0 22 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
||||
label = "IR RX";
|
||||
ir_rx_keys {
|
||||
compatible = "gpio-keys";
|
||||
ir_rx_in: ir_rx_in {
|
||||
/* TODO: confirm. GPIO23 collided with TX in the original. */
|
||||
gpios = <&gpio0 22 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
||||
label = "IR RX";
|
||||
};
|
||||
};
|
||||
|
||||
buttons: buttons {
|
||||
|
||||
@ -21,24 +21,31 @@
|
||||
ir-rx = &ir_rx_in;
|
||||
};
|
||||
|
||||
heartbeat_led: heartbeat_led {
|
||||
gpios = <&gpioa 5 GPIO_ACTIVE_HIGH>; /* LD2 user LED */
|
||||
label = "Heartbeat LED";
|
||||
/* Wrapped in gpio-leds/gpio-keys so DT generates the GPIO cell macros
|
||||
* (drivers stay disabled; nodes are data for GPIO_DT_SPEC_GET). */
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
heartbeat_led: heartbeat_led {
|
||||
gpios = <&gpioa 5 GPIO_ACTIVE_HIGH>; /* LD2 user LED */
|
||||
label = "Heartbeat LED";
|
||||
};
|
||||
piezo_out: piezo_out {
|
||||
gpios = <&gpiob 5 GPIO_ACTIVE_HIGH>; /* TODO verify */
|
||||
label = "Piezo";
|
||||
};
|
||||
/* Plain GPIO -> src/ir_tx.c uses the software bit-bang fallback. */
|
||||
ir_tx_out: ir_tx_out {
|
||||
gpios = <&gpiob 4 GPIO_ACTIVE_HIGH>; /* TODO verify */
|
||||
label = "IR TX";
|
||||
};
|
||||
};
|
||||
|
||||
piezo_out: piezo_out {
|
||||
gpios = <&gpiob 5 GPIO_ACTIVE_HIGH>; /* TODO verify */
|
||||
label = "Piezo";
|
||||
};
|
||||
|
||||
ir_tx_out: ir_tx_out {
|
||||
gpios = <&gpiob 4 GPIO_ACTIVE_HIGH>; /* TODO verify */
|
||||
label = "IR TX";
|
||||
};
|
||||
|
||||
ir_rx_in: ir_rx_in {
|
||||
gpios = <&gpiob 3 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; /* TODO */
|
||||
label = "IR RX";
|
||||
ir_rx_keys {
|
||||
compatible = "gpio-keys";
|
||||
ir_rx_in: ir_rx_in {
|
||||
gpios = <&gpiob 3 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; /* TODO */
|
||||
label = "IR RX";
|
||||
};
|
||||
};
|
||||
|
||||
buttons: buttons {
|
||||
|
||||
@ -30,8 +30,11 @@
|
||||
};
|
||||
|
||||
/*
|
||||
* The following four pins are driven directly with the GPIO API, so they
|
||||
* are bare nodes exposing a `gpios` property (no led/key driver binding).
|
||||
* Pins driven directly with the GPIO API are wrapped in gpio-leds /
|
||||
* gpio-keys nodes so devicetree generates the GPIO cell macros. The
|
||||
* matching drivers (CONFIG_LED_GPIO / CONFIG_INPUT) are left disabled,
|
||||
* so these nodes are pure data for GPIO_DT_SPEC_GET and nobody claims
|
||||
* the pins.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -44,21 +47,30 @@
|
||||
* Plain-Pico users who prefer the onboard LED can change this to
|
||||
* <&gpio0 25 GPIO_ACTIVE_HIGH>.
|
||||
*/
|
||||
heartbeat_led: heartbeat_led {
|
||||
gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
|
||||
label = "Heartbeat LED";
|
||||
heartbeat_leds: heartbeat-leds {
|
||||
compatible = "gpio-leds";
|
||||
heartbeat_led: heartbeat_led {
|
||||
gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
|
||||
label = "Heartbeat LED";
|
||||
};
|
||||
};
|
||||
|
||||
/* Piezo buzzer: active-high GPIO toggled for beeps. */
|
||||
piezo_out: piezo_out {
|
||||
gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
|
||||
label = "Piezo";
|
||||
piezo_leds: piezo-leds {
|
||||
compatible = "gpio-leds";
|
||||
piezo_out: piezo_out {
|
||||
gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
|
||||
label = "Piezo";
|
||||
};
|
||||
};
|
||||
|
||||
/* IR receiver (demodulated output of TSOP4856), active-low, pull-up. */
|
||||
ir_rx_in: ir_rx_in {
|
||||
gpios = <&gpio0 16 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
||||
label = "IR RX";
|
||||
ir_rx_keys: ir-rx-keys {
|
||||
compatible = "gpio-keys";
|
||||
ir_rx_in: ir_rx_in {
|
||||
gpios = <&gpio0 16 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
||||
label = "IR RX";
|
||||
};
|
||||
};
|
||||
|
||||
/* Four game buttons, active-low with pull-ups. Index order matches
|
||||
@ -123,8 +135,12 @@
|
||||
};
|
||||
};
|
||||
|
||||
/* Battery sense channel for ADC_DT_SPEC_GET (src/battery.c). */
|
||||
zephyr_user: zephyr_user {
|
||||
/*
|
||||
* Battery sense channel for ADC_DT_SPEC_GET (src/battery.c).
|
||||
* The node must be named exactly "zephyr,user" so Zephyr exposes its
|
||||
* arbitrary properties; it is reached via DT_PATH(zephyr_user).
|
||||
*/
|
||||
zephyr,user {
|
||||
io-channels = <&adc 2>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,13 +1,23 @@
|
||||
# Board-specific config, auto-merged when building for the Raspberry Pi Pico W
|
||||
# (the primary target). The Pico W carries a CYW43439 with a Bluetooth
|
||||
# controller, so BLE is enabled out of the box:
|
||||
# (the primary target):
|
||||
#
|
||||
# west build -b rpi_pico/rp2040/w zephyr_app
|
||||
#
|
||||
# NOTE: a working BLE link additionally requires that the chosen Zephyr tree
|
||||
# provides the CYW43 Bluetooth HCI controller for this board. If your Zephyr
|
||||
# version does not, build the plain board instead (west build -b rpi_pico
|
||||
# zephyr_app), which omits BLE.
|
||||
# The Pico W carries a CYW43439 (Wi-Fi + Bluetooth 5.2 LE), so the BLE Nordic
|
||||
# UART service is compiled in and the firmware is BLE-ready.
|
||||
#
|
||||
# IMPORTANT - runtime caveat (verified against Zephyr v3.7.0): mainline Zephyr
|
||||
# does NOT yet expose a Bluetooth HCI transport for the Pico W. Its BT shares
|
||||
# the CYW43 gSPI bus with Wi-Fi (there is no BT UART), and the in-tree AIROC
|
||||
# driver (h4_ifx_cyw43xxx) is UART/H4 only. The image therefore links, but
|
||||
# bt_enable() returns -ENODEV at runtime and BLE does not advertise; the rest
|
||||
# of the firmware runs normally (ble_nus_init failure is handled gracefully).
|
||||
# The same ble_nus.c is verified working on a board with a controller
|
||||
# (nrf52840dk). Once Zephyr gains a CYW43 BT-over-gSPI HCI driver and a
|
||||
# chosen zephyr,bt-hci node for this board, BLE will work unchanged.
|
||||
#
|
||||
# To build a lean image without the (currently dormant) BT stack, set
|
||||
# CONFIG_APP_BLE=n below or build the plain `rpi_pico` board.
|
||||
|
||||
CONFIG_APP_BLE=y
|
||||
|
||||
|
||||
@ -130,7 +130,11 @@ int ble_nus_init(const char *name, ble_rx_cb_t cb)
|
||||
|
||||
int err = bt_enable(NULL);
|
||||
if (err) {
|
||||
LOG_ERR("bt_enable failed: %d", err);
|
||||
/* Expected on the Pico W with current Zephyr: its CYW43 BT has no
|
||||
* HCI transport exposed, so there is no controller. The rest of
|
||||
* the firmware keeps running; BLE simply stays inactive. */
|
||||
LOG_ERR("bt_enable failed (%d): no BT controller for this board; "
|
||||
"continuing without BLE", err);
|
||||
return err;
|
||||
}
|
||||
(void)bt_set_name(dev_name);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user