mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-10-23 09:12:25 +00:00
add legacy nordic DFU service
This commit is contained in:
1 parent
ffe9ea652d
commit
9ef6774d6a
4 files changed
+85
No files matched your search
@@ -280,6 +280,17 @@ config ZEPHCORE_BLE_ADV_SLOW_INTERVAL
|
||||
Advertising interval in 0.625ms units.
|
||||
338 = 211.25ms (Apple-compliant, used after 60s fast window).
|
||||
|
||||
config ZEPHCORE_BLE_DFU
|
||||
bool "Buttonless BLE DFU (legacy Nordic/Adafruit OTA jump)"
|
||||
default y if SOC_SERIES_NRF52X || SOC_SERIES_NRF52
|
||||
help
|
||||
Register the legacy Nordic DFU service (00001530/00001531) in the
|
||||
running companion app so a paired phone can trigger the jump into the
|
||||
Adafruit bootloader's BLE OTA mode without pressing a button. On a write
|
||||
of 0x01 to the control point the device sets the bootloader GPREGRET
|
||||
magic (0xA8) and resets; the bootloader then advertises for DFU and the
|
||||
phone's DFU tool reconnects to flash. nRF52 only.
|
||||
|
||||
endmenu # BLE Configuration
|
||||
|
||||
menu "Linux Companion Transport (native_sim)"
|
||||
|
||||
@@ -237,6 +237,67 @@ BT_GATT_SERVICE_DEFINE(secure_nus_svc,
|
||||
NULL, secure_nus_rx_write, NULL),
|
||||
);
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZEPHCORE_BLE_DFU)
|
||||
/* ========== Legacy Nordic/Adafruit buttonless DFU service ==========
|
||||
*
|
||||
* Mirrors Adafruit BLEDfu (Arduino MeshCore >=1.15.0) so the same DFU tools
|
||||
* interoperate: a paired phone writes 0x01 to the control point and the device
|
||||
* resets into the bootloader's BLE OTA mode. We use the *unbonded* OTA reset
|
||||
* (GPREGRET 0xA8, same as `start ota`): the bootloader comes up as a fresh DFU
|
||||
* target and the tool re-scans for it (the legacy buttonless flow). Adafruit's
|
||||
* 0xB1 bonded-resume path needs SoftDevice peer-data enrollment we can't
|
||||
* replicate on Zephyr, so the phone makes a fresh connection to the bootloader.
|
||||
*/
|
||||
static struct bt_uuid_128 dfu_svc_uuid = BT_UUID_INIT_128(
|
||||
BT_UUID_128_ENCODE(0x00001530, 0x1212, 0xefde, 0x1523, 0x785feabcd123));
|
||||
static struct bt_uuid_128 dfu_ctrl_uuid = BT_UUID_INIT_128(
|
||||
BT_UUID_128_ENCODE(0x00001531, 0x1212, 0xefde, 0x1523, 0x785feabcd123));
|
||||
|
||||
static void dfu_jump_work_fn(struct k_work *work);
|
||||
static K_WORK_DELAYABLE_DEFINE(dfu_jump_work, dfu_jump_work_fn);
|
||||
|
||||
static void dfu_jump_work_fn(struct k_work *work)
|
||||
{
|
||||
ARG_UNUSED(work);
|
||||
if (ble_cbs && ble_cbs->on_dfu_request) {
|
||||
ble_cbs->on_dfu_request(); /* sets GPREGRET + resets; never returns */
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t dfu_ctrl_write(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
||||
const void *buf, uint16_t len, uint16_t offset, uint8_t flags)
|
||||
{
|
||||
ARG_UNUSED(conn);
|
||||
ARG_UNUSED(attr);
|
||||
ARG_UNUSED(offset);
|
||||
ARG_UNUSED(flags);
|
||||
/* Adafruit BLEDfu jump command: first byte 0x01 (1-2 byte write). */
|
||||
if (len >= 1 && ((const uint8_t *)buf)[0] == 0x01) {
|
||||
LOG_INF("buttonless DFU requested - rebooting to BLE OTA");
|
||||
/* Defer so the ATT write response flushes and the DFU tool can
|
||||
* arm its disconnect/rescan before we reset. */
|
||||
k_work_schedule(&dfu_jump_work, K_MSEC(250));
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static void dfu_ctrl_ccc_changed(const struct bt_gatt_attr *attr, uint16_t value)
|
||||
{
|
||||
ARG_UNUSED(attr);
|
||||
ARG_UNUSED(value);
|
||||
}
|
||||
|
||||
BT_GATT_SERVICE_DEFINE(dfu_svc,
|
||||
BT_GATT_PRIMARY_SERVICE(&dfu_svc_uuid),
|
||||
BT_GATT_CHARACTERISTIC(&dfu_ctrl_uuid.uuid,
|
||||
BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY,
|
||||
BT_GATT_PERM_WRITE_AUTHEN,
|
||||
NULL, dfu_ctrl_write, NULL),
|
||||
BT_GATT_CCC(dfu_ctrl_ccc_changed,
|
||||
BT_GATT_PERM_READ_AUTHEN | BT_GATT_PERM_WRITE_AUTHEN),
|
||||
);
|
||||
#endif /* CONFIG_ZEPHCORE_BLE_DFU */
|
||||
|
||||
/* ========== Work items ========== */
|
||||
|
||||
static void tx_drain_work_fn(struct k_work *work);
|
||||
|
||||
@@ -27,6 +27,9 @@ struct ble_callbacks {
|
||||
void (*on_connected)(void);
|
||||
/* BLE disconnected */
|
||||
void (*on_disconnected)(void);
|
||||
/* Buttonless DFU control-point write — defer reboot into the
|
||||
* bootloader's BLE OTA mode. May be NULL (feature disabled). */
|
||||
void (*on_dfu_request)(void);
|
||||
};
|
||||
|
||||
enum zephcore_iface {
|
||||
|
||||
@@ -241,11 +241,21 @@ static void ble_on_disconnected(void)
|
||||
ui_notify(UI_EVENT_BLE_DISCONNECTED);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZEPHCORE_BLE_DFU)
|
||||
static void ble_on_dfu_request(void)
|
||||
{
|
||||
mesh_reboot_to_ota_dfu(); /* GPREGRET 0xA8 + reset; never returns */
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct ble_callbacks ble_cbs = {
|
||||
.on_rx_frame = ble_on_rx_frame,
|
||||
.on_tx_idle = ble_on_tx_idle,
|
||||
.on_connected = ble_on_connected,
|
||||
.on_disconnected = ble_on_disconnected,
|
||||
#if IS_ENABLED(CONFIG_ZEPHCORE_BLE_DFU)
|
||||
.on_dfu_request = ble_on_dfu_request,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* ========== Frame send/receive (mesh ↔ BLE/USB) ========== */
|
||||
|
||||
Reference in new issue
Block a user