Implement BLE OTA

This commit is contained in:
2026-03-19 22:11:45 +01:00
parent 87fc2a3574
commit 395fd9b839
9 changed files with 163 additions and 4 deletions

View File

@@ -133,6 +133,9 @@ void onCommandWrite(uint16_t h, BLECharacteristic* c, uint8_t* d, uint16_t l) {
if (l < 1) return;
if (d[0] == 0x01) pendingCal = true;
if (d[0] == 0xFF) pendingReset = true;
#ifdef FEATURE_OTA
if (d[0] == 0x02) pendingOTA = true;
#endif
}
#ifdef FEATURE_IMU_STREAM
@@ -153,7 +156,7 @@ void setupConfigService() {
cfgBlob.begin();
pushConfigBlob();
cfgCommand.setProperties(CHR_PROPS_WRITE);
cfgCommand.setProperties(CHR_PROPS_WRITE | CHR_PROPS_WRITE_WO_RESP);
cfgCommand.setPermission(SECMODE_OPEN, SECMODE_OPEN);
cfgCommand.setFixedLen(1);
cfgCommand.setWriteCallback(onCommandWrite);

View File

@@ -11,6 +11,7 @@
#define FEATURE_BATTERY_MONITOR
#define FEATURE_BOOT_LOOP_DETECT
#define FEATURE_PHYSICAL_BUTTONS
#define FEATURE_OTA
// Debug
// #define DEBUG
@@ -205,6 +206,9 @@ extern float cachedTempC;
extern bool pendingCal;
extern bool pendingReset;
#ifdef FEATURE_OTA
extern bool pendingOTA;
#endif
extern ChargeStatus lastChargeStatus;
extern int idleFrames;
extern unsigned long idleStartMs;

View File

@@ -117,6 +117,9 @@ float cachedTempC = 25.0f;
uint32_t loopStalls = 0; // loop iterations where dt > 20ms (behind schedule)
bool pendingCal = false;
bool pendingReset = false;
#ifdef FEATURE_OTA
bool pendingOTA = false;
#endif
// Jerk-based shock detection - freeze cursor during tap impacts, doesn't work well yet!
unsigned long shockFreezeUntil = 0;
@@ -299,10 +302,28 @@ void loop() {
char cmd = Serial.read();
if (cmd == 'c') { Serial.println("[SERIAL] Calibrate"); pendingCal = true; }
if (cmd == 'r') { Serial.println("[SERIAL] Reset"); pendingReset = true; }
#ifdef FEATURE_OTA
if (cmd == 'o') { Serial.println("[SERIAL] OTA DFU"); pendingOTA = true; }
#endif
}
if (pendingCal) { pendingCal = false; calibrateGyroBias(); prevAx = imu.readFloatAccelX(); prevAy = imu.readFloatAccelY(); prevAz = imu.readFloatAccelZ(); }
if (pendingReset) { pendingReset = false; factoryReset(); }
#ifdef FEATURE_OTA
if (pendingOTA) {
pendingOTA = false;
Serial.println("[OTA] Disconnecting BLE and entering bootloader DFU mode...");
Serial.flush();
// Gracefully close the BLE connection first so the host can detect the
// disconnect and be ready to see DfuTarg advertise after the reboot.
if (Bluefruit.connected()) {
Bluefruit.disconnect(0);
delay(300);
}
delay(200);
enterOTADfu(); // Adafruit nRF52 core: sets GPREGRET correctly and resets into bootloader OTA mode
}
#endif
// Heartbeat LED
if (now - lastHeartbeat >= HEARTBEAT_MS) {