Skip to content

feat(firmware): add an advertise-only Bluetooth test image (make ble) - #13

Merged
isod89 merged 11 commits into
isod89:mainfrom
VinSpee:fm/openpocket-upstream-ble-advertise
Nov 8, 2026
Merged

isod89 merged 11 commits into
isod89:mainfrom
VinSpee:fm/openpocket-upstream-ble-advertise

Conversation

@VinSpee

@VinSpee VinSpee commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

This adds an advertise-only Bluetooth test image, built with make ble (only under OP_BLE_TEST). It broadcasts a single advertisement named OpenPocket-BLE-TEST with the BLE-MIDI service UUID. It makes no connections and does no pairing, GATT or MIDI over Bluetooth. The JieLi Apache-2.0 controller libraries are vendored in third_party/jieli-ble, with their licence and NOTICE.md. docs/BLE-TEST.md describes the image and how to flash it.

Normal firmware builds are unchanged: openpocket.bin and BlackBox_936.fwsc stay byte-identical. The image shows its progress on the pedal's screen, including the failing step when start-up stops and proof counters while it is advertising. The advertisement is defined in firmware/ble/ble_adv.h and checked against the Core Specification by host tests (tests/test_ble_status.c, tests/test_ble_sources.mjs), which pass with the rest of the host suite.

The image was flashed onto a real pedal and boots through the controller start-up to the ADVERTISING screen. The radio is not yet visible to a Mac or phone scanner, so Bluetooth does not work yet, and the radio trim values and the vendor code path remain unproven; a later change addresses the radio. The Bluetooth findings are recorded in docs/BLE-TEST.md.

A separate build target that links JieLi's Apache-2.0 LE controller
(third_party/jieli-ble) into the normal firmware and sends one scannable
advertisement named OpenPocket-BLE-TEST with the BLE-MIDI service UUID.
No connections, pairing or MIDI over Bluetooth. The normal firmware and
installer packages are byte-identical; the VM and BTIF areas are not touched.

Built, linked and packaged; not yet run on a pedal (docs/BLE-TEST.md lists
what is unverified).
… and refuse a link that would trip it

The first hardware run faulted at the first instruction of the first BLE task (EMU bit 3, stack limit):
the task stacks lie outside [_ustack_lo, _sstack_top]. The test image is now built with FM1_GUARD_STACK off
(OP_GUARD_STACK=0); the normal firmware is byte-identical. app.ld fails the link if the stack guard is on while the
task stacks are outside the window. docs/BLE-TEST.md lists the other guards as checked on paper only.
… full failure line

The status text now reads STARTING <stage> or FAILED <step> <code>; a timeout names the stage it stalled in. On FAILED the
whole line (step and stage in words) scrolls across the status area in the 500 ms redraw. The logic is in ble_status.h and
tested on the PC (tests/test_ble_status.c). The normal firmware is byte-identical.
… and two related fixes

The controller task deadlocked in ll_init -> thread_create -> crc_get_32bit: the lock is created by the vendor
__crc16_mutex_init(), which only the SDK's own start-up calls (FAILED 5 3 on the pedal). ble_test_start now calls it.
ll_hci_adv_set_params gets a six-byte direct address instead of NULL (the library reads six bytes), and the context
switch saves r4-r15, the registers the compiler preserves. The failure line gains two stage markers (radio replay
returned, baseband interrupts requested) and, at a timeout, the object the controller task waits on.
Normal firmware is byte-identical. Not run on a pedal.
…p Bluetooth off after a failed boot

The third hardware run froze in the first ble_poll: the library asserts the handle low_power_get returns, our empty
stand-in returned null, and a failed assertion parks in P33_SYSTEM_RESET (an endless loop) until the watchdog resets.
low_power_get now returns a non-null handle. A stall watch in the 10 kHz timer tick turns a ble_poll that has not
returned after 4 s into the normal crash screen (VEC 63, PC and RETS of the stuck code). Bluetooth is not started on a
boot that follows a failed one, so the boot guard cannot send the pedal to the loader. Normal firmware is byte-identical.
… spec check of the advertisement

The fourth flash showed ADVERTISING but no scanner saw the pedal. While advertising, the status now scrolls counters of
the two baseband interrupts (counted by ble_isr.S before the library's handlers run), HCI packets returned, library
timers fired, slot-timer stand-in calls, and the baseband, interrupt-config and block-enable registers. The controller's
public address was never set (all zeros): it is now a fixed non-zero locally administered address. The advertisement is
in ble_adv.h and tests/test_ble_status.c checks it against the Core Specification. Normal firmware is byte-identical.
@isod89
isod89 merged commit a43dd18 into isod89:main Nov 8, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants