Conversation
Introduces OTA (Over-the-Air) firmware update BLE service with new UUIDs and implementation files. Adds device settings management (header and source), updates build system for ESP-IDF/Arduino hybrid, and includes new partition and configuration files for dual OTA support. Also updates BMS CAN initialization and various build flags for improved compatibility.
Refactored OTA BLE service to use Espressif standard UUIDs and characteristics, separating command, data, and status. Added checks to suppress BLE notifications during OTA updates across all telemetry and config services. Improves compatibility and prevents notification conflicts during firmware updates.
Added CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE to sdkconfig.defaults to support OTA rollback. In main.cpp, added logic to mark the firmware as valid and cancel rollback after successful boot, ensuring OTA updates are confirmed.
Reworks OTA BLE service to use Espressif's sector-based protocol with CRC16 validation, sector buffering, and explicit ACK/ERR responses. OTA UUIDs are now NimBLEUUID constants for compatibility with official Espressif OTA apps. Improves reliability and error handling, and merges command/status characteristics as per Espressif's protocol.
Added tracking of total image length and received bytes during OTA updates. The service now validates that the received image size matches the expected size before completing the update, improving reliability and error handling. Also refined CRC and sector error handling to allow client-side retries instead of aborting the OTA process immediately.
Revised BLE OTA characteristic UUIDs to match Android esp-ble-ota-android app requirements and updated protocol handling in ota_service.cpp. ACK and command response logic now use new characteristics and payload formats. Also added 'rbl' as an alias for the 'reboot' serial command.
|
Needs tested with this https://github.com/EspressifApps/esp-ble-ota-android |
|
Likely conflicts with the work for #69 |
Replaces the previous CRC16 implementation with CRC16-CCITT (poly 0x1021, init 0) in ota_service.cpp to match the Espressif Android app. Updates all relevant CRC checks and calculations to use the new function.
Switched OTA BLE characteristics to use notify instead of indicate for ACKs and command responses, and added NOTIFY property to relevant characteristics. Added packet count logging and sector write progress in OTA service. In LVGL flush callback, ensured flush completion is signaled on SPI timeout to prevent deadlock, and moved CS pin selection after SPI bus acquisition. Added boot and running partition info logging during setup.
The setupAltimeter function no longer requires the alt_wire parameter, so it has been removed from the function signature and all call sites. This simplifies the interface and eliminates unused code.
BLE advertising is now started after the splash screen completes, rather than during BLE setup. This change ensures the device does not advertise until the UI is ready, improving startup flow and user experience. Added log messages to clarify advertising state.
Reorganize the main setup() into explicit boot phases, separating RTOS primitive creation, hardware initialization, UI setup, and task creation. Remove startup synchronization semaphores and flags in favor of a deterministic, phased boot. Move all queue and mutex creation to dedicated functions called before any tasks are started. Simplify UI task startup and ensure all dependencies are initialized before tasks run.
App rollback is now enabled in the configuration. The OTA validation logic in main.cpp has been improved to only mark the firmware as valid after confirming the first boot post-update, ensuring rollback protection is properly activated.
Introduced AltimeterTelemetry struct and global instance for thread-safe sharing of barometric sensor data. Added a dedicated altimeterTask for polling the sensor at 10 Hz, reducing I2C contention and simplifying access to altitude, temperature, pressure, and vertical speed across tasks. Updated BLE and display logic to read from the shared telemetry struct instead of direct sensor calls.
Introduces an AltimeterData struct and a FreeRTOS queue for thread-safe sharing of altimeter telemetry between tasks. Updates BLE and display tasks to read from the queue when available, with fallback to direct sensor reads. The altimeter task now samples at 20 Hz and publishes data to the queue, improving concurrency and reducing I2C contention.
Add OTA timeout/abort handling and dynamic BLE connection parameter switching to improve OTA reliability and normal operation battery usage. Introduces requestFastConnParams/requestNormalConnParams and activeConnHandle to tighten connection interval for OTA (15ms) and relax it for telemetry (~36ms). Implements abortOta() and checkOtaTimeout() (30s idle timeout), hooks timeout check into the BLE update task, and aborts OTA on disconnect. Other tweaks: set BLE TX power, advertise only primary UUID to fit payload, include ble_core in OTA code, and remove unused oldDeviceConnected variable. Also permit Bash(grep:*) in local claude settings.
Update the function prototype in inc/sp140/device_settings.h: replace parse_serial_commands() with poll_serial_commands() to reflect a change in naming/behavior. Ensure implementation and callers are updated to match the new symbol.
Set GitHub Actions python-version to "3.13" and normalize inline comment/whitespace formatting across source files for consistency. Changes touch .github/workflows/config.yml, inc/sp140/structs.h and src/sp140/main.cpp and are purely stylistic (spacing and comment alignment) with no functional logic changes.
Include OTA service and add handling to avoid interfering with over-the-air updates. Introduces gFastLinkSkippedOtaCount and checks isOtaInProgress() in fastlink telemetry to skip/not notify during OTA (and increments the skipped-OTA counter). Updates periodic FASTLINK stats output to include skippedOta and OTA-in-progress flag. Also blocks arming and cruise activation while an OTA update is in progress, printing a brief message when those actions are attempted.
Adjust OTA handling in src/sp140/ble/ota_service.cpp: correct the printf order for CMD CRC failure (expected vs got), use explicit uint32_t casts when assembling the image length to avoid integer promotion issues, reset packetCount on START, and change write-failure handling to abort the OTA instead of attempting a retry (preventing partial-write offset corruption). Includes a clarifying comment about why abort is required.
There was a problem hiding this comment.
Pull request overview
Migrates the OpenPPG controller firmware to an ESP-IDF + Arduino hybrid build and adds a NimBLE-based OTA GATT service compatible with Espressif’s Android BLE OTA app, alongside related boot/rollback and settings refactors.
Changes:
- Add BLE OTA service + pause BLE notifications during OTA; add OTA timeout/abort handling and post-boot rollback validation.
- Restructure
setup()into phased initialization and add an altimeter sampling task/telemetry scaffolding. - Introduce ESP-IDF CMake/project config, partition table for OTA slots, and updated CI/build configuration.
Reviewed changes
Copilot reviewed 28 out of 31 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| src/sp140/main.cpp | Phased boot sequence, OTA rollback marking, OTA gating for arm/cruise, new altimeter task + queue, BLE notify pacing/OTA timeout checks. |
| src/sp140/lvgl/lvgl_updates.cpp | Increase LVGL digit buffer sizes used with snprintf. |
| src/sp140/lvgl/lvgl_core.cpp | Fix LVGL flush deadlock by calling lv_disp_flush_ready() on SPI mutex timeout; adjust CS handling. |
| src/sp140/globals.cpp | Add global altimeterData struct instance. |
| src/sp140/esc.cpp | Fix enum logging by casting TelemetryState to int. |
| src/sp140/device_settings.cpp | Update includes for new settings module wiring. |
| src/sp140/buzzer.cpp | Switch to ESP-IDF-style FreeRTOS include paths. |
| src/sp140/ble/ota_service.cpp | New OTA GATT service implementing sector/CRC protocol + OTA state machine. |
| src/sp140/ble/fastlink_service.cpp | Skip FastLink notifications during OTA and add OTA skip stats. |
| src/sp140/ble/config_service.cpp | Skip throttle notifications during OTA. |
| src/sp140/ble/ble_core.cpp | Register OTA service, add conn-param tuning helpers, abort OTA on disconnect, set MTU/TX power. |
| src/sp140/ble.cpp | Remove unused oldDeviceConnected. |
| src/sp140/altimeter.cpp | Reformat/normalize file; altimeter logic unchanged functionally. |
| src/sp140/CMakeLists.txt | Add IDF component registration via broad source glob. |
| src/CMakeLists.txt | Add IDF component registration for src/sp140/*.cpp with Arduino requirement. |
| sdkconfig.defaults | Add default IDF settings (tick rate, Arduino autostart, BT enable, rollback enable, etc.). |
| sdkconfig.OpenPPG-CESP32S3-CAN-SP140 | Commit generated IDF sdkconfig for the target environment. |
| platformio.ini | Switch to arduino, espidf, set partitions CSV, adjust build flags. |
| partitions.csv | Define NVS/otadata + app0/app1 OTA slots + spiffs layout. |
| inc/sp140/structs.h | Add AltimeterTelemetry struct. |
| inc/sp140/globals.h | Export altimeterData. |
| inc/sp140/esc.h | Whitespace/line ending normalization. |
| inc/sp140/device_settings.h | New public header for device settings module APIs. |
| inc/sp140/bms.h | Add initBMSCAN(SPIClass*) declaration. |
| inc/sp140/ble/ota_service.h | New OTA service API header. |
| inc/sp140/ble/ble_ids.h | Add standard Espressif OTA UUID definitions. |
| inc/sp140/ble/ble_core.h | Add conn-parameter tuning API declarations. |
| inc/sp140/ble.h | Remove oldDeviceConnected extern. |
| inc/sp140/altimeter.h | Whitespace/line ending normalization. |
| CMakeLists.txt | Add top-level ESP-IDF project CMake entrypoint. |
| .github/workflows/config.yml | Pin Python to 3.13 for PlatformIO build/test jobs. |
Comments suppressed due to low confidence (4)
src/sp140/main.cpp:566
altimeterTask()callsgetAltitude()/getVerticalSpeed()on a 20Hz loop, but those APIs mutate the shared vario buffer and are already called from other tasks (UI + CtrlSensor). This introduces a multi-writer race on the altitude buffer and increases I2C contention. Prefer a single sampling task that owns the buffer/sensor and publishes results (TelemetryHub/queue), or add proper locking inside the altimeter module around buffer updates/reads.
src/sp140/main.cpp:879esp_ota_mark_app_valid_cancel_rollback()return value is ignored. If marking the app valid fails (e.g., OTA data corruption / flash write issue), the device may remain in PENDING_VERIFY and roll back unexpectedly on next boot. Consider checking the returnedesp_err_tand logging/handling failures explicitly.
src/sp140/main.cpp:731setup()no longer callsdiagnosticsInit(), but diagnostics are still used elsewhere (e.g., planned restart marking / diag_sync). This likely disables persistent boot diagnostics and shutdown snapshot registration. Consider callingdiagnosticsInit()early in Phase 1 after serial init (before any code that records/reads diagnostics).
src/sp140/main.cpp:764- The barometer enable workaround (
setupBarometer()sets GPIO 9 HIGH) is still present but is no longer called during hardware init. If the V2 board requires this pin,setupAltimeter()may fail or readings may stay invalid. Either callsetupBarometer()beforesetupAltimeter()in Phase 3, or remove the function/comment if the workaround is obsolete.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/sp140/globals.cpp
Outdated
| // Altimeter telemetry - single writer (altimeter task), multiple readers | ||
| AltimeterTelemetry altimeterData = { | ||
| .altitude = 0.0f, | ||
| .temperature = 0.0f, | ||
| .pressure = 0.0f, | ||
| .verticalSpeed = 0.0f, | ||
| .lastUpdate = 0, | ||
| .connected = false | ||
| }; | ||
|
|
src/sp140/ble/ota_service.cpp
Outdated
| void abortOta() { | ||
| if (otaInProgress) { | ||
| if (updateHandle) esp_ota_abort(updateHandle); | ||
| otaInProgress = false; | ||
| requestNormalConnParams(); | ||
| USBSerial.println("OTA: Aborted."); | ||
| } | ||
| sectorBufferLen = 0; | ||
| currentSectorIndex = 0; | ||
| receivedBytes = 0; | ||
| } |
| if (otaInProgress) { | ||
| // Defensive: Verify total bytes received match manifest | ||
| if (receivedBytes != imageTotalLen) { | ||
| USBSerial.printf("OTA Error: Size Mismatch Rx:%u Exp:%u\n", receivedBytes, imageTotalLen); |
| initConfigBleService(pServer, uniqueId); | ||
| initFastLinkBleService(pServer); | ||
| initOtaBleService(pServer); | ||
|
|
||
| startAdvertising(pServer); | ||
|
|
||
| USBSerial.println("BLE device ready"); | ||
| USBSerial.println("Waiting for a client connection..."); | ||
| USBSerial.println("BLE device ready (advertising deferred)"); | ||
| } |
| # This file was automatically generated for projects | ||
| # without default 'CMakeLists.txt' file. | ||
|
|
||
| FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/sp140/*.*) |
sdkconfig.OpenPPG-CESP32S3-CAN-SP140
Outdated
| CONFIG_PARTITION_TABLE_SINGLE_APP=y | ||
| # CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set | ||
| # CONFIG_PARTITION_TABLE_TWO_OTA is not set | ||
| # CONFIG_PARTITION_TABLE_CUSTOM is not set | ||
| CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" | ||
| CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" | ||
| CONFIG_PARTITION_TABLE_OFFSET=0x8000 | ||
| CONFIG_PARTITION_TABLE_MD5=y |
| float getAltitude(const STR_DEVICE_DATA_140_V1& deviceData) { | ||
| if (bmpPresent && i2cMutex != nullptr) { | ||
| if (xSemaphoreTake(i2cMutex, pdMS_TO_TICKS(20)) == pdTRUE) { | ||
| const float altitude = bmp.readAltitude(deviceData.sea_pressure); | ||
| xSemaphoreGive(i2cMutex); | ||
| float relativeAltitude = altitude - groundAltitude; | ||
|
|
||
| // Add new reading to buffer with timestamp | ||
| AltitudeReading reading = {relativeAltitude, millis()}; | ||
| altitudeBuffer.push(reading); | ||
|
|
Remove the AltimeterTelemetry extern declaration and its global instance to eliminate the unused/duplicated altimeter state. In ota_service::abortOta(), fully clear OTA-related state (updateHandle, updatePartition, imageTotalLen) so aborted updates leave no residual state. Simplify BLE startup log to "BLE device ready". Update platformio.ini comment for src_folder usage by extra_script.py.
Extract and consolidate OTA state/reset logic and command handling: add resetOtaState(), move CMD_START handling into handleCmdStart(), and centralize abort logic into abortOtaImpl() with an abortOta() wrapper. Expose isOtaInProgress(), relocate checkOtaTimeout() to use the new abort implementation, and remove duplicated functions/comments. These changes tidy control flow for OTA begin/abort, improve error handling, and make timeout/command handling clearer and more maintainable.
There was a problem hiding this comment.
Pull request overview
This PR migrates the firmware build toward an ESP-IDF + Arduino hybrid setup and adds a NimBLE-based BLE OTA implementation compatible with Espressif’s Android OTA app, along with boot/rollback handling and some settings/build cleanups.
Changes:
- Added a new BLE OTA GATT service (sector/CRC protocol) and integrated OTA state into BLE notification flow and connection parameter tuning.
- Reworked
setup()into a phased boot sequence (sync primitives → hardware → UI → services → tasks → interfaces) and added OTA rollback validation on successful first boot. - Added ESP-IDF build scaffolding/config (CMakeLists, partitions, sdkconfig defaults) and refactored settings module headers/includes.
Reviewed changes
Copilot reviewed 27 out of 30 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
src/sp140/main.cpp |
Phased boot sequence, OTA gating for arm/cruise + BLE notifications, new altimeter task/queue, OTA rollback marking |
src/sp140/ble/ota_service.cpp |
New BLE OTA service implementation (commands/data/CRC/sector ACKs) + timeout abort logic |
src/sp140/ble/ble_core.cpp |
OTA service registration, connection param tuning helpers, disconnect-abort behavior, TX power config |
inc/sp140/device_settings.h / src/sp140/device_settings.cpp |
Settings module interface and includes for the refactor |
sdkconfig.*, partitions.csv, platformio.ini, CMakeLists.txt |
ESP-IDF+Arduino build wiring, partitioning, and CI/build configuration updates |
src/sp140/lvgl/*, src/sp140/esc.cpp, src/sp140/buzzer.cpp, etc. |
Targeted robustness/lint/format adjustments supporting the migration |
Comments suppressed due to low confidence (5)
src/sp140/main.cpp:731
setup()no longer callsdiagnosticsInit(), butwatchdogTask()still callsdiagnosticsRefreshHeartbeat()and other code paths rely on diagnostics state/history. This looks like a regression from the previous boot sequence (diagnostics init was done up-front) and will likely break persistent boot diagnostics and shutdown handler registration. Re-introducediagnosticsInit()early insetup()(before tasks start) or move diagnostics initialization into an appropriate boot phase.
src/sp140/main.cpp:593setupBarometer()is still present (and documented as a V2-board fix), but it’s no longer called anywhere in the new phasedsetup(). If that GPIO enable is still required for the BMP3xx to function, the altimeter will silently fail on those boards. Either callsetupBarometer()during hardware init (beforesetupAltimeter()), or remove/replace the function and its comment so this doesn’t become dead/forgotten code.
src/sp140/main.cpp:573altimeterTask()adds an additional ~20Hz caller ofgetAltitude()/getBaroTemperature()/getVerticalSpeed(), but there are no consumers ofaltimeterQueueand bothctrlSensorTaskandrefreshDisplayalready callgetAltitude()(the UI comment even notes I2C mutex contention). As written, this increases I2C traffic/lock contention without any benefit. Either (a) remove the task/queue, or (b) make this task the sole sensor reader and have UI/TelemetryHub consume from the queue (or TelemetryHub) to eliminate contention.
src/sp140/main.cpp:644eepromSemaphoreis created and documented as guarding Preferences writes, but it is not referenced anywhere else in the codebase (no takes/gives outside this function). This adds complexity without providing synchronization. Either wire it into the settings persistence paths (e.g.writeDeviceData()/ diagnostics prefs) or remove it to avoid a false sense of thread safety.
src/sp140/main.cpp:866- The comment says
setupBLE()creates services but does not start advertising, and thenrestartBLEAdvertising()is called later. However,setupBLE()currently callsstartAdvertising(pServer)(seeble_core.cpp), so advertising is already started by the time Phase 7 runs. Please either adjust the comment/remove the redundantrestartBLEAdvertising()call, or changesetupBLE()so it truly defers advertising until Phase 7.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| #include "structs.h" | ||
| #include "esp32s3-config.h" |
There was a problem hiding this comment.
device_settings.h includes "structs.h" and "esp32s3-config.h" without the sp140/ prefix. With the current include path setup (e.g. include_dir = inc), these headers won’t be found (there is no inc/structs.h), which will break compilation for any TU including this header. Update the includes to the correct paths (e.g. sp140/structs.h and sp140/esp32s3-config.h) or adjust the build include directories consistently.
| #include "structs.h" | |
| #include "esp32s3-config.h" | |
| #include "sp140/structs.h" | |
| #include "sp140/esp32s3-config.h" |
src/sp140/ble/ota_service.cpp
Outdated
| abortOtaImpl(); | ||
| } | ||
| } else { | ||
| USBSerial.printf("OTA Error: CRC fail exp 0x%04X got 0x%04X\n", rxCrc, calcCrc); |
There was a problem hiding this comment.
The CRC failure log message swaps expected vs actual: rxCrc is the received CRC and calcCrc is the calculated one, but the log prints exp rxCrc got calcCrc. This makes troubleshooting OTA corruption confusing. Swap the arguments (or update the text) so “expected” corresponds to the calculated CRC.
| USBSerial.printf("OTA Error: CRC fail exp 0x%04X got 0x%04X\n", rxCrc, calcCrc); | |
| USBSerial.printf("OTA Error: CRC fail exp 0x%04X got 0x%04X\n", calcCrc, rxCrc); |
| // Set TX power to +9dBm for reliable connections at distance | ||
| NimBLEDevice::setPower(9); | ||
|
|
There was a problem hiding this comment.
NimBLEDevice::setPower(9) uses a raw integer value; in ESP-IDF/NimBLE APIs the power argument is typically an enum (e.g. ESP_PWR_LVL_P9), and numeric values don’t map 1:1 to dBm. Using a literal risks selecting the wrong power level and makes intent unclear. Prefer the appropriate enum constant (and optional power type) for +9dBm.
There was a problem hiding this comment.
@copilot open a new pull request to apply changes based on this feedback
sdkconfig.OpenPPG-CESP32S3-CAN-SP140
Outdated
| CONFIG_PARTITION_TABLE_SINGLE_APP=y | ||
| # CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set | ||
| # CONFIG_PARTITION_TABLE_TWO_OTA is not set | ||
| # CONFIG_PARTITION_TABLE_CUSTOM is not set | ||
| CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" | ||
| CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" |
There was a problem hiding this comment.
This sdkconfig selects the single-app partition table (CONFIG_PARTITION_TABLE_SINGLE_APP=y and CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv"), which conflicts with the repo’s partitions.csv (app0/app1/otadata) and the PR’s OTA/rollback goals. If this sdkconfig is used for builds, OTA slots/otadata won’t exist at runtime. Switch to a two-OTA or custom partition table selection (and ensure the build actually uses partitions.csv).
| CONFIG_PARTITION_TABLE_SINGLE_APP=y | |
| # CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set | |
| # CONFIG_PARTITION_TABLE_TWO_OTA is not set | |
| # CONFIG_PARTITION_TABLE_CUSTOM is not set | |
| CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" | |
| CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" | |
| # CONFIG_PARTITION_TABLE_SINGLE_APP is not set | |
| # CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set | |
| # CONFIG_PARTITION_TABLE_TWO_OTA is not set | |
| CONFIG_PARTITION_TABLE_CUSTOM=y | |
| CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" | |
| CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" |
| void abortOtaImpl() { | ||
| if (otaInProgress) { | ||
| if (updateHandle) esp_ota_abort(updateHandle); | ||
| otaInProgress = false; | ||
| requestNormalConnParams(); | ||
| USBSerial.println("OTA: Aborted."); | ||
| } | ||
| resetOtaState(); | ||
| } | ||
|
|
||
| static OtaCommandCallback cmdCallback; | ||
| static OtaDataCallback dataCallback; | ||
|
|
||
| } // namespace | ||
|
|
||
| void abortOta() { abortOtaImpl(); } | ||
|
|
||
| void checkOtaTimeout() { | ||
| if (otaInProgress && (millis() - lastOtaActivityMs > OTA_TIMEOUT_MS)) { | ||
| USBSerial.println("OTA: Idle timeout, aborting."); | ||
| abortOtaImpl(); | ||
| } |
There was a problem hiding this comment.
checkOtaTimeout() can call abortOtaImpl() from a non-BLE task context (it’s invoked from bleNotifyTask()), while OtaDataCallback::onWrite() may concurrently be appending to sectorBuffer and calling esp_ota_write(updateHandle, ...). Since abortOtaImpl() resets updateHandle/state without synchronization, this creates a real race (use-after-abort / corrupted OTA state). Protect all OTA state transitions and esp_ota_* calls with a mutex/critical section, or ensure timeout/abort runs in the same serialized context as the BLE write callbacks.
| FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/sp140/*.*) | ||
|
|
||
| idf_component_register(SRCS ${app_sources}) |
There was a problem hiding this comment.
FILE(GLOB_RECURSE app_sources ... *.*) will pick up non-source files (headers, CMakeLists, etc.) and can cause ESP-IDF to try compiling unsupported inputs. It also omits include dirs/requirements, so the component may not build even if the glob works. Restrict the glob to compilable sources (e.g. *.c/*.cpp/*.S) and declare INCLUDE_DIRS / REQUIRES as needed.
| FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/sp140/*.*) | |
| idf_component_register(SRCS ${app_sources}) | |
| FILE(GLOB_RECURSE app_sources | |
| ${CMAKE_SOURCE_DIR}/src/sp140/*.c | |
| ${CMAKE_SOURCE_DIR}/src/sp140/*.cpp | |
| ${CMAKE_SOURCE_DIR}/src/sp140/*.S | |
| ) | |
| idf_component_register(SRCS ${app_sources} | |
| INCLUDE_DIRS ".") |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
@zjwhitehead I've opened a new pull request, #99, to work on those changes. Once the pull request is ready, I'll request review from you. |
Co-authored-by: zjwhitehead <4623792+zjwhitehead@users.noreply.github.com> Agent-Logs-Url: https://github.com/openppg/eppg-controller/sessions/3e86426f-2b01-4f3a-a03a-954f9d772ddf
Use ESP_PWR_LVL_P9 enum for BLE TX power
Add 8MB partition table (default_8MB.csv) and switch PlatformIO/project settings to use QIO 8MB flash, 240MHz CPU and custom partition table. Fix platformio.ini typos (lib_dir) and rename src_folder -> custom_src_folder (also updated extra_script.py). Remove NimBLE tuning build flags and enable Bluedroid in sdkconfigs; enable several mbedTLS options and adjust core/flash/rollback settings. Code fixes: stop implicit BLE advertising in setupBLE, correct CRC args in OTA printf, tighten core-dump checks, and remove altimeter task/queue and EEPROM semaphore (cleanup of related declarations/creates/start). Also call diagnosticsInit earlier in setup.
Migrates the project to an ESP‑IDF + Arduino hybrid build, adds BLE OTA firmware updates compatible with Espressif’s Android app, and tightens OTA robustness/rollback behavior.
It also cleans up settings persistence and lint compliance.
Highlights
Updated the build setup and CMake layout to compile under ESP‑IDF while keeping Arduino libraries and setup()/loop() behavior.
Implemented the sector/CRC BLE OTA protocol, aligned service/characteristic UUIDs, and wired the OTA command/ACK + sector ACK flow to match Espressif’s client.
Added rollback marking on successful boot, image length validation, CRC validation, sector resync handling, and proper abort handling.
Settings persistence moved into a dedicated module, keeping preferences validation and serialization consistent.
Notes for reviewers