Add JetFleet BMS targets, C6 support, and ESP-IDF v6 migration - #92
Closed
Fajdiga wants to merge 14 commits into
Closed
Add JetFleet BMS targets, C6 support, and ESP-IDF v6 migration#92Fajdiga wants to merge 14 commits into
Fajdiga wants to merge 14 commits into
Conversation
Adds the JetFleet JFBMS32 hwconf for ESP32-C3. The target has v1 and v2 entry-point headers with common definitions in hw_jfbms32_core.h and the shared BQ769x2 implementation in hw_jfbms32.c. The shared implementation handles dual BQ76952 initialization, I2C address recovery, cell and temperature reporting, charge control, balancing, power-switch control, and BMS sleep/wakeup support. The hwconf ships its own bq769x2_defs.h copy, following the convention used by the existing VESC BMS hwconfs, and includes a generated config parser/XML/defaults set for JFBMS32 settings. External NTC resistance and beta are configurable per unit through that settings XML. CMake already finds the hw_*.h target files; this commit also adds the JetFleet/JFBMS32 include directories needed for the override config and hardware source files to compile.
Adds an optional hwconf macro that lets a board opt out of the COMM_PING_CAN broadcast scan. The default in main/hwconf/hw.h is 1 to preserve the existing behavior; a hwconf header can override it to 0 to skip the scan loop in commands.c. Useful for headless variants that share a CAN bus with a master and should never participate in VESC ping discovery.
Adds an optional hwconf macro that switches the TWAI driver into TWAI_MODE_NO_ACK at init. The default in main/hwconf/hw.h is 0, so the existing TWAI_MODE_NORMAL behavior is preserved unless a hwconf header opts in. Useful for bench / diagnostic builds that need to observe a live CAN bus without generating ACKs.
Adds HW_CAN_FILTER_CONFIG in main/hwconf/hw.h so a hwconf header can override the default TWAI acceptance filter. The default expands to false, so behavior remains TWAI_FILTER_CONFIG_ACCEPT_ALL() when no hardware provides an override. The filter is re-applied on both initial CAN bring-up and after comm_can_update_baudrate() so a hwconf override survives baud changes. f_config is made non-const so update_filter() can replace it. Also dispatches an optional weak hw_can_rx_hook() from the CAN process task after Lisp CAN processing and before the normal VESC/BMS decoder path. Hardware variants such as JFBMS_SLAVE can use this to consume custom 11-bit protocol frames without changing generic CAN decoding. Matches the existing HW_INIT_HOOK() / HW_POST_LISPIF_HOOK() pattern: a hwconf header declares its hardware-specific function and wires it through a small macro or weak-symbol implementation.
Adds a hwconf-defined HW_IS_SLAVE flag that suppresses two pieces of boot-time behavior in main.c: - BLE and WiFi initialization. A slave variant has no user-facing radios; running these only wastes RAM and adds attack surface. - main_store_backup_data() copying controller_id and can_baud_rate from the live config into the persisted backup. Headless slave builds use their own slave-specific config and should not mirror these shared VESC Express compatibility fields back into backup storage. When HW_IS_SLAVE is not defined, behavior is unchanged. The flag is expected to be set in a hwconf header alongside HW_NAME and the other HW_* macros.
Adds a headless JFBMS slave hwconf for ESP32-C3 that uses the hwconf hooks introduced by the preceding commits: - HW_IS_SLAVE skips BLE and WiFi init at boot. - HW_CAN_PING_SCAN_ENABLED 0 suppresses the COMM_PING_CAN scan loop so the slave does not participate in VESC ping discovery. - HW_CAN_NO_ACK_MODE 0 keeps normal ACK behavior; it is declared explicitly so the slave CAN mode is visible alongside the other CAN options. - HW_CAN_FILTER_CONFIG forwards to hw_can_get_filter_config(), which installs a TWAI acceptance filter for the balance-command ID derived from the configured slave_id. The slave drives up to two BQ76952 ICs over I2C with per-IC enable pins, runs an active-low buzzer on GPIO3, and persists a small slave-only config: slave_id, can_baud_rate, cells_ic1/cells_ic2, NTC resistance, and NTC beta. It also documents the private 11-bit JFBMS master/slave CAN protocol and adds the JFBMS slave include directory to main/CMakeLists.txt so the override config and hardware files are visible to the build.
esp_sleep_enable_timer_wakeup expects a uint64_t microsecond count, but ext_sleep_deep / ext_sleep_light cast the float-seconds product to uint32_t first. That wraps for sleep_time > ~4294 s, so a customer-configured 2 h wake cycle silently aliased to ~48.5 min and the unit woke up far too often. Use uint64_t for the cast.
Leaving Bluedroid and the BT controller enabled across esp_deep_sleep_start has been observed to corrupt BLE state over many sleep cycles - the BMS freezes after weeks of 2 h-cycle wakes. Tear them down before sleeping. Light sleep returns to the caller after wake, so the stacks must still be usable. Split the helper into: - sleep_disable_radios() - reversible (wifi_stop, bluedroid_disable, bt_controller_disable). Used by ext_sleep_light. - sleep_deinit_radios() - full teardown, calls disable + bluedroid_deinit + bt_controller_deinit. Used by ext_sleep_deep, where the chip reboots on wake so deinit is free.
CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 only monitors the idle task, so an LBM eval thread stuck on a mutex can leave idle running while the unit appears frozen. In that state the old configuration never tripped the task WDT, so recovery required a power cycle. Enable task WDT panic/reset on C3, C6, and S3 defaults and add a low-priority monitor task in main.c. The monitor registers itself with the WDT and feeds it while the LispBM evaluator heartbeat advances. The heartbeat is driven by the evaluator scheduler in eval_cps.c, so normal Lisp execution, sleeps, and pauses are treated as healthy. If the heartbeat stops after the monitor has armed, the monitor waits for a 30-second stall window, then stops feeding the WDT; with the configured 5-second task-WDT timeout, the chip then panics/resets shortly after. Pre-arm: feed unconditionally until the first heartbeat fires so units where the evaluator never starts do not self-reset. Includes lbm_get_eval_heartbeat() and heartbeat bumps in the evaluator loop so the watchdog has a reliable, GC-independent liveness signal.
Grow the shared BMS cell array limit from 50 to 255 cells so aggregate master/slave reporting can represent larger packs. Clamp received and transmitted cell/temperature counts to the local array sizes before indexing. The CAN status replies now report the clamped counts, preventing malformed or oversized BMS frames from driving out-of-bounds accesses. Keep COMM_BMS_GET_VALUES large enough for the expanded payload by moving it to a 1024-byte static buffer, protected by a reply mutex because the buffer is no longer stack-local.
Adds the JetFleet JF Link hwconf for ESP32-C3, including its config defaults, parser, XML, and CMake include directory. JF Link listens to the private JFBMS slave 11-bit CAN protocol, tracks up to eight slave BMS boards, aggregates their cell/temperature/status data into the shared BMS value structure, and exposes that aggregate to VESC Tool through the existing BMS command path. The target also coordinates slave balancing: it sends balance masks, waits for slave voltage-settled status, computes balancing candidates from the aggregate pack state, and keeps balance commands alive on the bus. A new BMS command hook lets JF Link intercept force-balance and manual balance override commands before the generic BMS forwarding path.
Adds a NimBLE implementation of the VESC Express BLE protocol for ESP32-C6 builds while keeping the existing Bluedroid implementation for targets that still use it. main/CMakeLists.txt now selects comm_ble_nimble.c and ble/custom_ble_nimble.c when CONFIG_BT_NIMBLE_ENABLED is set, otherwise it builds the original comm_ble.c and ble/custom_ble.c files. The new ble_compat.h shim provides the Bluedroid-shaped UUID, permission, characteristic-property, and advertising types used by the existing custom BLE API so the LispBM BLE extensions can build against either host stack. The NimBLE backend implements the VESC UART-style RX/TX GATT service, packet chunking/notifications, advertising, pairing reset handling, and the dynamic custom BLE service API used by LispBM scripts. ESP32-C6 defaults are switched to NimBLE with matching controller/host settings.
Split the ESP32-C6 devkit target into explicit 4 MB and 8 MB hardware configs. The default ESP32-C6 HW_NAME becomes "Devkit C6 8M", while "Devkit C6 4M" is available for modules with smaller flash. The 4 MB target adds sdkconfig.defaults.hw_c6_4m with the 4 MB flash size and 4 MB OTA partition table. CMake now applies shared sdkconfig.defaults.<target> first and then appends any sdkconfig.defaults.<hw_file> overrides, so hardware-specific defaults only need to contain the board-specific differences. README.md documents the shared/default override layering and which C6 target to select for 4 MB versus 8 MB modules.
Move the build to ESP-IDF v6.0.1 and update APIs that changed in the new toolchain. - add an esp_driver_i2c-backed compatibility layer for legacy I2C call sites - migrate ADC reads to the oneshot/calibration drivers - update WiFi, BLE, sleep wakeup, bootloader, and component-manager APIs - migrate TWAI/CAN code to the ESP-IDF v6 on-chip TWAI node API - update BME280, IMU, display, touch, RGB LED, and hwconf call sites for ESP-IDF v6 API and header changes - keep C6 4 MB builds on NimBLE and size optimization to fit the 1600 KiB OTA slots - update the main and bootloader CMake files for the new toolchain layout - update README.md from ESP-IDF 5.5.4 to the supported 6.0.1 release Verified with ESP-IDF v6.0.1: - Devkit C6 4M
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR brings the upstream-ready JetFleet/VESC Express work from
Fajdiga:cleanup/upstream-readyontovedderb:main.Changes
HW_CAN_PING_SCAN_ENABLEDHW_CAN_NO_ACK_MODEHW_IS_SLAVEuint32_twraparound in Lisp sleep timer wakeups.Motivation
The branch makes the JetFleet BMS hardware usable from the upstream tree and includes the generic infrastructure needed for headless/private-CAN BMS variants. It also carries reliability fixes found while running long sleep/wake BMS cycles and the ESP32-C6/ESP-IDF v6 updates used by the current hardware work.
Compatibility
Existing hardware targets keep their default behavior unless they opt into the new hardware macros. The ESP-IDF v6 migration is included in this branch, so this PR intentionally updates the project baseline rather than only adding hardware files.
Tested
cleanup/upstream-ready.