diff --git a/inc/sp140/ble/ble_ids.h b/inc/sp140/ble/ble_ids.h index ad651c22..cf7fa640 100644 --- a/inc/sp140/ble/ble_ids.h +++ b/inc/sp140/ble/ble_ids.h @@ -19,6 +19,28 @@ #define THROTTLE_VALUE_UUID "50AB3859-9FBF-4D30-BF97-2516EE632FAD" #define DEVICE_STATE_UUID "8F80BCF5-B58F-4908-B079-E8AD6F5EE257" +// ESC config relay (phone -> controller -> ESC over CAN). CMD is written by the +// app (opcode-multiplexed); STATUS is read/notify for the async result. +// See: powerpack-flash-qc/configs/ESC-Config-Relay-Design.md +#define ESC_RELAY_CMD_UUID "E5C0C0DE-0001-4A5C-9B21-7E5C0F1A2B30" +#define ESC_RELAY_STATUS_UUID "E5C0C0DE-0002-4A5C-9B21-7E5C0F1A2B30" + +// ESC firmware relay: CTRL is written with FW_START/FW_END/ABORT opcodes and +// read/notify for flasher status; DATA receives offset-addressed image chunks +// (write-without-response for throughput). See ESC-Config-Relay-Design.md §4. +#define ESC_FW_CTRL_UUID "E5C0C0DE-0003-4A5C-9B21-7E5C0F1A2B30" +#define ESC_FW_DATA_UUID "E5C0C0DE-0004-4A5C-9B21-7E5C0F1A2B30" + +// ESC parameter read-all result blob: app writes [offset u32 LE] then reads back +// up to ~240 bytes of the result blob from that offset (paged fetch). +#define ESC_PARAM_DATA_UUID "E5C0C0DE-0005-4A5C-9B21-7E5C0F1A2B30" + +// ESC relay NOTIFY: the controller pushes status + streams the result blob here, +// because GATT reads of the config service return null on this stack while +// notify is reliable. Frames: [0x01]=STATUS[code][phase][detail][len u16], +// [0x02]=DATA[offset u16][bytes]. See ESC-Config-Relay-Design.md. +#define ESC_RELAY_NOTIFY_UUID "E5C0C0DE-0006-4A5C-9B21-7E5C0F1A2B30" + // Device info service #define DEVICE_INFO_SERVICE_UUID "180A" #define MANUFACTURER_NAME_UUID "2A29" diff --git a/inc/sp140/ble/config_service.h b/inc/sp140/ble/config_service.h index f4abc423..a9bcb3e9 100644 --- a/inc/sp140/ble/config_service.h +++ b/inc/sp140/ble/config_service.h @@ -8,4 +8,8 @@ class NimBLEServer; void initConfigBleService(NimBLEServer* server, const std::string& uniqueId); void updateThrottleBLE(int value); +// Push ESC relay status + stream the result blob over notify. Call from the +// 50 Hz BLE notify task. +void pumpEscRelayNotify(); + #endif // INC_SP140_BLE_CONFIG_SERVICE_H_ diff --git a/inc/sp140/bms.h b/inc/sp140/bms.h index 63605ff0..fa2a5c5c 100644 --- a/inc/sp140/bms.h +++ b/inc/sp140/bms.h @@ -18,6 +18,47 @@ constexpr uint8_t BMS_CELL_PROBE_COUNT = 4; constexpr uint8_t BMS_MAX_IGNORED_DISCONNECTED_PROBES = 2; +// How long the BMS link may go silent before it counts as disconnected. Must +// stay well clear of the bmsTask poll period (100 ms): with the library's 100 ms +// default there is zero timing margin, so a single skipped CAN drain — e.g. the +// SPI-mutex bail in updateBMSData() — publishes a spurious disconnect, which +// force-clears every BMS alert. +constexpr unsigned long BMS_LINK_TIMEOUT_MS = 500; + +// A just-connected BMS spreads its state across several CAN frames (basic +// info 1: pack voltage/SOC/current, basic info 2: cell voltages, 0x18B4: +// temperatures). Treating the link as CONNECTED on the first frame let +// monitors and the UI see zero-initialized fields — a 0.000 V "highest cell" +// fired a critical displayed as cell-voltage-high at every boot. Only report +// CONNECTED once both basic frames have populated the snapshot. +// +// Deliberately tests HIGHEST cell voltage, not lowest: both are written by the +// same frame (0x18FE28F4), so either proves that frame arrived — but a shorted +// cell or broken sense lead drives the LOWEST cell to 0.000 V on a healthy, +// still-transmitting pack. Keying on lowest would read that catastrophic fault +// as "no data" and drop the whole BMS to NOT_CONNECTED, suppressing the very +// low-cell and voltage-differential alerts that exist to catch it. No +// single-cell fault can pull the highest cell of a live pack below this floor. +// Callers must latch the result (see bmsTask) so this stays a boot-ordering +// gate and never becomes a runtime state. +inline bool bmsSnapshotCoherent(const STR_BMS_TELEMETRY_140& t) { + return t.battery_voltage > 5.0f && // basic info 1 received + t.highest_cell_voltage > 0.5f; // basic info 2 received +} + +// True once at least one reading from the BMS temperature frame has been +// parsed. Before that frame arrives every probe reads NaN — indistinguishable +// from "all probes disconnected" — and the disconnect sentinel policy below +// must not run, or it fires -40 °C criticals for T3/T4 at every boot. +inline bool bmsTempFrameSeen(float mosTemp, float balanceTemp, + const float cellTemps[BMS_CELL_PROBE_COUNT]) { + if (!isnan(mosTemp) || !isnan(balanceTemp)) return true; + for (uint8_t i = 0; i < BMS_CELL_PROBE_COUNT; i++) { + if (!isnan(cellTemps[i])) return true; + } + return false; +} + inline void sanitizeCellProbeTemps( const float temps[BMS_CELL_PROBE_COUNT], float out[BMS_CELL_PROBE_COUNT]) { diff --git a/inc/sp140/esc.h b/inc/sp140/esc.h index 86f43529..972d858c 100644 --- a/inc/sp140/esc.h +++ b/inc/sp140/esc.h @@ -30,6 +30,11 @@ void setESCThrottle(int throttlePWM); void readESCTelemetry(); bool setupTWAI(); +// Accessor to the single shared CanardAdapter (the controller's sole CAN owner). +// Used by the ESC config relay so its requests go out on the same adapter the +// throttle task drives — keeping all CAN traffic on one task, no mutex needed. +CanardAdapter& escAdapter(); + // Request ESC hardware info (HW ID, FW version, bootloader, serial number). // Thread-safe: sets a flag consumed by readESCTelemetry() on its next tick. // Also called automatically the first time the ESC connects. diff --git a/inc/sp140/esc_config_relay.h b/inc/sp140/esc_config_relay.h new file mode 100644 index 00000000..666d6c1a --- /dev/null +++ b/inc/sp140/esc_config_relay.h @@ -0,0 +1,145 @@ +#ifndef INC_SP140_ESC_CONFIG_RELAY_H_ +#define INC_SP140_ESC_CONFIG_RELAY_H_ + +#include + +// ============================================================================= +// ESC Configuration Relay +// +// Relays SINE / Mad Motors ESC parameter-config commands from the phone app +// (over BLE) to the ESC (over CAN), using the proven SetConfig / SaveConfig / +// RestartNode / GetConfig sequence ported from powerpack-flash-qc. +// +// Concurrency model: the controller's single CAN owner is the throttle task +// (readESCTelemetry() -> adapter.processTxRxOnce()). All CAN traffic for a +// relay session therefore runs on that task via escConfigRelayServiceTick(). +// The BLE task only ENQUEUES a request (escConfigRelayRequest*), exactly like +// the existing requestEscHardwareInfo() flag handoff in esc.cpp. The CanardAdapter +// is never touched from two tasks, so no mutex is needed on it. +// +// Safety: a session only starts while the device is DISARMED. The session is +// fully non-blocking — it never calls delay()/vTaskDelay(), so it cannot stall +// the 50 Hz control loop. Only the ESC reboots; the controller does not. +// +// See: powerpack-flash-qc/configs/ESC-Config-Relay-Design.md +// ============================================================================= + +// Canonical "reverse motor direction" parameter (SINE config_id 0x0080, UINT16, +// 0 = positive/normal, 1 = inversion/reversed). It is a "basic" parameter, +// documented as accessible WITHOUT the password — see +// powerpack-flash-qc/configs/ESC-CAN-Config-Protocol.md. +static const uint16_t ESC_PARAM_DIRECTION = 0x0080; + +enum class EscRelayPhase : uint8_t { + IDLE = 0, + UNLOCK, + WRITE, + SAVE, + RESTART, + WAIT_REBOOT, + VERIFY, + READING, // read-all: iterating GetConfig over every param + BATCH_WRITE, // batch: iterating SetConfig over every queued param + BATCH_VERIFY, // batch: iterating GetConfig to confirm each queued param persisted + DONE_OK, + DONE_FAIL, +}; + +// Status codes surfaced to the app (ESC_RELAY_STATUS notify byte 0 in the +// design doc). +enum class EscRelayStatusCode : uint8_t { + IDLE = 0x00, + ACCEPTED = 0x01, + RUNNING = 0x02, + REBOOTING = 0x03, + VERIFIED_OK = 0x04, + READING = 0x06, // read-all in progress (detail = percent) + READ_DONE = 0x07, // read-all complete (config_id field = result blob length) + FAILED = 0x80, + REJECTED_ARMED = 0x81, + TIMEOUT = 0x82, + VERIFY_MISMATCH = 0x83, + ESC_FLAG_ERROR = 0x85, +}; + +struct EscRelayStatus { + EscRelayStatusCode code; + EscRelayPhase phase; + uint16_t config_id; + uint8_t detail; // raw ESC flag byte on failure, else 0 + uint8_t readback[8]; // verified read-back bytes (valid on VERIFIED_OK) + uint8_t readback_len; +}; + +// Call once from initESC() (after the CanardAdapter has been begun). +void escConfigRelayInit(); + +// Drive the session state machine. MUST be called from the throttle task — it +// is invoked from readESCTelemetry(). Non-blocking. +void escConfigRelayServiceTick(); + +// ---- Request API (safe to call from the BLE task) -------------------------- +// Returns false if a session is already in progress, the payload is too large, +// or the relay is not initialized. The DISARMED check is (re)enforced on the +// throttle task before the session actually starts. +// +// Writes a single parameter, persists it (SaveConfig), restarts the ESC, then +// verifies the read-back across the reboot (GetConfig byte-compare). +bool escConfigRelayRequestSetParam(uint16_t config_id, + const uint8_t* data, uint8_t len); + +// Convenience for the canonical reverse-direction toggle. +bool escConfigRelayRequestReverseDirection(bool reversed); + +// Start a "read all parameters" session: switch to host node 0x40, unlock, then +// GetConfig every id in ESC_PARAM_IDS into a result blob, then restore node 0x01. +// On completion the status code is READ_DONE and config_id holds the blob length. +// Returns false if a session is already in progress. +bool escConfigRelayRequestReadAll(); + +// ---- Batch write (apply many params with a SINGLE save + restart) ----------- +// Mirrors the flash-qc sequence: unlock -> SetConfig every queued param -> +// SaveConfig once -> RestartNode once -> verify each param persisted across the +// reboot. The phone streams the batch first (Begin, then Add per param) and then +// Commit triggers the session. Safe to call Begin/Add from the BLE task — they +// only touch the staging buffer, which the throttle task does not read until a +// Commit starts the session. +// +// Begin: clear the staging buffer. Returns false if a session is in progress. +bool escConfigRelayBatchBegin(); +// Add one param to the staging buffer ([config_id u16][len u8][data[len]]). +// Returns false if the buffer is full or a session is in progress. +bool escConfigRelayBatchAdd(uint16_t config_id, const uint8_t* data, uint8_t len); +// Commit: run the batch session over the staged params. Returns false if nothing +// is staged or a session is already in progress. +bool escConfigRelayRequestBatchCommit(); + +// Length of the last completed read-all result blob (0 until READ_DONE). +uint16_t escConfigRelayResultLen(); + +// Copy up to maxLen bytes of the result blob starting at offset into out. +// Returns the number of bytes copied. Blob format is a sequence of tuples: +// [config_id u16 LE][flag u8][len u8][data[len]] +// (flag 0xFF = the controller timed out reading that param.) +uint16_t escConfigRelayReadResult(uint32_t offset, uint8_t* out, uint16_t maxLen); + +// Latched status snapshot for the BLE status characteristic / UI. +EscRelayStatus escConfigRelayGetStatus(); + +// True while a session is in progress OR a request is pending (for the arm +// interlock — block arming while this is true). +bool escConfigRelayIsActive(); + +// True while a session is active OR within a short settle window after it ends. +// Used to keep the high-rate telemetry notify throttled so the phone's status +// poll and result-blob reads aren't starved by the notify flood. See +// fastlink_service.cpp / ESC-Config-Relay-Design.md. +bool escConfigRelayResultPending(); + +// Require PasswordUnlock (SINE service 225) before writing, and re-unlock after +// the ESC reboots. Default false. The reverse-direction param does NOT need it; +// restricted params do. The decisive bench test runs with this false to confirm +// that 0x0080 is writable from the controller's node 0x01 with no unlock. +void escConfigRelaySetRequireUnlock(bool require); + +#endif // INC_SP140_ESC_CONFIG_RELAY_H_ diff --git a/inc/sp140/esc_flasher_relay.h b/inc/sp140/esc_flasher_relay.h new file mode 100644 index 00000000..b610319d --- /dev/null +++ b/inc/sp140/esc_flasher_relay.h @@ -0,0 +1,94 @@ +#ifndef INC_SP140_ESC_FLASHER_RELAY_H_ +#define INC_SP140_ESC_FLASHER_RELAY_H_ + +#include + +// ============================================================================= +// ESC Firmware Relay +// +// Relays an ESC firmware image from the phone app (over BLE) to the ESC (over +// CAN), using the SINE/Mad Motors bootloader protocol (GetBootStatus 200 / +// StartFwUpgrade 201 / SendFwData 202 / EndFwUpgrade 203) ported from +// powerpack-flash-qc/src/esc_flasher.cpp. +// +// Transport model: BUFFER-THEN-FLASH. +// 1. The app sends FW_START(hwId, totalSize), then streams the complete image +// (32-byte header + firmware) in offset-addressed chunks into a controller +// heap/PSRAM buffer (BLE task), then FW_END. +// 2. Only after the full image is received does the throttle task (the sole +// CAN owner) stream it to the ESC bootloader in 256-byte SendFwData chunks, +// paced by the ESC's next_index flow control. +// This decouples the BLE transfer from the CAN streaming entirely, so a slow +// ESC flash cannot trip a BLE idle timeout, and the buffer is written by only +// one task at a time (BLE during RECEIVING, throttle during flashing). +// +// Safety: only starts while DISARMED; aborts if the device arms; the controller +// never reboots (only the ESC does); the hardware_id is validated against the +// connected ESC before entering the bootloader. Fully non-blocking on the +// throttle task (no delay()/vTaskDelay()), so the 50 Hz control loop is never +// stalled. See: powerpack-flash-qc/configs/ESC-Config-Relay-Design.md (§4). +// ============================================================================= + +enum class EscFwPhase : uint8_t { + IDLE = 0, + RECEIVING, // BLE filling the image buffer + RESTARTING, // RestartNode sent, waiting (non-blocking) for ESC reboot + CHECKING_BOOT, // polling GetBootStatus for bootloader mode + STARTING, // StartFwUpgrade sent + SENDING, // streaming SendFwData chunks + ENDING, // EndFwUpgrade sent + DONE_OK, + DONE_FAIL, +}; + +enum class EscFwCode : uint8_t { + IDLE = 0x00, + RECEIVING = 0x01, + ENTER_BOOTLDR = 0x02, + FLASHING = 0x03, + SUCCESS = 0x04, + FAILED = 0x80, + REJECTED_ARMED = 0x81, + TIMEOUT = 0x82, + REJECTED_HWID = 0x83, // image hardware_id != connected ESC + REJECTED_BUSY = 0x84, // another ESC session active / alloc failed / bad size + ESC_REJECTED = 0x85, // ESC refused the image (bootloader/Start/End state != 0) +}; + +struct EscFwStatus { + EscFwCode code; + EscFwPhase phase; + uint16_t progressPermille; // 0..1000 +}; + +// Call once from initESC() (after the CanardAdapter has been begun). +void escFlasherRelayInit(); + +// Drive the flasher state machine. MUST be called from the throttle task — it +// is invoked from readESCTelemetry(). Non-blocking. +void escFlasherRelayServiceTick(); + +// ---- BLE-side API (safe to call from the BLE task) ------------------------- +// Begin a transfer: allocate a buffer for totalSize bytes (the complete image +// incl. 32-byte header) and validate hwId against the connected ESC. Returns +// false if armed, busy, hwId mismatch, size out of range, or allocation fails. +bool escFlasherRelayBegin(uint16_t hardwareId, uint32_t totalSize); + +// Copy a received chunk into the image buffer at the given offset. Returns the +// total number of contiguous-from-zero bytes received so far, or -1 on error. +int32_t escFlasherRelayWriteChunk(uint32_t offset, const uint8_t* data, uint16_t len); + +// All bytes sent: validate and hand off to the throttle task to flash. Returns +// false if the image is incomplete/invalid. +bool escFlasherRelayEnd(); + +// Abort and free the buffer. +void escFlasherRelayAbort(); + +// Latched status snapshot for the BLE status read/notify. +EscFwStatus escFlasherRelayGetStatus(); + +// True while receiving OR flashing (for the arm interlock). +bool escFlasherRelayIsActive(); + +#endif // INC_SP140_ESC_FLASHER_RELAY_H_ diff --git a/inc/sp140/esc_param_ids.h b/inc/sp140/esc_param_ids.h new file mode 100644 index 00000000..71840d0a --- /dev/null +++ b/inc/sp140/esc_param_ids.h @@ -0,0 +1,35 @@ +#ifndef INC_SP140_ESC_PARAM_IDS_H_ +#define INC_SP140_ESC_PARAM_IDS_H_ + +#include + +// The full set of SINE/Mad Motors ESC config_ids to read back during a +// "read all" session. Ported from powerpack-flash-qc/inc/param_table.h +// (PRODUCTION_CONFIG order). The controller only needs the id list — GetConfig +// returns each value as TAO data with its own length; the app holds the catalog +// (name / type / scaling) for display. See ESC-Config-Relay-Design.md. +static const uint16_t ESC_PARAM_IDS[] = { + 0x0001, // config_name + 0x0002, 0x0004, 0x0003, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0038, + 0x0040, 0x0041, 0x0042, // board + 0x0050, 0x0051, 0x0052, 0x0053, 0x0056, 0x0057, 0x0058, 0x0060, 0x0061, // motor + 0x0071, 0x0072, 0x0080, 0x0081, 0x0082, 0x0091, 0x0100, 0x0101, // control + 0x0110, 0x0111, 0x0112, 0x0118, 0x0119, 0x0120, 0x0121, 0x0130, 0x0131, + 0x0150, 0x0151, 0x0152, 0x0154, 0x0155, 0x0157, 0x0158, 0x0140, 0x0141, // speed + 0x0600, 0x0601, 0x0602, 0x0603, 0x0604, 0x0605, 0x0606, 0x060B, 0x060E, + 0x060F, 0x0610, // throttle + 0x0210, 0x0212, 0x0211, 0x0240, 0x0241, 0x0230, 0x0231, 0x0220, 0x0221, + 0x0250, 0x0251, // advance + 0x0300, 0x0301, 0x0302, // observer + 0x0400, 0x0404, 0x0405, 0x0402, 0x0403, 0x0401, 0x0410, 0x0420, 0x0421, + 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0381, 0x0035, 0x0036, 0x0382, + 0x0391, 0x0392, 0x0393, 0x0390, // protect + 0x0607, 0x0608, 0x0609, 0x060A, 0x060C, 0x060D, // bidirectional throttle + 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, 0x0186, 0x0187, 0x0188, + 0x0189, 0x018A, 0x018B, 0x018C, 0x018D, // position mode +}; + +static const uint16_t ESC_PARAM_IDS_COUNT = + sizeof(ESC_PARAM_IDS) / sizeof(ESC_PARAM_IDS[0]); + +#endif // INC_SP140_ESC_PARAM_IDS_H_ diff --git a/inc/sp140/lvgl/lv_conf.h b/inc/sp140/lvgl/lv_conf.h index 8baef2fb..0d36c138 100644 --- a/inc/sp140/lvgl/lv_conf.h +++ b/inc/sp140/lvgl/lv_conf.h @@ -136,16 +136,18 @@ #define LV_USE_ANIMIMG 0 -#define LV_USE_ARC 1 +#define LV_USE_ARC 0 #define LV_USE_BAR 1 -#define LV_USE_BUTTON 1 +#define LV_USE_BUTTON 0 -#define LV_USE_BUTTONMATRIX 1 /* Required by other components */ +#define LV_USE_BUTTONMATRIX 0 #define LV_USE_CANVAS 0 /* Don't need canvas */ +#define LV_USE_CHART 0 + #define LV_USE_CALENDAR 0 /* Explicitly disable calendar widget */ #define LV_USE_CHECKBOX 0 /* Don't need checkbox */ @@ -154,6 +156,8 @@ #define LV_USE_IMAGE 1 /*Requires: lv_label*/ +#define LV_USE_IMAGEBUTTON 0 + #define LV_USE_LABEL 1 #if LV_USE_LABEL #define LV_LABEL_TEXT_SELECTION 1 /*Enable selecting text of the label*/ @@ -162,21 +166,39 @@ #define LV_USE_LINE 1 +#define LV_USE_LIST 0 + +#define LV_USE_MENU 0 + +#define LV_USE_MSGBOX 0 + #define LV_USE_ROLLER 0 /* Don't need roller */ +#define LV_USE_SCALE 0 + #define LV_USE_SLIDER 0 /* Don't need slider */ -#define LV_USE_SPAN 1 +#define LV_USE_SPAN 0 #if LV_USE_SPAN /*A line text can contain maximum num of span descriptor */ #define LV_SPAN_SNIPPET_STACK_SIZE 64 #endif +#define LV_USE_SPINBOX 0 + #define LV_USE_SWITCH 0 /* Don't need switch */ -#define LV_USE_TEXTAREA 1 /* Required by other components */ +#define LV_USE_TABLE 0 + +#define LV_USE_TABVIEW 0 + +#define LV_USE_TEXTAREA 0 + +#define LV_USE_TILEVIEW 0 + +#define LV_USE_WIN 0 -#define LV_USE_SPINNER 1 +#define LV_USE_SPINNER 0 /* keyboard widget (set to 0 since we don't use it) */ #define LV_USE_KEYBOARD 0 @@ -207,10 +229,10 @@ *==================*/ /*A layout similar to Flexbox in CSS.*/ -#define LV_USE_FLEX 1 +#define LV_USE_FLEX 0 /*A layout similar to Grid in CSS.*/ -#define LV_USE_GRID 1 +#define LV_USE_GRID 0 /*==================== * 3RD PARTS LIBRARIES diff --git a/inc/sp140/lvgl/lvgl_core.h b/inc/sp140/lvgl/lvgl_core.h index 0b3be14a..bb0d0aac 100644 --- a/inc/sp140/lvgl/lvgl_core.h +++ b/inc/sp140/lvgl/lvgl_core.h @@ -16,14 +16,13 @@ // v9 uses byte-based buffers: width * height * bytes_per_pixel / 2 #define LVGL_BUF_BYTES (SCREEN_WIDTH * SCREEN_HEIGHT * 2 / 2) -// LVGL refresh time in ms - match the config file setting +// Poll period for the blocking splash-screen loop in ms #define LVGL_REFRESH_TIME 40 // Core LVGL globals extern int8_t displayCS; // Display chip select pin extern lv_display_t* main_display; extern Adafruit_ST7735* tft_driver; -extern uint32_t lvgl_last_update; // Shared SPI bus mutex (guards TFT + MCP2515 access) extern SemaphoreHandle_t spiBusMutex; @@ -31,7 +30,6 @@ extern SemaphoreHandle_t spiBusMutex; void setupLvglBuffer(); void setupLvglDisplay(const STR_DEVICE_DATA_140_V1& deviceData, int8_t dc_pin, int8_t rst_pin, SPIClass* spi); void lvgl_flush_cb(lv_display_t* disp, const lv_area_t* area, uint8_t* px_map); -void lv_tick_handler(); void updateLvgl(); void displayLvglSplash(const STR_DEVICE_DATA_140_V1& deviceData, int duration); diff --git a/inc/sp140/lvgl/lvgl_main_screen.h b/inc/sp140/lvgl/lvgl_main_screen.h index 30bb766f..f15799cf 100644 --- a/inc/sp140/lvgl/lvgl_main_screen.h +++ b/inc/sp140/lvgl/lvgl_main_screen.h @@ -21,6 +21,16 @@ enum ScreenPage { #define LVGL_PURPLE lv_color_make(128, 0, 128) #define LVGL_GRAY lv_color_make(128, 128, 128) +// Dark-theme accents are intentionally subdued so white foreground text stays +// readable whether it falls over a filled indicator or the black background. +#define LVGL_DARK_GREEN lv_color_make(0, 112, 48) +#define LVGL_DARK_YELLOW lv_color_make(128, 96, 0) +#define LVGL_DARK_RED lv_color_make(176, 0, 32) +#define LVGL_DARK_CYAN lv_color_make(0, 96, 104) +#define LVGL_DARK_BLE_BLUE lv_color_make(64, 160, 255) +#define LVGL_DARK_DESCENT_BLUE lv_color_make(74, 144, 226) +#define LVGL_DARK_DESCENT_PURPLE lv_color_make(192, 128, 255) + // LVGL styles for temperature warnings and critical states extern lv_style_t style_warning; @@ -61,6 +71,8 @@ extern lv_obj_t* climb_rate_fill_sections[12]; // Critical border (used by flash animations) extern lv_obj_t* critical_border; +void setCriticalBorderOpacity(lv_opa_t opacity); +lv_opa_t getCriticalBorderOpacity(); // Helper functions void setAltitudeVisibility(bool visible); diff --git a/inc/sp140/lvgl/lvgl_splash.h b/inc/sp140/lvgl/lvgl_splash.h new file mode 100644 index 00000000..4c623f91 --- /dev/null +++ b/inc/sp140/lvgl/lvgl_splash.h @@ -0,0 +1,12 @@ +#ifndef INC_SP140_LVGL_LVGL_SPLASH_H_ +#define INC_SP140_LVGL_LVGL_SPLASH_H_ + +#include + +#include "sp140/structs.h" + +// Builds and loads the production splash screen. The caller owns the returned +// screen and may delete it after transitioning to the main screen. +lv_obj_t* createLvglSplashScreen(const STR_DEVICE_DATA_140_V1& deviceData); + +#endif // INC_SP140_LVGL_LVGL_SPLASH_H_ diff --git a/inc/sp140/lvgl/lvgl_updates.h b/inc/sp140/lvgl/lvgl_updates.h index 89ac66ee..82548d7c 100644 --- a/inc/sp140/lvgl/lvgl_updates.h +++ b/inc/sp140/lvgl/lvgl_updates.h @@ -28,6 +28,10 @@ extern bool isFlashingCriticalBorder; extern lv_timer_t* ble_pairing_flash_timer; extern bool isFlashingBLEPairingIcon; +// Forget cached last-applied UI state (alignment modes, attached tile +// styles). Must be called whenever the main screen widgets are (re)created. +void resetLvglUpdateCache(); + // Main update function void updateLvglMainScreen( const STR_DEVICE_DATA_140_V1& deviceData, @@ -39,7 +43,7 @@ void updateLvglMainScreen( ); // Helper update functions -void updateClimbRateIndicator(float climbRate); +void updateClimbRateIndicator(float climbRate, bool darkMode); // Test function void updateLvglMainScreenWithTestData(const STR_DEVICE_DATA_140_V1& deviceData); diff --git a/inc/sp140/monitor_config.h b/inc/sp140/monitor_config.h index d80b37dd..9fa7d8b8 100644 --- a/inc/sp140/monitor_config.h +++ b/inc/sp140/monitor_config.h @@ -14,12 +14,22 @@ static const Thresholds motorTempThresholds = {.warnLow = -20, .warnHigh = 105, // -- BMS Thresholds -- static const Thresholds bmsTempThresholds = {.warnLow = -10, .warnHigh = 50, .critLow = -15, .critHigh = 60, .hysteresis = 1.0f}; static const Thresholds bmsCellTempThresholds = {.warnLow = -10, .warnHigh = 50, .critLow = -15, .critHigh = 56, .hysteresis = 1.0f}; -static const Thresholds bmsHighCellVoltageThresholds = {.warnLow = 0.0, .warnHigh = 4.19, .critLow = 0.0, .critHigh = 4.20}; +// High-cell monitor is high-side only: SensorMonitor fires at v <= critLow, so +// the old critLow of 0.0 turned a zero-initialized (pre-data) reading into a +// critical that displayed as "BC-CV-H". Low readings belong to the low monitor. +static const Thresholds bmsHighCellVoltageThresholds = {.warnLow = -1.0, .warnHigh = 4.19, .critLow = -1.0, .critHigh = 4.20}; static const Thresholds bmsLowCellVoltageThresholds = {.warnLow = 3.2, .warnHigh = 4.5, .critLow = 3.0, .critHigh = 4.8}; static const Thresholds bmsSOCThresholds = {.warnLow = 15.0, .warnHigh = 101.0, .critLow = 5.0, .critHigh = 110.0}; static const Thresholds bmsTotalVoltageThresholds = {.warnLow = 79.2, .warnHigh = 100.4, .critLow = 69.6, .critHigh = 100.8}; static const Thresholds bmsVoltageDifferentialThresholds = {.warnLow = -1.0, .warnHigh = 0.2, .critLow = -2.0, .critHigh = 0.4}; +// Hold BMS monitors off for this long after the FIRST NOT_CONNECTED -> +// CONNECTED transition: a BMS that is itself still booting can emit +// sentinel/garbage readings in its first frames, and alarming on those caused +// spurious criticals at power-on and on hot-plug. Applied once per power-on — +// see checkAllSensorsWithData for why re-arming it per reconnect is unsafe. +static const uint32_t BMS_ALERT_GRACE_MS = 2000; + // -- Altimeter Thresholds -- static const Thresholds baroTempThresholds = {.warnLow = 0, .warnHigh = 50, .critLow = -10, .critHigh = 80, .hysteresis = 1.0f}; diff --git a/inc/version.h b/inc/version.h index b7a8dfbe..125c70ec 100644 --- a/inc/version.h +++ b/inc/version.h @@ -2,7 +2,7 @@ #pragma once #define VERSION_MAJOR 8 -#define VERSION_MINOR 0 +#define VERSION_MINOR 1 // Monotonic build counter, independent of MAJOR/MINOR. Injected at build time // by extra_script.py (git commit count) so it climbs on every release. The diff --git a/platformio.ini b/platformio.ini index f7c0d9f1..4f1654ee 100644 --- a/platformio.ini +++ b/platformio.ini @@ -41,6 +41,10 @@ build_flags = -D LV_LVGL_H_INCLUDE_SIMPLE -D CORE_DEBUG_LEVEL=2 -D CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 + ; Headroom for stored notify/indicate subscriptions (default 8). The ESC + ; relay added read/write chars (no new notify), but bump for safety margin so + ; dev re-bonds don't exhaust the CCCD store. See ESC-Config-Relay-Design.md. + -D CONFIG_BT_NIMBLE_MAX_CCCDS=16 -Wno-error=format ; NimBLE ble_hs.h: BLE_HS_HCI_ERR(x) uses (x) in ternary; GCC -Wint-in-bool-context is -Werror in IDF -Wno-error=int-in-bool-context diff --git a/sdkconfig.OpenPPG-CESP32S3-CAN-SP140 b/sdkconfig.OpenPPG-CESP32S3-CAN-SP140 index 09110754..2111f743 100644 --- a/sdkconfig.OpenPPG-CESP32S3-CAN-SP140 +++ b/sdkconfig.OpenPPG-CESP32S3-CAN-SP140 @@ -1,2037 +1,2037 @@ -# -# Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) Project Configuration -# -CONFIG_IDF_CMAKE=y -CONFIG_IDF_TARGET_ARCH_XTENSA=y -CONFIG_IDF_TARGET="esp32s3" -CONFIG_IDF_TARGET_ESP32S3=y -CONFIG_IDF_FIRMWARE_CHIP_ID=0x0009 - -# -# SDK tool configuration -# -CONFIG_SDK_TOOLPREFIX="xtensa-esp32s3-elf-" -# CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS is not set -# end of SDK tool configuration - -# -# Build type -# -CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y -# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set -CONFIG_APP_BUILD_GENERATE_BINARIES=y -CONFIG_APP_BUILD_BOOTLOADER=y -CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y -# end of Build type - -# -# Application manager -# -CONFIG_APP_COMPILE_TIME_DATE=y -# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set -# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set -# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set -CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 -# end of Application manager - -# -# Bootloader config -# -CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x0 -CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set -CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y -# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set -CONFIG_BOOTLOADER_LOG_LEVEL=3 - -# -# Serial Flash Configurations -# -# CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set -CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y -# end of Serial Flash Configurations - -CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y -# CONFIG_BOOTLOADER_FACTORY_RESET is not set -# CONFIG_BOOTLOADER_APP_TEST is not set -CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y -CONFIG_BOOTLOADER_WDT_ENABLE=y -# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set -CONFIG_BOOTLOADER_WDT_TIME_MS=9000 -CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y -# CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set -CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 -# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set -# end of Bootloader config - -# -# Security features -# -CONFIG_SECURE_BOOT_SUPPORTS_RSA=y -CONFIG_SECURE_TARGET_HAS_SECURE_ROM_DL_MODE=y -# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set -# CONFIG_SECURE_BOOT is not set -# CONFIG_SECURE_FLASH_ENC_ENABLED is not set -# end of Security features - -# -# Boot ROM Behavior -# -CONFIG_BOOT_ROM_LOG_ALWAYS_ON=y -# CONFIG_BOOT_ROM_LOG_ALWAYS_OFF is not set -# CONFIG_BOOT_ROM_LOG_ON_GPIO_HIGH is not set -# CONFIG_BOOT_ROM_LOG_ON_GPIO_LOW is not set -# end of Boot ROM Behavior - -# -# Serial flasher config -# -CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 -# CONFIG_ESPTOOLPY_NO_STUB is not set -# CONFIG_ESPTOOLPY_OCT_FLASH is not set -CONFIG_ESPTOOLPY_FLASHMODE_QIO=y -# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set -# CONFIG_ESPTOOLPY_FLASHMODE_DIO is not set -# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set -CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y -CONFIG_ESPTOOLPY_FLASHMODE="dio" -CONFIG_ESPTOOLPY_S3_STR=y -# CONFIG_ESPTOOLPY_FLASHFREQ_120M is not set -CONFIG_ESPTOOLPY_FLASHFREQ_80M=y -# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set -CONFIG_ESPTOOLPY_FLASHFREQ="80m" -# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y -# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE="8MB" -CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y -CONFIG_ESPTOOLPY_BEFORE_RESET=y -# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set -CONFIG_ESPTOOLPY_BEFORE="default_reset" -CONFIG_ESPTOOLPY_AFTER_RESET=y -# CONFIG_ESPTOOLPY_AFTER_NORESET is not set -CONFIG_ESPTOOLPY_AFTER="hard_reset" -# CONFIG_ESPTOOLPY_MONITOR_BAUD_CONSOLE is not set -# CONFIG_ESPTOOLPY_MONITOR_BAUD_9600B is not set -# CONFIG_ESPTOOLPY_MONITOR_BAUD_57600B is not set -CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y -# CONFIG_ESPTOOLPY_MONITOR_BAUD_230400B is not set -# CONFIG_ESPTOOLPY_MONITOR_BAUD_921600B is not set -# CONFIG_ESPTOOLPY_MONITOR_BAUD_2MB is not set -# CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER is not set -CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER_VAL=115200 -CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 -# end of Serial flasher config - -# -# Partition Table -# -# 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="default_8MB.csv" -CONFIG_PARTITION_TABLE_FILENAME="default_8MB.csv" -CONFIG_PARTITION_TABLE_OFFSET=0x8000 -CONFIG_PARTITION_TABLE_MD5=y -# end of Partition Table - -# -# Arduino Configuration -# -CONFIG_ARDUINO_VARIANT="esp32s3" -CONFIG_ENABLE_ARDUINO_DEPENDS=y -CONFIG_AUTOSTART_ARDUINO=y -# CONFIG_ARDUINO_RUN_CORE0 is not set -CONFIG_ARDUINO_RUN_CORE1=y -# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_RUNNING_CORE=1 -CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 -# CONFIG_ARDUINO_EVENT_RUN_CORE0 is not set -CONFIG_ARDUINO_EVENT_RUN_CORE1=y -# CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 -# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE0 is not set -# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE1 is not set -CONFIG_ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY=y -CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE=-1 -CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=2048 -CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY=24 -CONFIG_ARDUINO_UDP_RUN_CORE0=y -# CONFIG_ARDUINO_UDP_RUN_CORE1 is not set -# CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_UDP_RUNNING_CORE=0 -CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 -# CONFIG_ARDUINO_ISR_IRAM is not set -# CONFIG_DISABLE_HAL_LOCKS is not set - -# -# Debug Log Configuration -# -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE is not set -CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR=y -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_WARN is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=1 -# CONFIG_ARDUHAL_LOG_COLORS is not set -# CONFIG_ARDUHAL_ESP_LOG is not set -# end of Debug Log Configuration - -CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT=y -# CONFIG_ARDUHAL_PARTITION_SCHEME_MINIMAL is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_NO_OTA is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_HUGE_APP is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS is not set -CONFIG_ARDUHAL_PARTITION_SCHEME="default" -# CONFIG_AUTOCONNECT_WIFI is not set -# CONFIG_ARDUINO_SELECTIVE_COMPILATION is not set -# end of Arduino Configuration - -# -# Compiler options -# -CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y -# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set -# CONFIG_COMPILER_OPTIMIZATION_PERF is not set -# CONFIG_COMPILER_OPTIMIZATION_NONE is not set -CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y -# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set -# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set -CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 -# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set -CONFIG_COMPILER_HIDE_PATHS_MACROS=y -CONFIG_COMPILER_CXX_EXCEPTIONS=y -CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=0 -# CONFIG_COMPILER_CXX_RTTI is not set -CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y -# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set -# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set -# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set -# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set -# CONFIG_COMPILER_DISABLE_GCC8_WARNINGS is not set -# CONFIG_COMPILER_DUMP_RTL_FILES is not set -# end of Compiler options - -# -# Component config -# - -# -# Application Level Tracing -# -# CONFIG_APPTRACE_DEST_JTAG is not set -CONFIG_APPTRACE_DEST_NONE=y -CONFIG_APPTRACE_LOCK_ENABLE=y -# end of Application Level Tracing - -# -# ESP-ASIO -# -# CONFIG_ASIO_SSL_SUPPORT is not set -# end of ESP-ASIO - -# -# Bluetooth -# -CONFIG_BT_ENABLED=y -CONFIG_BT_SOC_SUPPORT_5_0=y - -# -# Bluetooth controller -# -CONFIG_BT_CTRL_MODE_EFF=1 -CONFIG_BT_CTRL_BLE_MAX_ACT=6 -CONFIG_BT_CTRL_BLE_MAX_ACT_EFF=6 -CONFIG_BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB=0 -CONFIG_BT_CTRL_PINNED_TO_CORE_0=y -# CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set -CONFIG_BT_CTRL_PINNED_TO_CORE=0 -CONFIG_BT_CTRL_HCI_MODE_VHCI=y -# CONFIG_BT_CTRL_HCI_MODE_UART_H4 is not set -CONFIG_BT_CTRL_HCI_TL=1 -CONFIG_BT_CTRL_ADV_DUP_FILT_MAX=30 -CONFIG_BT_BLE_CCA_MODE_NONE=y -# CONFIG_BT_BLE_CCA_MODE_HW is not set -# CONFIG_BT_BLE_CCA_MODE_SW is not set -CONFIG_BT_BLE_CCA_MODE=0 -CONFIG_BT_CTRL_HW_CCA_VAL=20 -CONFIG_BT_CTRL_HW_CCA_EFF=0 -CONFIG_BT_CTRL_CE_LENGTH_TYPE_ORIG=y -# CONFIG_BT_CTRL_CE_LENGTH_TYPE_CE is not set -# CONFIG_BT_CTRL_CE_LENGTH_TYPE_SD is not set -CONFIG_BT_CTRL_CE_LENGTH_TYPE_EFF=0 -CONFIG_BT_CTRL_TX_ANTENNA_INDEX_0=y -# CONFIG_BT_CTRL_TX_ANTENNA_INDEX_1 is not set -CONFIG_BT_CTRL_TX_ANTENNA_INDEX_EFF=0 -CONFIG_BT_CTRL_RX_ANTENNA_INDEX_0=y -# CONFIG_BT_CTRL_RX_ANTENNA_INDEX_1 is not set -CONFIG_BT_CTRL_RX_ANTENNA_INDEX_EFF=0 -# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N24 is not set -# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N21 is not set -# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N18 is not set -# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N15 is not set -# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N12 is not set -# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N9 is not set -# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N6 is not set -# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N3 is not set -# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N0 is not set -# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P3 is not set -# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P6 is not set -CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P9=y -# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P12 is not set -# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P15 is not set -# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P18 is not set -# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P21 is not set -CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=11 -CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y -CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 -CONFIG_BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 -CONFIG_BT_CTRL_BLE_SCAN_DUPL=y -CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DEVICE=y -# CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA is not set -# CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE is not set -CONFIG_BT_CTRL_SCAN_DUPL_TYPE=0 -CONFIG_BT_CTRL_SCAN_DUPL_CACHE_SIZE=100 -CONFIG_BT_CTRL_DUPL_SCAN_CACHE_REFRESH_PERIOD=0 -# CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN is not set -# CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EN is not set -CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_DIS=y -CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EFF=0 - -# -# MODEM SLEEP Options -# -# CONFIG_BT_CTRL_MODEM_SLEEP is not set -# end of MODEM SLEEP Options - -CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 -CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 -CONFIG_BT_CTRL_HCI_TL_EFF=1 -# CONFIG_BT_CTRL_AGC_RECORRECT_EN is not set -# CONFIG_BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set -# CONFIG_BT_BLE_ADV_DATA_LENGTH_ZERO_AUX is not set -# end of Bluetooth controller - -CONFIG_BT_BLUEDROID_ENABLED=y -# CONFIG_BT_NIMBLE_ENABLED is not set -# CONFIG_BT_CONTROLLER_ONLY is not set - -# -# Bluedroid Options -# -CONFIG_BT_BTC_TASK_STACK_SIZE=3072 -CONFIG_BT_BLUEDROID_PINNED_TO_CORE_0=y -# CONFIG_BT_BLUEDROID_PINNED_TO_CORE_1 is not set -CONFIG_BT_BLUEDROID_PINNED_TO_CORE=0 -CONFIG_BT_BTU_TASK_STACK_SIZE=4352 -# CONFIG_BT_BLUEDROID_MEM_DEBUG is not set -CONFIG_BT_BLE_ENABLED=y -CONFIG_BT_GATTS_ENABLE=y -# CONFIG_BT_GATTS_PPCP_CHAR_GAP is not set -# CONFIG_BT_BLE_BLUFI_ENABLE is not set -CONFIG_BT_GATT_MAX_SR_PROFILES=8 -CONFIG_BT_GATT_MAX_SR_ATTRIBUTES=100 -# CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL is not set -CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_AUTO=y -CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MODE=0 -# CONFIG_BT_GATTS_ROBUST_CACHING_ENABLED is not set -# CONFIG_BT_GATTS_DEVICE_NAME_WRITABLE is not set -# CONFIG_BT_GATTS_APPEARANCE_WRITABLE is not set -CONFIG_BT_GATTC_ENABLE=y -CONFIG_BT_GATTC_MAX_CACHE_CHAR=40 -CONFIG_BT_GATTC_NOTIF_REG_MAX=5 -# CONFIG_BT_GATTC_CACHE_NVS_FLASH is not set -CONFIG_BT_GATTC_CONNECT_RETRY_COUNT=3 -CONFIG_BT_BLE_SMP_ENABLE=y -# CONFIG_BT_SMP_SLAVE_CON_PARAMS_UPD_ENABLE is not set -# CONFIG_BT_STACK_NO_LOG is not set - -# -# BT DEBUG LOG LEVEL -# -# CONFIG_BT_LOG_HCI_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_HCI_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_HCI_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_HCI_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_HCI_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_HCI_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_HCI_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_HCI_TRACE_LEVEL=2 -# CONFIG_BT_LOG_BTM_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_BTM_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_BTM_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_BTM_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_BTM_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_BTM_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_BTM_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_BTM_TRACE_LEVEL=2 -# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_L2CAP_TRACE_LEVEL=2 -# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL=2 -# CONFIG_BT_LOG_SDP_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_SDP_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_SDP_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_SDP_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_SDP_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_SDP_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_SDP_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_SDP_TRACE_LEVEL=2 -# CONFIG_BT_LOG_GAP_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_GAP_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_GAP_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_GAP_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_GAP_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_GAP_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_GAP_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_GAP_TRACE_LEVEL=2 -# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_BNEP_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_BNEP_TRACE_LEVEL=2 -# CONFIG_BT_LOG_PAN_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_PAN_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_PAN_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_PAN_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_PAN_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_PAN_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_PAN_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_PAN_TRACE_LEVEL=2 -# CONFIG_BT_LOG_A2D_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_A2D_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_A2D_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_A2D_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_A2D_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_A2D_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_A2D_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_A2D_TRACE_LEVEL=2 -# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_AVDT_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_AVDT_TRACE_LEVEL=2 -# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_AVCT_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_AVCT_TRACE_LEVEL=2 -# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_AVRC_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_AVRC_TRACE_LEVEL=2 -# CONFIG_BT_LOG_MCA_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_MCA_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_MCA_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_MCA_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_MCA_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_MCA_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_MCA_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_MCA_TRACE_LEVEL=2 -# CONFIG_BT_LOG_HID_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_HID_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_HID_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_HID_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_HID_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_HID_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_HID_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_HID_TRACE_LEVEL=2 -# CONFIG_BT_LOG_APPL_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_APPL_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_APPL_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_APPL_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_APPL_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_APPL_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_APPL_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_APPL_TRACE_LEVEL=2 -# CONFIG_BT_LOG_GATT_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_GATT_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_GATT_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_GATT_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_GATT_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_GATT_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_GATT_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_GATT_TRACE_LEVEL=2 -# CONFIG_BT_LOG_SMP_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_SMP_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_SMP_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_SMP_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_SMP_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_SMP_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_SMP_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_SMP_TRACE_LEVEL=2 -# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_BTIF_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_BTIF_TRACE_LEVEL=2 -# CONFIG_BT_LOG_BTC_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_BTC_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_BTC_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_BTC_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_BTC_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_BTC_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_BTC_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_BTC_TRACE_LEVEL=2 -# CONFIG_BT_LOG_OSI_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_OSI_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_OSI_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_OSI_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_OSI_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_OSI_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_OSI_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_OSI_TRACE_LEVEL=2 -# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_NONE is not set -# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_ERROR is not set -CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_WARNING=y -# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_API is not set -# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_EVENT is not set -# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_DEBUG is not set -# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_VERBOSE is not set -CONFIG_BT_LOG_BLUFI_TRACE_LEVEL=2 -# end of BT DEBUG LOG LEVEL - -CONFIG_BT_ACL_CONNECTIONS=4 -CONFIG_BT_MULTI_CONNECTION_ENBALE=y -# CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST is not set -# CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY is not set -# CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set -CONFIG_BT_SMP_ENABLE=y -CONFIG_BT_SMP_MAX_BONDS=15 -# CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set -CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 -CONFIG_BT_MAX_DEVICE_NAME_LEN=32 -CONFIG_BT_BLE_RPA_TIMEOUT=900 -CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y -# CONFIG_BT_BLE_42_FEATURES_SUPPORTED is not set -# CONFIG_BT_BLE_HIGH_DUTY_ADV_INTERVAL is not set -# end of Bluedroid Options -# end of Bluetooth - -# CONFIG_BLE_MESH is not set - -# -# CoAP Configuration -# -CONFIG_COAP_MBEDTLS_PSK=y -# CONFIG_COAP_MBEDTLS_PKI is not set -# CONFIG_COAP_MBEDTLS_DEBUG is not set -CONFIG_COAP_LOG_DEFAULT_LEVEL=0 -# end of CoAP Configuration - -# -# Driver configurations -# - -# -# ADC configuration -# -# CONFIG_ADC_FORCE_XPD_FSM is not set -CONFIG_ADC_DISABLE_DAC=y -# CONFIG_ADC_CONTINUOUS_FORCE_USE_ADC2_ON_C3_S3 is not set -# end of ADC configuration - -# -# MCPWM configuration -# -# CONFIG_MCPWM_ISR_IN_IRAM is not set -# end of MCPWM configuration - -# -# SPI configuration -# -# CONFIG_SPI_MASTER_IN_IRAM is not set -CONFIG_SPI_MASTER_ISR_IN_IRAM=y -# CONFIG_SPI_SLAVE_IN_IRAM is not set -CONFIG_SPI_SLAVE_ISR_IN_IRAM=y -# end of SPI configuration - -# -# TWAI configuration -# -# CONFIG_TWAI_ISR_IN_IRAM is not set -# CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM is not set -# end of TWAI configuration - -# -# UART configuration -# -# CONFIG_UART_ISR_IN_IRAM is not set -# end of UART configuration - -# -# GDMA Configuration -# -# CONFIG_GDMA_CTRL_FUNC_IN_IRAM is not set -# CONFIG_GDMA_ISR_IRAM_SAFE is not set -# end of GDMA Configuration -# end of Driver configurations - -# -# eFuse Bit Manager -# -# CONFIG_EFUSE_CUSTOM_TABLE is not set -# CONFIG_EFUSE_VIRTUAL is not set -CONFIG_EFUSE_MAX_BLK_LEN=256 -# end of eFuse Bit Manager - -# -# ESP-TLS -# -CONFIG_ESP_TLS_USING_MBEDTLS=y -CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y -# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set -# CONFIG_ESP_TLS_SERVER is not set -# CONFIG_ESP_TLS_PSK_VERIFICATION is not set -# CONFIG_ESP_TLS_INSECURE is not set -# end of ESP-TLS - -# -# ESP32S3-Specific -# -CONFIG_ESP32S3_REV_MIN_0=y -# CONFIG_ESP32S3_REV_MIN_1 is not set -# CONFIG_ESP32S3_REV_MIN_2 is not set -CONFIG_ESP32S3_REV_MIN_FULL=0 -CONFIG_ESP_REV_MIN_FULL=0 -CONFIG_ESP32S3_REV_MAX_FULL_STR_OPT=y -CONFIG_ESP32S3_REV_MAX_FULL=99 -CONFIG_ESP_REV_MAX_FULL=99 -# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_80 is not set -# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_160 is not set -CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y -CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ=240 - -# -# Cache config -# -CONFIG_ESP32S3_INSTRUCTION_CACHE_16KB=y -# CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB is not set -CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE=0x4000 -# CONFIG_ESP32S3_INSTRUCTION_CACHE_4WAYS is not set -CONFIG_ESP32S3_INSTRUCTION_CACHE_8WAYS=y -CONFIG_ESP32S3_ICACHE_ASSOCIATED_WAYS=8 -# CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B is not set -CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B=y -CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_SIZE=32 -# CONFIG_ESP32S3_INSTRUCTION_CACHE_WRAP is not set -# CONFIG_ESP32S3_DATA_CACHE_16KB is not set -CONFIG_ESP32S3_DATA_CACHE_32KB=y -# CONFIG_ESP32S3_DATA_CACHE_64KB is not set -CONFIG_ESP32S3_DATA_CACHE_SIZE=0x8000 -# CONFIG_ESP32S3_DATA_CACHE_4WAYS is not set -CONFIG_ESP32S3_DATA_CACHE_8WAYS=y -CONFIG_ESP32S3_DCACHE_ASSOCIATED_WAYS=8 -# CONFIG_ESP32S3_DATA_CACHE_LINE_16B is not set -CONFIG_ESP32S3_DATA_CACHE_LINE_32B=y -# CONFIG_ESP32S3_DATA_CACHE_LINE_64B is not set -CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE=32 -# CONFIG_ESP32S3_DATA_CACHE_WRAP is not set -# end of Cache config - -# CONFIG_ESP32S3_SPIRAM_SUPPORT is not set -# CONFIG_ESP32S3_TRAX is not set -CONFIG_ESP32S3_TRACEMEM_RESERVE_DRAM=0x0 -# CONFIG_ESP32S3_ULP_COPROC_ENABLED is not set -CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM=0 -CONFIG_ESP32S3_DEBUG_OCDAWARE=y -CONFIG_ESP32S3_BROWNOUT_DET=y -CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_7=y -# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_1 is not set -CONFIG_ESP32S3_BROWNOUT_DET_LVL=7 -CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC_FRC1=y -# CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC is not set -# CONFIG_ESP32S3_TIME_SYSCALL_USE_FRC1 is not set -# CONFIG_ESP32S3_TIME_SYSCALL_USE_NONE is not set -CONFIG_ESP32S3_RTC_CLK_SRC_INT_RC=y -# CONFIG_ESP32S3_RTC_CLK_SRC_EXT_CRYS is not set -# CONFIG_ESP32S3_RTC_CLK_SRC_EXT_OSC is not set -# CONFIG_ESP32S3_RTC_CLK_SRC_INT_8MD256 is not set -CONFIG_ESP32S3_RTC_CLK_CAL_CYCLES=1024 -CONFIG_ESP32S3_DEEP_SLEEP_WAKEUP_DELAY=2000 -# CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM is not set -# CONFIG_ESP32S3_USE_FIXED_STATIC_RAM_SIZE is not set -# end of ESP32S3-Specific - -# -# ADC-Calibration -# -# end of ADC-Calibration - -# -# Common ESP-related -# -CONFIG_ESP_ERR_TO_NAME_LOOKUP=y -# end of Common ESP-related - -# -# Ethernet -# -CONFIG_ETH_ENABLED=y -CONFIG_ETH_USE_SPI_ETHERNET=y -# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set -# CONFIG_ETH_SPI_ETHERNET_W5500 is not set -# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set -# CONFIG_ETH_USE_OPENETH is not set -# end of Ethernet - -# -# Event Loop Library -# -# CONFIG_ESP_EVENT_LOOP_PROFILING is not set -CONFIG_ESP_EVENT_POST_FROM_ISR=y -CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y -# end of Event Loop Library - -# -# GDB Stub -# -# end of GDB Stub - -# -# ESP HTTP client -# -CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y -# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set -CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH=y -# end of ESP HTTP client - -# -# HTTP Server -# -CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 -CONFIG_HTTPD_MAX_URI_LEN=512 -CONFIG_HTTPD_ERR_RESP_NO_DELAY=y -CONFIG_HTTPD_PURGE_BUF_LEN=32 -# CONFIG_HTTPD_LOG_PURGE_DATA is not set -# CONFIG_HTTPD_WS_SUPPORT is not set -# end of HTTP Server - -# -# ESP HTTPS OTA -# -# CONFIG_OTA_ALLOW_HTTP is not set -# end of ESP HTTPS OTA - -# -# ESP HTTPS server -# -# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set -# end of ESP HTTPS server - -# -# Hardware Settings -# - -# -# MAC Config -# -CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y -# CONFIG_ESP32S3_UNIVERSAL_MAC_ADDRESSES_TWO is not set -CONFIG_ESP32S3_UNIVERSAL_MAC_ADDRESSES_FOUR=y -CONFIG_ESP32S3_UNIVERSAL_MAC_ADDRESSES=4 -# end of MAC Config - -# -# Sleep Config -# -# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set -CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y -CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND=y -CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y -CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU=y -CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y -# end of Sleep Config - -# -# RTC Clock Config -# -CONFIG_RTC_CLOCK_BBPLL_POWER_ON_WITH_USB=y -# end of RTC Clock Config -# end of Hardware Settings - -# -# IPC (Inter-Processor Call) -# -CONFIG_ESP_IPC_TASK_STACK_SIZE=1536 -CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y -CONFIG_ESP_IPC_ISR_ENABLE=y -# end of IPC (Inter-Processor Call) - -# -# LCD and Touch Panel -# - -# -# LCD Touch Drivers are maintained in the IDF Component Registry -# - -# -# LCD Peripheral Configuration -# -CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32 -# CONFIG_LCD_RGB_ISR_IRAM_SAFE is not set -# end of LCD Peripheral Configuration -# end of LCD and Touch Panel - -# -# ESP NETIF Adapter -# -CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 -CONFIG_ESP_NETIF_TCPIP_LWIP=y -# CONFIG_ESP_NETIF_LOOPBACK is not set -CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=y -# end of ESP NETIF Adapter - -# -# PHY -# -CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y -# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set -CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 -CONFIG_ESP_PHY_MAX_TX_POWER=20 -# CONFIG_ESP_PHY_REDUCE_TX_POWER is not set -CONFIG_ESP_PHY_ENABLE_USB=y -CONFIG_ESP_PHY_RF_CAL_PARTIAL=y -# CONFIG_ESP_PHY_RF_CAL_NONE is not set -# CONFIG_ESP_PHY_RF_CAL_FULL is not set -CONFIG_ESP_PHY_CALIBRATION_MODE=0 -# end of PHY - -# -# Power Management -# -# CONFIG_PM_ENABLE is not set -CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP=y -CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP=y -# end of Power Management - -# -# ESP Ringbuf -# -# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set -# CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH is not set -# end of ESP Ringbuf - -# -# ESP System Settings -# -# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set -CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y -# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set -# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set -# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set -CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y -CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y - -# -# Memory protection -# -# end of Memory protection - -CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 -CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 -CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y -# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set -# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 -CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 -CONFIG_ESP_CONSOLE_UART_DEFAULT=y -# CONFIG_ESP_CONSOLE_USB_CDC is not set -# CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG is not set -# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set -# CONFIG_ESP_CONSOLE_NONE is not set -# CONFIG_ESP_CONSOLE_SECONDARY_NONE is not set -CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG=y -CONFIG_ESP_CONSOLE_UART=y -CONFIG_ESP_CONSOLE_MULTIPLE_UART=y -CONFIG_ESP_CONSOLE_UART_NUM=0 -CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 -CONFIG_ESP_INT_WDT=y -CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 -CONFIG_ESP_INT_WDT_CHECK_CPU1=y -CONFIG_ESP_TASK_WDT=y -CONFIG_ESP_TASK_WDT_PANIC=y -CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 -CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y -CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -# CONFIG_ESP_PANIC_HANDLER_IRAM is not set -# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set -CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y -CONFIG_ESP_SYSTEM_BBPLL_RECALIB=y -# end of ESP System Settings - -# -# High resolution timer (esp_timer) -# -# CONFIG_ESP_TIMER_PROFILING is not set -CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y -CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y -CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 -CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 -# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set -CONFIG_ESP_TIMER_IMPL_SYSTIMER=y -# end of High resolution timer (esp_timer) - -# -# Wi-Fi -# -CONFIG_ESP32_WIFI_ENABLED=y -CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y -CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 -CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 -# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set -CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 -CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 -CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y -# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set -CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 -CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 -# CONFIG_ESP32_WIFI_CSI_ENABLED is not set -CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y -CONFIG_ESP32_WIFI_TX_BA_WIN=6 -CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y -CONFIG_ESP32_WIFI_RX_BA_WIN=6 -CONFIG_ESP32_WIFI_NVS_ENABLED=y -CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y -# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set -CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 -CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 -CONFIG_ESP32_WIFI_IRAM_OPT=y -CONFIG_ESP32_WIFI_RX_IRAM_OPT=y -CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y -# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set -# CONFIG_ESP_WIFI_FTM_ENABLE is not set -# CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set -# CONFIG_ESP_WIFI_GCMP_SUPPORT is not set -# CONFIG_ESP_WIFI_GMAC_SUPPORT is not set -CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y -# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set -CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 -# end of Wi-Fi - -# -# Core dump -# -CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y -# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set -# CONFIG_ESP_COREDUMP_ENABLE_TO_NONE is not set -# CONFIG_ESP_COREDUMP_DATA_FORMAT_BIN is not set -CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y -CONFIG_ESP_COREDUMP_CHECKSUM_CRC32=y -CONFIG_ESP_COREDUMP_CHECK_BOOT=y -CONFIG_ESP_COREDUMP_ENABLE=y -CONFIG_ESP_COREDUMP_LOGS=y -CONFIG_ESP_COREDUMP_MAX_TASKS_NUM=64 -CONFIG_ESP_COREDUMP_STACK_SIZE=0 -# end of Core dump - -# -# FAT Filesystem support -# -# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set -CONFIG_FATFS_CODEPAGE_437=y -# CONFIG_FATFS_CODEPAGE_720 is not set -# CONFIG_FATFS_CODEPAGE_737 is not set -# CONFIG_FATFS_CODEPAGE_771 is not set -# CONFIG_FATFS_CODEPAGE_775 is not set -# CONFIG_FATFS_CODEPAGE_850 is not set -# CONFIG_FATFS_CODEPAGE_852 is not set -# CONFIG_FATFS_CODEPAGE_855 is not set -# CONFIG_FATFS_CODEPAGE_857 is not set -# CONFIG_FATFS_CODEPAGE_860 is not set -# CONFIG_FATFS_CODEPAGE_861 is not set -# CONFIG_FATFS_CODEPAGE_862 is not set -# CONFIG_FATFS_CODEPAGE_863 is not set -# CONFIG_FATFS_CODEPAGE_864 is not set -# CONFIG_FATFS_CODEPAGE_865 is not set -# CONFIG_FATFS_CODEPAGE_866 is not set -# CONFIG_FATFS_CODEPAGE_869 is not set -# CONFIG_FATFS_CODEPAGE_932 is not set -# CONFIG_FATFS_CODEPAGE_936 is not set -# CONFIG_FATFS_CODEPAGE_949 is not set -# CONFIG_FATFS_CODEPAGE_950 is not set -CONFIG_FATFS_CODEPAGE=437 -CONFIG_FATFS_LFN_NONE=y -# CONFIG_FATFS_LFN_HEAP is not set -# CONFIG_FATFS_LFN_STACK is not set -CONFIG_FATFS_FS_LOCK=0 -CONFIG_FATFS_TIMEOUT_MS=10000 -CONFIG_FATFS_PER_FILE_CACHE=y -# CONFIG_FATFS_USE_FASTSEEK is not set -# end of FAT Filesystem support - -# -# Modbus configuration -# -CONFIG_FMB_COMM_MODE_TCP_EN=y -CONFIG_FMB_TCP_PORT_DEFAULT=502 -CONFIG_FMB_TCP_PORT_MAX_CONN=5 -CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20 -CONFIG_FMB_COMM_MODE_RTU_EN=y -CONFIG_FMB_COMM_MODE_ASCII_EN=y -CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150 -CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 -CONFIG_FMB_QUEUE_LENGTH=20 -CONFIG_FMB_PORT_TASK_STACK_SIZE=4096 -CONFIG_FMB_SERIAL_BUF_SIZE=256 -CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8 -CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000 -CONFIG_FMB_PORT_TASK_PRIO=10 -# CONFIG_FMB_PORT_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_FMB_PORT_TASK_AFFINITY_CPU0=y -# CONFIG_FMB_PORT_TASK_AFFINITY_CPU1 is not set -CONFIG_FMB_PORT_TASK_AFFINITY=0x0 -CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y -CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233 -CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 -CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 -CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 -CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 -# CONFIG_FMB_TIMER_PORT_ENABLED is not set -# CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD is not set -# end of Modbus configuration - -# -# FreeRTOS -# -# CONFIG_FREERTOS_UNICORE is not set -CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF -CONFIG_FREERTOS_TICK_SUPPORT_SYSTIMER=y -CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL1=y -# CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL3 is not set -CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER=y -CONFIG_FREERTOS_HZ=1000 -CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y -# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set -# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set -CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y -# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set -CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y -CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 -CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y -# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set -# CONFIG_FREERTOS_ASSERT_DISABLE is not set -CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 -CONFIG_FREERTOS_ISR_STACKSIZE=2096 -# CONFIG_FREERTOS_LEGACY_HOOKS is not set -CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 -CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y -# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set -CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 -CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=4096 -CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 -CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 -# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set -# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set -CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y -CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y -# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set -# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set -CONFIG_FREERTOS_DEBUG_OCDAWARE=y -CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y -# CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH is not set -# end of FreeRTOS - -# -# Hardware Abstraction Layer (HAL) and Low Level (LL) -# -CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y -# CONFIG_HAL_ASSERTION_DISABLE is not set -# CONFIG_HAL_ASSERTION_SILIENT is not set -# CONFIG_HAL_ASSERTION_ENABLE is not set -CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 -# end of Hardware Abstraction Layer (HAL) and Low Level (LL) - -# -# Heap memory debugging -# -CONFIG_HEAP_POISONING_DISABLED=y -# CONFIG_HEAP_POISONING_LIGHT is not set -# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set -CONFIG_HEAP_TRACING_OFF=y -# CONFIG_HEAP_TRACING_STANDALONE is not set -# CONFIG_HEAP_TRACING_TOHOST is not set -# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set -# end of Heap memory debugging - -# -# jsmn -# -# CONFIG_JSMN_PARENT_LINKS is not set -# CONFIG_JSMN_STRICT is not set -# end of jsmn - -# -# libsodium -# -# end of libsodium - -# -# Log output -# -# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set -CONFIG_LOG_DEFAULT_LEVEL_ERROR=y -# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set -# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set -# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set -# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_LOG_DEFAULT_LEVEL=1 -CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y -# CONFIG_LOG_MAXIMUM_LEVEL_WARN is not set -# CONFIG_LOG_MAXIMUM_LEVEL_INFO is not set -# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set -# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set -CONFIG_LOG_MAXIMUM_LEVEL=1 -CONFIG_LOG_COLORS=y -CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y -# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set -# end of Log output - -# -# LWIP -# -CONFIG_LWIP_LOCAL_HOSTNAME="espressif" -# CONFIG_LWIP_NETIF_API is not set -CONFIG_LWIP_TCPIP_TASK_PRIO=18 -# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set -# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set -CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -# CONFIG_LWIP_L2_TO_L3_COPY is not set -# CONFIG_LWIP_IRAM_OPTIMIZATION is not set -CONFIG_LWIP_TIMERS_ONDEMAND=y -CONFIG_LWIP_MAX_SOCKETS=10 -# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set -# CONFIG_LWIP_SO_LINGER is not set -CONFIG_LWIP_SO_REUSE=y -CONFIG_LWIP_SO_REUSE_RXTOALL=y -CONFIG_LWIP_SO_RCVBUF=y -# CONFIG_LWIP_NETBUF_RECVINFO is not set -CONFIG_LWIP_IP_DEFAULT_TTL=64 -CONFIG_LWIP_IP4_FRAG=y -CONFIG_LWIP_IP6_FRAG=y -# CONFIG_LWIP_IP4_REASSEMBLY is not set -# CONFIG_LWIP_IP6_REASSEMBLY is not set -# CONFIG_LWIP_IP_FORWARD is not set -# CONFIG_LWIP_STATS is not set -# CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set -CONFIG_LWIP_ESP_GRATUITOUS_ARP=y -CONFIG_LWIP_GARP_TMR_INTERVAL=60 -CONFIG_LWIP_ESP_MLDV6_REPORT=y -CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 -CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 -CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y -# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set -CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y -# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set -CONFIG_LWIP_DHCP_OPTIONS_LEN=68 -CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 - -# -# DHCP server -# -CONFIG_LWIP_DHCPS=y -CONFIG_LWIP_DHCPS_LEASE_UNIT=60 -CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 -# end of DHCP server - -# CONFIG_LWIP_AUTOIP is not set -CONFIG_LWIP_IPV6=y -# CONFIG_LWIP_IPV6_AUTOCONFIG is not set -CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 -# CONFIG_LWIP_IPV6_FORWARD is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 - -# -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5760 -CONFIG_LWIP_TCP_WND_DEFAULT=5760 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 -CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 -# CONFIG_LWIP_TCP_SACK_OUT is not set -# CONFIG_LWIP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -CONFIG_LWIP_TCP_RTO_TIME=1500 -# end of TCP - -# -# UDP -# -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# end of UDP - -# -# Checksums -# -# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set -# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set -CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y -# end of Checksums - -CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 -CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y -# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set -# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set -CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF -# CONFIG_LWIP_PPP_SUPPORT is not set -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 -# CONFIG_LWIP_SLIP_SUPPORT is not set - -# -# ICMP -# -CONFIG_LWIP_ICMP=y -# CONFIG_LWIP_MULTICAST_PING is not set -# CONFIG_LWIP_BROADCAST_PING is not set -# end of ICMP - -# -# LWIP RAW API -# -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API - -# -# SNTP -# -CONFIG_LWIP_SNTP_MAX_SERVERS=1 -# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set -CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 -# end of SNTP - -# -# DNS -# -CONFIG_LWIP_DNS_MAX_SERVERS=3 -# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set -# end of DNS - -CONFIG_LWIP_ESP_LWIP_ASSERT=y - -# -# Hooks -# -# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set -CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y -# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set -CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y -# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set -# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set -CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y -# CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT is not set -# CONFIG_LWIP_HOOK_ND6_GET_GW_CUSTOM is not set -CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y -# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set -# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set -# end of Hooks - -# CONFIG_LWIP_DEBUG is not set -# end of LWIP - -# -# mbedTLS -# -CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y -# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set -# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set -CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y -CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 -CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 -# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set -# CONFIG_MBEDTLS_DEBUG is not set - -# -# mbedTLS v2.28.x related -# -# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set -CONFIG_MBEDTLS_ECDH_LEGACY_CONTEXT=y -# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set -# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set -CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y -# end of mbedTLS v2.28.x related - -# -# Certificate Bundle -# -CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y -CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set -# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set -CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 -# end of Certificate Bundle - -CONFIG_MBEDTLS_ECP_RESTARTABLE=y -CONFIG_MBEDTLS_CMAC_C=y -CONFIG_MBEDTLS_HARDWARE_AES=y -CONFIG_MBEDTLS_AES_USE_INTERRUPT=y -CONFIG_MBEDTLS_HARDWARE_MPI=y -CONFIG_MBEDTLS_HARDWARE_SHA=y -CONFIG_MBEDTLS_ROM_MD5=y -# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set -# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set -CONFIG_MBEDTLS_HAVE_TIME=y -# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set -CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y -CONFIG_MBEDTLS_SHA512_C=y -CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y -# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set -# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set -# CONFIG_MBEDTLS_TLS_DISABLED is not set -CONFIG_MBEDTLS_TLS_SERVER=y -CONFIG_MBEDTLS_TLS_CLIENT=y -CONFIG_MBEDTLS_TLS_ENABLED=y - -# -# TLS Key Exchange Methods -# -# CONFIG_MBEDTLS_PSK_MODES is not set -CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y -# end of TLS Key Exchange Methods - -CONFIG_MBEDTLS_SSL_RENEGOTIATION=y -# CONFIG_MBEDTLS_SSL_PROTO_SSL3 is not set -CONFIG_MBEDTLS_SSL_PROTO_TLS1=y -CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y -CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y -# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set -# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set -CONFIG_MBEDTLS_SSL_ALPN=y -CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y -CONFIG_MBEDTLS_X509_CHECK_KEY_USAGE=y -CONFIG_MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE=y -CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y - -# -# Symmetric Ciphers -# -CONFIG_MBEDTLS_AES_C=y -# CONFIG_MBEDTLS_CAMELLIA_C is not set -# CONFIG_MBEDTLS_DES_C is not set -CONFIG_MBEDTLS_RC4_DISABLED=y -# CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT is not set -# CONFIG_MBEDTLS_RC4_ENABLED is not set -# CONFIG_MBEDTLS_BLOWFISH_C is not set -# CONFIG_MBEDTLS_XTEA_C is not set -CONFIG_MBEDTLS_CCM_C=y -CONFIG_MBEDTLS_GCM_C=y -# CONFIG_MBEDTLS_NIST_KW_C is not set -# end of Symmetric Ciphers - -# CONFIG_MBEDTLS_RIPEMD160_C is not set - -# -# Certificates -# -CONFIG_MBEDTLS_PEM_PARSE_C=y -CONFIG_MBEDTLS_PEM_WRITE_C=y -CONFIG_MBEDTLS_X509_CRL_PARSE_C=y -CONFIG_MBEDTLS_X509_CSR_PARSE_C=y -# end of Certificates - -CONFIG_MBEDTLS_ECP_C=y -CONFIG_MBEDTLS_ECDH_C=y -CONFIG_MBEDTLS_ECDSA_C=y -# CONFIG_MBEDTLS_ECJPAKE_C is not set -CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y -CONFIG_MBEDTLS_ECP_NIST_OPTIM=y -# CONFIG_MBEDTLS_POLY1305_C is not set -# CONFIG_MBEDTLS_CHACHA20_C is not set -# CONFIG_MBEDTLS_HKDF_C is not set -# CONFIG_MBEDTLS_THREADING_C is not set -# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set -# CONFIG_MBEDTLS_SECURITY_RISKS is not set -# end of mbedTLS - -# -# mDNS -# -CONFIG_MDNS_MAX_SERVICES=10 -CONFIG_MDNS_TASK_PRIORITY=1 -CONFIG_MDNS_TASK_STACK_SIZE=4096 -# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_MDNS_TASK_AFFINITY_CPU0=y -# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set -CONFIG_MDNS_TASK_AFFINITY=0x0 -CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 -# CONFIG_MDNS_STRICT_MODE is not set -CONFIG_MDNS_TIMER_PERIOD_MS=100 -# CONFIG_MDNS_NETWORKING_SOCKET is not set -CONFIG_MDNS_MULTIPLE_INSTANCE=y -# end of mDNS - -# -# ESP-MQTT Configurations -# -CONFIG_MQTT_PROTOCOL_311=y -CONFIG_MQTT_TRANSPORT_SSL=y -CONFIG_MQTT_TRANSPORT_WEBSOCKET=y -CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y -# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set -# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set -# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set -# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set -# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set -# CONFIG_MQTT_CUSTOM_OUTBOX is not set -# end of ESP-MQTT Configurations - -# -# Newlib -# -CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y -# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set -# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set -# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set -# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set -CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y -# CONFIG_NEWLIB_NANO_FORMAT is not set -# end of Newlib - -# -# NVS -# -# CONFIG_NVS_ASSERT_ERROR_CHECK is not set -# end of NVS - -# -# OpenSSL -# -# CONFIG_OPENSSL_DEBUG is not set -CONFIG_OPENSSL_ERROR_STACK=y -# CONFIG_OPENSSL_ASSERT_DO_NOTHING is not set -CONFIG_OPENSSL_ASSERT_EXIT=y -# end of OpenSSL - -# -# OpenThread -# -# CONFIG_OPENTHREAD_ENABLED is not set -# end of OpenThread - -# -# PThreads -# -CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 -CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 -CONFIG_PTHREAD_STACK_MIN=768 -CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y -# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set -# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set -CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 -CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" -# end of PThreads - -# -# Main Flash configuration -# - -# -# Optional and Experimental Features (READ DOCS FIRST) -# - -# -# Features here require specific hardware (READ DOCS FIRST!) -# -# CONFIG_SPI_FLASH_HPM_ENA is not set -CONFIG_SPI_FLASH_HPM_AUTO=y -# CONFIG_SPI_FLASH_HPM_DIS is not set -CONFIG_SPI_FLASH_HPM_ON=y -CONFIG_SPI_FLASH_HPM_DC_AUTO=y -# CONFIG_SPI_FLASH_HPM_DC_DISABLE is not set -# end of Optional and Experimental Features (READ DOCS FIRST) -# end of Main Flash configuration - -# -# SPI Flash driver -# -# CONFIG_SPI_FLASH_VERIFY_WRITE is not set -# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set -CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y -# CONFIG_SPI_FLASH_ROM_IMPL is not set -CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y -# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set -# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set -# CONFIG_SPI_FLASH_USE_LEGACY_IMPL is not set -# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set -# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set -CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y -CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 -CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 -CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 -# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set -# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set -# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set - -# -# Auto-detect flash chips -# -CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_TH_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP=y -# end of Auto-detect flash chips - -CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y -# end of SPI Flash driver - -# -# SPIFFS Configuration -# -CONFIG_SPIFFS_MAX_PARTITIONS=3 - -# -# SPIFFS Cache Configuration -# -CONFIG_SPIFFS_CACHE=y -CONFIG_SPIFFS_CACHE_WR=y -# CONFIG_SPIFFS_CACHE_STATS is not set -# end of SPIFFS Cache Configuration - -CONFIG_SPIFFS_PAGE_CHECK=y -CONFIG_SPIFFS_GC_MAX_RUNS=10 -# CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 -# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set -CONFIG_SPIFFS_USE_MAGIC=y -CONFIG_SPIFFS_USE_MAGIC_LENGTH=y -CONFIG_SPIFFS_META_LENGTH=4 -CONFIG_SPIFFS_USE_MTIME=y - -# -# Debug Configuration -# -# CONFIG_SPIFFS_DBG is not set -# CONFIG_SPIFFS_API_DBG is not set -# CONFIG_SPIFFS_GC_DBG is not set -# CONFIG_SPIFFS_CACHE_DBG is not set -# CONFIG_SPIFFS_CHECK_DBG is not set -# CONFIG_SPIFFS_TEST_VISUALISATION is not set -# end of Debug Configuration -# end of SPIFFS Configuration - -# -# TCP Transport -# - -# -# Websocket -# -CONFIG_WS_TRANSPORT=y -CONFIG_WS_BUFFER_SIZE=1024 -# end of Websocket -# end of TCP Transport - -# -# TinyUSB Stack -# -# CONFIG_TINYUSB is not set -# end of TinyUSB Stack - -# -# Unity unit testing library -# -CONFIG_UNITY_ENABLE_FLOAT=y -CONFIG_UNITY_ENABLE_DOUBLE=y -# CONFIG_UNITY_ENABLE_64BIT is not set -# CONFIG_UNITY_ENABLE_COLOR is not set -CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y -# CONFIG_UNITY_ENABLE_FIXTURE is not set -# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set -# end of Unity unit testing library - -# -# USB-OTG -# -CONFIG_USB_OTG_SUPPORTED=y -CONFIG_USB_HOST_CONTROL_TRANSFER_MAX_SIZE=256 -CONFIG_USB_HOST_HW_BUFFER_BIAS_BALANCED=y -# CONFIG_USB_HOST_HW_BUFFER_BIAS_IN is not set -# CONFIG_USB_HOST_HW_BUFFER_BIAS_PERIODIC_OUT is not set - -# -# Root Hub configuration -# -CONFIG_USB_HOST_DEBOUNCE_DELAY_MS=250 -CONFIG_USB_HOST_RESET_HOLD_MS=30 -CONFIG_USB_HOST_RESET_RECOVERY_MS=30 -CONFIG_USB_HOST_SET_ADDR_RECOVERY_MS=10 -# end of Root Hub configuration -# end of USB-OTG - -# -# Virtual file system -# -CONFIG_VFS_SUPPORT_IO=y -CONFIG_VFS_SUPPORT_DIR=y -CONFIG_VFS_SUPPORT_SELECT=y -CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y -CONFIG_VFS_SUPPORT_TERMIOS=y - -# -# Host File System I/O (Semihosting) -# -CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -# end of Host File System I/O (Semihosting) -# end of Virtual file system - -# -# Wear Levelling -# -# CONFIG_WL_SECTOR_SIZE_512 is not set -CONFIG_WL_SECTOR_SIZE_4096=y -CONFIG_WL_SECTOR_SIZE=4096 -# end of Wear Levelling - -# -# Wi-Fi Provisioning Manager -# -CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 -CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 -# CONFIG_WIFI_PROV_BLE_BONDING is not set -# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set -# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set -# end of Wi-Fi Provisioning Manager - -# -# Supplicant -# -CONFIG_WPA_MBEDTLS_CRYPTO=y -# CONFIG_WPA_WAPI_PSK is not set -# CONFIG_WPA_SUITE_B_192 is not set -# CONFIG_WPA_DEBUG_PRINT is not set -# CONFIG_WPA_TESTING_OPTIONS is not set -# CONFIG_WPA_WPS_STRICT is not set -# CONFIG_WPA_11KV_SUPPORT is not set -# CONFIG_WPA_MBO_SUPPORT is not set -# CONFIG_WPA_DPP_SUPPORT is not set -# end of Supplicant -# end of Component config - -# -# Compatibility options -# -# CONFIG_LEGACY_INCLUDE_COMMON_HEADERS is not set -# end of Compatibility options - -# Deprecated options for backward compatibility -CONFIG_TOOLPREFIX="xtensa-esp32s3-elf-" -# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set -CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y -# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set -CONFIG_LOG_BOOTLOADER_LEVEL=3 -CONFIG_APP_ROLLBACK_ENABLE=y -# CONFIG_APP_ANTI_ROLLBACK is not set -# CONFIG_FLASH_ENCRYPTION_ENABLED is not set -CONFIG_FLASHMODE_QIO=y -# CONFIG_FLASHMODE_QOUT is not set -# CONFIG_FLASHMODE_DIO is not set -# CONFIG_FLASHMODE_DOUT is not set -# CONFIG_MONITOR_BAUD_9600B is not set -# CONFIG_MONITOR_BAUD_57600B is not set -CONFIG_MONITOR_BAUD_115200B=y -# CONFIG_MONITOR_BAUD_230400B is not set -# CONFIG_MONITOR_BAUD_921600B is not set -# CONFIG_MONITOR_BAUD_2MB is not set -# CONFIG_MONITOR_BAUD_OTHER is not set -CONFIG_MONITOR_BAUD_OTHER_VAL=115200 -CONFIG_MONITOR_BAUD=115200 -CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y -# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set -CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y -# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set -# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set -CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 -CONFIG_CXX_EXCEPTIONS=y -CONFIG_CXX_EXCEPTIONS_EMG_POOL_SIZE=0 -CONFIG_STACK_CHECK_NONE=y -# CONFIG_STACK_CHECK_NORM is not set -# CONFIG_STACK_CHECK_STRONG is not set -# CONFIG_STACK_CHECK_ALL is not set -# CONFIG_WARN_WRITE_STRINGS is not set -# CONFIG_DISABLE_GCC8_WARNINGS is not set -# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set -CONFIG_ESP32_APPTRACE_DEST_NONE=y -CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y -CONFIG_BLUEDROID_ENABLED=y -# CONFIG_NIMBLE_ENABLED is not set -CONFIG_BTC_TASK_STACK_SIZE=3072 -CONFIG_BLUEDROID_PINNED_TO_CORE_0=y -# CONFIG_BLUEDROID_PINNED_TO_CORE_1 is not set -CONFIG_BLUEDROID_PINNED_TO_CORE=0 -CONFIG_BTU_TASK_STACK_SIZE=4352 -# CONFIG_BLUEDROID_MEM_DEBUG is not set -CONFIG_GATTS_ENABLE=y -# CONFIG_GATTS_SEND_SERVICE_CHANGE_MANUAL is not set -CONFIG_GATTS_SEND_SERVICE_CHANGE_AUTO=y -CONFIG_GATTS_SEND_SERVICE_CHANGE_MODE=0 -CONFIG_GATTC_ENABLE=y -# CONFIG_GATTC_CACHE_NVS_FLASH is not set -CONFIG_BLE_SMP_ENABLE=y -# CONFIG_SMP_SLAVE_CON_PARAMS_UPD_ENABLE is not set -# CONFIG_HCI_TRACE_LEVEL_NONE is not set -# CONFIG_HCI_TRACE_LEVEL_ERROR is not set -CONFIG_HCI_TRACE_LEVEL_WARNING=y -# CONFIG_HCI_TRACE_LEVEL_API is not set -# CONFIG_HCI_TRACE_LEVEL_EVENT is not set -# CONFIG_HCI_TRACE_LEVEL_DEBUG is not set -# CONFIG_HCI_TRACE_LEVEL_VERBOSE is not set -CONFIG_HCI_INITIAL_TRACE_LEVEL=2 -# CONFIG_BTM_TRACE_LEVEL_NONE is not set -# CONFIG_BTM_TRACE_LEVEL_ERROR is not set -CONFIG_BTM_TRACE_LEVEL_WARNING=y -# CONFIG_BTM_TRACE_LEVEL_API is not set -# CONFIG_BTM_TRACE_LEVEL_EVENT is not set -# CONFIG_BTM_TRACE_LEVEL_DEBUG is not set -# CONFIG_BTM_TRACE_LEVEL_VERBOSE is not set -CONFIG_BTM_INITIAL_TRACE_LEVEL=2 -# CONFIG_L2CAP_TRACE_LEVEL_NONE is not set -# CONFIG_L2CAP_TRACE_LEVEL_ERROR is not set -CONFIG_L2CAP_TRACE_LEVEL_WARNING=y -# CONFIG_L2CAP_TRACE_LEVEL_API is not set -# CONFIG_L2CAP_TRACE_LEVEL_EVENT is not set -# CONFIG_L2CAP_TRACE_LEVEL_DEBUG is not set -# CONFIG_L2CAP_TRACE_LEVEL_VERBOSE is not set -CONFIG_L2CAP_INITIAL_TRACE_LEVEL=2 -# CONFIG_RFCOMM_TRACE_LEVEL_NONE is not set -# CONFIG_RFCOMM_TRACE_LEVEL_ERROR is not set -CONFIG_RFCOMM_TRACE_LEVEL_WARNING=y -# CONFIG_RFCOMM_TRACE_LEVEL_API is not set -# CONFIG_RFCOMM_TRACE_LEVEL_EVENT is not set -# CONFIG_RFCOMM_TRACE_LEVEL_DEBUG is not set -# CONFIG_RFCOMM_TRACE_LEVEL_VERBOSE is not set -CONFIG_RFCOMM_INITIAL_TRACE_LEVEL=2 -# CONFIG_SDP_TRACE_LEVEL_NONE is not set -# CONFIG_SDP_TRACE_LEVEL_ERROR is not set -CONFIG_SDP_TRACE_LEVEL_WARNING=y -# CONFIG_SDP_TRACE_LEVEL_API is not set -# CONFIG_SDP_TRACE_LEVEL_EVENT is not set -# CONFIG_SDP_TRACE_LEVEL_DEBUG is not set -# CONFIG_SDP_TRACE_LEVEL_VERBOSE is not set -CONFIG_BTH_LOG_SDP_INITIAL_TRACE_LEVEL=2 -# CONFIG_GAP_TRACE_LEVEL_NONE is not set -# CONFIG_GAP_TRACE_LEVEL_ERROR is not set -CONFIG_GAP_TRACE_LEVEL_WARNING=y -# CONFIG_GAP_TRACE_LEVEL_API is not set -# CONFIG_GAP_TRACE_LEVEL_EVENT is not set -# CONFIG_GAP_TRACE_LEVEL_DEBUG is not set -# CONFIG_GAP_TRACE_LEVEL_VERBOSE is not set -CONFIG_GAP_INITIAL_TRACE_LEVEL=2 -CONFIG_BNEP_INITIAL_TRACE_LEVEL=2 -# CONFIG_PAN_TRACE_LEVEL_NONE is not set -# CONFIG_PAN_TRACE_LEVEL_ERROR is not set -CONFIG_PAN_TRACE_LEVEL_WARNING=y -# CONFIG_PAN_TRACE_LEVEL_API is not set -# CONFIG_PAN_TRACE_LEVEL_EVENT is not set -# CONFIG_PAN_TRACE_LEVEL_DEBUG is not set -# CONFIG_PAN_TRACE_LEVEL_VERBOSE is not set -CONFIG_PAN_INITIAL_TRACE_LEVEL=2 -# CONFIG_A2D_TRACE_LEVEL_NONE is not set -# CONFIG_A2D_TRACE_LEVEL_ERROR is not set -CONFIG_A2D_TRACE_LEVEL_WARNING=y -# CONFIG_A2D_TRACE_LEVEL_API is not set -# CONFIG_A2D_TRACE_LEVEL_EVENT is not set -# CONFIG_A2D_TRACE_LEVEL_DEBUG is not set -# CONFIG_A2D_TRACE_LEVEL_VERBOSE is not set -CONFIG_A2D_INITIAL_TRACE_LEVEL=2 -# CONFIG_AVDT_TRACE_LEVEL_NONE is not set -# CONFIG_AVDT_TRACE_LEVEL_ERROR is not set -CONFIG_AVDT_TRACE_LEVEL_WARNING=y -# CONFIG_AVDT_TRACE_LEVEL_API is not set -# CONFIG_AVDT_TRACE_LEVEL_EVENT is not set -# CONFIG_AVDT_TRACE_LEVEL_DEBUG is not set -# CONFIG_AVDT_TRACE_LEVEL_VERBOSE is not set -CONFIG_AVDT_INITIAL_TRACE_LEVEL=2 -# CONFIG_AVCT_TRACE_LEVEL_NONE is not set -# CONFIG_AVCT_TRACE_LEVEL_ERROR is not set -CONFIG_AVCT_TRACE_LEVEL_WARNING=y -# CONFIG_AVCT_TRACE_LEVEL_API is not set -# CONFIG_AVCT_TRACE_LEVEL_EVENT is not set -# CONFIG_AVCT_TRACE_LEVEL_DEBUG is not set -# CONFIG_AVCT_TRACE_LEVEL_VERBOSE is not set -CONFIG_AVCT_INITIAL_TRACE_LEVEL=2 -# CONFIG_AVRC_TRACE_LEVEL_NONE is not set -# CONFIG_AVRC_TRACE_LEVEL_ERROR is not set -CONFIG_AVRC_TRACE_LEVEL_WARNING=y -# CONFIG_AVRC_TRACE_LEVEL_API is not set -# CONFIG_AVRC_TRACE_LEVEL_EVENT is not set -# CONFIG_AVRC_TRACE_LEVEL_DEBUG is not set -# CONFIG_AVRC_TRACE_LEVEL_VERBOSE is not set -CONFIG_AVRC_INITIAL_TRACE_LEVEL=2 -# CONFIG_MCA_TRACE_LEVEL_NONE is not set -# CONFIG_MCA_TRACE_LEVEL_ERROR is not set -CONFIG_MCA_TRACE_LEVEL_WARNING=y -# CONFIG_MCA_TRACE_LEVEL_API is not set -# CONFIG_MCA_TRACE_LEVEL_EVENT is not set -# CONFIG_MCA_TRACE_LEVEL_DEBUG is not set -# CONFIG_MCA_TRACE_LEVEL_VERBOSE is not set -CONFIG_MCA_INITIAL_TRACE_LEVEL=2 -# CONFIG_HID_TRACE_LEVEL_NONE is not set -# CONFIG_HID_TRACE_LEVEL_ERROR is not set -CONFIG_HID_TRACE_LEVEL_WARNING=y -# CONFIG_HID_TRACE_LEVEL_API is not set -# CONFIG_HID_TRACE_LEVEL_EVENT is not set -# CONFIG_HID_TRACE_LEVEL_DEBUG is not set -# CONFIG_HID_TRACE_LEVEL_VERBOSE is not set -CONFIG_HID_INITIAL_TRACE_LEVEL=2 -# CONFIG_APPL_TRACE_LEVEL_NONE is not set -# CONFIG_APPL_TRACE_LEVEL_ERROR is not set -CONFIG_APPL_TRACE_LEVEL_WARNING=y -# CONFIG_APPL_TRACE_LEVEL_API is not set -# CONFIG_APPL_TRACE_LEVEL_EVENT is not set -# CONFIG_APPL_TRACE_LEVEL_DEBUG is not set -# CONFIG_APPL_TRACE_LEVEL_VERBOSE is not set -CONFIG_APPL_INITIAL_TRACE_LEVEL=2 -# CONFIG_GATT_TRACE_LEVEL_NONE is not set -# CONFIG_GATT_TRACE_LEVEL_ERROR is not set -CONFIG_GATT_TRACE_LEVEL_WARNING=y -# CONFIG_GATT_TRACE_LEVEL_API is not set -# CONFIG_GATT_TRACE_LEVEL_EVENT is not set -# CONFIG_GATT_TRACE_LEVEL_DEBUG is not set -# CONFIG_GATT_TRACE_LEVEL_VERBOSE is not set -CONFIG_GATT_INITIAL_TRACE_LEVEL=2 -# CONFIG_SMP_TRACE_LEVEL_NONE is not set -# CONFIG_SMP_TRACE_LEVEL_ERROR is not set -CONFIG_SMP_TRACE_LEVEL_WARNING=y -# CONFIG_SMP_TRACE_LEVEL_API is not set -# CONFIG_SMP_TRACE_LEVEL_EVENT is not set -# CONFIG_SMP_TRACE_LEVEL_DEBUG is not set -# CONFIG_SMP_TRACE_LEVEL_VERBOSE is not set -CONFIG_SMP_INITIAL_TRACE_LEVEL=2 -# CONFIG_BTIF_TRACE_LEVEL_NONE is not set -# CONFIG_BTIF_TRACE_LEVEL_ERROR is not set -CONFIG_BTIF_TRACE_LEVEL_WARNING=y -# CONFIG_BTIF_TRACE_LEVEL_API is not set -# CONFIG_BTIF_TRACE_LEVEL_EVENT is not set -# CONFIG_BTIF_TRACE_LEVEL_DEBUG is not set -# CONFIG_BTIF_TRACE_LEVEL_VERBOSE is not set -CONFIG_BTIF_INITIAL_TRACE_LEVEL=2 -# CONFIG_BTC_TRACE_LEVEL_NONE is not set -# CONFIG_BTC_TRACE_LEVEL_ERROR is not set -CONFIG_BTC_TRACE_LEVEL_WARNING=y -# CONFIG_BTC_TRACE_LEVEL_API is not set -# CONFIG_BTC_TRACE_LEVEL_EVENT is not set -# CONFIG_BTC_TRACE_LEVEL_DEBUG is not set -# CONFIG_BTC_TRACE_LEVEL_VERBOSE is not set -CONFIG_BTC_INITIAL_TRACE_LEVEL=2 -# CONFIG_OSI_TRACE_LEVEL_NONE is not set -# CONFIG_OSI_TRACE_LEVEL_ERROR is not set -CONFIG_OSI_TRACE_LEVEL_WARNING=y -# CONFIG_OSI_TRACE_LEVEL_API is not set -# CONFIG_OSI_TRACE_LEVEL_EVENT is not set -# CONFIG_OSI_TRACE_LEVEL_DEBUG is not set -# CONFIG_OSI_TRACE_LEVEL_VERBOSE is not set -CONFIG_OSI_INITIAL_TRACE_LEVEL=2 -# CONFIG_BLUFI_TRACE_LEVEL_NONE is not set -# CONFIG_BLUFI_TRACE_LEVEL_ERROR is not set -CONFIG_BLUFI_TRACE_LEVEL_WARNING=y -# CONFIG_BLUFI_TRACE_LEVEL_API is not set -# CONFIG_BLUFI_TRACE_LEVEL_EVENT is not set -# CONFIG_BLUFI_TRACE_LEVEL_DEBUG is not set -# CONFIG_BLUFI_TRACE_LEVEL_VERBOSE is not set -CONFIG_BLUFI_INITIAL_TRACE_LEVEL=2 -# CONFIG_BLE_HOST_QUEUE_CONGESTION_CHECK is not set -CONFIG_SMP_ENABLE=y -# CONFIG_BLE_ACTIVE_SCAN_REPORT_ADV_SCAN_RSP_INDIVIDUALLY is not set -CONFIG_BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT=30 -CONFIG_ADC2_DISABLE_DAC=y -# CONFIG_EVENT_LOOP_PROFILING is not set -CONFIG_POST_EVENTS_FROM_ISR=y -CONFIG_POST_EVENTS_FROM_IRAM_ISR=y -# CONFIG_ESP_SYSTEM_PD_FLASH is not set -CONFIG_ESP32C3_LIGHTSLEEP_GPIO_RESET_WORKAROUND=y -CONFIG_IPC_TASK_STACK_SIZE=1536 -CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y -# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set -CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 -CONFIG_ESP32_PHY_MAX_TX_POWER=20 -# CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set -CONFIG_ESP_SYSTEM_PM_POWER_DOWN_CPU=y -# CONFIG_ESP32S2_PANIC_PRINT_HALT is not set -CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y -# CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set -# CONFIG_ESP32S2_PANIC_GDBSTUB is not set -CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP=y -CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 -CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_MAIN_TASK_STACK_SIZE=3584 -CONFIG_CONSOLE_UART_DEFAULT=y -# CONFIG_CONSOLE_UART_CUSTOM is not set -# CONFIG_ESP_CONSOLE_UART_NONE is not set -CONFIG_CONSOLE_UART=y -CONFIG_CONSOLE_UART_NUM=0 -CONFIG_CONSOLE_UART_BAUDRATE=115200 -CONFIG_INT_WDT=y -CONFIG_INT_WDT_TIMEOUT_MS=300 -CONFIG_INT_WDT_CHECK_CPU1=y -CONFIG_TASK_WDT=y -CONFIG_TASK_WDT_PANIC=y -CONFIG_TASK_WDT_TIMEOUT_S=5 -CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y -CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set -CONFIG_TIMER_TASK_STACK_SIZE=3584 -CONFIG_SW_COEXIST_ENABLE=y -CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH=y -# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set -# CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE is not set -# CONFIG_ESP32_COREDUMP_DATA_FORMAT_BIN is not set -CONFIG_ESP32_COREDUMP_DATA_FORMAT_ELF=y -CONFIG_ESP32_COREDUMP_CHECKSUM_CRC32=y -CONFIG_ESP32_ENABLE_COREDUMP=y -CONFIG_ESP32_CORE_DUMP_MAX_TASKS_NUM=64 -CONFIG_ESP32_CORE_DUMP_STACK_SIZE=0 -CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=150 -CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 -CONFIG_MB_QUEUE_LENGTH=20 -CONFIG_MB_SERIAL_TASK_STACK_SIZE=4096 -CONFIG_MB_SERIAL_BUF_SIZE=256 -CONFIG_MB_SERIAL_TASK_PRIO=10 -CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT=y -CONFIG_MB_CONTROLLER_SLAVE_ID=0x00112233 -CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 -CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 -CONFIG_MB_CONTROLLER_STACK_SIZE=4096 -CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 -# CONFIG_MB_TIMER_PORT_ENABLED is not set -# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set -CONFIG_TIMER_TASK_PRIORITY=1 -CONFIG_TIMER_TASK_STACK_DEPTH=4096 -CONFIG_TIMER_QUEUE_LENGTH=10 -# CONFIG_L2_TO_L3_COPY is not set -# CONFIG_USE_ONLY_LWIP_SELECT is not set -CONFIG_ESP_GRATUITOUS_ARP=y -CONFIG_GARP_TMR_INTERVAL=60 -CONFIG_TCPIP_RECVMBOX_SIZE=32 -CONFIG_TCP_MAXRTX=12 -CONFIG_TCP_SYNMAXRTX=12 -CONFIG_TCP_MSS=1440 -CONFIG_TCP_MSL=60000 -CONFIG_TCP_SND_BUF_DEFAULT=5760 -CONFIG_TCP_WND_DEFAULT=5760 -CONFIG_TCP_RECVMBOX_SIZE=6 -CONFIG_TCP_QUEUE_OOSEQ=y -# CONFIG_ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set -CONFIG_TCP_OVERSIZE_MSS=y -# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_TCP_OVERSIZE_DISABLE is not set -CONFIG_UDP_RECVMBOX_SIZE=6 -CONFIG_TCPIP_TASK_STACK_SIZE=3072 -CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y -# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set -# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set -CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF -# CONFIG_PPP_SUPPORT is not set -CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 -CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 -CONFIG_ESP32_PTHREAD_STACK_MIN=768 -CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y -# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set -# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set -CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 -CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" -CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y -# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set -# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set -# CONFIG_USB_ENABLED is not set -CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y -CONFIG_SUPPORT_TERMIOS=y -CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -# End of deprecated options +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) Project Configuration +# +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET="esp32s3" +CONFIG_IDF_TARGET_ESP32S3=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0009 + +# +# SDK tool configuration +# +CONFIG_SDK_TOOLPREFIX="xtensa-esp32s3-elf-" +# CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS is not set +# end of SDK tool configuration + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# end of Build type + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 +# end of Application manager + +# +# Bootloader config +# +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x0 +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_LOG_LEVEL=3 + +# +# Serial Flash Configurations +# +# CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set +CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y +# end of Serial Flash Configurations + +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y +CONFIG_BOOTLOADER_WDT_ENABLE=y +# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set +CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y +# CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +# end of Bootloader config + +# +# Security features +# +CONFIG_SECURE_BOOT_SUPPORTS_RSA=y +CONFIG_SECURE_TARGET_HAS_SECURE_ROM_DL_MODE=y +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +# end of Security features + +# +# Boot ROM Behavior +# +CONFIG_BOOT_ROM_LOG_ALWAYS_ON=y +# CONFIG_BOOT_ROM_LOG_ALWAYS_OFF is not set +# CONFIG_BOOT_ROM_LOG_ON_GPIO_HIGH is not set +# CONFIG_BOOT_ROM_LOG_ON_GPIO_LOW is not set +# end of Boot ROM Behavior + +# +# Serial flasher config +# +CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_OCT_FLASH is not set +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +# CONFIG_ESPTOOLPY_FLASHMODE_DIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y +CONFIG_ESPTOOLPY_FLASHMODE="dio" +CONFIG_ESPTOOLPY_S3_STR=y +# CONFIG_ESPTOOLPY_FLASHFREQ_120M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ="80m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="8MB" +CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +# CONFIG_ESPTOOLPY_MONITOR_BAUD_CONSOLE is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_9600B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_57600B is not set +CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y +# CONFIG_ESPTOOLPY_MONITOR_BAUD_230400B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_921600B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_2MB is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER is not set +CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER_VAL=115200 +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +# end of Serial flasher config + +# +# Partition Table +# +# 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="default_8MB.csv" +CONFIG_PARTITION_TABLE_FILENAME="default_8MB.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Arduino Configuration +# +CONFIG_ARDUINO_VARIANT="esp32s3" +CONFIG_ENABLE_ARDUINO_DEPENDS=y +CONFIG_AUTOSTART_ARDUINO=y +# CONFIG_ARDUINO_RUN_CORE0 is not set +CONFIG_ARDUINO_RUN_CORE1=y +# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_RUNNING_CORE=1 +CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 +# CONFIG_ARDUINO_EVENT_RUN_CORE0 is not set +CONFIG_ARDUINO_EVENT_RUN_CORE1=y +# CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 +# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE0 is not set +# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE1 is not set +CONFIG_ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY=y +CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE=-1 +CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=2048 +CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY=24 +CONFIG_ARDUINO_UDP_RUN_CORE0=y +# CONFIG_ARDUINO_UDP_RUN_CORE1 is not set +# CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set +CONFIG_ARDUINO_UDP_RUNNING_CORE=0 +CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 +# CONFIG_ARDUINO_ISR_IRAM is not set +# CONFIG_DISABLE_HAL_LOCKS is not set + +# +# Debug Log Configuration +# +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE is not set +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR=y +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_WARN is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=1 +# CONFIG_ARDUHAL_LOG_COLORS is not set +# CONFIG_ARDUHAL_ESP_LOG is not set +# end of Debug Log Configuration + +CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT=y +# CONFIG_ARDUHAL_PARTITION_SCHEME_MINIMAL is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_NO_OTA is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_HUGE_APP is not set +# CONFIG_ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS is not set +CONFIG_ARDUHAL_PARTITION_SCHEME="default" +# CONFIG_AUTOCONNECT_WIFI is not set +# CONFIG_ARDUINO_SELECTIVE_COMPILATION is not set +# end of Arduino Configuration + +# +# Compiler options +# +CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y +# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set +# CONFIG_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set +CONFIG_COMPILER_HIDE_PATHS_MACROS=y +CONFIG_COMPILER_CXX_EXCEPTIONS=y +CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=0 +# CONFIG_COMPILER_CXX_RTTI is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +# CONFIG_COMPILER_DISABLE_GCC8_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_JTAG is not set +CONFIG_APPTRACE_DEST_NONE=y +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# ESP-ASIO +# +# CONFIG_ASIO_SSL_SUPPORT is not set +# end of ESP-ASIO + +# +# Bluetooth +# +CONFIG_BT_ENABLED=y +CONFIG_BT_SOC_SUPPORT_5_0=y + +# +# Bluetooth controller +# +CONFIG_BT_CTRL_MODE_EFF=1 +CONFIG_BT_CTRL_BLE_MAX_ACT=6 +CONFIG_BT_CTRL_BLE_MAX_ACT_EFF=6 +CONFIG_BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB=0 +CONFIG_BT_CTRL_PINNED_TO_CORE_0=y +# CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set +CONFIG_BT_CTRL_PINNED_TO_CORE=0 +CONFIG_BT_CTRL_HCI_MODE_VHCI=y +# CONFIG_BT_CTRL_HCI_MODE_UART_H4 is not set +CONFIG_BT_CTRL_HCI_TL=1 +CONFIG_BT_CTRL_ADV_DUP_FILT_MAX=30 +CONFIG_BT_BLE_CCA_MODE_NONE=y +# CONFIG_BT_BLE_CCA_MODE_HW is not set +# CONFIG_BT_BLE_CCA_MODE_SW is not set +CONFIG_BT_BLE_CCA_MODE=0 +CONFIG_BT_CTRL_HW_CCA_VAL=20 +CONFIG_BT_CTRL_HW_CCA_EFF=0 +CONFIG_BT_CTRL_CE_LENGTH_TYPE_ORIG=y +# CONFIG_BT_CTRL_CE_LENGTH_TYPE_CE is not set +# CONFIG_BT_CTRL_CE_LENGTH_TYPE_SD is not set +CONFIG_BT_CTRL_CE_LENGTH_TYPE_EFF=0 +CONFIG_BT_CTRL_TX_ANTENNA_INDEX_0=y +# CONFIG_BT_CTRL_TX_ANTENNA_INDEX_1 is not set +CONFIG_BT_CTRL_TX_ANTENNA_INDEX_EFF=0 +CONFIG_BT_CTRL_RX_ANTENNA_INDEX_0=y +# CONFIG_BT_CTRL_RX_ANTENNA_INDEX_1 is not set +CONFIG_BT_CTRL_RX_ANTENNA_INDEX_EFF=0 +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N24 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N21 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N18 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N15 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N12 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N9 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N6 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N3 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N0 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P3 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P6 is not set +CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P9=y +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P12 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P15 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P18 is not set +# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P21 is not set +CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=11 +CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y +CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 +CONFIG_BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 +CONFIG_BT_CTRL_BLE_SCAN_DUPL=y +CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DEVICE=y +# CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA is not set +# CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE is not set +CONFIG_BT_CTRL_SCAN_DUPL_TYPE=0 +CONFIG_BT_CTRL_SCAN_DUPL_CACHE_SIZE=100 +CONFIG_BT_CTRL_DUPL_SCAN_CACHE_REFRESH_PERIOD=0 +# CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN is not set +# CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EN is not set +CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_DIS=y +CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EFF=0 + +# +# MODEM SLEEP Options +# +# CONFIG_BT_CTRL_MODEM_SLEEP is not set +# end of MODEM SLEEP Options + +CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 +CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 +CONFIG_BT_CTRL_HCI_TL_EFF=1 +# CONFIG_BT_CTRL_AGC_RECORRECT_EN is not set +# CONFIG_BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set +# CONFIG_BT_BLE_ADV_DATA_LENGTH_ZERO_AUX is not set +# end of Bluetooth controller + +CONFIG_BT_BLUEDROID_ENABLED=y +# CONFIG_BT_NIMBLE_ENABLED is not set +# CONFIG_BT_CONTROLLER_ONLY is not set + +# +# Bluedroid Options +# +CONFIG_BT_BTC_TASK_STACK_SIZE=3072 +CONFIG_BT_BLUEDROID_PINNED_TO_CORE_0=y +# CONFIG_BT_BLUEDROID_PINNED_TO_CORE_1 is not set +CONFIG_BT_BLUEDROID_PINNED_TO_CORE=0 +CONFIG_BT_BTU_TASK_STACK_SIZE=4352 +# CONFIG_BT_BLUEDROID_MEM_DEBUG is not set +CONFIG_BT_BLE_ENABLED=y +CONFIG_BT_GATTS_ENABLE=y +# CONFIG_BT_GATTS_PPCP_CHAR_GAP is not set +# CONFIG_BT_BLE_BLUFI_ENABLE is not set +CONFIG_BT_GATT_MAX_SR_PROFILES=8 +CONFIG_BT_GATT_MAX_SR_ATTRIBUTES=100 +# CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL is not set +CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_AUTO=y +CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MODE=0 +# CONFIG_BT_GATTS_ROBUST_CACHING_ENABLED is not set +# CONFIG_BT_GATTS_DEVICE_NAME_WRITABLE is not set +# CONFIG_BT_GATTS_APPEARANCE_WRITABLE is not set +CONFIG_BT_GATTC_ENABLE=y +CONFIG_BT_GATTC_MAX_CACHE_CHAR=40 +CONFIG_BT_GATTC_NOTIF_REG_MAX=5 +# CONFIG_BT_GATTC_CACHE_NVS_FLASH is not set +CONFIG_BT_GATTC_CONNECT_RETRY_COUNT=3 +CONFIG_BT_BLE_SMP_ENABLE=y +# CONFIG_BT_SMP_SLAVE_CON_PARAMS_UPD_ENABLE is not set +# CONFIG_BT_STACK_NO_LOG is not set + +# +# BT DEBUG LOG LEVEL +# +# CONFIG_BT_LOG_HCI_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_HCI_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_HCI_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_HCI_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_HCI_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_HCI_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_HCI_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_HCI_TRACE_LEVEL=2 +# CONFIG_BT_LOG_BTM_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_BTM_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_BTM_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_BTM_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_BTM_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_BTM_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_BTM_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_BTM_TRACE_LEVEL=2 +# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_L2CAP_TRACE_LEVEL=2 +# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL=2 +# CONFIG_BT_LOG_SDP_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_SDP_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_SDP_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_SDP_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_SDP_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_SDP_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_SDP_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_SDP_TRACE_LEVEL=2 +# CONFIG_BT_LOG_GAP_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_GAP_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_GAP_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_GAP_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_GAP_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_GAP_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_GAP_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_GAP_TRACE_LEVEL=2 +# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_BNEP_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_BNEP_TRACE_LEVEL=2 +# CONFIG_BT_LOG_PAN_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_PAN_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_PAN_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_PAN_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_PAN_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_PAN_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_PAN_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_PAN_TRACE_LEVEL=2 +# CONFIG_BT_LOG_A2D_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_A2D_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_A2D_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_A2D_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_A2D_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_A2D_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_A2D_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_A2D_TRACE_LEVEL=2 +# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_AVDT_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_AVDT_TRACE_LEVEL=2 +# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_AVCT_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_AVCT_TRACE_LEVEL=2 +# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_AVRC_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_AVRC_TRACE_LEVEL=2 +# CONFIG_BT_LOG_MCA_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_MCA_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_MCA_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_MCA_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_MCA_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_MCA_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_MCA_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_MCA_TRACE_LEVEL=2 +# CONFIG_BT_LOG_HID_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_HID_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_HID_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_HID_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_HID_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_HID_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_HID_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_HID_TRACE_LEVEL=2 +# CONFIG_BT_LOG_APPL_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_APPL_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_APPL_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_APPL_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_APPL_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_APPL_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_APPL_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_APPL_TRACE_LEVEL=2 +# CONFIG_BT_LOG_GATT_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_GATT_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_GATT_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_GATT_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_GATT_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_GATT_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_GATT_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_GATT_TRACE_LEVEL=2 +# CONFIG_BT_LOG_SMP_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_SMP_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_SMP_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_SMP_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_SMP_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_SMP_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_SMP_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_SMP_TRACE_LEVEL=2 +# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_BTIF_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_BTIF_TRACE_LEVEL=2 +# CONFIG_BT_LOG_BTC_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_BTC_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_BTC_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_BTC_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_BTC_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_BTC_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_BTC_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_BTC_TRACE_LEVEL=2 +# CONFIG_BT_LOG_OSI_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_OSI_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_OSI_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_OSI_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_OSI_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_OSI_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_OSI_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_OSI_TRACE_LEVEL=2 +# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_NONE is not set +# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_ERROR is not set +CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_WARNING=y +# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_API is not set +# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_EVENT is not set +# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_DEBUG is not set +# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_VERBOSE is not set +CONFIG_BT_LOG_BLUFI_TRACE_LEVEL=2 +# end of BT DEBUG LOG LEVEL + +CONFIG_BT_ACL_CONNECTIONS=4 +CONFIG_BT_MULTI_CONNECTION_ENBALE=y +# CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST is not set +# CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY is not set +# CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set +CONFIG_BT_SMP_ENABLE=y +CONFIG_BT_SMP_MAX_BONDS=15 +# CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set +CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30 +CONFIG_BT_MAX_DEVICE_NAME_LEN=32 +CONFIG_BT_BLE_RPA_TIMEOUT=900 +CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y +# CONFIG_BT_BLE_42_FEATURES_SUPPORTED is not set +# CONFIG_BT_BLE_HIGH_DUTY_ADV_INTERVAL is not set +# end of Bluedroid Options +# end of Bluetooth + +# CONFIG_BLE_MESH is not set + +# +# CoAP Configuration +# +CONFIG_COAP_MBEDTLS_PSK=y +# CONFIG_COAP_MBEDTLS_PKI is not set +# CONFIG_COAP_MBEDTLS_DEBUG is not set +CONFIG_COAP_LOG_DEFAULT_LEVEL=0 +# end of CoAP Configuration + +# +# Driver configurations +# + +# +# ADC configuration +# +# CONFIG_ADC_FORCE_XPD_FSM is not set +CONFIG_ADC_DISABLE_DAC=y +# CONFIG_ADC_CONTINUOUS_FORCE_USE_ADC2_ON_C3_S3 is not set +# end of ADC configuration + +# +# MCPWM configuration +# +# CONFIG_MCPWM_ISR_IN_IRAM is not set +# end of MCPWM configuration + +# +# SPI configuration +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of SPI configuration + +# +# TWAI configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +# CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM is not set +# end of TWAI configuration + +# +# UART configuration +# +# CONFIG_UART_ISR_IN_IRAM is not set +# end of UART configuration + +# +# GDMA Configuration +# +# CONFIG_GDMA_CTRL_FUNC_IN_IRAM is not set +# CONFIG_GDMA_ISR_IRAM_SAFE is not set +# end of GDMA Configuration +# end of Driver configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +CONFIG_EFUSE_MAX_BLK_LEN=256 +# end of eFuse Bit Manager + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y +# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + +# +# ESP32S3-Specific +# +CONFIG_ESP32S3_REV_MIN_0=y +# CONFIG_ESP32S3_REV_MIN_1 is not set +# CONFIG_ESP32S3_REV_MIN_2 is not set +CONFIG_ESP32S3_REV_MIN_FULL=0 +CONFIG_ESP_REV_MIN_FULL=0 +CONFIG_ESP32S3_REV_MAX_FULL_STR_OPT=y +CONFIG_ESP32S3_REV_MAX_FULL=99 +CONFIG_ESP_REV_MAX_FULL=99 +# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_80 is not set +# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_160 is not set +CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y +CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ=240 + +# +# Cache config +# +CONFIG_ESP32S3_INSTRUCTION_CACHE_16KB=y +# CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB is not set +CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE=0x4000 +# CONFIG_ESP32S3_INSTRUCTION_CACHE_4WAYS is not set +CONFIG_ESP32S3_INSTRUCTION_CACHE_8WAYS=y +CONFIG_ESP32S3_ICACHE_ASSOCIATED_WAYS=8 +# CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B is not set +CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B=y +CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_SIZE=32 +# CONFIG_ESP32S3_INSTRUCTION_CACHE_WRAP is not set +# CONFIG_ESP32S3_DATA_CACHE_16KB is not set +CONFIG_ESP32S3_DATA_CACHE_32KB=y +# CONFIG_ESP32S3_DATA_CACHE_64KB is not set +CONFIG_ESP32S3_DATA_CACHE_SIZE=0x8000 +# CONFIG_ESP32S3_DATA_CACHE_4WAYS is not set +CONFIG_ESP32S3_DATA_CACHE_8WAYS=y +CONFIG_ESP32S3_DCACHE_ASSOCIATED_WAYS=8 +# CONFIG_ESP32S3_DATA_CACHE_LINE_16B is not set +CONFIG_ESP32S3_DATA_CACHE_LINE_32B=y +# CONFIG_ESP32S3_DATA_CACHE_LINE_64B is not set +CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE=32 +# CONFIG_ESP32S3_DATA_CACHE_WRAP is not set +# end of Cache config + +# CONFIG_ESP32S3_SPIRAM_SUPPORT is not set +# CONFIG_ESP32S3_TRAX is not set +CONFIG_ESP32S3_TRACEMEM_RESERVE_DRAM=0x0 +# CONFIG_ESP32S3_ULP_COPROC_ENABLED is not set +CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM=0 +CONFIG_ESP32S3_DEBUG_OCDAWARE=y +CONFIG_ESP32S3_BROWNOUT_DET=y +CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_7=y +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_1 is not set +CONFIG_ESP32S3_BROWNOUT_DET_LVL=7 +CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32S3_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32S3_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32S3_RTC_CLK_SRC_INT_RC=y +# CONFIG_ESP32S3_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32S3_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32S3_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_ESP32S3_RTC_CLK_CAL_CYCLES=1024 +CONFIG_ESP32S3_DEEP_SLEEP_WAKEUP_DELAY=2000 +# CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM is not set +# CONFIG_ESP32S3_USE_FIXED_STATIC_RAM_SIZE is not set +# end of ESP32S3-Specific + +# +# ADC-Calibration +# +# end of ADC-Calibration + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +# end of Common ESP-related + +# +# Ethernet +# +CONFIG_ETH_ENABLED=y +CONFIG_ETH_USE_SPI_ETHERNET=y +# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set +# CONFIG_ETH_SPI_ETHERNET_W5500 is not set +# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set +# CONFIG_ETH_USE_OPENETH is not set +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +# end of GDB Stub + +# +# ESP HTTP client +# +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH=y +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_OTA_ALLOW_HTTP is not set +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +# end of ESP HTTPS server + +# +# Hardware Settings +# + +# +# MAC Config +# +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y +# CONFIG_ESP32S3_UNIVERSAL_MAC_ADDRESSES_TWO is not set +CONFIG_ESP32S3_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP32S3_UNIVERSAL_MAC_ADDRESSES=4 +# end of MAC Config + +# +# Sleep Config +# +# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set +CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND=y +CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y +CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU=y +CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y +# end of Sleep Config + +# +# RTC Clock Config +# +CONFIG_RTC_CLOCK_BBPLL_POWER_ON_WITH_USB=y +# end of RTC Clock Config +# end of Hardware Settings + +# +# IPC (Inter-Processor Call) +# +CONFIG_ESP_IPC_TASK_STACK_SIZE=1536 +CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y +CONFIG_ESP_IPC_ISR_ENABLE=y +# end of IPC (Inter-Processor Call) + +# +# LCD and Touch Panel +# + +# +# LCD Touch Drivers are maintained in the IDF Component Registry +# + +# +# LCD Peripheral Configuration +# +CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32 +# CONFIG_LCD_RGB_ISR_IRAM_SAFE is not set +# end of LCD Peripheral Configuration +# end of LCD and Touch Panel + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=y +# end of ESP NETIF Adapter + +# +# PHY +# +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP_PHY_MAX_TX_POWER=20 +# CONFIG_ESP_PHY_REDUCE_TX_POWER is not set +CONFIG_ESP_PHY_ENABLE_USB=y +CONFIG_ESP_PHY_RF_CAL_PARTIAL=y +# CONFIG_ESP_PHY_RF_CAL_NONE is not set +# CONFIG_ESP_PHY_RF_CAL_FULL is not set +CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# end of PHY + +# +# Power Management +# +# CONFIG_PM_ENABLE is not set +CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP=y +CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP=y +# end of Power Management + +# +# ESP Ringbuf +# +# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set +# CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH is not set +# end of ESP Ringbuf + +# +# ESP System Settings +# +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set +CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y +CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y + +# +# Memory protection +# +# end of Memory protection + +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 +CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y +# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set +# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_USB_CDC is not set +# CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG is not set +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +# CONFIG_ESP_CONSOLE_SECONDARY_NONE is not set +CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG=y +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_MULTIPLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +CONFIG_ESP_INT_WDT_CHECK_CPU1=y +CONFIG_ESP_TASK_WDT=y +CONFIG_ESP_TASK_WDT_PANIC=y +CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 +# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set +# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 is not set +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y +CONFIG_ESP_SYSTEM_BBPLL_RECALIB=y +# end of ESP System Settings + +# +# High resolution timer (esp_timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set +CONFIG_ESP_TIMER_IMPL_SYSTIMER=y +# end of High resolution timer (esp_timer) + +# +# Wi-Fi +# +CONFIG_ESP32_WIFI_ENABLED=y +CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y +# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 +CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=6 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP32_WIFI_IRAM_OPT=y +CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +# CONFIG_ESP_WIFI_FTM_ENABLE is not set +# CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set +# CONFIG_ESP_WIFI_GCMP_SUPPORT is not set +# CONFIG_ESP_WIFI_GMAC_SUPPORT is not set +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set +CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# end of Wi-Fi + +# +# Core dump +# +CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_NONE is not set +# CONFIG_ESP_COREDUMP_DATA_FORMAT_BIN is not set +CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y +CONFIG_ESP_COREDUMP_CHECKSUM_CRC32=y +CONFIG_ESP_COREDUMP_CHECK_BOOT=y +CONFIG_ESP_COREDUMP_ENABLE=y +CONFIG_ESP_COREDUMP_LOGS=y +CONFIG_ESP_COREDUMP_MAX_TASKS_NUM=64 +CONFIG_ESP_COREDUMP_STACK_SIZE=0 +# end of Core dump + +# +# FAT Filesystem support +# +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_LFN_NONE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +# CONFIG_FATFS_USE_FASTSEEK is not set +# end of FAT Filesystem support + +# +# Modbus configuration +# +CONFIG_FMB_COMM_MODE_TCP_EN=y +CONFIG_FMB_TCP_PORT_DEFAULT=502 +CONFIG_FMB_TCP_PORT_MAX_CONN=5 +CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20 +CONFIG_FMB_COMM_MODE_RTU_EN=y +CONFIG_FMB_COMM_MODE_ASCII_EN=y +CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150 +CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_FMB_QUEUE_LENGTH=20 +CONFIG_FMB_PORT_TASK_STACK_SIZE=4096 +CONFIG_FMB_SERIAL_BUF_SIZE=256 +CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8 +CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000 +CONFIG_FMB_PORT_TASK_PRIO=10 +# CONFIG_FMB_PORT_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_FMB_PORT_TASK_AFFINITY_CPU0=y +# CONFIG_FMB_PORT_TASK_AFFINITY_CPU1 is not set +CONFIG_FMB_PORT_TASK_AFFINITY=0x0 +CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 +CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 +# CONFIG_FMB_TIMER_PORT_ENABLED is not set +# CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD is not set +# end of Modbus configuration + +# +# FreeRTOS +# +# CONFIG_FREERTOS_UNICORE is not set +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_TICK_SUPPORT_SYSTIMER=y +CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL1=y +# CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL3 is not set +CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y +# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set +# CONFIG_FREERTOS_ASSERT_DISABLE is not set +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +CONFIG_FREERTOS_ISR_STACKSIZE=2096 +# CONFIG_FREERTOS_LEGACY_HOOKS is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=4096 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +# CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH is not set +# end of FreeRTOS + +# +# Hardware Abstraction Layer (HAL) and Low Level (LL) +# +CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y +# CONFIG_HAL_ASSERTION_DISABLE is not set +# CONFIG_HAL_ASSERTION_SILIENT is not set +# CONFIG_HAL_ASSERTION_ENABLE is not set +CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 +# end of Hardware Abstraction Layer (HAL) and Low Level (LL) + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# end of Heap memory debugging + +# +# jsmn +# +# CONFIG_JSMN_PARENT_LINKS is not set +# CONFIG_JSMN_STRICT is not set +# end of jsmn + +# +# libsodium +# +# end of libsodium + +# +# Log output +# +# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set +CONFIG_LOG_DEFAULT_LEVEL_ERROR=y +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=1 +CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +# CONFIG_LOG_MAXIMUM_LEVEL_WARN is not set +# CONFIG_LOG_MAXIMUM_LEVEL_INFO is not set +# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set +# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set +CONFIG_LOG_MAXIMUM_LEVEL=1 +CONFIG_LOG_COLORS=y +CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set +# end of Log output + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# CONFIG_LWIP_NETIF_API is not set +CONFIG_LWIP_TCPIP_TASK_PRIO=18 +# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +CONFIG_LWIP_TIMERS_ONDEMAND=y +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +CONFIG_LWIP_SO_RCVBUF=y +# CONFIG_LWIP_NETBUF_RECVINFO is not set +CONFIG_LWIP_IP_DEFAULT_TTL=64 +CONFIG_LWIP_IP4_FRAG=y +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP4_REASSEMBLY is not set +# CONFIG_LWIP_IP6_REASSEMBLY is not set +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +# CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set +CONFIG_LWIP_ESP_GRATUITOUS_ARP=y +CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_ESP_MLDV6_REPORT=y +CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 + +# +# DHCP server +# +CONFIG_LWIP_DHCPS=y +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5760 +CONFIG_LWIP_TCP_WND_DEFAULT=5760 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 +CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 +# CONFIG_LWIP_TCP_SACK_OUT is not set +# CONFIG_LWIP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +# end of SNTP + +# +# DNS +# +CONFIG_LWIP_DNS_MAX_SERVERS=3 +# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set +# end of DNS + +CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y +# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set +CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y +# CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT is not set +# CONFIG_LWIP_HOOK_ND6_GET_GW_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +# end of Hooks + +# CONFIG_LWIP_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# CONFIG_MBEDTLS_DEBUG is not set + +# +# mbedTLS v2.28.x related +# +# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +CONFIG_MBEDTLS_ECDH_LEGACY_CONTEXT=y +# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set +CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y +# end of mbedTLS v2.28.x related + +# +# Certificate Bundle +# +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 +# end of Certificate Bundle + +CONFIG_MBEDTLS_ECP_RESTARTABLE=y +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_AES_USE_INTERRUPT=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set +CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA512_C=y +CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +# CONFIG_MBEDTLS_TLS_DISABLED is not set +CONFIG_MBEDTLS_TLS_SERVER=y +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +# CONFIG_MBEDTLS_PSK_MODES is not set +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +# CONFIG_MBEDTLS_SSL_PROTO_SSL3 is not set +CONFIG_MBEDTLS_SSL_PROTO_TLS1=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_X509_CHECK_KEY_USAGE=y +CONFIG_MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +# CONFIG_MBEDTLS_DES_C is not set +CONFIG_MBEDTLS_RC4_DISABLED=y +# CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT is not set +# CONFIG_MBEDTLS_RC4_ENABLED is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +# CONFIG_MBEDTLS_XTEA_C is not set +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C is not set + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set +# CONFIG_MBEDTLS_SECURITY_RISKS is not set +# end of mbedTLS + +# +# mDNS +# +CONFIG_MDNS_MAX_SERVICES=10 +CONFIG_MDNS_TASK_PRIORITY=1 +CONFIG_MDNS_TASK_STACK_SIZE=4096 +# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_MDNS_TASK_AFFINITY_CPU0=y +# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set +CONFIG_MDNS_TASK_AFFINITY=0x0 +CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 +# CONFIG_MDNS_STRICT_MODE is not set +CONFIG_MDNS_TIMER_PERIOD_MS=100 +# CONFIG_MDNS_NETWORKING_SOCKET is not set +CONFIG_MDNS_MULTIPLE_INSTANCE=y +# end of mDNS + +# +# ESP-MQTT Configurations +# +CONFIG_MQTT_PROTOCOL_311=y +CONFIG_MQTT_TRANSPORT_SSL=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +# end of Newlib + +# +# NVS +# +# CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# end of NVS + +# +# OpenSSL +# +# CONFIG_OPENSSL_DEBUG is not set +CONFIG_OPENSSL_ERROR_STACK=y +# CONFIG_OPENSSL_ASSERT_DO_NOTHING is not set +CONFIG_OPENSSL_ASSERT_EXIT=y +# end of OpenSSL + +# +# OpenThread +# +# CONFIG_OPENTHREAD_ENABLED is not set +# end of OpenThread + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y +# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set +# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# Main Flash configuration +# + +# +# Optional and Experimental Features (READ DOCS FIRST) +# + +# +# Features here require specific hardware (READ DOCS FIRST!) +# +# CONFIG_SPI_FLASH_HPM_ENA is not set +CONFIG_SPI_FLASH_HPM_AUTO=y +# CONFIG_SPI_FLASH_HPM_DIS is not set +CONFIG_SPI_FLASH_HPM_ON=y +CONFIG_SPI_FLASH_HPM_DC_AUTO=y +# CONFIG_SPI_FLASH_HPM_DC_DISABLE is not set +# end of Optional and Experimental Features (READ DOCS FIRST) +# end of Main Flash configuration + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +# CONFIG_SPI_FLASH_ROM_IMPL is not set +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_USE_LEGACY_IMPL is not set +# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_TH_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP=y +# end of Auto-detect flash chips + +CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +CONFIG_WS_TRANSPORT=y +CONFIG_WS_BUFFER_SIZE=1024 +# end of Websocket +# end of TCP Transport + +# +# TinyUSB Stack +# +# CONFIG_TINYUSB is not set +# end of TinyUSB Stack + +# +# Unity unit testing library +# +CONFIG_UNITY_ENABLE_FLOAT=y +CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_64BIT is not set +# CONFIG_UNITY_ENABLE_COLOR is not set +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# USB-OTG +# +CONFIG_USB_OTG_SUPPORTED=y +CONFIG_USB_HOST_CONTROL_TRANSFER_MAX_SIZE=256 +CONFIG_USB_HOST_HW_BUFFER_BIAS_BALANCED=y +# CONFIG_USB_HOST_HW_BUFFER_BIAS_IN is not set +# CONFIG_USB_HOST_HW_BUFFER_BIAS_PERIODIC_OUT is not set + +# +# Root Hub configuration +# +CONFIG_USB_HOST_DEBOUNCE_DELAY_MS=250 +CONFIG_USB_HOST_RESET_HOLD_MS=30 +CONFIG_USB_HOST_RESET_RECOVERY_MS=30 +CONFIG_USB_HOST_SET_ADDR_RECOVERY_MS=10 +# end of Root Hub configuration +# end of USB-OTG + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_VFS_SUPPORT_TERMIOS=y + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# end of Host File System I/O (Semihosting) +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# CONFIG_WIFI_PROV_BLE_BONDING is not set +# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set +# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set +# end of Wi-Fi Provisioning Manager + +# +# Supplicant +# +CONFIG_WPA_MBEDTLS_CRYPTO=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_SUITE_B_192 is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# CONFIG_WPA_MBO_SUPPORT is not set +# CONFIG_WPA_DPP_SUPPORT is not set +# end of Supplicant +# end of Component config + +# +# Compatibility options +# +# CONFIG_LEGACY_INCLUDE_COMMON_HEADERS is not set +# end of Compatibility options + +# Deprecated options for backward compatibility +CONFIG_TOOLPREFIX="xtensa-esp32s3-elf-" +# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set +CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=3 +CONFIG_APP_ROLLBACK_ENABLE=y +# CONFIG_APP_ANTI_ROLLBACK is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set +CONFIG_FLASHMODE_QIO=y +# CONFIG_FLASHMODE_QOUT is not set +# CONFIG_FLASHMODE_DIO is not set +# CONFIG_FLASHMODE_DOUT is not set +# CONFIG_MONITOR_BAUD_9600B is not set +# CONFIG_MONITOR_BAUD_57600B is not set +CONFIG_MONITOR_BAUD_115200B=y +# CONFIG_MONITOR_BAUD_230400B is not set +# CONFIG_MONITOR_BAUD_921600B is not set +# CONFIG_MONITOR_BAUD_2MB is not set +# CONFIG_MONITOR_BAUD_OTHER is not set +CONFIG_MONITOR_BAUD_OTHER_VAL=115200 +CONFIG_MONITOR_BAUD=115200 +CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +CONFIG_CXX_EXCEPTIONS=y +CONFIG_CXX_EXCEPTIONS_EMG_POOL_SIZE=0 +CONFIG_STACK_CHECK_NONE=y +# CONFIG_STACK_CHECK_NORM is not set +# CONFIG_STACK_CHECK_STRONG is not set +# CONFIG_STACK_CHECK_ALL is not set +# CONFIG_WARN_WRITE_STRINGS is not set +# CONFIG_DISABLE_GCC8_WARNINGS is not set +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +CONFIG_BLUEDROID_ENABLED=y +# CONFIG_NIMBLE_ENABLED is not set +CONFIG_BTC_TASK_STACK_SIZE=3072 +CONFIG_BLUEDROID_PINNED_TO_CORE_0=y +# CONFIG_BLUEDROID_PINNED_TO_CORE_1 is not set +CONFIG_BLUEDROID_PINNED_TO_CORE=0 +CONFIG_BTU_TASK_STACK_SIZE=4352 +# CONFIG_BLUEDROID_MEM_DEBUG is not set +CONFIG_GATTS_ENABLE=y +# CONFIG_GATTS_SEND_SERVICE_CHANGE_MANUAL is not set +CONFIG_GATTS_SEND_SERVICE_CHANGE_AUTO=y +CONFIG_GATTS_SEND_SERVICE_CHANGE_MODE=0 +CONFIG_GATTC_ENABLE=y +# CONFIG_GATTC_CACHE_NVS_FLASH is not set +CONFIG_BLE_SMP_ENABLE=y +# CONFIG_SMP_SLAVE_CON_PARAMS_UPD_ENABLE is not set +# CONFIG_HCI_TRACE_LEVEL_NONE is not set +# CONFIG_HCI_TRACE_LEVEL_ERROR is not set +CONFIG_HCI_TRACE_LEVEL_WARNING=y +# CONFIG_HCI_TRACE_LEVEL_API is not set +# CONFIG_HCI_TRACE_LEVEL_EVENT is not set +# CONFIG_HCI_TRACE_LEVEL_DEBUG is not set +# CONFIG_HCI_TRACE_LEVEL_VERBOSE is not set +CONFIG_HCI_INITIAL_TRACE_LEVEL=2 +# CONFIG_BTM_TRACE_LEVEL_NONE is not set +# CONFIG_BTM_TRACE_LEVEL_ERROR is not set +CONFIG_BTM_TRACE_LEVEL_WARNING=y +# CONFIG_BTM_TRACE_LEVEL_API is not set +# CONFIG_BTM_TRACE_LEVEL_EVENT is not set +# CONFIG_BTM_TRACE_LEVEL_DEBUG is not set +# CONFIG_BTM_TRACE_LEVEL_VERBOSE is not set +CONFIG_BTM_INITIAL_TRACE_LEVEL=2 +# CONFIG_L2CAP_TRACE_LEVEL_NONE is not set +# CONFIG_L2CAP_TRACE_LEVEL_ERROR is not set +CONFIG_L2CAP_TRACE_LEVEL_WARNING=y +# CONFIG_L2CAP_TRACE_LEVEL_API is not set +# CONFIG_L2CAP_TRACE_LEVEL_EVENT is not set +# CONFIG_L2CAP_TRACE_LEVEL_DEBUG is not set +# CONFIG_L2CAP_TRACE_LEVEL_VERBOSE is not set +CONFIG_L2CAP_INITIAL_TRACE_LEVEL=2 +# CONFIG_RFCOMM_TRACE_LEVEL_NONE is not set +# CONFIG_RFCOMM_TRACE_LEVEL_ERROR is not set +CONFIG_RFCOMM_TRACE_LEVEL_WARNING=y +# CONFIG_RFCOMM_TRACE_LEVEL_API is not set +# CONFIG_RFCOMM_TRACE_LEVEL_EVENT is not set +# CONFIG_RFCOMM_TRACE_LEVEL_DEBUG is not set +# CONFIG_RFCOMM_TRACE_LEVEL_VERBOSE is not set +CONFIG_RFCOMM_INITIAL_TRACE_LEVEL=2 +# CONFIG_SDP_TRACE_LEVEL_NONE is not set +# CONFIG_SDP_TRACE_LEVEL_ERROR is not set +CONFIG_SDP_TRACE_LEVEL_WARNING=y +# CONFIG_SDP_TRACE_LEVEL_API is not set +# CONFIG_SDP_TRACE_LEVEL_EVENT is not set +# CONFIG_SDP_TRACE_LEVEL_DEBUG is not set +# CONFIG_SDP_TRACE_LEVEL_VERBOSE is not set +CONFIG_BTH_LOG_SDP_INITIAL_TRACE_LEVEL=2 +# CONFIG_GAP_TRACE_LEVEL_NONE is not set +# CONFIG_GAP_TRACE_LEVEL_ERROR is not set +CONFIG_GAP_TRACE_LEVEL_WARNING=y +# CONFIG_GAP_TRACE_LEVEL_API is not set +# CONFIG_GAP_TRACE_LEVEL_EVENT is not set +# CONFIG_GAP_TRACE_LEVEL_DEBUG is not set +# CONFIG_GAP_TRACE_LEVEL_VERBOSE is not set +CONFIG_GAP_INITIAL_TRACE_LEVEL=2 +CONFIG_BNEP_INITIAL_TRACE_LEVEL=2 +# CONFIG_PAN_TRACE_LEVEL_NONE is not set +# CONFIG_PAN_TRACE_LEVEL_ERROR is not set +CONFIG_PAN_TRACE_LEVEL_WARNING=y +# CONFIG_PAN_TRACE_LEVEL_API is not set +# CONFIG_PAN_TRACE_LEVEL_EVENT is not set +# CONFIG_PAN_TRACE_LEVEL_DEBUG is not set +# CONFIG_PAN_TRACE_LEVEL_VERBOSE is not set +CONFIG_PAN_INITIAL_TRACE_LEVEL=2 +# CONFIG_A2D_TRACE_LEVEL_NONE is not set +# CONFIG_A2D_TRACE_LEVEL_ERROR is not set +CONFIG_A2D_TRACE_LEVEL_WARNING=y +# CONFIG_A2D_TRACE_LEVEL_API is not set +# CONFIG_A2D_TRACE_LEVEL_EVENT is not set +# CONFIG_A2D_TRACE_LEVEL_DEBUG is not set +# CONFIG_A2D_TRACE_LEVEL_VERBOSE is not set +CONFIG_A2D_INITIAL_TRACE_LEVEL=2 +# CONFIG_AVDT_TRACE_LEVEL_NONE is not set +# CONFIG_AVDT_TRACE_LEVEL_ERROR is not set +CONFIG_AVDT_TRACE_LEVEL_WARNING=y +# CONFIG_AVDT_TRACE_LEVEL_API is not set +# CONFIG_AVDT_TRACE_LEVEL_EVENT is not set +# CONFIG_AVDT_TRACE_LEVEL_DEBUG is not set +# CONFIG_AVDT_TRACE_LEVEL_VERBOSE is not set +CONFIG_AVDT_INITIAL_TRACE_LEVEL=2 +# CONFIG_AVCT_TRACE_LEVEL_NONE is not set +# CONFIG_AVCT_TRACE_LEVEL_ERROR is not set +CONFIG_AVCT_TRACE_LEVEL_WARNING=y +# CONFIG_AVCT_TRACE_LEVEL_API is not set +# CONFIG_AVCT_TRACE_LEVEL_EVENT is not set +# CONFIG_AVCT_TRACE_LEVEL_DEBUG is not set +# CONFIG_AVCT_TRACE_LEVEL_VERBOSE is not set +CONFIG_AVCT_INITIAL_TRACE_LEVEL=2 +# CONFIG_AVRC_TRACE_LEVEL_NONE is not set +# CONFIG_AVRC_TRACE_LEVEL_ERROR is not set +CONFIG_AVRC_TRACE_LEVEL_WARNING=y +# CONFIG_AVRC_TRACE_LEVEL_API is not set +# CONFIG_AVRC_TRACE_LEVEL_EVENT is not set +# CONFIG_AVRC_TRACE_LEVEL_DEBUG is not set +# CONFIG_AVRC_TRACE_LEVEL_VERBOSE is not set +CONFIG_AVRC_INITIAL_TRACE_LEVEL=2 +# CONFIG_MCA_TRACE_LEVEL_NONE is not set +# CONFIG_MCA_TRACE_LEVEL_ERROR is not set +CONFIG_MCA_TRACE_LEVEL_WARNING=y +# CONFIG_MCA_TRACE_LEVEL_API is not set +# CONFIG_MCA_TRACE_LEVEL_EVENT is not set +# CONFIG_MCA_TRACE_LEVEL_DEBUG is not set +# CONFIG_MCA_TRACE_LEVEL_VERBOSE is not set +CONFIG_MCA_INITIAL_TRACE_LEVEL=2 +# CONFIG_HID_TRACE_LEVEL_NONE is not set +# CONFIG_HID_TRACE_LEVEL_ERROR is not set +CONFIG_HID_TRACE_LEVEL_WARNING=y +# CONFIG_HID_TRACE_LEVEL_API is not set +# CONFIG_HID_TRACE_LEVEL_EVENT is not set +# CONFIG_HID_TRACE_LEVEL_DEBUG is not set +# CONFIG_HID_TRACE_LEVEL_VERBOSE is not set +CONFIG_HID_INITIAL_TRACE_LEVEL=2 +# CONFIG_APPL_TRACE_LEVEL_NONE is not set +# CONFIG_APPL_TRACE_LEVEL_ERROR is not set +CONFIG_APPL_TRACE_LEVEL_WARNING=y +# CONFIG_APPL_TRACE_LEVEL_API is not set +# CONFIG_APPL_TRACE_LEVEL_EVENT is not set +# CONFIG_APPL_TRACE_LEVEL_DEBUG is not set +# CONFIG_APPL_TRACE_LEVEL_VERBOSE is not set +CONFIG_APPL_INITIAL_TRACE_LEVEL=2 +# CONFIG_GATT_TRACE_LEVEL_NONE is not set +# CONFIG_GATT_TRACE_LEVEL_ERROR is not set +CONFIG_GATT_TRACE_LEVEL_WARNING=y +# CONFIG_GATT_TRACE_LEVEL_API is not set +# CONFIG_GATT_TRACE_LEVEL_EVENT is not set +# CONFIG_GATT_TRACE_LEVEL_DEBUG is not set +# CONFIG_GATT_TRACE_LEVEL_VERBOSE is not set +CONFIG_GATT_INITIAL_TRACE_LEVEL=2 +# CONFIG_SMP_TRACE_LEVEL_NONE is not set +# CONFIG_SMP_TRACE_LEVEL_ERROR is not set +CONFIG_SMP_TRACE_LEVEL_WARNING=y +# CONFIG_SMP_TRACE_LEVEL_API is not set +# CONFIG_SMP_TRACE_LEVEL_EVENT is not set +# CONFIG_SMP_TRACE_LEVEL_DEBUG is not set +# CONFIG_SMP_TRACE_LEVEL_VERBOSE is not set +CONFIG_SMP_INITIAL_TRACE_LEVEL=2 +# CONFIG_BTIF_TRACE_LEVEL_NONE is not set +# CONFIG_BTIF_TRACE_LEVEL_ERROR is not set +CONFIG_BTIF_TRACE_LEVEL_WARNING=y +# CONFIG_BTIF_TRACE_LEVEL_API is not set +# CONFIG_BTIF_TRACE_LEVEL_EVENT is not set +# CONFIG_BTIF_TRACE_LEVEL_DEBUG is not set +# CONFIG_BTIF_TRACE_LEVEL_VERBOSE is not set +CONFIG_BTIF_INITIAL_TRACE_LEVEL=2 +# CONFIG_BTC_TRACE_LEVEL_NONE is not set +# CONFIG_BTC_TRACE_LEVEL_ERROR is not set +CONFIG_BTC_TRACE_LEVEL_WARNING=y +# CONFIG_BTC_TRACE_LEVEL_API is not set +# CONFIG_BTC_TRACE_LEVEL_EVENT is not set +# CONFIG_BTC_TRACE_LEVEL_DEBUG is not set +# CONFIG_BTC_TRACE_LEVEL_VERBOSE is not set +CONFIG_BTC_INITIAL_TRACE_LEVEL=2 +# CONFIG_OSI_TRACE_LEVEL_NONE is not set +# CONFIG_OSI_TRACE_LEVEL_ERROR is not set +CONFIG_OSI_TRACE_LEVEL_WARNING=y +# CONFIG_OSI_TRACE_LEVEL_API is not set +# CONFIG_OSI_TRACE_LEVEL_EVENT is not set +# CONFIG_OSI_TRACE_LEVEL_DEBUG is not set +# CONFIG_OSI_TRACE_LEVEL_VERBOSE is not set +CONFIG_OSI_INITIAL_TRACE_LEVEL=2 +# CONFIG_BLUFI_TRACE_LEVEL_NONE is not set +# CONFIG_BLUFI_TRACE_LEVEL_ERROR is not set +CONFIG_BLUFI_TRACE_LEVEL_WARNING=y +# CONFIG_BLUFI_TRACE_LEVEL_API is not set +# CONFIG_BLUFI_TRACE_LEVEL_EVENT is not set +# CONFIG_BLUFI_TRACE_LEVEL_DEBUG is not set +# CONFIG_BLUFI_TRACE_LEVEL_VERBOSE is not set +CONFIG_BLUFI_INITIAL_TRACE_LEVEL=2 +# CONFIG_BLE_HOST_QUEUE_CONGESTION_CHECK is not set +CONFIG_SMP_ENABLE=y +# CONFIG_BLE_ACTIVE_SCAN_REPORT_ADV_SCAN_RSP_INDIVIDUALLY is not set +CONFIG_BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT=30 +CONFIG_ADC2_DISABLE_DAC=y +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +# CONFIG_ESP_SYSTEM_PD_FLASH is not set +CONFIG_ESP32C3_LIGHTSLEEP_GPIO_RESET_WORKAROUND=y +CONFIG_IPC_TASK_STACK_SIZE=1536 +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP32_PHY_MAX_TX_POWER=20 +# CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set +CONFIG_ESP_SYSTEM_PM_POWER_DOWN_CPU=y +# CONFIG_ESP32S2_PANIC_PRINT_HALT is not set +CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32S2_PANIC_GDBSTUB is not set +CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP=y +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_MAIN_TASK_STACK_SIZE=3584 +CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART=y +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=300 +CONFIG_INT_WDT_CHECK_CPU1=y +CONFIG_TASK_WDT=y +CONFIG_TASK_WDT_PANIC=y +CONFIG_TASK_WDT_TIMEOUT_S=5 +# CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set +# CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1 is not set +# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set +CONFIG_TIMER_TASK_STACK_SIZE=3584 +CONFIG_SW_COEXIST_ENABLE=y +CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH=y +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE is not set +# CONFIG_ESP32_COREDUMP_DATA_FORMAT_BIN is not set +CONFIG_ESP32_COREDUMP_DATA_FORMAT_ELF=y +CONFIG_ESP32_COREDUMP_CHECKSUM_CRC32=y +CONFIG_ESP32_ENABLE_COREDUMP=y +CONFIG_ESP32_CORE_DUMP_MAX_TASKS_NUM=64 +CONFIG_ESP32_CORE_DUMP_STACK_SIZE=0 +CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=150 +CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_MB_QUEUE_LENGTH=20 +CONFIG_MB_SERIAL_TASK_STACK_SIZE=4096 +CONFIG_MB_SERIAL_BUF_SIZE=256 +CONFIG_MB_SERIAL_TASK_PRIO=10 +CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_MB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_MB_CONTROLLER_STACK_SIZE=4096 +CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 +# CONFIG_MB_TIMER_PORT_ENABLED is not set +# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +CONFIG_TIMER_TASK_PRIORITY=1 +CONFIG_TIMER_TASK_STACK_DEPTH=4096 +CONFIG_TIMER_QUEUE_LENGTH=10 +# CONFIG_L2_TO_L3_COPY is not set +# CONFIG_USE_ONLY_LWIP_SELECT is not set +CONFIG_ESP_GRATUITOUS_ARP=y +CONFIG_GARP_TMR_INTERVAL=60 +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=12 +CONFIG_TCP_MSS=1440 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5760 +CONFIG_TCP_WND_DEFAULT=5760 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +# CONFIG_ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set +CONFIG_TCP_OVERSIZE_MSS=y +# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_TCP_OVERSIZE_DISABLE is not set +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_PPP_SUPPORT is not set +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_ESP32_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set +CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +# CONFIG_USB_ENABLED is not set +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# End of deprecated options diff --git a/sdkconfig.defaults b/sdkconfig.defaults index 0f07dab5..503da6c0 100644 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -27,4 +27,12 @@ CONFIG_ESP_TASK_WDT_PANIC=y # panic/WDT reset. diagnostics.cpp already has the reader; this populates it so a # field crash backtrace can be pulled over USB (espcoredump.py) during testing. CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y -CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y \ No newline at end of file +CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y +# Watchdog scope: only the throttle control loop + its watchdog task explicitly +# subscribe to the Task WDT (see main.cpp). Do NOT also watch the idle tasks — +# with idle-task checking on, ANY non-safety task (UI/BMS/BLE/a cache-disabled +# NVS commit) that monopolizes a core for >5 s would panic-reboot a *flying* +# device, which the design explicitly forbids. A genuine throttle-loop stall +# still reboots via its own esp_task_wdt_add subscription. +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=n +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=n \ No newline at end of file diff --git a/src/sp140/ble/ble_core.cpp b/src/sp140/ble/ble_core.cpp index f7afbdf5..4fde6476 100644 --- a/src/sp140/ble/ble_core.cpp +++ b/src/sp140/ble/ble_core.cpp @@ -402,8 +402,12 @@ void requestFastConnParams() { if (pServer == nullptr || !deviceConnected) { return; } - // Tighten to 15ms interval for OTA throughput - pServer->updateConnParams(activeConnHandle, 12, 12, 0, 200); + // Tighten to 15ms interval for OTA throughput, but lengthen the supervision + // timeout to 8s (was 2s). A multi-second flash-erase stall or a sluggish phone + // must not drop the link at the link-layer level mid-flash. Slower recovery of + // a genuinely dead link is acceptable (OTA_TIMEOUT_MS=30s is the backstop); + // reliability of the flash matters more than fast dead-link detection. + pServer->updateConnParams(activeConnHandle, 12, 12, 0, 800); } void requestNormalConnParams() { diff --git a/src/sp140/ble/config_service.cpp b/src/sp140/ble/config_service.cpp index 8196d25b..f12b3288 100644 --- a/src/sp140/ble/config_service.cpp +++ b/src/sp140/ble/config_service.cpp @@ -18,11 +18,17 @@ #include "sp140/throttle.h" #include "version.h" #include "sp140/ble/ota_service.h" +#include "sp140/esc_config_relay.h" +#include "sp140/esc_flasher_relay.h" extern void writeDeviceData(); extern QueueHandle_t throttleUpdateQueue; extern volatile DeviceState currentState; +// ESC relay NOTIFY characteristic — the controller pushes status + result blob +// here (config-service GATT reads return null on this BLE stack). +static NimBLECharacteristic* pEscRelayNotifyCharacteristic = nullptr; + namespace { constexpr uint32_t kReadSecure = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_ENC; @@ -36,6 +42,10 @@ constexpr uint32_t kReadWriteNotifyIndicateSecure = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::NOTIFY | NIMBLE_PROPERTY::INDICATE | NIMBLE_PROPERTY::READ_ENC | NIMBLE_PROPERTY::WRITE_ENC; +// Write-without-response (plus plain write) on an encrypted link — used for the +// high-throughput ESC firmware data stream. +__attribute__((unused)) constexpr uint32_t kWriteNrSecure = +NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR | NIMBLE_PROPERTY::WRITE_ENC; class MetricAltCallbacks : public NimBLECharacteristicCallbacks { void onWrite(NimBLECharacteristic* characteristic, NimBLEConnInfo& connInfo) override { @@ -260,6 +270,173 @@ class MetricTempCallbacks : public NimBLECharacteristicCallbacks { } }; +// ESC config relay command characteristic. The app writes an opcode-multiplexed +// payload; we parse it and hand a single-parameter request to the relay module, +// which runs the write/save/restart/verify on the throttle task (CAN owner). +// 0x10 SET_PARAM / 0x1F SET_AND_COMMIT : [op][config_id u16 LE][len u8][data...] +// The DISARMED gate is enforced inside the relay (status reports REJECTED_ARMED). +class EscRelayCmdCallbacks : public NimBLECharacteristicCallbacks { + void onWrite(NimBLECharacteristic* characteristic, NimBLEConnInfo& connInfo) override { + (void)connInfo; + std::string value = characteristic->getValue(); + if (value.size() < 1) return; + const uint8_t op = static_cast(value[0]); + switch (op) { + case 0x10: // SET_PARAM (single param, write + commit + verify) + case 0x1F: { // SET_AND_COMMIT + if (value.size() < 4) return; // op + config_id(2) + len(1) + uint16_t configId = static_cast(value[1]) | + (static_cast(static_cast(value[2])) << 8); + uint8_t len = static_cast(value[3]); + if (len > 48 || value.size() < static_cast(4 + len)) return; + bool accepted = escConfigRelayRequestSetParam( + configId, reinterpret_cast(value.data()) + 4, len); + USBSerial.printf("ESC relay cmd op=0x%02X id=0x%04X len=%d accepted=%d\n", + op, configId, len, accepted); + break; + } + case 0x30: { // READ_ALL parameters + bool accepted = escConfigRelayRequestReadAll(); + USBSerial.printf("ESC relay READ_ALL accepted=%d\n", accepted); + break; + } + case 0x40: { // BATCH_BEGIN — clear the staging buffer + bool accepted = escConfigRelayBatchBegin(); + USBSerial.printf("ESC relay BATCH_BEGIN accepted=%d\n", accepted); + break; + } + case 0x41: { // BATCH_ADD — [op][config_id u16][len u8][data...] + if (value.size() < 4) return; + uint16_t configId = static_cast(value[1]) | + (static_cast(static_cast(value[2])) << 8); + uint8_t len = static_cast(value[3]); + if (len > 48 || value.size() < static_cast(4 + len)) return; + escConfigRelayBatchAdd(configId, + reinterpret_cast(value.data()) + 4, len); + break; + } + case 0x42: { // BATCH_COMMIT — run write-all + save + restart + verify + bool accepted = escConfigRelayRequestBatchCommit(); + USBSerial.printf("ESC relay BATCH_COMMIT accepted=%d\n", accepted); + break; + } + default: + USBSerial.printf("ESC relay: unknown opcode 0x%02X\n", op); + break; + } + } +}; + +// ESC parameter read-all result fetch. The app writes [offset u32 LE] to set the +// read cursor, then reads back up to ~240 bytes of the result blob from there. +class EscParamDataCallbacks : public NimBLECharacteristicCallbacks { + uint32_t offset_ = 0; + + void onWrite(NimBLECharacteristic* characteristic, NimBLEConnInfo& connInfo) override { + (void)connInfo; + std::string value = characteristic->getValue(); + if (value.size() < 4) return; + offset_ = static_cast(static_cast(value[0])) | + (static_cast(static_cast(value[1])) << 8) | + (static_cast(static_cast(value[2])) << 16) | + (static_cast(static_cast(value[3])) << 24); + } + + void onRead(NimBLECharacteristic* characteristic, NimBLEConnInfo& connInfo) override { + (void)connInfo; + uint8_t buf[240]; + uint16_t n = escConfigRelayReadResult(offset_, buf, sizeof(buf)); + characteristic->setValue(buf, n); + } +}; + +// ESC config relay status characteristic (read + notify). Returns the latched +// session status so the app can poll until a terminal result (the design's +// poll-until-terminal contract, which also survives a BLE drop + reconnect). +// [code][config_id u16 LE][phase][detail][progress u16 LE][readback...] +class EscRelayStatusCallbacks : public NimBLECharacteristicCallbacks { + void onRead(NimBLECharacteristic* characteristic, NimBLEConnInfo& connInfo) override { + (void)connInfo; + EscRelayStatus s = escConfigRelayGetStatus(); + uint8_t buf[16]; + buf[0] = static_cast(s.code); + buf[1] = s.config_id & 0xFF; + buf[2] = (s.config_id >> 8) & 0xFF; + buf[3] = static_cast(s.phase); + buf[4] = s.detail; + buf[5] = 0; // progress permille LSB (config = 0) + buf[6] = 0; // progress permille MSB + uint8_t n = (s.readback_len > 8) ? 8 : s.readback_len; + for (uint8_t i = 0; i < n; i++) buf[7 + i] = s.readback[i]; + characteristic->setValue(buf, 7 + n); + } +}; + +// ESC firmware relay control: opcodes from the app, status on read/notify. +// 0x20 FW_START : [0x20][hardware_id u16 LE][total_size u32 LE] +// 0x21 FW_END : [0x21] +// 0x22 FW_ABORT : [0x22] +// Status read layout: [code][phase][progress permille u16 LE]. +class EscFwCtrlCallbacks : public NimBLECharacteristicCallbacks { + void onWrite(NimBLECharacteristic* characteristic, NimBLEConnInfo& connInfo) override { + (void)connInfo; + std::string value = characteristic->getValue(); + if (value.size() < 1) return; + const uint8_t op = static_cast(value[0]); + switch (op) { + case 0x20: { // FW_START + if (value.size() < 7) return; // op + hwId(2) + size(4) + uint16_t hwId = static_cast(value[1]) | + (static_cast(static_cast(value[2])) << 8); + uint32_t size = static_cast(static_cast(value[3])) | + (static_cast(static_cast(value[4])) << 8) | + (static_cast(static_cast(value[5])) << 16) | + (static_cast(static_cast(value[6])) << 24); + bool ok = escFlasherRelayBegin(hwId, size); + USBSerial.printf("ESC FW START hwId=0x%04X size=%u ok=%d\n", hwId, size, ok); + break; + } + case 0x21: // FW_END + escFlasherRelayEnd(); + break; + case 0x22: // FW_ABORT + escFlasherRelayAbort(); + break; + default: + USBSerial.printf("ESC FW: unknown opcode 0x%02X\n", op); + break; + } + } + + void onRead(NimBLECharacteristic* characteristic, NimBLEConnInfo& connInfo) override { + (void)connInfo; + EscFwStatus s = escFlasherRelayGetStatus(); + uint8_t buf[4]; + buf[0] = static_cast(s.code); + buf[1] = static_cast(s.phase); + buf[2] = s.progressPermille & 0xFF; + buf[3] = (s.progressPermille >> 8) & 0xFF; + characteristic->setValue(buf, 4); + } +}; + +// ESC firmware image data: [offset u32 LE][image bytes...]. Write-no-response +// for throughput; the controller copies each chunk into its image buffer. +class EscFwDataCallbacks : public NimBLECharacteristicCallbacks { + void onWrite(NimBLECharacteristic* characteristic, NimBLEConnInfo& connInfo) override { + (void)connInfo; + std::string value = characteristic->getValue(); + if (value.size() < 4) return; // need at least the offset + uint32_t offset = static_cast(static_cast(value[0])) | + (static_cast(static_cast(value[1])) << 8) | + (static_cast(static_cast(value[2])) << 16) | + (static_cast(static_cast(value[3])) << 24); + const uint8_t* data = reinterpret_cast(value.data()) + 4; + uint16_t len = static_cast(value.size() - 4); + escFlasherRelayWriteChunk(offset, data, len); + } +}; + } // namespace void initConfigBleService(NimBLEServer* server, const std::string& uniqueId) { @@ -361,6 +538,41 @@ void initConfigBleService(NimBLEServer* server, const std::string& uniqueId) { static ThrottleValueCallbacks throttleValueCallbacks; pThrottleCharacteristic->setCallbacks(&throttleValueCallbacks); +#if 1 // ESC relay chars: all read/write/write-nr (NO notify) — zero CCCD footprint. + // ESC config relay: command (write) + status (read). + NimBLECharacteristic* escRelayCmd = configService->createCharacteristic( + NimBLEUUID(ESC_RELAY_CMD_UUID), kReadWriteSecure); + static EscRelayCmdCallbacks escRelayCmdCallbacks; + escRelayCmd->setCallbacks(&escRelayCmdCallbacks); + + NimBLECharacteristic* escRelayStatus = configService->createCharacteristic( + NimBLEUUID(ESC_RELAY_STATUS_UUID), kReadSecure); + static EscRelayStatusCallbacks escRelayStatusCallbacks; + escRelayStatus->setCallbacks(&escRelayStatusCallbacks); + + // ESC firmware relay: control (read status + write opcodes; NO notify) + data. + NimBLECharacteristic* escFwCtrl = configService->createCharacteristic( + NimBLEUUID(ESC_FW_CTRL_UUID), kReadWriteSecure); + static EscFwCtrlCallbacks escFwCtrlCallbacks; + escFwCtrl->setCallbacks(&escFwCtrlCallbacks); + + NimBLECharacteristic* escFwData = configService->createCharacteristic( + NimBLEUUID(ESC_FW_DATA_UUID), kWriteNrSecure); + static EscFwDataCallbacks escFwDataCallbacks; + escFwData->setCallbacks(&escFwDataCallbacks); + + // ESC parameter read-all result fetch (write offset, read chunk). + NimBLECharacteristic* escParamData = configService->createCharacteristic( + NimBLEUUID(ESC_PARAM_DATA_UUID), kReadWriteSecure); + static EscParamDataCallbacks escParamDataCallbacks; + escParamData->setCallbacks(&escParamDataCallbacks); + + // ESC relay NOTIFY: status + result-blob stream (GATT reads return null on + // this stack; notify is reliable). Pumped from the 50 Hz notify task. + pEscRelayNotifyCharacteristic = configService->createCharacteristic( + NimBLEUUID(ESC_RELAY_NOTIFY_UUID), kNotifyReadSecure); +#endif // ESC_RELAY_BLE_CHARS + NimBLEService* deviceInfoService = server->createService(NimBLEUUID(DEVICE_INFO_SERVICE_UUID)); NimBLECharacteristic* manufacturer = deviceInfoService->createCharacteristic( NimBLEUUID(MANUFACTURER_NAME_UUID), kReadSecure); @@ -389,3 +601,79 @@ void updateThrottleBLE(int value) { USBSerial.println("Error sending BLE notification"); } } + +// Push ESC relay status + stream the result blob over the notify characteristic. +// Called from the 50 Hz notify task. Config-service GATT reads return null on +// this BLE stack, so the result is delivered via notify (reliable, like +// telemetry). Frames: 0x01=STATUS[code][phase][detail][len u16], +// 0x02=DATA[offset u16][bytes]. The blob is streamed a few redundant passes +// because notify is lossy; the app reassembles by offset. +void pumpEscRelayNotify() { + if (pEscRelayNotifyCharacteristic == nullptr || !deviceConnected) return; + + static EscRelayStatusCode lastCode = EscRelayStatusCode::IDLE; + static uint8_t lastPhase = 0xFF; + static uint8_t lastDetail = 0xFF; + static uint16_t streamOffset = 0; + static uint8_t streamPass = 0; + static uint8_t terminalResend = 0; // redundant re-sends of a write's terminal status + constexpr uint8_t kStreamPasses = 3; + constexpr uint8_t kTerminalResends = 4; + + EscRelayStatus s = escConfigRelayGetStatus(); + + // During a read-all the code/phase stay READING while only the percent (detail) + // advances — so without this the app's progress would stick at 0%. Re-send when + // the read-all percentage changes too. + const bool readingProgressed = + (s.code == EscRelayStatusCode::READING) && (s.detail != lastDetail); + + // A write's terminal result (VERIFIED_OK or a failure code) is a single status + // change — but notify is lossy, and losing it would make a persisted write look + // like a timeout. Re-send terminal write statuses a few times for reliability. + const bool isTerminalWrite = + (s.code == EscRelayStatusCode::VERIFIED_OK) || + (static_cast(s.code) >= static_cast(EscRelayStatusCode::FAILED)); + + const bool changed = (s.code != lastCode || static_cast(s.phase) != lastPhase + || readingProgressed); + if (changed || (isTerminalWrite && terminalResend > 0)) { + if (changed) { + lastCode = s.code; + lastPhase = static_cast(s.phase); + lastDetail = s.detail; + terminalResend = isTerminalWrite ? kTerminalResends : 0; + } else { + terminalResend--; // redundant resend of an unchanged terminal status + } + uint8_t f[8]; + f[0] = 0x01; // STATUS + f[1] = static_cast(s.code); + f[2] = static_cast(s.phase); + f[3] = s.detail; + f[4] = s.config_id & 0xFF; // result blob length on READ_DONE + f[5] = (s.config_id >> 8) & 0xFF; + pEscRelayNotifyCharacteristic->setValue(f, 6); + pEscRelayNotifyCharacteristic->notify(); + if (s.code == EscRelayStatusCode::READ_DONE) { streamOffset = 0; streamPass = 0; } + } + + if (s.code == EscRelayStatusCode::READ_DONE && streamPass < kStreamPasses) { + const uint16_t total = escConfigRelayResultLen(); + if (total == 0) { streamPass = kStreamPasses; return; } + if (streamOffset >= total) { streamPass++; streamOffset = 0; return; } + // DATA frame carries the total length too, so the app can allocate from any + // chunk even if it missed the READ_DONE status notify (single-point loss). + uint8_t f[208]; + f[0] = 0x02; // DATA + f[1] = streamOffset & 0xFF; + f[2] = (streamOffset >> 8) & 0xFF; + f[3] = total & 0xFF; + f[4] = (total >> 8) & 0xFF; + uint16_t n = escConfigRelayReadResult(streamOffset, f + 5, 198); + if (n == 0) { streamPass++; streamOffset = 0; return; } + pEscRelayNotifyCharacteristic->setValue(f, 5 + n); + pEscRelayNotifyCharacteristic->notify(); + streamOffset += n; + } +} diff --git a/src/sp140/ble/fastlink_service.cpp b/src/sp140/ble/fastlink_service.cpp index cb435214..dc3c5d10 100644 --- a/src/sp140/ble/fastlink_service.cpp +++ b/src/sp140/ble/fastlink_service.cpp @@ -7,6 +7,8 @@ #include "sp140/ble/ble_ids.h" #include "sp140/ble/ota_service.h" #include "sp140/esc.h" // For requestEscHardwareInfo() +#include "sp140/esc_config_relay.h" // throttle telemetry during config relay +#include "sp140/esc_flasher_relay.h" // ... and firmware relay #include #include #include @@ -19,6 +21,12 @@ uint32_t gFastLinkSkippedNoConnCount = 0; uint32_t gFastLinkSkippedOtaCount = 0; uint32_t gFastLinkLastStatsMs = 0; uint32_t gFastLinkPacketId = 0; +// During OTA the normal ~50Hz telemetry stream is suppressed, but we still emit +// a low-rate keepalive so the phone's connection-health watchdog sees the link +// as alive (otherwise the central tears it down mid-flash -> HCI 0x13 / +// reason=531, aborting OTA ~20% in). +uint32_t gFastLinkLastOtaKeepaliveMs = 0; +constexpr uint32_t kOtaKeepaliveIntervalMs = 1000; constexpr uint32_t kFastLinkTelemetryProperties = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY | @@ -139,8 +147,29 @@ void updateFastLinkTelemetry(const BLE_FastLink_Telemetry &data) { if (pFastLinkCharacteristic != nullptr) { pFastLinkCharacteristic->setValue((uint8_t *)&data, sizeof(BLE_FastLink_Telemetry)); - if (isOtaInProgress()) { - ++gFastLinkSkippedOtaCount; + // Throttle the ~50Hz stream during OTA AND during an ESC config/firmware + // relay session (plus its short read-back settle window): at ~66Hz the + // notify flood saturates every connection event and starves the phone's + // config-service reads (status poll + result blob), so they never complete. + if (isOtaInProgress() || escConfigRelayResultPending() || escFlasherRelayIsActive()) { + // Suppress the full ~50Hz stream during OTA to give the flash bandwidth, + // but emit a ~1Hz keepalive notify so the central keeps the link up. The + // keepalive ships the packet just setValue()'d above, whose advancing + // packet_id/uptime_ms the app counts as telemetry progress. Wrap-safe + // unsigned subtraction. At 1Hz vs the 15ms OTA interval it does not + // meaningfully slow the flash. + const uint32_t nowMs = millis(); + if (deviceConnected && + (nowMs - gFastLinkLastOtaKeepaliveMs >= kOtaKeepaliveIntervalMs)) { + gFastLinkLastOtaKeepaliveMs = nowMs; + if (pFastLinkCharacteristic->notify()) { + ++gFastLinkNotifyOkCount; + } else { + ++gFastLinkNotifyFailCount; + } + } else { + ++gFastLinkSkippedOtaCount; + } } else if (deviceConnected) { const bool sent = pFastLinkCharacteristic->notify(); if (sent) { diff --git a/src/sp140/ble/ota_service.cpp b/src/sp140/ble/ota_service.cpp index 664535d8..a92550e7 100644 --- a/src/sp140/ble/ota_service.cpp +++ b/src/sp140/ble/ota_service.cpp @@ -3,6 +3,8 @@ #include #include "esp_ota_ops.h" #include "esp_partition.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" #include "sp140/ble/ble_core.h" #include "sp140/ble/ble_ids.h" #include "sp140/device_state.h" @@ -13,6 +15,33 @@ extern volatile DeviceState currentState; namespace { +// Serializes every OTA state mutation. The command/data write callbacks run on +// the NimBLE host task while checkOtaTimeout() runs on bleNotifyTask. Without +// this, a timeout-driven abort on bleNotifyTask could call esp_ota_abort() and +// resetOtaState() while a data callback is mid esp_ota_write() on the host task +// — a use-after-abort on updateHandle/sectorBuffer that corrupts flash/heap. +// abortOtaImpl() assumes the lock is already held; the public entry points +// (callbacks, checkOtaTimeout, abortOta) acquire it. +SemaphoreHandle_t otaStateMutex = nullptr; + +class OtaStateLock { + public: + explicit OtaStateLock(TickType_t timeout) { + if (otaStateMutex != nullptr) { + held_ = (xSemaphoreTake(otaStateMutex, timeout) == pdTRUE); + } + } + ~OtaStateLock() { + if (held_ && otaStateMutex != nullptr) { + xSemaphoreGive(otaStateMutex); + } + } + bool held() const { return held_; } + + private: + bool held_ = false; +}; + // Protocol Constants const uint16_t CMD_START = 0x0001; const uint16_t CMD_END = 0x0002; @@ -122,6 +151,15 @@ void abortOtaImpl(); void handleCmdStart(const uint8_t* data) { USBSerial.println("OTA: CMD_START"); + // A duplicate CMD_START (app restarted the transfer) would orphan the live + // esp_ota handle, because resetOtaState() below only zeroes updateHandle + // without esp_ota_abort(). Abort the previous session cleanly first. Runs + // under the OtaStateLock already held by OtaCommandCallback::onWrite. + if (otaInProgress) { + USBSerial.println("OTA: CMD_START during active update - aborting previous session"); + abortOtaImpl(); + } + if (currentState == ARMED || currentState == ARMED_CRUISING) { USBSerial.println("OTA Blocked: Device ARMED"); sendCommandResponse(CMD_START, 0x0001); @@ -164,6 +202,7 @@ void handleCmdStart(const uint8_t* data) { class OtaCommandCallback : public NimBLECharacteristicCallbacks { void onWrite(NimBLECharacteristic* pChar, NimBLEConnInfo& connInfo) override { + OtaStateLock lock(portMAX_DELAY); // serialize vs checkOtaTimeout (other task) std::string value = pChar->getValue(); // Command Packet: ID(2) + Payload(16) + CRC(2) = 20 bytes if (value.length() < 20) { @@ -222,6 +261,7 @@ class OtaCommandCallback : public NimBLECharacteristicCallbacks { class OtaDataCallback : public NimBLECharacteristicCallbacks { void onWrite(NimBLECharacteristic* pChar, NimBLEConnInfo& connInfo) override { + OtaStateLock lock(portMAX_DELAY); // serialize vs checkOtaTimeout (other task) if (!otaInProgress) return; std::string valStr = pChar->getValue(); @@ -323,9 +363,17 @@ static OtaDataCallback dataCallback; } // namespace -void abortOta() { abortOtaImpl(); } +void abortOta() { + // Called from the BLE disconnect callback (host task); lock vs checkOtaTimeout. + OtaStateLock lock(portMAX_DELAY); + abortOtaImpl(); +} void checkOtaTimeout() { + // Take the lock without waiting: if a host-task callback is mid-write the + // device is clearly not idle, so skip this tick rather than block or race. + OtaStateLock lock(0); + if (!lock.held()) return; if (otaInProgress && (millis() - lastOtaActivityMs > OTA_TIMEOUT_MS)) { USBSerial.println("OTA: Idle timeout, aborting."); abortOtaImpl(); @@ -337,6 +385,10 @@ bool isOtaInProgress() { } void initOtaBleService(NimBLEServer* pServer) { + if (otaStateMutex == nullptr) { + otaStateMutex = xSemaphoreCreateMutex(); + } + NimBLEService* pService = pServer->createService(OTA_SERVICE_UUID); // Firmware data (Write No Response + Indicate for ACKs) diff --git a/src/sp140/bms.cpp b/src/sp140/bms.cpp index 77664fc7..922f99af 100644 --- a/src/sp140/bms.cpp +++ b/src/sp140/bms.cpp @@ -50,8 +50,6 @@ void updateBMSData() { if (bms_can == nullptr || !bmsCanInitialized) return; // TODO track bms incrementing cycle count - // Ensure display CS is deselected and BMS CS is selected - digitalWrite(displayCS, HIGH); // Take the shared SPI mutex to prevent contention with TFT flush if (spiBusMutex != NULL) { if (xSemaphoreTake(spiBusMutex, pdMS_TO_TICKS(150)) != pdTRUE) { @@ -60,12 +58,25 @@ void updateBMSData() { return; // Use stale BMS data this cycle rather than hang } } + // Ensure display CS is deselected and BMS CS is selected. This must happen + // only AFTER the bus mutex is held: writing displayCS while a TFT flush is + // streaming pixels deselects the panel mid-transfer and the rest of that + // flush is silently lost, leaving stale bands on screen. + digitalWrite(displayCS, HIGH); digitalWrite(bmsCS, LOW); // USBSerial.println("Updating BMS Data"); unsigned long tStart = millis(); bms_can->update(); + // All SPI traffic happens inside update() — the getters below only read + // values the library cached in RAM. Release the bus first so a pending + // display flush waits only for the CAN drain, not the whole copy-out. + digitalWrite(bmsCS, HIGH); + if (spiBusMutex != NULL) { + xSemaphoreGive(spiBusMutex); + } + // Basic measurements bmsTelemetryData.battery_voltage = bms_can->getBatteryVoltage(); bmsTelemetryData.battery_current = bms_can->getBatteryCurrent(); @@ -117,16 +128,37 @@ void updateBMSData() { bms_can->getTemperature(4), bms_can->getTemperature(5) }; + // Latched: once a temperature frame has ever been parsed, keep applying the + // disconnect policy. Re-testing the live readings every cycle would mean a + // later all-NaN frame (BMS temperature subsystem failed, or the BMS rebooting + // and broadcasting zeros) silently disables the too-many-probes-disconnected + // critical — total loss of the temperature path must not be silent. + static bool tempFrameSeen = false; + if (!tempFrameSeen && + bmsTempFrameSeen(bmsTelemetryData.mos_temperature, + bmsTelemetryData.balance_temperature, cellTemps)) { + tempFrameSeen = true; + } + float sanitizedCellTemps[BMS_CELL_PROBE_COUNT]; - sanitizeCellProbeTemps(cellTemps, sanitizedCellTemps); + if (tempFrameSeen) { + sanitizeCellProbeTemps(cellTemps, sanitizedCellTemps); + // Emit transition logs to help field-debug intermittent probe wiring + // issues. Only once real temp data exists — otherwise every boot would + // log a spurious "reconnected" burst when the first frame arrives. + logBmsCellProbeConnectionTransitions(sanitizedCellTemps); + } else { + // No temperature frame parsed yet: pass NaN through so temp monitors + // stay silent instead of firing the -40 disconnect sentinel. + for (uint8_t i = 0; i < BMS_CELL_PROBE_COUNT; i++) { + sanitizedCellTemps[i] = cellTemps[i]; + } + } bmsTelemetryData.t1_temperature = sanitizedCellTemps[0]; bmsTelemetryData.t2_temperature = sanitizedCellTemps[1]; bmsTelemetryData.t3_temperature = sanitizedCellTemps[2]; bmsTelemetryData.t4_temperature = sanitizedCellTemps[3]; - // Emit transition logs to help field-debug intermittent probe wiring issues. - logBmsCellProbeConnectionTransitions(sanitizedCellTemps); - // Library already excludes disconnected probes from high/low temps bmsTelemetryData.highest_temperature = bms_can->getHighestTemperature(); bmsTelemetryData.lowest_temperature = bms_can->getLowestTemperature(); @@ -139,12 +171,6 @@ void updateBMSData() { USBSerial.println("ms"); } // printBMSData(); - - // Deselect BMS CS when done and release mutex - digitalWrite(bmsCS, HIGH); - if (spiBusMutex != NULL) { - xSemaphoreGive(spiBusMutex); - } } void printBMSData() { diff --git a/src/sp140/bms_monitors.cpp b/src/sp140/bms_monitors.cpp index 023e5648..48f37b9d 100644 --- a/src/sp140/bms_monitors.cpp +++ b/src/sp140/bms_monitors.cpp @@ -15,11 +15,15 @@ extern bool bmsCanInitialized; // A freshly-connected BMS reports zero-initialized fields (soc=0, all voltages // 0, discharge-MOS=false) until its first data frames are parsed — which looks // exactly like a dead, critically-low pack and fired spurious CRIT_LOW / MOS-off -// alarms on every connect. Treat readings as "no data" until the pack-voltage -// frame proves real telemetry has arrived. A real pack (even deeply discharged) -// sits far above this 5 V floor, so this never masks a genuine low condition. -// SensorMonitor skips NaN; the discharge-MOS monitor reads its non-alerting -// state (true) until data is valid. +// alarms on every connect. bmsTask now holds bmsState at NOT_CONNECTED until +// the snapshot is coherent (see bmsSnapshotCoherent), so this guard is +// defense-in-depth against future changes to that gating. SensorMonitor skips +// NaN; the discharge-MOS monitor reads its non-alerting state (true) until data +// is valid. +// +// Deliberately checks pack voltage only. A per-cell floor here would NaN out +// every voltage reader on a pack with one collapsed cell — exactly the fault +// the low-cell and voltage-differential monitors exist to report. static constexpr float BMS_MIN_VALID_PACK_V = 5.0f; static inline bool bmsDataValid() { return monitoringBmsData.battery_voltage > BMS_MIN_VALID_PACK_V; diff --git a/src/sp140/device_settings.cpp b/src/sp140/device_settings.cpp index e7004242..f3b0df8b 100644 --- a/src/sp140/device_settings.cpp +++ b/src/sp140/device_settings.cpp @@ -7,6 +7,9 @@ #include "sp140/globals.h" #include "../../inc/sp140/esp32s3-config.h" #include // Add ESP32 Preferences library +#include // Raw NVS API for the batched (single-commit) write +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" #include "../../inc/sp140/throttle.h" #include "../../inc/sp140/diagnostics.h" @@ -75,6 +78,20 @@ const char* KEY_TIMEZONE_OFFSET = "tz_offset"; // Create a Preferences instance Preferences preferences; +// Serializes all NVS settings access. writeDeviceData() is reachable +// concurrently from the BLE host task (config-service onWrite callbacks), the +// button task (disarmSystem) and the serial task (parse_serial_command_line); +// the single shared NVS namespace was previously written with no lock, so two +// writers could interleave and silently lose/corrupt a settings write. Created +// once in refreshDeviceData() while still single-threaded in setup(). +static SemaphoreHandle_t s_prefsMutex = nullptr; + +static void prefsEnsureMutex() { + if (s_prefsMutex == nullptr) { + s_prefsMutex = xSemaphoreCreateMutex(); + } +} + namespace { constexpr size_t kWebSerialCommandBufferSize = 256; @@ -86,6 +103,10 @@ bool gWebSerialCommandOverflow = false; // Read saved data from Preferences void refreshDeviceData() { + // Create the NVS mutex now, while still single-threaded in setup(), so every + // later (multi-task) writeDeviceData() call takes an already-existing lock. + prefsEnsureMutex(); + // Try to initialize preferences, with corruption recovery if (!preferences.begin(PREFS_NAMESPACE, false)) { USBSerial.println(F("Failed to initialize Preferences - may be corrupted")); @@ -147,32 +168,54 @@ void refreshDeviceData() { USBSerial.println(F("Device data loaded from Preferences")); } -// Write to Preferences +// Write to NVS. Uses the raw NVS API (not the Preferences wrapper) so all 11 +// keys share ONE nvs_commit() instead of committing per key — a single flash +// transaction that, together with s_prefsMutex, removes any window in which a +// concurrent writer could observe or produce a torn/partial save. The key names +// and NVS value types here MATCH exactly what the Preferences getters in +// refreshDeviceData() expect (u8/u16/i32, and a 4-byte blob for the float), so +// data written by older firmware remains fully readable. void writeDeviceData() { - if (!preferences.begin(PREFS_NAMESPACE, false)) { - USBSerial.println(F("Failed to initialize Preferences for writing")); + prefsEnsureMutex(); + if (s_prefsMutex != nullptr) { + xSemaphoreTake(s_prefsMutex, portMAX_DELAY); + } + + nvs_handle_t handle = 0; + esp_err_t err = nvs_open(PREFS_NAMESPACE, NVS_READWRITE, &handle); + if (err != ESP_OK) { + USBSerial.println(F("Failed to open NVS for writing")); + if (s_prefsMutex != nullptr) { + xSemaphoreGive(s_prefsMutex); + } return; } - // Save all values to preferences with error checking bool success = true; - success &= (preferences.putUChar(KEY_VERSION_MAJOR, deviceData.version_major) > 0); - success &= (preferences.putUChar(KEY_VERSION_MINOR, deviceData.version_minor) > 0); - success &= (preferences.putUChar(KEY_SCREEN_ROTATION, deviceData.screen_rotation) > 0); - success &= (preferences.putFloat(KEY_SEA_PRESSURE, deviceData.sea_pressure) > 0); - success &= (preferences.putBool(KEY_METRIC_TEMP, deviceData.metric_temp) > 0); - success &= (preferences.putBool(KEY_METRIC_ALT, deviceData.metric_alt) > 0); - success &= (preferences.putUChar(KEY_PERFORMANCE_MODE, deviceData.performance_mode) > 0); - success &= (preferences.putUChar(KEY_THEME, deviceData.theme) > 0); - success &= (preferences.putUShort(KEY_ARMED_TIME, deviceData.armed_time) > 0); - success &= (preferences.putUChar(KEY_REVISION, deviceData.revision) > 0); - success &= (preferences.putInt(KEY_TIMEZONE_OFFSET, deviceData.timezone_offset) > 0); + success &= (nvs_set_u8(handle, KEY_VERSION_MAJOR, deviceData.version_major) == ESP_OK); + success &= (nvs_set_u8(handle, KEY_VERSION_MINOR, deviceData.version_minor) == ESP_OK); + success &= (nvs_set_u8(handle, KEY_SCREEN_ROTATION, deviceData.screen_rotation) == ESP_OK); + success &= (nvs_set_blob(handle, KEY_SEA_PRESSURE, &deviceData.sea_pressure, + sizeof(deviceData.sea_pressure)) == ESP_OK); + success &= (nvs_set_u8(handle, KEY_METRIC_TEMP, deviceData.metric_temp ? 1 : 0) == ESP_OK); + success &= (nvs_set_u8(handle, KEY_METRIC_ALT, deviceData.metric_alt ? 1 : 0) == ESP_OK); + success &= (nvs_set_u8(handle, KEY_PERFORMANCE_MODE, deviceData.performance_mode) == ESP_OK); + success &= (nvs_set_u8(handle, KEY_THEME, deviceData.theme) == ESP_OK); + success &= (nvs_set_u16(handle, KEY_ARMED_TIME, deviceData.armed_time) == ESP_OK); + success &= (nvs_set_u8(handle, KEY_REVISION, deviceData.revision) == ESP_OK); + success &= (nvs_set_i32(handle, KEY_TIMEZONE_OFFSET, deviceData.timezone_offset) == ESP_OK); + + // One commit for the whole settings blob. + success &= (nvs_commit(handle) == ESP_OK); + nvs_close(handle); + + if (s_prefsMutex != nullptr) { + xSemaphoreGive(s_prefsMutex); + } if (success) { - preferences.end(); USBSerial.println(F("Device data saved to Preferences")); } else { - preferences.end(); USBSerial.println(F("Warning: Some preferences may not have been saved correctly")); } } diff --git a/src/sp140/diagnostics.cpp b/src/sp140/diagnostics.cpp index 4e909362..4b06bf11 100644 --- a/src/sp140/diagnostics.cpp +++ b/src/sp140/diagnostics.cpp @@ -433,7 +433,8 @@ CoreDumpSummary diagReadCoreDumpSummary(DiagResetReason reason) { esp_core_dump_summary_t core_dump = {}; if (esp_core_dump_get_summary(&core_dump) == ESP_OK) { summary.valid = 1; - strncpy(summary.task, core_dump.exc_task, sizeof(summary.task) - 1); + memcpy(summary.task, core_dump.exc_task, sizeof(summary.task) - 1); + summary.task[sizeof(summary.task) - 1] = '\0'; summary.pc = core_dump.exc_pc; summary.exc_cause = core_dump.ex_info.exc_cause; summary.exc_vaddr = core_dump.ex_info.exc_vaddr; diff --git a/src/sp140/esc.cpp b/src/sp140/esc.cpp index 7c470503..9643ba29 100644 --- a/src/sp140/esc.cpp +++ b/src/sp140/esc.cpp @@ -1,5 +1,7 @@ #include "sp140/esc.h" #include "sp140/globals.h" +#include "sp140/esc_config_relay.h" +#include "sp140/esc_flasher_relay.h" #include #pragma GCC diagnostic ignored "-Wmissing-field-initializers" @@ -14,6 +16,9 @@ static CanardAdapter adapter; static uint8_t memory_pool[1024] __attribute__((aligned(8))); static SineEsc esc(adapter); + +// Expose the single shared adapter to the ESC config relay module. +CanardAdapter& escAdapter() { return adapter; } static unsigned long lastSuccessfulCommTimeMs = 0; // Store millis() time of last successful ESC comm // Flag set by requestEscHardwareInfo() (may be called from BLE task), // consumed safely inside readESCTelemetry() on the throttle task. @@ -206,6 +211,10 @@ void initESC() { esc.setThrottleSettings2(IdleThrottle_us); adapter.processTxRxOnce(); vTaskDelay(pdMS_TO_TICKS(20)); // Wait for ESC to process the command + + // Register the ESC config-relay + firmware-relay nodes on the shared adapter. + escConfigRelayInit(); + escFlasherRelayInit(); } /** @@ -337,6 +346,12 @@ void readESCTelemetry() { syncEscOutputs(); adapter.processTxRxOnce(); // Process CAN messages + + // Drive any in-flight ESC config-relay / firmware-relay session. Both run on + // the throttle task so all CAN traffic stays single-owner. Non-blocking; only + // one can be active at a time (mutually gated) and only when DISARMED. + escConfigRelayServiceTick(); + escFlasherRelayServiceTick(); } /** diff --git a/src/sp140/esc_config_relay.cpp b/src/sp140/esc_config_relay.cpp new file mode 100644 index 00000000..432a836e --- /dev/null +++ b/src/sp140/esc_config_relay.cpp @@ -0,0 +1,883 @@ +#include "sp140/esc_config_relay.h" + +#include +#include +#include +#include +#include + +#include "sp140/esc.h" // escAdapter() +#include "sp140/device_state.h" // DeviceState +#include "sp140/esc_flasher_relay.h" // escFlasherRelayIsActive() cross-gate +#include "sp140/esc_param_ids.h" // ESC_PARAM_IDS for read-all + +// Device arming state, owned by the device-state machine (same symbol the OTA +// service gates on — see ble/ota_service.cpp). Relay only runs when DISARMED. +extern volatile DeviceState currentState; + +// ============================================================================= +// SINE / Mad Motors vendor config service definitions +// (ported from powerpack-flash-qc/inc/esc_config_protocol.h — kept local so the +// controller does not depend on the flash-qc tree) +// ============================================================================= +#define SINE_ESC_SETCONFIG_ID 220 +#define SINE_ESC_SETCONFIG_SIGNATURE 0x8764693A96F2952EULL +#define SINE_ESC_GETCONFIG_ID 221 +#define SINE_ESC_GETCONFIG_SIGNATURE 0x2EEE28C9EB22CF0CULL +#define SINE_ESC_SAVECONFIG_ID 222 +#define SINE_ESC_SAVECONFIG_SIGNATURE 0xA3F15F80DDB60005ULL +#define SINE_ESC_PASSWORD_UNLOCK_ID 225 +#define SINE_ESC_PASSWORD_UNLOCK_SIGNATURE 0xB970F68E635BAD53ULL + +static const uint8_t ESC_CAN_NODE_ID = 0x20; // ESC's CAN node id (esc.cpp esc.begin(0x20)) +static const uint8_t CONFIG_HOST_NODE_ID = 0x40; // ESC restricts config access to host node 0x40 +static const uint8_t CTRL_NORMAL_NODE_ID = 0x01; // controller's normal CAN node id (esc.cpp LOCAL_NODE_ID) +static const char ESC_PASSWORD[] = "123456"; // confirmed via Mad Motors PC-tool capture + +// Per-request timing. Each tick (~20 ms) issues at most one request and polls +// for its response across subsequent ticks — never blocking. +static const unsigned long RELAY_TIMEOUT_MS = 200; // per-request response wait +// Array/curve params (int16[21]) come back as a multi-frame CAN transfer that +// takes much longer to reassemble than a single-frame scalar response; 200 ms +// is too short and they were getting marked timed-out and skipped during a +// read-all. Give array reads a longer window so all 115 params come back. +static const unsigned long RELAY_ARRAY_TIMEOUT_MS = 1200; +static const uint8_t RELAY_MAX_RETRIES = 8; +static const unsigned long REBOOT_WAIT_MS = 5000; // ESC reboot before it answers again +static const unsigned long WARMUP_WINDOW_MS = 9000; // probe window after reboot wait +static const unsigned long REUNLOCK_WINDOW_MS = 5000; // post-reboot unlock retries window +static const unsigned long PROBE_INTERVAL_MS = 400; +// While reading all params the device is DISARMED, so we can pump the CAN bus +// hard for a slice of each tick (process many params per tick) instead of one +// param per 20 ms control tick — that's the difference between a multi-second +// read and a sub-second one. Bounded so we still yield to the rest of the system. +static const unsigned long READ_TICK_BUDGET_MS = 12; + +// True for the SINE int16[21] curve params, which answer over a multi-frame +// transfer and therefore need RELAY_ARRAY_TIMEOUT_MS rather than the scalar wait. +static inline bool relayIsArrayParamId(uint16_t id) { + return id == 0x0140 || id == 0x0141 || // normal acc/dec curves + id == 0x060E || id == 0x060F || id == 0x0610; // speed curves +} + +// ============================================================================= +// Decoded responses (written on the throttle task from the Canard callback, +// read in the same task by the state machine — single-task, so plain statics). +// ============================================================================= +struct SetConfigResp { uint16_t recv_config_id; int8_t flag; }; +struct GetConfigResp { uint16_t recv_config_id; int8_t flag; uint8_t data[48]; uint8_t data_len; }; +struct SaveConfigResp { uint8_t save_success; uint8_t save_error; uint8_t state; }; +struct UnlockResp { uint16_t cmd_id; uint8_t flag; }; + +static volatile bool s_gotSet = false, s_gotGet = false, s_gotSave = false, s_gotUnlock = false; +static SetConfigResp s_setResp; +static GetConfigResp s_getResp; +static SaveConfigResp s_saveResp; +static UnlockResp s_unlockResp; + +static uint8_t s_tidSet = 0, s_tidGet = 0, s_tidSave = 0, s_tidUnlock = 0, s_tidRestart = 0; + +// ============================================================================= +// CanardAdapterNode that captures the ESC's config-service responses. +// Mirrors EscConfigNode in powerpack-flash-qc/src/esc_config.cpp. +// ============================================================================= +class EscConfigRelayNode : public CanardAdapterNode { + public: + explicit EscConfigRelayNode(CanardAdapter& adapter) : CanardAdapterNode(adapter) {} + void begin() { _beginNode(); } + CanardInstance* canard() { return _canard; } + + bool shouldAcceptTransfer(uint64_t* out_signature, + uint16_t data_type_id, + CanardTransferType transfer_type, + uint8_t source_node_id) override { + if (transfer_type != CanardTransferTypeResponse || source_node_id != ESC_CAN_NODE_ID) + return false; + switch (data_type_id) { + case SINE_ESC_SETCONFIG_ID: *out_signature = SINE_ESC_SETCONFIG_SIGNATURE; return true; + case SINE_ESC_GETCONFIG_ID: *out_signature = SINE_ESC_GETCONFIG_SIGNATURE; return true; + case SINE_ESC_SAVECONFIG_ID: *out_signature = SINE_ESC_SAVECONFIG_SIGNATURE; return true; + case SINE_ESC_PASSWORD_UNLOCK_ID:*out_signature = SINE_ESC_PASSWORD_UNLOCK_SIGNATURE; return true; + case UAVCAN_PROTOCOL_RESTARTNODE_REQUEST_ID: + *out_signature = UAVCAN_PROTOCOL_RESTARTNODE_REQUEST_SIGNATURE; return true; + default: return false; + } + } + + void onTransferReceived(CanardRxTransfer* t) override { + if (t->transfer_type != CanardTransferTypeResponse) return; + uint32_t ofs = 0; + switch (t->data_type_id) { + case SINE_ESC_SETCONFIG_ID: { + canardDecodeScalar(t, 0, 16, false, &s_setResp.recv_config_id); + int8_t flag = 0; canardDecodeScalar(t, 16, 8, true, &flag); + s_setResp.flag = flag; s_gotSet = true; + break; + } + case SINE_ESC_GETCONFIG_ID: { + canardDecodeScalar(t, 0, 16, false, &s_getResp.recv_config_id); + int8_t flag = 0; canardDecodeScalar(t, 16, 8, true, &flag); + s_getResp.flag = flag; ofs = 24; + uint16_t total_bits = (uint16_t)t->payload_len * 8; + s_getResp.data_len = 0; + while (ofs + 8 <= total_bits && s_getResp.data_len < 48) { + canardDecodeScalar(t, ofs, 8, false, &s_getResp.data[s_getResp.data_len]); + ofs += 8; s_getResp.data_len++; + } + s_gotGet = true; + break; + } + case SINE_ESC_SAVECONFIG_ID: { + canardDecodeScalar(t, 0, 8, false, &s_saveResp.save_success); + s_gotSave = true; + break; + } + case SINE_ESC_PASSWORD_UNLOCK_ID: { + canardDecodeScalar(t, 0, 16, false, &s_unlockResp.cmd_id); + canardDecodeScalar(t, 16, 8, false, &s_unlockResp.flag); + s_gotUnlock = true; + break; + } + default: break; + } + } +}; + +static EscConfigRelayNode* s_node = nullptr; + +// ============================================================================= +// Send helpers (all run on the throttle task) +// ============================================================================= +static void sendSetConfig(uint16_t config_id, const uint8_t* data, uint8_t len) { + uint8_t buffer[64]; + memset(buffer, 0, sizeof(buffer)); + uint32_t bit = 0; + canardEncodeScalar(buffer, bit, 16, &config_id); bit += 16; + for (uint8_t i = 0; i < len && i < 48; i++) { canardEncodeScalar(buffer, bit, 8, &data[i]); bit += 8; } + uint32_t payload_len = (bit + 7) / 8; + + CanardTxTransfer transfer = { + .transfer_type = CanardTransferTypeRequest, + .data_type_signature = SINE_ESC_SETCONFIG_SIGNATURE, + .data_type_id = SINE_ESC_SETCONFIG_ID, + .inout_transfer_id = &s_tidSet, + .priority = CANARD_TRANSFER_PRIORITY_HIGHEST, + .payload = buffer, + .payload_len = (uint16_t)payload_len + }; + canardRequestOrRespondObj(s_node->canard(), ESC_CAN_NODE_ID, &transfer); +} + +static void sendGetConfig(uint16_t config_id) { + uint8_t buffer[4]; + memset(buffer, 0, sizeof(buffer)); + canardEncodeScalar(buffer, 0, 16, &config_id); + + CanardTxTransfer transfer = { + .transfer_type = CanardTransferTypeRequest, + .data_type_signature = SINE_ESC_GETCONFIG_SIGNATURE, + .data_type_id = SINE_ESC_GETCONFIG_ID, + .inout_transfer_id = &s_tidGet, + .priority = CANARD_TRANSFER_PRIORITY_HIGHEST, + .payload = buffer, + .payload_len = 2 + }; + canardRequestOrRespondObj(s_node->canard(), ESC_CAN_NODE_ID, &transfer); +} + +static void sendSaveConfig() { + uint8_t buffer[4]; // empty payload, but pass a valid pointer + memset(buffer, 0, sizeof(buffer)); + CanardTxTransfer transfer = { + .transfer_type = CanardTransferTypeRequest, + .data_type_signature = SINE_ESC_SAVECONFIG_SIGNATURE, + .data_type_id = SINE_ESC_SAVECONFIG_ID, + .inout_transfer_id = &s_tidSave, + .priority = CANARD_TRANSFER_PRIORITY_HIGHEST, + .payload = buffer, + .payload_len = 0 + }; + canardRequestOrRespondObj(s_node->canard(), ESC_CAN_NODE_ID, &transfer); +} + +static void sendPasswordUnlock() { + uint8_t buffer[64]; + memset(buffer, 0, sizeof(buffer)); + uint16_t cmd_id = 0x0001; + uint32_t bit = 0; + canardEncodeScalar(buffer, bit, 16, &cmd_id); bit += 16; + uint8_t pwlen = (uint8_t)strlen(ESC_PASSWORD); + uint8_t pad = (pwlen < 10) ? 10 : pwlen; // zero-pad to 10 bytes (matches PC tool) + for (uint8_t i = 0; i < pad; i++) { + uint8_t c = (i < pwlen) ? (uint8_t)ESC_PASSWORD[i] : 0; + canardEncodeScalar(buffer, bit, 8, &c); bit += 8; + } + uint32_t payload_len = (bit + 7) / 8; + + CanardTxTransfer transfer = { + .transfer_type = CanardTransferTypeRequest, + .data_type_signature = SINE_ESC_PASSWORD_UNLOCK_SIGNATURE, + .data_type_id = SINE_ESC_PASSWORD_UNLOCK_ID, + .inout_transfer_id = &s_tidUnlock, + .priority = CANARD_TRANSFER_PRIORITY_HIGHEST, + .payload = buffer, + .payload_len = (uint16_t)payload_len + }; + canardRequestOrRespondObj(s_node->canard(), ESC_CAN_NODE_ID, &transfer); +} + +static void sendRestart() { + uavcan_protocol_RestartNodeRequest req; + req.magic_number = UAVCAN_PROTOCOL_RESTARTNODE_REQUEST_MAGIC_NUMBER; // 0xACCE551B1E + uint8_t buffer[UAVCAN_PROTOCOL_RESTARTNODE_REQUEST_MAX_SIZE]; + memset(buffer, 0, sizeof(buffer)); + uint32_t len = uavcan_protocol_RestartNodeRequest_encode(&req, buffer); + + CanardTxTransfer transfer = { + .transfer_type = CanardTransferTypeRequest, + .data_type_signature = UAVCAN_PROTOCOL_RESTARTNODE_REQUEST_SIGNATURE, + .data_type_id = UAVCAN_PROTOCOL_RESTARTNODE_REQUEST_ID, + .inout_transfer_id = &s_tidRestart, + .priority = CANARD_TRANSFER_PRIORITY_HIGHEST, + .payload = buffer, + .payload_len = (uint16_t)len + }; + canardRequestOrRespondObj(s_node->canard(), ESC_CAN_NODE_ID, &transfer); +} + +// ============================================================================= +// Session state +// ============================================================================= +static portMUX_TYPE s_mux = portMUX_INITIALIZER_UNLOCKED; + +// Pending request handoff (written by BLE task, consumed by throttle task). +static volatile bool s_reqPending = false; +static uint16_t s_reqId = 0; +static uint8_t s_reqData[48]; +static uint8_t s_reqLen = 0; + +// Default ON: the ESC requires host node 0x40 + password unlock for config +// access (confirmed on hardware — node 0x01 without unlock is ignored). +static volatile bool s_requireUnlock = true; + +static EscRelayPhase s_phase = EscRelayPhase::IDLE; +static EscRelayStatus s_status = {}; + +// Active session working set. +static uint16_t s_targetId = 0; +static uint8_t s_expData[48]; +static uint8_t s_expLen = 0; +static unsigned long s_lastSendMs = 0; +static unsigned long s_phaseStartMs = 0; +static unsigned long s_lastProbeMs = 0; +static uint8_t s_retries = 0; +static bool s_reUnlocked = false; + +// Read-all session state. +static volatile bool s_readReqPending = false; +static bool s_readMode = false; +static uint16_t s_readIndex = 0; +static uint8_t s_resultBlob[3072]; // tuples: [config_id u16][flag u8][len u8][data] +static uint16_t s_resultLen = 0; + +// Batch session state. Staging buffer holds [config_id u16][len u8][data[len]] +// tuples; the batch session writes them all, saves once, restarts once, verifies. +static volatile bool s_batchReqPending = false; +static bool s_batchMode = false; +static uint8_t s_batchBuf[2560]; +static uint16_t s_batchLen = 0; // bytes used in s_batchBuf +static uint16_t s_batchCount = 0; // number of staged params +static uint16_t s_batchOffset = 0; // walk cursor during write/verify iteration +static uint16_t s_batchIndex = 0; // staged-param index during iteration +static uint16_t s_batchMismatch = 0; // verify mismatches + +// Read the staged tuple at s_batchOffset. Returns false at end of buffer. +static bool batchCurrentTuple(uint16_t* id, const uint8_t** data, uint8_t* len) { + if (s_batchOffset + 3 > s_batchLen) return false; + uint16_t off = s_batchOffset; + *id = s_batchBuf[off] | (uint16_t)(s_batchBuf[off + 1] << 8); + *len = s_batchBuf[off + 2]; + *data = &s_batchBuf[off + 3]; + if (off + 3 + *len > s_batchLen) return false; + return true; +} + +static void batchAdvanceCursor(uint8_t len) { + s_batchOffset += 3 + len; + s_batchIndex++; +} + +// Telemetry-throttle settle window: after a session ends, keep telemetry notify +// suppressed for this long so the app can poll the final status and fetch the +// result blob over a quiet link (telemetry at ~66 Hz otherwise starves reads). +static volatile unsigned long s_terminalAtMs = 0; +static volatile bool s_hadSession = false; +static const unsigned long RESULT_SETTLE_MS = 9000; + +static void setStatus(EscRelayStatusCode code, EscRelayPhase phase, uint8_t detail) { + portENTER_CRITICAL(&s_mux); + s_status.code = code; + s_status.phase = phase; + s_status.config_id = s_targetId; + s_status.detail = detail; + portEXIT_CRITICAL(&s_mux); +} + +static void finishOk(const uint8_t* readback, uint8_t len) { + portENTER_CRITICAL(&s_mux); + s_status.code = EscRelayStatusCode::VERIFIED_OK; + s_status.phase = EscRelayPhase::DONE_OK; + s_status.config_id = s_targetId; + s_status.detail = 0; + s_status.readback_len = (len > 8) ? 8 : len; + for (uint8_t i = 0; i < s_status.readback_len; i++) s_status.readback[i] = readback[i]; + portEXIT_CRITICAL(&s_mux); + escAdapter().setLocalNodeId(CTRL_NORMAL_NODE_ID); // restore normal CAN identity + s_terminalAtMs = millis(); + s_hadSession = true; // open the telemetry-throttle settle window for read-back + s_phase = EscRelayPhase::DONE_OK; +} + +static void finishFail(EscRelayStatusCode code, uint8_t detail) { + setStatus(code, EscRelayPhase::DONE_FAIL, detail); + escAdapter().setLocalNodeId(CTRL_NORMAL_NODE_ID); // restore normal CAN identity + s_terminalAtMs = millis(); + s_hadSession = true; // open the telemetry-throttle settle window for read-back + s_phase = EscRelayPhase::DONE_FAIL; +} + +static bool dataMatches(const uint8_t* got, uint8_t gotLen, const uint8_t* exp, uint8_t expLen) { + if (gotLen < expLen) return false; + for (uint8_t i = 0; i < expLen; i++) { + if (got[i] != exp[i]) return false; + } + return true; +} + +// ---- read-all helpers ------------------------------------------------------- +static void readStoreTuple(uint16_t id, uint8_t flag, const uint8_t* data, uint8_t dlen) { + if ((uint32_t)s_resultLen + 4 + dlen > sizeof(s_resultBlob)) return; // drop if full + s_resultBlob[s_resultLen++] = id & 0xFF; + s_resultBlob[s_resultLen++] = (id >> 8) & 0xFF; + s_resultBlob[s_resultLen++] = flag; + s_resultBlob[s_resultLen++] = dlen; + if (dlen && data) { memcpy(&s_resultBlob[s_resultLen], data, dlen); s_resultLen += dlen; } +} + +static void finishReadDone() { + portENTER_CRITICAL(&s_mux); + s_status.code = EscRelayStatusCode::READ_DONE; + s_status.phase = EscRelayPhase::DONE_OK; + s_status.config_id = s_resultLen; // blob length for the app to fetch + s_status.detail = 100; + portEXIT_CRITICAL(&s_mux); + escAdapter().setLocalNodeId(CTRL_NORMAL_NODE_ID); // restore normal CAN identity + s_terminalAtMs = millis(); + s_hadSession = true; // open the telemetry-throttle settle window for read-back + s_phase = EscRelayPhase::DONE_OK; +} + +static void readAdvance(unsigned long now) { + s_readIndex++; + s_retries = 0; + s_gotGet = false; + if (s_readIndex >= ESC_PARAM_IDS_COUNT) { finishReadDone(); return; } + uint8_t pct = (uint8_t)((uint32_t)s_readIndex * 100 / ESC_PARAM_IDS_COUNT); + setStatus(EscRelayStatusCode::READING, EscRelayPhase::READING, pct); + sendGetConfig(ESC_PARAM_IDS[s_readIndex]); + s_lastSendMs = now; +} + +static void beginReadSession() { + escAdapter().setLocalNodeId(CONFIG_HOST_NODE_ID); + s_readMode = true; + s_batchMode = false; + s_readIndex = 0; + s_resultLen = 0; + s_retries = 0; + s_reUnlocked = false; + s_gotSet = s_gotGet = s_gotSave = s_gotUnlock = false; + if (s_requireUnlock) { + s_phase = EscRelayPhase::UNLOCK; + setStatus(EscRelayStatusCode::READING, EscRelayPhase::UNLOCK, 0); + sendPasswordUnlock(); + } else { + s_phase = EscRelayPhase::READING; + setStatus(EscRelayStatusCode::READING, EscRelayPhase::READING, 0); + sendGetConfig(ESC_PARAM_IDS[0]); + } + s_lastSendMs = millis(); +} + +static void beginSession(uint16_t id, const uint8_t* data, uint8_t len) { + // The ESC restricts config access to host node 0x40 — present as 0x40 for the + // session so the ESC accepts our requests and addresses its responses to us. + // Restored to 0x01 on every exit path (finishOk / finishFail). + escAdapter().setLocalNodeId(CONFIG_HOST_NODE_ID); + + s_readMode = false; + s_batchMode = false; + s_targetId = id; + s_expLen = (len > 48) ? 48 : len; + memcpy(s_expData, data, s_expLen); + s_retries = 0; + s_reUnlocked = false; + s_gotSet = s_gotGet = s_gotSave = s_gotUnlock = false; + + if (s_requireUnlock) { + s_phase = EscRelayPhase::UNLOCK; + setStatus(EscRelayStatusCode::RUNNING, EscRelayPhase::UNLOCK, 0); + sendPasswordUnlock(); + } else { + s_phase = EscRelayPhase::WRITE; + setStatus(EscRelayStatusCode::RUNNING, EscRelayPhase::WRITE, 0); + sendSetConfig(s_targetId, s_expData, s_expLen); + } + s_lastSendMs = millis(); +} + +// Start a batch session over the staged params: unlock -> SetConfig each -> +// SaveConfig once -> RestartNode -> verify each across the reboot. +static void beginBatchSession() { + escAdapter().setLocalNodeId(CONFIG_HOST_NODE_ID); + s_readMode = false; + s_batchMode = true; + s_batchOffset = 0; + s_batchIndex = 0; + s_batchMismatch = 0; + s_retries = 0; + s_reUnlocked = false; + s_gotSet = s_gotGet = s_gotSave = s_gotUnlock = false; + + // First staged tuple is the working target (used as the post-reboot probe id). + uint16_t id = 0; const uint8_t* d = nullptr; uint8_t len = 0; + if (batchCurrentTuple(&id, &d, &len)) { + s_targetId = id; s_expLen = len; memcpy(s_expData, d, len); + } + + if (s_requireUnlock) { + s_phase = EscRelayPhase::UNLOCK; + setStatus(EscRelayStatusCode::RUNNING, EscRelayPhase::UNLOCK, 0); + sendPasswordUnlock(); + } else { + s_phase = EscRelayPhase::BATCH_WRITE; + setStatus(EscRelayStatusCode::RUNNING, EscRelayPhase::BATCH_WRITE, 0); + if (d) sendSetConfig(id, d, len); + } + s_lastSendMs = millis(); +} + +// ============================================================================= +// Public API +// ============================================================================= +void escConfigRelayInit() { + if (!s_node) { + s_node = new EscConfigRelayNode(escAdapter()); + s_node->begin(); + } + s_phase = EscRelayPhase::IDLE; + s_status = {}; + s_status.code = EscRelayStatusCode::IDLE; + s_status.phase = EscRelayPhase::IDLE; +} + +void escConfigRelaySetRequireUnlock(bool require) { s_requireUnlock = require; } + +bool escConfigRelayIsActive() { + if (s_reqPending || s_readReqPending || s_batchReqPending) return true; + return s_phase != EscRelayPhase::IDLE && + s_phase != EscRelayPhase::DONE_OK && + s_phase != EscRelayPhase::DONE_FAIL; +} + +bool escConfigRelayResultPending() { + if (escConfigRelayIsActive()) return true; + if (!s_hadSession) return false; + return (millis() - s_terminalAtMs) < RESULT_SETTLE_MS; +} + +bool escConfigRelayRequestSetParam(uint16_t config_id, const uint8_t* data, uint8_t len) { + if (!s_node || len > 48 || data == nullptr) return false; + if (escConfigRelayIsActive() || escFlasherRelayIsActive()) return false; + + portENTER_CRITICAL(&s_mux); + s_reqId = config_id; + s_reqLen = len; + memcpy((void*)s_reqData, data, len); + s_reqPending = true; + s_status.code = EscRelayStatusCode::ACCEPTED; + s_status.config_id = config_id; + portEXIT_CRITICAL(&s_mux); + return true; +} + +bool escConfigRelayRequestReverseDirection(bool reversed) { + uint16_t v = reversed ? 1 : 0; + uint8_t d[2] = { (uint8_t)(v & 0xFF), (uint8_t)((v >> 8) & 0xFF) }; + return escConfigRelayRequestSetParam(ESC_PARAM_DIRECTION, d, 2); +} + +bool escConfigRelayRequestReadAll() { + if (!s_node) return false; + if (escConfigRelayIsActive() || escFlasherRelayIsActive()) return false; + portENTER_CRITICAL(&s_mux); + s_readReqPending = true; + s_status.code = EscRelayStatusCode::ACCEPTED; + portEXIT_CRITICAL(&s_mux); + return true; +} + +bool escConfigRelayBatchBegin() { + if (escConfigRelayIsActive() || escFlasherRelayIsActive()) return false; + portENTER_CRITICAL(&s_mux); + s_batchLen = 0; + s_batchCount = 0; + portEXIT_CRITICAL(&s_mux); + return true; +} + +bool escConfigRelayBatchAdd(uint16_t config_id, const uint8_t* data, uint8_t len) { + if (escConfigRelayIsActive() || escFlasherRelayIsActive()) return false; + if (data == nullptr || len == 0 || len > 48) return false; + if ((uint32_t)s_batchLen + 3 + len > sizeof(s_batchBuf)) return false; // full + portENTER_CRITICAL(&s_mux); + s_batchBuf[s_batchLen++] = config_id & 0xFF; + s_batchBuf[s_batchLen++] = (config_id >> 8) & 0xFF; + s_batchBuf[s_batchLen++] = len; + memcpy(&s_batchBuf[s_batchLen], data, len); + s_batchLen += len; + s_batchCount++; + portEXIT_CRITICAL(&s_mux); + return true; +} + +bool escConfigRelayRequestBatchCommit() { + if (!s_node || s_batchCount == 0) return false; + if (escConfigRelayIsActive() || escFlasherRelayIsActive()) return false; + portENTER_CRITICAL(&s_mux); + s_batchReqPending = true; + s_status.code = EscRelayStatusCode::ACCEPTED; + portEXIT_CRITICAL(&s_mux); + return true; +} + +uint16_t escConfigRelayResultLen() { return s_resultLen; } + +uint16_t escConfigRelayReadResult(uint32_t offset, uint8_t* out, uint16_t maxLen) { + if (!out || offset >= s_resultLen) return 0; + uint16_t avail = s_resultLen - (uint16_t)offset; + uint16_t n = (avail < maxLen) ? avail : maxLen; + memcpy(out, &s_resultBlob[offset], n); + return n; +} + +EscRelayStatus escConfigRelayGetStatus() { + EscRelayStatus copy; + portENTER_CRITICAL(&s_mux); + copy = s_status; + portEXIT_CRITICAL(&s_mux); + return copy; +} + +// ============================================================================= +// State machine — driven each throttle tick (~20 ms). NEVER blocks. +// ============================================================================= +void escConfigRelayServiceTick() { + if (!s_node) return; + + const bool terminal = (s_phase == EscRelayPhase::IDLE || + s_phase == EscRelayPhase::DONE_OK || + s_phase == EscRelayPhase::DONE_FAIL); + // Nothing to do: don't touch the CAN bus when fully idle (keeps the existing + // telemetry cadence undisturbed). + if (terminal && !s_reqPending && !s_readReqPending && !s_batchReqPending) return; + + // Pump CAN so responses to our requests are captured between ticks. + for (int i = 0; i < 6; i++) escAdapter().processTxRxOnce(); + + // --- pick up a new request only when idle/terminal ----------------------- + if (terminal) { + bool pending = false, readPending = false, batchPending = false; + uint16_t id = 0; uint8_t data[48]; uint8_t len = 0; + portENTER_CRITICAL(&s_mux); + if (s_reqPending) { + pending = true; id = s_reqId; len = s_reqLen; + memcpy(data, (const void*)s_reqData, len); + s_reqPending = false; + } else if (s_readReqPending) { + readPending = true; + s_readReqPending = false; + } else if (s_batchReqPending) { + batchPending = true; + s_batchReqPending = false; + } + portEXIT_CRITICAL(&s_mux); + if (!pending && !readPending && !batchPending) return; + + // Safety gate (defense in depth — the BLE handler also checks). + if (currentState != DISARMED) { + if (pending) s_targetId = id; + finishFail(EscRelayStatusCode::REJECTED_ARMED, 0); + return; + } + if (pending) beginSession(id, data, len); + else if (readPending) beginReadSession(); + else beginBatchSession(); + return; + } + + // Defense in depth: if the device arms while a session is in flight, abort + // immediately and stop driving the CAN bus. (The param may already be saved, + // but we will not continue restart/verify traffic once armed.) + if (currentState != DISARMED) { + finishFail(EscRelayStatusCode::REJECTED_ARMED, 0); + return; + } + + const unsigned long now = millis(); + // Array/curve params answer over a slower multi-frame transfer — give them a + // longer per-request window while reading; everything else uses the scalar wait. + unsigned long timeoutWindow = RELAY_TIMEOUT_MS; + if (s_phase == EscRelayPhase::READING && s_readIndex < ESC_PARAM_IDS_COUNT && + relayIsArrayParamId(ESC_PARAM_IDS[s_readIndex])) { + timeoutWindow = RELAY_ARRAY_TIMEOUT_MS; + } + const bool timedOut = (now - s_lastSendMs) > timeoutWindow; + + switch (s_phase) { + // --------------------------------------------------------------------- + case EscRelayPhase::UNLOCK: + if (s_gotUnlock) { + s_retries = 0; + if (s_readMode) { + s_phase = EscRelayPhase::READING; + setStatus(EscRelayStatusCode::READING, EscRelayPhase::READING, 0); + s_gotGet = false; + sendGetConfig(ESC_PARAM_IDS[0]); + } else if (s_batchMode) { + s_phase = EscRelayPhase::BATCH_WRITE; + setStatus(EscRelayStatusCode::RUNNING, EscRelayPhase::BATCH_WRITE, 0); + s_gotSet = false; + uint16_t id; const uint8_t* d; uint8_t len; + if (batchCurrentTuple(&id, &d, &len)) sendSetConfig(id, d, len); + } else { + s_phase = EscRelayPhase::WRITE; + setStatus(EscRelayStatusCode::RUNNING, EscRelayPhase::WRITE, 0); + s_gotSet = false; + sendSetConfig(s_targetId, s_expData, s_expLen); + } + s_lastSendMs = now; + } else if (timedOut) { + if (s_retries++ < RELAY_MAX_RETRIES) { + s_gotUnlock = false; sendPasswordUnlock(); s_lastSendMs = now; + } else { + finishFail(EscRelayStatusCode::TIMEOUT, 0); + } + } + break; + + // --------------------------------------------------------------------- + // READING: read-all — GetConfig each param into the result blob. + case EscRelayPhase::READING: { + // Process as many params as fit in this tick's budget (disarmed → safe to + // busy-pump the bus). We still send one GetConfig at a time and wait for + // its response, but with short sub-tick waits instead of a full 20 ms tick. + const unsigned long deadline = now + READ_TICK_BUDGET_MS; + for (;;) { + if (s_gotGet) { + readStoreTuple(ESC_PARAM_IDS[s_readIndex], (uint8_t)s_getResp.flag, + s_getResp.data, s_getResp.data_len); + readAdvance(millis()); // store + send next GetConfig + if (s_phase != EscRelayPhase::READING) break; // finished (node restored) + escAdapter().processTxRxOnce(); // push the next request out + } else { + const unsigned long win = relayIsArrayParamId(ESC_PARAM_IDS[s_readIndex]) + ? RELAY_ARRAY_TIMEOUT_MS : RELAY_TIMEOUT_MS; + if ((millis() - s_lastSendMs) > win) { + if (s_retries++ < RELAY_MAX_RETRIES) { + s_gotGet = false; sendGetConfig(ESC_PARAM_IDS[s_readIndex]); s_lastSendMs = millis(); + } else { + readStoreTuple(ESC_PARAM_IDS[s_readIndex], 0xFF, nullptr, 0); // timed out — skip + readAdvance(millis()); + if (s_phase != EscRelayPhase::READING) break; + } + } + escAdapter().processTxRxOnce(); // drain RX — response may arrive + delayMicroseconds(150); + } + if (millis() >= deadline) break; // yield; resume next tick + } + break; + } + + // --------------------------------------------------------------------- + // BATCH_WRITE: SetConfig every staged param, then SaveConfig once. + case EscRelayPhase::BATCH_WRITE: { + uint16_t id; const uint8_t* d; uint8_t len; + if (!batchCurrentTuple(&id, &d, &len)) { + // All params written — persist once. + s_phase = EscRelayPhase::SAVE; + setStatus(EscRelayStatusCode::RUNNING, EscRelayPhase::SAVE, 0); + s_retries = 0; s_gotSave = false; sendSaveConfig(); s_lastSendMs = now; + break; + } + if (s_gotSet) { + int8_t flag = s_setResp.flag; + bool ok = (s_setResp.recv_config_id == id) && (flag == 0 || flag == 6 || flag == 7); + if (ok) { + batchAdvanceCursor(len); s_retries = 0; s_gotSet = false; + uint8_t pct = (uint8_t)((uint32_t)s_batchIndex * 100 / (s_batchCount ? s_batchCount : 1)); + setStatus(EscRelayStatusCode::RUNNING, EscRelayPhase::BATCH_WRITE, pct); + uint16_t nid; const uint8_t* nd; uint8_t nlen; + if (batchCurrentTuple(&nid, &nd, &nlen)) { sendSetConfig(nid, nd, nlen); s_lastSendMs = now; } + } else if (s_retries++ < RELAY_MAX_RETRIES) { + s_gotSet = false; sendSetConfig(id, d, len); s_lastSendMs = now; + } else { + finishFail(EscRelayStatusCode::ESC_FLAG_ERROR, (uint8_t)flag); + } + } else if (timedOut) { + if (s_retries++ < RELAY_MAX_RETRIES) { s_gotSet = false; sendSetConfig(id, d, len); s_lastSendMs = now; } + else finishFail(EscRelayStatusCode::TIMEOUT, 0); + } + break; + } + + // --------------------------------------------------------------------- + // BATCH_VERIFY: after the reboot, GetConfig every staged param and confirm + // it persisted (byte-match). Mismatches are counted, not fatal per-param. + case EscRelayPhase::BATCH_VERIFY: { + uint16_t id; const uint8_t* d; uint8_t len; + if (!batchCurrentTuple(&id, &d, &len)) { + if (s_batchMismatch == 0) finishOk(nullptr, 0); + else finishFail(EscRelayStatusCode::VERIFY_MISMATCH, + (uint8_t)(s_batchMismatch > 255 ? 255 : s_batchMismatch)); + break; + } + if (s_gotGet) { + bool match = (s_getResp.recv_config_id == id) && (s_getResp.flag == 0) && + dataMatches(s_getResp.data, s_getResp.data_len, d, len); + if (!match) s_batchMismatch++; + batchAdvanceCursor(len); s_retries = 0; s_gotGet = false; + uint8_t pct = (uint8_t)((uint32_t)s_batchIndex * 100 / (s_batchCount ? s_batchCount : 1)); + setStatus(EscRelayStatusCode::RUNNING, EscRelayPhase::BATCH_VERIFY, pct); + uint16_t nid; const uint8_t* nd; uint8_t nlen; + if (batchCurrentTuple(&nid, &nd, &nlen)) { sendGetConfig(nid); s_lastSendMs = now; } + } else if (timedOut) { + if (s_retries++ < RELAY_MAX_RETRIES) { + s_gotGet = false; sendGetConfig(id); s_lastSendMs = now; + } else { + s_batchMismatch++; // gave up reading this one + batchAdvanceCursor(len); s_retries = 0; s_gotGet = false; + uint16_t nid; const uint8_t* nd; uint8_t nlen; + if (batchCurrentTuple(&nid, &nd, &nlen)) { sendGetConfig(nid); s_lastSendMs = now; } + } + } + break; + } + + // --------------------------------------------------------------------- + case EscRelayPhase::WRITE: + if (s_gotSet) { + int8_t flag = s_setResp.flag; + bool ok = (s_setResp.recv_config_id == s_targetId) && (flag == 0 || flag == 6 || flag == 7); + if (ok) { + s_phase = EscRelayPhase::SAVE; + setStatus(EscRelayStatusCode::RUNNING, EscRelayPhase::SAVE, 0); + s_retries = 0; + s_gotSave = false; + sendSaveConfig(); + s_lastSendMs = now; + } else if (s_retries++ < RELAY_MAX_RETRIES) { + s_gotSet = false; sendSetConfig(s_targetId, s_expData, s_expLen); s_lastSendMs = now; + } else { + finishFail(EscRelayStatusCode::ESC_FLAG_ERROR, (uint8_t)flag); + } + } else if (timedOut) { + if (s_retries++ < RELAY_MAX_RETRIES) { s_gotSet = false; sendSetConfig(s_targetId, s_expData, s_expLen); s_lastSendMs = now; } + else finishFail(EscRelayStatusCode::TIMEOUT, 0); + } + break; + + // --------------------------------------------------------------------- + case EscRelayPhase::SAVE: + if (s_gotSave) { + if (s_saveResp.save_success == 0) { + s_phase = EscRelayPhase::RESTART; + // fall through to RESTART on the next tick after sending below + setStatus(EscRelayStatusCode::REBOOTING, EscRelayPhase::RESTART, 0); + sendRestart(); + for (int i = 0; i < 10; i++) escAdapter().processTxRxOnce(); // flush, non-blocking + s_phase = EscRelayPhase::WAIT_REBOOT; + s_phaseStartMs = now; + s_lastProbeMs = 0; + } else { + finishFail(EscRelayStatusCode::FAILED, s_saveResp.save_success); + } + } else if (timedOut) { + if (s_retries++ < RELAY_MAX_RETRIES) { s_gotSave = false; sendSaveConfig(); s_lastSendMs = now; } + else finishFail(EscRelayStatusCode::TIMEOUT, 0); + } + break; + + // --------------------------------------------------------------------- + // WAIT_REBOOT: non-blocking. Wait for the ESC to reboot, (optionally) + // re-unlock, then probe with GetConfig until it answers; that answer IS + // the verification. + // --------------------------------------------------------------------- + case EscRelayPhase::WAIT_REBOOT: { + const unsigned long elapsed = now - s_phaseStartMs; + + // Phase A: give the ESC time to reboot before it answers. + if (elapsed < REBOOT_WAIT_MS) { + setStatus(EscRelayStatusCode::REBOOTING, EscRelayPhase::WAIT_REBOOT, 0); + break; + } + + // Phase B: re-unlock if required (password state is lost on reboot). + if (s_requireUnlock && !s_reUnlocked) { + if (now - s_lastSendMs > 500) { + s_gotUnlock = false; sendPasswordUnlock(); s_lastSendMs = now; + } + if (s_gotUnlock) { s_reUnlocked = true; } + if (elapsed > REBOOT_WAIT_MS + REUNLOCK_WINDOW_MS) { + finishFail(EscRelayStatusCode::TIMEOUT, 0); // post-reboot unlock failed + } + break; + } + + // Phase C (batch): the re-unlock above already proves the ESC is back, so + // go straight to verifying every staged param via GetConfig. + if (s_batchMode) { + s_batchOffset = 0; s_batchIndex = 0; s_batchMismatch = 0; + s_phase = EscRelayPhase::BATCH_VERIFY; + setStatus(EscRelayStatusCode::RUNNING, EscRelayPhase::BATCH_VERIFY, 0); + uint16_t id; const uint8_t* d; uint8_t len; + if (batchCurrentTuple(&id, &d, &len)) { s_gotGet = false; sendGetConfig(id); s_lastSendMs = now; } + break; + } + + // Phase C: probe / verify. + setStatus(EscRelayStatusCode::RUNNING, EscRelayPhase::VERIFY, 0); + if (now - s_lastProbeMs > PROBE_INTERVAL_MS) { + s_gotGet = false; + sendGetConfig(s_targetId); + s_lastProbeMs = now; + } + if (s_gotGet && s_getResp.recv_config_id == s_targetId && s_getResp.flag == 0) { + if (dataMatches(s_getResp.data, s_getResp.data_len, s_expData, s_expLen)) { + finishOk(s_getResp.data, s_getResp.data_len); + } else { + finishFail(EscRelayStatusCode::VERIFY_MISMATCH, 0); + } + break; + } + if (elapsed > REBOOT_WAIT_MS + WARMUP_WINDOW_MS) { + finishFail(EscRelayStatusCode::TIMEOUT, 0); // ESC never answered after reboot + } + break; + } + + default: + break; + } +} diff --git a/src/sp140/esc_flasher_relay.cpp b/src/sp140/esc_flasher_relay.cpp new file mode 100644 index 00000000..22df9e27 --- /dev/null +++ b/src/sp140/esc_flasher_relay.cpp @@ -0,0 +1,524 @@ +#include "sp140/esc_flasher_relay.h" + +#include +#include +#include +#include +#include +#include +#include "esp_heap_caps.h" + +#include "sp140/esc.h" // escAdapter(), escTelemetryData +#include "sp140/device_state.h" // DeviceState +#include "sp140/esc_config_relay.h" // escConfigRelayIsActive() cross-gate + +extern volatile DeviceState currentState; + +static const uint8_t ESC_CAN_NODE_ID = 0x20; +static const uint8_t CONFIG_HOST_NODE_ID = 0x40; // ESC restricts bootloader/config to host 0x40 +static const uint8_t CTRL_NORMAL_NODE_ID = 0x01; // controller's normal CAN node id +static const uint16_t FW_CHUNK_SIZE = 256; // SendFwData payload (matches flash-qc) +static const unsigned long FW_TIMEOUT_MS = 150; // per-request response wait +static const uint8_t FW_MAX_RETRIES = 10; +static const unsigned long REBOOT_WAIT_MS = 700; // ESC reboot before bootloader answers +static const unsigned long RX_TIMEOUT_MS = 15000; // abort if the app stalls mid-transfer +static const uint32_t MAX_IMAGE_SIZE = 256u * 1024u; // sanity cap +static const uint32_t HEADER_SIZE = 32; // firmware data starts at byte 32 + +// ============================================================================= +// Response capture (decoded on the throttle task inside processTxRxOnce). +// ============================================================================= +static volatile bool s_gotResponse = false; +static volatile uint8_t s_responseState = 0xFF; +static volatile uint16_t s_responseNextIndex = 0; +static volatile uint8_t s_bootMode = 0; + +static uint8_t s_tidRestart = 0, s_tidBoot = 0, s_tidStart = 0, s_tidData = 0, s_tidEnd = 0; + +// ============================================================================= +// CanardAdapterNode capturing the bootloader-protocol responses. +// Mirrors EscFlasherNode in powerpack-flash-qc/src/esc_flasher.cpp. +// ============================================================================= +class EscFlasherRelayNode : public CanardAdapterNode { + public: + explicit EscFlasherRelayNode(CanardAdapter& adapter) : CanardAdapterNode(adapter) {} + void begin() { _beginNode(); } + CanardInstance* canard() { return _canard; } + + bool shouldAcceptTransfer(uint64_t* out_signature, + uint16_t data_type_id, + CanardTransferType transfer_type, + uint8_t source_node_id) override { + if (transfer_type != CanardTransferTypeResponse || source_node_id != ESC_CAN_NODE_ID) + return false; + switch (data_type_id) { + case SINE_ESC_GETBOOTSTATUS_ID: *out_signature = SINE_ESC_GETBOOTSTATUS_SIGNATURE; return true; + case SINE_ESC_STARTFWUPGRADE_ID: *out_signature = SINE_ESC_STARTFWUPGRADE_SIGNATURE; return true; + case SINE_ESC_SENDFWDATA_RESPONSE_ID: *out_signature = SINE_ESC_SENDFWDATA_RESPONSE_SIGNATURE; return true; + case SINE_ESC_ENDFWUPGRADE_ID: *out_signature = SINE_ESC_ENDFWUPGRADE_SIGNATURE; return true; + case UAVCAN_PROTOCOL_RESTARTNODE_REQUEST_ID: + *out_signature = UAVCAN_PROTOCOL_RESTARTNODE_REQUEST_SIGNATURE; return true; + default: return false; + } + } + + void onTransferReceived(CanardRxTransfer* t) override { + if (t->transfer_type != CanardTransferTypeResponse) return; + switch (t->data_type_id) { + case SINE_ESC_GETBOOTSTATUS_ID: { + sine_esc_GetBootStatusResponse res; + if (!sine_esc_GetBootStatusResponse_decode(t, &res)) { s_bootMode = res.mode; s_gotResponse = true; } + break; + } + case SINE_ESC_STARTFWUPGRADE_ID: { + sine_esc_StartFwUpgradeResponse res; + if (!sine_esc_StartFwUpgradeResponse_decode(t, &res)) { s_responseState = res.state; s_gotResponse = true; } + break; + } + case SINE_ESC_SENDFWDATA_RESPONSE_ID: { + sine_esc_SendFwDataResponse res; + if (!sine_esc_SendFwDataResponse_decode(t, &res)) { + s_responseState = res.state; s_responseNextIndex = res.next_index; s_gotResponse = true; + } + break; + } + case SINE_ESC_ENDFWUPGRADE_ID: { + sine_esc_EndFwUpgradeResponse res; + if (!sine_esc_EndFwUpgradeResponse_decode(t, &res)) { s_responseState = res.state; s_gotResponse = true; } + break; + } + case UAVCAN_PROTOCOL_RESTARTNODE_REQUEST_ID: { + uavcan_protocol_RestartNodeResponse res; + if (!uavcan_protocol_RestartNodeResponse_decode(t, &res)) { s_responseState = res.ok ? 0 : 1; s_gotResponse = true; } + break; + } + default: break; + } + } +}; + +static EscFlasherRelayNode* s_node = nullptr; + +// ============================================================================= +// Session state (guarded by s_mux; buffer contents are written only during +// RECEIVING on the BLE task and read only during flashing on the throttle task) +// ============================================================================= +static portMUX_TYPE s_mux = portMUX_INITIALIZER_UNLOCKED; + +static uint8_t* s_buf = nullptr; +static uint32_t s_bufSize = 0; // total image size (header + firmware) +static uint32_t s_received = 0; // contiguous bytes received from offset 0 +static volatile bool s_abortRequested = false; + +static EscFwPhase s_phase = EscFwPhase::IDLE; +static EscFwStatus s_status = { EscFwCode::IDLE, EscFwPhase::IDLE, 0 }; + +// Parsed header / flash progress (throttle task). +static uint16_t s_hwId = 0, s_sizeKb = 0, s_crc = 0; +static uint16_t s_totalChunks = 0, s_curChunk = 0; +static unsigned long s_lastSendMs = 0, s_phaseStartMs = 0, s_lastRxMs = 0; +static uint8_t s_retries = 0; + +static void setStatus(EscFwCode code, EscFwPhase phase, uint16_t permille) { + portENTER_CRITICAL(&s_mux); + s_status.code = code; s_status.phase = phase; s_status.progressPermille = permille; + portEXIT_CRITICAL(&s_mux); +} + +// Free the buffer. Only ever called on the throttle task (in the tick) or by +// Begin's own failure path before any throttle access. +static void freeBuffer() { + portENTER_CRITICAL(&s_mux); + uint8_t* p = s_buf; + s_buf = nullptr; + s_bufSize = 0; + s_received = 0; + portEXIT_CRITICAL(&s_mux); + if (p) free(p); +} + +static void finishFail(EscFwCode code) { + freeBuffer(); + setStatus(code, EscFwPhase::DONE_FAIL, s_status.progressPermille); + escAdapter().setLocalNodeId(CTRL_NORMAL_NODE_ID); // restore normal CAN identity + s_phase = EscFwPhase::DONE_FAIL; +} + +// ============================================================================= +// CAN send helpers (throttle task) — use the library encoders directly. +// ============================================================================= +static void sendRestartNode() { + uavcan_protocol_RestartNodeRequest req; + req.magic_number = UAVCAN_PROTOCOL_RESTARTNODE_REQUEST_MAGIC_NUMBER; // 0xACCE551B1E + uint8_t buffer[UAVCAN_PROTOCOL_RESTARTNODE_REQUEST_MAX_SIZE]; + uint32_t len = uavcan_protocol_RestartNodeRequest_encode(&req, buffer); + CanardTxTransfer transfer = { + .transfer_type = CanardTransferTypeRequest, + .data_type_signature = UAVCAN_PROTOCOL_RESTARTNODE_REQUEST_SIGNATURE, + .data_type_id = UAVCAN_PROTOCOL_RESTARTNODE_REQUEST_ID, + .inout_transfer_id = &s_tidRestart, + .priority = CANARD_TRANSFER_PRIORITY_HIGHEST, + .payload = buffer, + .payload_len = (uint16_t)len, + }; + canardRequestOrRespondObj(s_node->canard(), ESC_CAN_NODE_ID, &transfer); +} + +static void sendGetBootStatus() { + sine_esc_GetBootStatusRequest req; + uint8_t buffer[SINE_ESC_GETBOOTSTATUS_REQUEST_MAX_SIZE]; + uint32_t len = sine_esc_GetBootStatusRequest_encode(&req, buffer); + CanardTxTransfer transfer = { + .transfer_type = CanardTransferTypeRequest, + .data_type_signature = SINE_ESC_GETBOOTSTATUS_REQUEST_SIGNATURE, + .data_type_id = SINE_ESC_GETBOOTSTATUS_REQUEST_ID, + .inout_transfer_id = &s_tidBoot, + .priority = CANARD_TRANSFER_PRIORITY_HIGHEST, + .payload = buffer, + .payload_len = (uint16_t)len, + }; + canardRequestOrRespondObj(s_node->canard(), ESC_CAN_NODE_ID, &transfer); +} + +static void sendStartUpgrade() { + sine_esc_StartFwUpgradeRequest req = { + .hardware_id = s_hwId, + .filse_size_kb = s_sizeKb, + .file_crc = s_crc, + }; + uint8_t buffer[SINE_ESC_STARTFWUPGRADE_REQUEST_MAX_SIZE]; + uint32_t len = sine_esc_StartFwUpgradeRequest_encode(&req, buffer); + CanardTxTransfer transfer = { + .transfer_type = CanardTransferTypeRequest, + .data_type_signature = SINE_ESC_STARTFWUPGRADE_REQUEST_SIGNATURE, + .data_type_id = SINE_ESC_STARTFWUPGRADE_REQUEST_ID, + .inout_transfer_id = &s_tidStart, + .priority = CANARD_TRANSFER_PRIORITY_HIGHEST, + .payload = buffer, + .payload_len = (uint16_t)len, + }; + canardRequestOrRespondObj(s_node->canard(), ESC_CAN_NODE_ID, &transfer); +} + +static void sendFwDataChunk(uint16_t index) { + sine_esc_SendFwDataRequest req; + req.index = index; + memset(req.data, 0xFF, FW_CHUNK_SIZE); + uint32_t off = HEADER_SIZE + (uint32_t)index * FW_CHUNK_SIZE; + if (s_buf && off < s_bufSize) { + uint32_t remaining = s_bufSize - off; + uint32_t copyLen = (remaining < FW_CHUNK_SIZE) ? remaining : FW_CHUNK_SIZE; + memcpy(req.data, s_buf + off, copyLen); + } + uint8_t buffer[SINE_ESC_SENDFWDATA_REQUEST_MAX_SIZE]; + uint32_t len = sine_esc_SendFwDataRequest_encode(&req, buffer); + CanardTxTransfer transfer = { + .transfer_type = CanardTransferTypeRequest, + .data_type_signature = SINE_ESC_SENDFWDATA_REQUEST_SIGNATURE, + .data_type_id = SINE_ESC_SENDFWDATA_REQUEST_ID, + .inout_transfer_id = &s_tidData, + .priority = CANARD_TRANSFER_PRIORITY_HIGHEST, + .payload = buffer, + .payload_len = (uint16_t)len, + }; + canardRequestOrRespondObj(s_node->canard(), ESC_CAN_NODE_ID, &transfer); +} + +static void sendEndUpgrade() { + sine_esc_EndFwUpgradeRequest req; + uint8_t buffer[SINE_ESC_ENDFWUPGRADE_REQUEST_MAX_SIZE]; + uint32_t len = sine_esc_EndFwUpgradeRequest_encode(&req, buffer); + CanardTxTransfer transfer = { + .transfer_type = CanardTransferTypeRequest, + .data_type_signature = SINE_ESC_ENDFWUPGRADE_REQUEST_SIGNATURE, + .data_type_id = SINE_ESC_ENDFWUPGRADE_REQUEST_ID, + .inout_transfer_id = &s_tidEnd, + .priority = CANARD_TRANSFER_PRIORITY_HIGHEST, + .payload = buffer, + .payload_len = (uint16_t)len, + }; + canardRequestOrRespondObj(s_node->canard(), ESC_CAN_NODE_ID, &transfer); +} + +// ============================================================================= +// Public API +// ============================================================================= +void escFlasherRelayInit() { + if (!s_node) { + s_node = new EscFlasherRelayNode(escAdapter()); + s_node->begin(); + } + s_phase = EscFwPhase::IDLE; + setStatus(EscFwCode::IDLE, EscFwPhase::IDLE, 0); +} + +bool escFlasherRelayIsActive() { + return s_phase != EscFwPhase::IDLE && + s_phase != EscFwPhase::DONE_OK && + s_phase != EscFwPhase::DONE_FAIL; +} + +bool escFlasherRelayBegin(uint16_t hardwareId, uint32_t totalSize) { + if (!s_node) return false; + if (escFlasherRelayIsActive() || escConfigRelayIsActive()) { + setStatus(EscFwCode::REJECTED_BUSY, EscFwPhase::DONE_FAIL, 0); + return false; + } + if (currentState != DISARMED) { + setStatus(EscFwCode::REJECTED_ARMED, EscFwPhase::DONE_FAIL, 0); + return false; + } + if (totalSize < HEADER_SIZE || totalSize > MAX_IMAGE_SIZE) { + setStatus(EscFwCode::REJECTED_BUSY, EscFwPhase::DONE_FAIL, 0); + return false; + } + // Validate against the connected ESC: refuse a mismatched image before we + // ever put the ESC into the bootloader (classic brick cause). + uint16_t connectedHw = escTelemetryData.hardware_id; + if (connectedHw == 0 || connectedHw != hardwareId) { + setStatus(EscFwCode::REJECTED_HWID, EscFwPhase::DONE_FAIL, 0); + return false; + } + + uint8_t* buf = static_cast(heap_caps_malloc(totalSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT)); + if (!buf) buf = static_cast(malloc(totalSize)); + if (!buf) { + setStatus(EscFwCode::REJECTED_BUSY, EscFwPhase::DONE_FAIL, 0); + return false; + } + + portENTER_CRITICAL(&s_mux); + s_buf = buf; + s_bufSize = totalSize; + s_received = 0; + s_abortRequested = false; + s_phase = EscFwPhase::RECEIVING; + s_status.code = EscFwCode::RECEIVING; + s_status.phase = EscFwPhase::RECEIVING; + s_status.progressPermille = 0; + portEXIT_CRITICAL(&s_mux); + s_lastRxMs = millis(); + s_hwId = hardwareId; + USBSerial.printf("ESC FW relay: begin hwId=0x%04X size=%u\n", hardwareId, totalSize); + return true; +} + +int32_t escFlasherRelayWriteChunk(uint32_t offset, const uint8_t* data, uint16_t len) { + if (!data) return -1; + int32_t received = -1; + portENTER_CRITICAL(&s_mux); + if (s_phase == EscFwPhase::RECEIVING && s_buf && !s_abortRequested && + offset <= s_bufSize && (uint64_t)offset + len <= s_bufSize) { + memcpy(s_buf + offset, data, len); + // Track contiguous-from-zero progress (the app writes sequentially). + if (offset <= s_received && offset + len > s_received) { + s_received = offset + len; + } + received = (int32_t)s_received; + uint16_t permille = s_bufSize ? (uint16_t)((uint64_t)s_received * 500 / s_bufSize) : 0; // receive = first 50% + s_status.progressPermille = permille; + } + portEXIT_CRITICAL(&s_mux); + if (received >= 0) s_lastRxMs = millis(); + return received; +} + +bool escFlasherRelayEnd() { + bool ok = false; + portENTER_CRITICAL(&s_mux); + if (s_phase == EscFwPhase::RECEIVING && s_buf && s_received >= s_bufSize && s_bufSize >= HEADER_SIZE) { + // Parse header (little-endian): hwId[0..1], sizeKb[4..5], crc[6..7]. + s_hwId = s_buf[0] | ((uint16_t)s_buf[1] << 8); + s_sizeKb = s_buf[4] | ((uint16_t)s_buf[5] << 8); + s_crc = s_buf[6] | ((uint16_t)s_buf[7] << 8); + uint32_t fwBytes = s_bufSize - HEADER_SIZE; + s_totalChunks = (uint16_t)((fwBytes + FW_CHUNK_SIZE - 1) / FW_CHUNK_SIZE); + s_curChunk = 0; + s_retries = 0; + s_gotResponse = false; + s_phase = EscFwPhase::RESTARTING; + s_status.code = EscFwCode::ENTER_BOOTLDR; + s_status.phase = EscFwPhase::RESTARTING; + ok = true; + } + portEXIT_CRITICAL(&s_mux); + if (ok) { + s_phaseStartMs = millis(); + s_lastSendMs = 0; // force first restart send on next tick + USBSerial.printf("ESC FW relay: end, flashing hwId=0x%04X sizeKb=%u chunks=%u\n", + s_hwId, s_sizeKb, s_totalChunks); + } else { + USBSerial.println("ESC FW relay: end rejected (incomplete image)"); + } + return ok; +} + +void escFlasherRelayAbort() { + s_abortRequested = true; // the throttle tick frees and finishes +} + +EscFwStatus escFlasherRelayGetStatus() { + EscFwStatus copy; + portENTER_CRITICAL(&s_mux); + copy = s_status; + portEXIT_CRITICAL(&s_mux); + return copy; +} + +// ============================================================================= +// State machine — driven each throttle tick (~20 ms). NEVER blocks. +// ============================================================================= +void escFlasherRelayServiceTick() { + if (!s_node) return; + if (!escFlasherRelayIsActive()) return; + + if (s_abortRequested) { + finishFail(EscFwCode::FAILED); + s_abortRequested = false; + return; + } + + const unsigned long now = millis(); + + // RECEIVING: no CAN traffic; just guard against an app that stalls. + if (s_phase == EscFwPhase::RECEIVING) { + if (now - s_lastRxMs > RX_TIMEOUT_MS) { + USBSerial.println("ESC FW relay: receive timeout"); + finishFail(EscFwCode::TIMEOUT); + } + return; + } + + // Abort if the device arms mid-flash (defense in depth). + if (currentState != DISARMED) { + finishFail(EscFwCode::REJECTED_ARMED); + return; + } + + for (int i = 0; i < 6; i++) escAdapter().processTxRxOnce(); + + const bool timedOut = (s_lastSendMs != 0) && (now - s_lastSendMs) > FW_TIMEOUT_MS; + + switch (s_phase) { + // --------------------------------------------------------------------- + case EscFwPhase::RESTARTING: + if (s_lastSendMs == 0) { // first entry: kick the restart + // The ESC bootloader only accepts the upgrade protocol from host 0x40. + escAdapter().setLocalNodeId(CONFIG_HOST_NODE_ID); + sendRestartNode(); + s_lastSendMs = now; + s_phaseStartMs = now; + setStatus(EscFwCode::ENTER_BOOTLDR, EscFwPhase::RESTARTING, 0); + break; + } + // Non-blocking reboot wait, then move to bootloader check (the ESC may + // not answer RestartNode before rebooting — proceed regardless). + if ((now - s_phaseStartMs) >= REBOOT_WAIT_MS) { + s_phase = EscFwPhase::CHECKING_BOOT; + s_retries = 0; + s_gotResponse = false; + sendGetBootStatus(); + s_lastSendMs = now; + setStatus(EscFwCode::ENTER_BOOTLDR, EscFwPhase::CHECKING_BOOT, 0); + } + break; + + // --------------------------------------------------------------------- + case EscFwPhase::CHECKING_BOOT: + if (s_gotResponse) { + if (s_bootMode == 2) { + s_phase = EscFwPhase::STARTING; + s_retries = 0; + s_gotResponse = false; + sendStartUpgrade(); + s_lastSendMs = now; + } else if (s_retries++ < FW_MAX_RETRIES) { + // Not in bootloader yet: re-kick a restart and re-probe. + s_gotResponse = false; + sendRestartNode(); + s_phase = EscFwPhase::RESTARTING; + s_phaseStartMs = now; + s_lastSendMs = now; + } else { + finishFail(EscFwCode::ESC_REJECTED); // won't enter bootloader + } + } else if (timedOut) { + if (s_retries++ < FW_MAX_RETRIES) { s_gotResponse = false; sendGetBootStatus(); s_lastSendMs = now; } + else finishFail(EscFwCode::TIMEOUT); + } + break; + + // --------------------------------------------------------------------- + case EscFwPhase::STARTING: + if (s_gotResponse) { + if (s_responseState == 0) { + s_phase = EscFwPhase::SENDING; + s_curChunk = 0; + s_retries = 0; + s_gotResponse = false; + setStatus(EscFwCode::FLASHING, EscFwPhase::SENDING, 500); + sendFwDataChunk(0); + s_lastSendMs = now; + } else { + finishFail(EscFwCode::ESC_REJECTED); // image rejected by ESC + } + } else if (timedOut) { + if (s_retries++ < FW_MAX_RETRIES) { s_gotResponse = false; sendStartUpgrade(); s_lastSendMs = now; } + else finishFail(EscFwCode::TIMEOUT); + } + break; + + // --------------------------------------------------------------------- + case EscFwPhase::SENDING: + if (s_gotResponse) { + if (s_responseState == 0) { + s_curChunk = s_responseNextIndex; // ESC flow control + s_retries = 0; + // Progress: receive was 0..500, flashing is 500..1000. + uint16_t permille = s_totalChunks + ? (uint16_t)(500 + (uint32_t)s_curChunk * 500 / s_totalChunks) : 1000; + setStatus(EscFwCode::FLASHING, EscFwPhase::SENDING, permille); + if (s_curChunk >= s_totalChunks) { + s_phase = EscFwPhase::ENDING; + s_retries = 0; + s_gotResponse = false; + sendEndUpgrade(); + s_lastSendMs = now; + } else { + s_gotResponse = false; + sendFwDataChunk(s_curChunk); + s_lastSendMs = now; + } + } else if (s_retries++ < FW_MAX_RETRIES) { + s_gotResponse = false; sendFwDataChunk(s_curChunk); s_lastSendMs = now; // resend same chunk + } else { + finishFail(EscFwCode::ESC_REJECTED); + } + } else if (timedOut) { + if (s_retries++ < FW_MAX_RETRIES) { s_gotResponse = false; sendFwDataChunk(s_curChunk); s_lastSendMs = now; } + else finishFail(EscFwCode::TIMEOUT); + } + break; + + // --------------------------------------------------------------------- + case EscFwPhase::ENDING: + if (s_gotResponse) { + if (s_responseState == 0) { + freeBuffer(); + escAdapter().setLocalNodeId(CTRL_NORMAL_NODE_ID); // restore normal CAN identity + setStatus(EscFwCode::SUCCESS, EscFwPhase::DONE_OK, 1000); + s_phase = EscFwPhase::DONE_OK; + USBSerial.println("ESC FW relay: SUCCESS"); + } else { + finishFail(EscFwCode::ESC_REJECTED); // ESC CRC/verify failed + } + } else if (timedOut) { + if (s_retries++ < FW_MAX_RETRIES) { s_gotResponse = false; sendEndUpgrade(); s_lastSendMs = now; } + else finishFail(EscFwCode::TIMEOUT); + } + break; + + default: + break; + } +} diff --git a/src/sp140/lvgl/lvgl_core.cpp b/src/sp140/lvgl/lvgl_core.cpp index b4df9d35..183a7149 100644 --- a/src/sp140/lvgl/lvgl_core.cpp +++ b/src/sp140/lvgl/lvgl_core.cpp @@ -1,6 +1,6 @@ // Copyright 2020 #include "../../../inc/sp140/lvgl/lvgl_core.h" -#include "../../../inc/version.h" +#include "sp140/lvgl/lvgl_splash.h" #include "../../../inc/sp140/esp32s3-config.h" // Global variables for core LVGL functionality @@ -8,13 +8,20 @@ lv_display_t* main_display = nullptr; static uint8_t buf[LVGL_BUF_BYTES]; static uint8_t buf2[LVGL_BUF_BYTES]; Adafruit_ST7735* tft_driver = nullptr; -uint32_t lvgl_last_update = 0; // Define the shared SPI bus mutex SemaphoreHandle_t spiBusMutex = NULL; +// Set when a flush had to be skipped because the SPI bus was busy. LVGL is +// told the flush succeeded (required to keep rendering), so the skipped area +// would otherwise never be repainted — updateLvgl() checks this flag and +// forces a full repaint to recover. +static volatile bool flushSkipped = false; void setupLvglBuffer() { // Initialize LVGL library lv_init(); + // Let LVGL read time directly so animation/refresh pacing stays accurate + // regardless of how often lv_timer_handler() gets called. + lv_tick_set_cb([]() -> uint32_t { return millis(); }); } void setupLvglDisplay( @@ -77,7 +84,10 @@ void lvgl_flush_cb(lv_display_t* disp, const lv_area_t* area, uint8_t* px_map) { if (xSemaphoreTake(spiBusMutex, pdMS_TO_TICKS(200)) != pdTRUE) { // SPI bus timeout - BMS might be doing long operation, skip display flush USBSerial.println("[DISPLAY] SPI bus timeout - skipping display flush"); - // Must still signal LVGL that flush is done to avoid deadlock + // Must still signal LVGL that flush is done to avoid deadlock. That + // marks the area clean without it ever reaching the panel, so flag it + // for a recovery repaint (handled in updateLvgl). + flushSkipped = true; lv_display_flush_ready(disp); return; } @@ -103,88 +113,26 @@ void lvgl_flush_cb(lv_display_t* disp, const lv_area_t* area, uint8_t* px_map) { lv_display_flush_ready(disp); } -// LVGL tick handler - to be called from timer or in main loop -void lv_tick_handler() { - static uint32_t last_tick = 0; - uint32_t current_ms = millis(); - - if (current_ms - last_tick > 5) { // 5ms tick rate for LVGL - lv_tick_inc(current_ms - last_tick); - last_tick = current_ms; - } -} - -// Update LVGL - call this regularly +// Update LVGL - call this regularly with lvglMutex held. LVGL paces actual +// redraws internally (LV_DEF_REFR_PERIOD), so no extra gating is needed here. void updateLvgl() { - uint32_t current_ms = millis(); - - // Update LVGL at the defined refresh rate - if (current_ms - lvgl_last_update > LVGL_REFRESH_TIME) { - lv_tick_handler(); - lv_timer_handler(); - lvgl_last_update = current_ms; + lv_timer_handler(); + + // A flush was dropped because the SPI bus was busy: LVGL believes those + // pixels reached the panel, so invalidate everything once to repaint any + // stale content on the next refresh cycle. + if (flushSkipped) { + flushSkipped = false; + lv_obj_t* screen = lv_screen_active(); + if (screen != NULL) { + lv_obj_invalidate(screen); + } } } void displayLvglSplash(const STR_DEVICE_DATA_140_V1& deviceData, int duration) { USBSerial.println("Displaying LVGL splash screen"); - - // Create a new screen for the splash - lv_obj_t* splash_screen = lv_obj_create(NULL); - lv_screen_load(splash_screen); - - // Disable scrollbars - lv_obj_remove_flag(splash_screen, LV_OBJ_FLAG_SCROLLABLE); - - // Set background color based on theme - lv_obj_set_style_bg_color(splash_screen, - deviceData.theme == 1 ? lv_color_black() : lv_color_white(), - LV_PART_MAIN); - - // OpenPPG title - lv_obj_t* title_label = lv_label_create(splash_screen); - lv_label_set_text(title_label, "OpenPPG"); - // Use a larger font for the title - lv_obj_set_style_text_font(title_label, &lv_font_montserrat_28, 0); - lv_obj_set_style_text_color(title_label, - deviceData.theme == 1 ? lv_color_white() : lv_color_black(), - 0); - lv_obj_align(title_label, LV_ALIGN_TOP_MID, 0, 15); - - // Create animation for title - lv_anim_t title_anim; - lv_anim_init(&title_anim); - lv_anim_set_var(&title_anim, title_label); - lv_anim_set_values(&title_anim, 0, 255); - lv_anim_set_time(&title_anim, 500); - lv_anim_set_exec_cb(&title_anim, [](void* var, int32_t value) { - lv_obj_set_style_opa((lv_obj_t*)var, value, 0); // NOLINT(readability/casting) - }); - lv_anim_start(&title_anim); - - // Version label - lv_obj_t* version_label = lv_label_create(splash_screen); - char version_str[10]; - snprintf(version_str, sizeof(version_str), "v%d.%d", VERSION_MAJOR, VERSION_MINOR); - lv_label_set_text(version_label, version_str); - lv_obj_set_style_text_font(version_label, &lv_font_montserrat_16, 0); - lv_obj_set_style_text_color(version_label, - deviceData.theme == 1 ? lv_color_white() : lv_color_black(), - 0); - lv_obj_align(version_label, LV_ALIGN_CENTER, 0, 0); - - // Time used label - lv_obj_t* time_label = lv_label_create(splash_screen); - char time_str[10]; - const int hours = deviceData.armed_time / 60; - const int minutes = deviceData.armed_time % 60; - snprintf(time_str, sizeof(time_str), "%02d:%02d", hours, minutes); - lv_label_set_text(time_label, time_str); - lv_obj_set_style_text_font(time_label, &lv_font_montserrat_16, 0); - lv_obj_set_style_text_color(time_label, - deviceData.theme == 1 ? lv_color_white() : lv_color_black(), - 0); - lv_obj_align(time_label, LV_ALIGN_BOTTOM_MID, 0, -20); + createLvglSplashScreen(deviceData); // Process LVGL for the duration uint32_t start_time = millis(); diff --git a/src/sp140/lvgl/lvgl_main_screen.cpp b/src/sp140/lvgl/lvgl_main_screen.cpp index e0d75ff8..feff8589 100644 --- a/src/sp140/lvgl/lvgl_main_screen.cpp +++ b/src/sp140/lvgl/lvgl_main_screen.cpp @@ -1,5 +1,6 @@ #include "../../../inc/sp140/lvgl/lvgl_main_screen.h" #include "../../../inc/sp140/lvgl/lvgl_alerts.h" +#include "../../../inc/sp140/lvgl/lvgl_updates.h" #include "../../../inc/sp140/esp32s3-config.h" #include "../../assets/img/cruise-control-340255-30.c" // Cruise control icon // NOLINT(build/include) @@ -52,6 +53,26 @@ lv_obj_t* climb_rate_fill_sections[12] = {NULL}; // Critical border (used by flash animations) lv_obj_t* critical_border = NULL; +// The critical border is a transparent parent containing four narrow red +// strips. Changing a strip only invalidates its edge instead of the complete +// 160x128 display. +void setCriticalBorderOpacity(lv_opa_t opacity) { + if (critical_border == NULL) return; + const uint32_t childCount = lv_obj_get_child_count(critical_border); + for (uint32_t i = 0; i < childCount; ++i) { + lv_obj_set_style_bg_opa(lv_obj_get_child(critical_border, i), opacity, + LV_PART_MAIN); + } +} + +lv_opa_t getCriticalBorderOpacity() { + if (critical_border == NULL || lv_obj_get_child_count(critical_border) == 0) { + return LV_OPA_0; + } + return lv_obj_get_style_bg_opa(lv_obj_get_child(critical_border, 0), + LV_PART_MAIN); +} + // Helper function to hide/show all altitude character labels void setAltitudeVisibility(bool visible) { for (int i = 0; i < 7; i++) { @@ -103,9 +124,16 @@ void init_temp_styles(bool darkMode) { // Setup the main screen layout once void setupMainScreen(bool darkMode) { if (main_screen != NULL) { + // critical_border is owned by main_screen and becomes invalid when its + // parent is deleted. Clear the non-owning handle before rebuilding. + critical_border = NULL; lv_obj_delete(main_screen); } + // Fresh widgets have no cached update state — forget the last-applied values + // so updateLvglMainScreen() re-applies styles/positions to the new objects. + resetLvglUpdateCache(); + // Create main screen main_screen = lv_obj_create(NULL); @@ -133,9 +161,13 @@ void setupMainScreen(bool darkMode) { battery_label = lv_label_create(main_screen); lv_obj_align(battery_label, LV_ALIGN_TOP_MID, 0, 3); // Move up for better vertical centering in battery bar lv_obj_set_style_text_font(battery_label, &lv_font_montserrat_28, 0); // Large font for prominent percentage display - lv_obj_set_style_text_color(battery_label, LVGL_BLACK, 0); + lv_obj_set_style_text_color(battery_label, + darkMode ? LVGL_WHITE : LVGL_BLACK, 0); // Center-align battery percentage since it's in the middle lv_obj_set_style_text_align(battery_label, LV_TEXT_ALIGN_CENTER, 0); + // Blank until the first update writes real content — a label with no text + // set renders LVGL's default "Text", which flashed on-screen at boot. + lv_label_set_text(battery_label, ""); // Left voltage label voltage_left_label = lv_label_create(main_screen); @@ -143,6 +175,7 @@ void setupMainScreen(bool darkMode) { lv_obj_set_style_text_font(voltage_left_label, &lv_font_montserrat_12, 0); // Much smaller font for voltage lv_obj_set_style_text_color(voltage_left_label, darkMode ? LVGL_WHITE : LVGL_BLACK, 0); + lv_label_set_text(voltage_left_label, ""); // Blank until first update // Right voltage label voltage_right_label = lv_label_create(main_screen); @@ -152,6 +185,7 @@ void setupMainScreen(bool darkMode) { darkMode ? LVGL_WHITE : LVGL_BLACK, 0); // Right-align right voltage so numbers grow from right to left lv_obj_set_style_text_align(voltage_right_label, LV_TEXT_ALIGN_RIGHT, 0); + lv_label_set_text(voltage_right_label, ""); // Blank until first update // Middle section - power display with individual character positions // Layout: [tens][ones][.][tenths] kW (4 positions for numbers + decimal) @@ -203,6 +237,7 @@ void setupMainScreen(bool darkMode) { darkMode ? LVGL_WHITE : LVGL_BLACK, 0); // Ensure text within the label is centered lv_obj_set_style_text_align(perf_mode_label, LV_TEXT_ALIGN_CENTER, 0); + lv_label_set_text(perf_mode_label, ""); // Blank until first update // Armed time label - adjust position now that there's no bluetooth icon armed_time_label = lv_label_create(main_screen); @@ -212,6 +247,7 @@ void setupMainScreen(bool darkMode) { darkMode ? LVGL_WHITE : LVGL_BLACK, 0); // Right-align time so numbers grow from right to left lv_obj_set_style_text_align(armed_time_label, LV_TEXT_ALIGN_RIGHT, 0); + lv_label_set_text(armed_time_label, ""); // Blank until first update // Bottom section - altitude and temperatures // Create individual character position labels for fixed positioning @@ -311,6 +347,7 @@ void setupMainScreen(bool darkMode) { lv_obj_set_style_pad_top(batt_temp_label, 1, 0); lv_obj_set_style_pad_bottom(batt_temp_label, 1, 0); lv_obj_set_style_text_align(batt_temp_label, LV_TEXT_ALIGN_RIGHT, 0); // Right align temperature values + lv_label_set_text(batt_temp_label, "-"); // "No data" placeholder until first update // Create letter label for B batt_letter_label = lv_label_create(main_screen); @@ -343,6 +380,7 @@ void setupMainScreen(bool darkMode) { lv_obj_set_style_pad_top(esc_temp_label, 1, 0); lv_obj_set_style_pad_bottom(esc_temp_label, 1, 0); lv_obj_set_style_text_align(esc_temp_label, LV_TEXT_ALIGN_RIGHT, 0); // Right align temperature values + lv_label_set_text(esc_temp_label, "-"); // "No data" placeholder until first update // Create letter label for E esc_letter_label = lv_label_create(main_screen); @@ -382,6 +420,7 @@ void setupMainScreen(bool darkMode) { lv_obj_set_style_pad_top(motor_temp_label, 1, 0); lv_obj_set_style_pad_bottom(motor_temp_label, 1, 0); lv_obj_set_style_text_align(motor_temp_label, LV_TEXT_ALIGN_RIGHT, 0); // Right align temperature values + lv_label_set_text(motor_temp_label, "-"); // "No data" placeholder until first update // Create letter label for M motor_letter_label = lv_label_create(main_screen); @@ -529,7 +568,8 @@ void setupMainScreen(bool darkMode) { ble_pairing_icon = lv_label_create(main_screen); lv_label_set_text(ble_pairing_icon, LV_SYMBOL_BLUETOOTH); lv_obj_set_style_text_font(ble_pairing_icon, &lv_font_montserrat_14, 0); - lv_obj_set_style_text_color(ble_pairing_icon, LVGL_BLUE, 0); + lv_obj_set_style_text_color( + ble_pairing_icon, darkMode ? LVGL_DARK_BLE_BLUE : LVGL_BLUE, 0); lv_obj_set_pos(ble_pairing_icon, 103, 72); lv_obj_add_flag(ble_pairing_icon, LV_OBJ_FLAG_HIDDEN); // Hide initially @@ -551,9 +591,11 @@ void setupMainScreen(bool darkMode) { lv_line_set_points(climb_rate_divider_lines[i], line_points[i], 2); - // Make the center line (line 6) special: 3 pixels wide and black + // Make the center line (line 6) thicker and theme-visible. if (i == 6) { - lv_obj_set_style_line_color(climb_rate_divider_lines[i], LVGL_BLACK, LV_PART_MAIN); + lv_obj_set_style_line_color( + climb_rate_divider_lines[i], darkMode ? LVGL_WHITE : LVGL_BLACK, + LV_PART_MAIN); lv_obj_set_style_line_width(climb_rate_divider_lines[i], 3, LV_PART_MAIN); } else { lv_obj_set_style_line_color(climb_rate_divider_lines[i], LVGL_GRAY, LV_PART_MAIN); @@ -581,19 +623,35 @@ void setupMainScreen(bool darkMode) { lv_obj_move_background(climb_rate_fill_sections[i]); } - // Create critical alert border (initially hidden) - moved from updates file - if (critical_border == NULL) { - critical_border = lv_obj_create(main_screen); - lv_obj_set_size(critical_border, SCREEN_WIDTH, SCREEN_HEIGHT); - lv_obj_set_pos(critical_border, 0, 0); - lv_obj_set_style_border_width(critical_border, 4, LV_PART_MAIN); - lv_obj_set_style_border_color(critical_border, LVGL_RED, LV_PART_MAIN); - lv_obj_set_style_bg_opa(critical_border, LV_OPA_0, LV_PART_MAIN); // Transparent background - lv_obj_set_style_radius(critical_border, 0, LV_PART_MAIN); // Sharp corners - lv_obj_set_style_border_opa(critical_border, LV_OPA_0, LV_PART_MAIN); // Initially invisible border - // Move border to front so it's visible over all other elements - lv_obj_move_foreground(critical_border); + // Create the critical alert border as four narrow edge strips. A full-screen + // bordered object causes LVGL to invalidate and flush the full display on + // every flash, even though only the outer four pixels change. + critical_border = lv_obj_create(main_screen); + lv_obj_set_size(critical_border, SCREEN_WIDTH, SCREEN_HEIGHT); + lv_obj_set_pos(critical_border, 0, 0); + lv_obj_remove_flag(critical_border, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_style_bg_opa(critical_border, LV_OPA_0, LV_PART_MAIN); + lv_obj_set_style_border_width(critical_border, 0, LV_PART_MAIN); + lv_obj_set_style_pad_all(critical_border, 0, LV_PART_MAIN); + + static const int16_t edgeGeometry[4][4] = { + {0, 0, SCREEN_WIDTH, 4}, + {0, SCREEN_HEIGHT - 4, SCREEN_WIDTH, 4}, + {0, 4, 4, SCREEN_HEIGHT - 8}, + {SCREEN_WIDTH - 4, 4, 4, SCREEN_HEIGHT - 8}, + }; + for (const auto& edge : edgeGeometry) { + lv_obj_t* strip = lv_obj_create(critical_border); + lv_obj_set_pos(strip, edge[0], edge[1]); + lv_obj_set_size(strip, edge[2], edge[3]); + lv_obj_remove_flag(strip, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_style_bg_color(strip, LVGL_RED, LV_PART_MAIN); + lv_obj_set_style_bg_opa(strip, LV_OPA_0, LV_PART_MAIN); + lv_obj_set_style_border_width(strip, 0, LV_PART_MAIN); + lv_obj_set_style_radius(strip, 0, LV_PART_MAIN); + lv_obj_set_style_pad_all(strip, 0, LV_PART_MAIN); } + lv_obj_move_foreground(critical_border); // Setup alert counter UI elements (circles, labels, and alert text display) setupAlertCounterUI(darkMode); diff --git a/src/sp140/lvgl/lvgl_splash.cpp b/src/sp140/lvgl/lvgl_splash.cpp new file mode 100644 index 00000000..34d8cb72 --- /dev/null +++ b/src/sp140/lvgl/lvgl_splash.cpp @@ -0,0 +1,58 @@ +#include "sp140/lvgl/lvgl_splash.h" + +#include + +#include "version.h" + +lv_obj_t* createLvglSplashScreen(const STR_DEVICE_DATA_140_V1& deviceData) { + lv_obj_t* splash_screen = lv_obj_create(NULL); + lv_screen_load(splash_screen); + lv_obj_remove_flag(splash_screen, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_style_bg_color( + splash_screen, + deviceData.theme == 1 ? lv_color_black() : lv_color_white(), + LV_PART_MAIN); + + lv_obj_t* title_label = lv_label_create(splash_screen); + lv_label_set_text(title_label, "OpenPPG"); + lv_obj_set_style_text_font(title_label, &lv_font_montserrat_28, 0); + lv_obj_set_style_text_color( + title_label, + deviceData.theme == 1 ? lv_color_white() : lv_color_black(), 0); + lv_obj_align(title_label, LV_ALIGN_TOP_MID, 0, 15); + + lv_anim_t title_anim; + lv_anim_init(&title_anim); + lv_anim_set_var(&title_anim, title_label); + lv_anim_set_values(&title_anim, 0, 255); + lv_anim_set_time(&title_anim, 500); + lv_anim_set_exec_cb(&title_anim, [](void* var, int32_t value) { + lv_obj_set_style_opa((lv_obj_t*)var, value, 0); // NOLINT(readability/casting) + }); + lv_anim_start(&title_anim); + + lv_obj_t* version_label = lv_label_create(splash_screen); + char version_str[10]; + snprintf(version_str, sizeof(version_str), "v%d.%d", VERSION_MAJOR, + VERSION_MINOR); + lv_label_set_text(version_label, version_str); + lv_obj_set_style_text_font(version_label, &lv_font_montserrat_16, 0); + lv_obj_set_style_text_color( + version_label, + deviceData.theme == 1 ? lv_color_white() : lv_color_black(), 0); + lv_obj_align(version_label, LV_ALIGN_CENTER, 0, 0); + + lv_obj_t* time_label = lv_label_create(splash_screen); + char time_str[10]; + const int hours = deviceData.armed_time / 60; + const int minutes = deviceData.armed_time % 60; + snprintf(time_str, sizeof(time_str), "%02d:%02d", hours, minutes); + lv_label_set_text(time_label, time_str); + lv_obj_set_style_text_font(time_label, &lv_font_montserrat_16, 0); + lv_obj_set_style_text_color( + time_label, + deviceData.theme == 1 ? lv_color_white() : lv_color_black(), 0); + lv_obj_align(time_label, LV_ALIGN_BOTTOM_MID, 0, -20); + + return splash_screen; +} diff --git a/src/sp140/lvgl/lvgl_updates.cpp b/src/sp140/lvgl/lvgl_updates.cpp index 350740f7..55be4da4 100644 --- a/src/sp140/lvgl/lvgl_updates.cpp +++ b/src/sp140/lvgl/lvgl_updates.cpp @@ -7,6 +7,65 @@ #include "../../../inc/sp140/ble.h" #include "../../../inc/sp140/ble/ble_core.h" #include +#include + +// --------------------------------------------------------------------------- +// Change-detecting setters for the per-frame update path. +// LVGL invalidates (and re-flushes over SPI) any object touched by +// lv_label_set_text() or a style setter even when the new value is identical +// to the current one. updateLvglMainScreen() runs every UI frame, so +// unguarded setters redraw nearly the whole screen at the full frame rate. +// These helpers skip the LVGL call when nothing actually changed, so only +// areas with new content get invalidated and flushed. + +static void setLabelText(lv_obj_t* label, const char* text) { + if (label == NULL || text == NULL) return; + const char* current = lv_label_get_text(label); + if (current != NULL && strcmp(current, text) == 0) return; + lv_label_set_text(label, text); +} + +static void setLabelTextColor(lv_obj_t* label, lv_color_t color) { + if (label == NULL) return; + if (lv_color_eq(lv_obj_get_style_text_color(label, LV_PART_MAIN), color)) return; + lv_obj_set_style_text_color(label, color, 0); +} + +static void setBgColor(lv_obj_t* obj, lv_color_t color, lv_part_t part) { + if (obj == NULL) return; + if (lv_color_eq(lv_obj_get_style_bg_color(obj, part), color)) return; + lv_obj_set_style_bg_color(obj, color, part); +} + +static void setBgOpa(lv_obj_t* obj, lv_opa_t opa) { + if (obj == NULL) return; + if (lv_obj_get_style_bg_opa(obj, LV_PART_MAIN) == opa) return; + lv_obj_set_style_bg_opa(obj, opa, LV_PART_MAIN); +} + +static void setImageRecolor(lv_obj_t* obj, lv_color_t color) { + if (obj == NULL) return; + if (lv_color_eq(lv_obj_get_style_image_recolor(obj, LV_PART_MAIN), color)) return; + lv_obj_set_style_image_recolor(obj, color, LV_PART_MAIN); +} + +// Last-applied UI state that cannot be read back from the widgets (label +// alignment mode, which bg style is attached). Kept at file scope so +// resetLvglUpdateCache() can invalidate it whenever the screen widgets are +// (re)created - e.g. setupMainScreen() on boot or between screenshot tests. +static int8_t lastVoltLeftMode = -1; // 0 = BMS, 1 = "NO BMS", 2 = none +static uint8_t lastBattTempLevel = 0xFF; // 0 = normal, 1 = warning, 2 = critical +static uint8_t lastEscTempLevel = 0xFF; +static uint8_t lastMotorTempLevel = 0xFF; +static int32_t lastChargingIconBattW = -1; // battery_label width the icon was aligned to + +void resetLvglUpdateCache() { + lastVoltLeftMode = -1; + lastBattTempLevel = 0xFF; + lastEscTempLevel = 0xFF; + lastMotorTempLevel = 0xFF; + lastChargingIconBattW = -1; +} // Flash timer globals - definitions lv_timer_t* cruise_flash_timer = NULL; @@ -188,25 +247,19 @@ static void critical_border_flash_timer_cb(lv_timer_t* timer) { // This callback runs within the LVGL task handler, so no mutex needed here. if (critical_border != NULL) { // Toggle opacity: 300ms on (opaque), 700ms off (transparent) - uint8_t current_opa = lv_obj_get_style_border_opa(critical_border, LV_PART_MAIN); + const lv_opa_t current_opa = getCriticalBorderOpacity(); if (current_opa == LV_OPA_100) { - lv_obj_set_style_border_opa(critical_border, LV_OPA_0, LV_PART_MAIN); + setCriticalBorderOpacity(LV_OPA_0); lv_timer_set_period(timer, 700); // Off duration - // Invalidate entire screen when hiding to ensure clean removal of border pixels - lv_obj_invalidate(lv_screen_active()); } else { - lv_obj_set_style_border_opa(critical_border, LV_OPA_100, LV_PART_MAIN); + setCriticalBorderOpacity(LV_OPA_100); lv_timer_set_period(timer, 300); // On duration // Trigger vibration pulse in sync with border "on" if (ENABLE_VIBE) { pulseVibration(300, 200); // 300ms pulse, intensity 200 } - // Invalidate the border area when showing - lv_obj_invalidate(critical_border); } - // Force immediate refresh to minimize tearing - lv_refr_now(lv_display_get_default()); } } @@ -214,7 +267,7 @@ void startCriticalBorderFlash() { if (xSemaphoreTake(lvglMutex, pdMS_TO_TICKS(50)) == pdTRUE) { if (critical_border != NULL && !isFlashingCriticalBorder) { isFlashingCriticalBorder = true; - lv_obj_set_style_border_opa(critical_border, LV_OPA_100, LV_PART_MAIN); // Start visible + setCriticalBorderOpacity(LV_OPA_100); critical_border_flash_timer = lv_timer_create(critical_border_flash_timer_cb, 300, NULL); } xSemaphoreGive(lvglMutex); @@ -228,9 +281,7 @@ void stopCriticalBorderFlash() { critical_border_flash_timer = NULL; } if (critical_border != NULL) { - lv_obj_set_style_border_opa(critical_border, LV_OPA_0, LV_PART_MAIN); - // Invalidate entire screen to ensure clean removal - lv_obj_invalidate(lv_screen_active()); + setCriticalBorderOpacity(LV_OPA_0); } isFlashingCriticalBorder = false; xSemaphoreGive(lvglMutex); @@ -245,11 +296,8 @@ bool isCriticalBorderFlashing() { void startCriticalBorderFlashDirect() { if (critical_border != NULL && !isFlashingCriticalBorder) { isFlashingCriticalBorder = true; - lv_obj_set_style_border_opa(critical_border, LV_OPA_100, LV_PART_MAIN); // Start visible - lv_obj_invalidate(critical_border); // Ensure clean initial draw + setCriticalBorderOpacity(LV_OPA_100); critical_border_flash_timer = lv_timer_create(critical_border_flash_timer_cb, 300, NULL); - // Force immediate refresh for clean start - lv_refr_now(lv_display_get_default()); } } @@ -259,10 +307,7 @@ void stopCriticalBorderFlashDirect() { critical_border_flash_timer = NULL; } if (critical_border != NULL) { - lv_obj_set_style_border_opa(critical_border, LV_OPA_0, LV_PART_MAIN); - lv_obj_invalidate(lv_screen_active()); // Ensure clean removal of border - // Force immediate refresh for clean stop - lv_refr_now(lv_display_get_default()); + setCriticalBorderOpacity(LV_OPA_0); } isFlashingCriticalBorder = false; } @@ -343,20 +388,13 @@ void stopBLEPairingIconFlash() { } // Update the climb rate indicator -void updateClimbRateIndicator(float climbRate) { +void updateClimbRateIndicator(float climbRate, bool darkMode) { // Vario display scale: 6 segments per direction cover a +/-3 m/s climb/descent // envelope. The raw value is NOT clamped here - sectionsToFill is capped at 6 // below, so rates beyond +/-3 m/s simply pin the gauge to full deflection. const float kVarioSegment = 3.0f / 6.0f; // m/s per segment (0.5) const float kVarioDeadzone = kVarioSegment / 2.0f; // neutral zone near 0 (0.25 m/s) - // Reset all sections to transparent - for (int i = 0; i < 12; i++) { - if (climb_rate_fill_sections[i] != NULL) { - lv_obj_set_style_bg_opa(climb_rate_fill_sections[i], LV_OPA_0, LV_PART_MAIN); - } - } - // Define colors for positive climb rates (from center upward) lv_color_t positive_colors[6] = { lv_color_make(0, 255, 0), // Bright green @@ -371,12 +409,21 @@ void updateClimbRateIndicator(float climbRate) { lv_color_t negative_colors[6] = { lv_color_make(173, 216, 230), // Light blue lv_color_make(173, 216, 230), // Light blue (again) - lv_color_make(70, 130, 180), // Darker blue - lv_color_make(70, 130, 180), // Darker blue (again) - lv_color_make(75, 0, 130), // Dark purple - lv_color_make(75, 0, 130) // Dark purple (again) + darkMode ? LVGL_DARK_DESCENT_BLUE : lv_color_make(70, 130, 180), + darkMode ? LVGL_DARK_DESCENT_BLUE : lv_color_make(70, 130, 180), + darkMode ? LVGL_DARK_DESCENT_PURPLE : lv_color_make(75, 0, 130), + darkMode ? LVGL_DARK_DESCENT_PURPLE : lv_color_make(75, 0, 130) }; + // Compute the desired state for all 12 sections, then diff-apply so only + // sections that actually changed are invalidated and redrawn. + lv_opa_t section_opa[12]; + lv_color_t section_color[12]; + for (int i = 0; i < 12; i++) { + section_opa[i] = LV_OPA_0; + section_color[i] = lv_color_black(); // unused while transparent + } + if (climbRate >= kVarioDeadzone) { // Positive climb rate - fill sections above center line int sectionsToFill = (int)(climbRate / kVarioSegment); @@ -384,10 +431,8 @@ void updateClimbRateIndicator(float climbRate) { for (int i = 0; i < sectionsToFill; i++) { int sectionIndex = 5 - i; // Section 5 is closest to center line, going up to 0 - if (climb_rate_fill_sections[sectionIndex] != NULL) { - lv_obj_set_style_bg_opa(climb_rate_fill_sections[sectionIndex], LV_OPA_100, LV_PART_MAIN); - lv_obj_set_style_bg_color(climb_rate_fill_sections[sectionIndex], positive_colors[i], LV_PART_MAIN); - } + section_opa[sectionIndex] = LV_OPA_100; + section_color[sectionIndex] = positive_colors[i]; } } else if (climbRate <= -kVarioDeadzone) { // Negative climb rate - fill sections below center line @@ -396,13 +441,20 @@ void updateClimbRateIndicator(float climbRate) { for (int i = 0; i < sectionsToFill; i++) { int sectionIndex = 6 + i; // Section 6 is closest to center line, going down to 11 - if (climb_rate_fill_sections[sectionIndex] != NULL) { - lv_obj_set_style_bg_opa(climb_rate_fill_sections[sectionIndex], LV_OPA_100, LV_PART_MAIN); - lv_obj_set_style_bg_color(climb_rate_fill_sections[sectionIndex], negative_colors[i], LV_PART_MAIN); - } + section_opa[sectionIndex] = LV_OPA_100; + section_color[sectionIndex] = negative_colors[i]; } } // If |climb rate| is within kVarioDeadzone, no sections are filled (neutral) + + for (int i = 0; i < 12; i++) { + if (climb_rate_fill_sections[i] == NULL) continue; + // Only recolor visible sections; color is irrelevant while transparent + if (section_opa[i] == LV_OPA_100) { + setBgColor(climb_rate_fill_sections[i], section_color[i], LV_PART_MAIN); + } + setBgOpa(climb_rate_fill_sections[i], section_opa[i]); + } } void updateLvglMainScreen( @@ -436,7 +488,7 @@ void updateLvglMainScreen( hasValidBatteryTemp = true; } } - // Show whichever ESC temperature is hotter — capacitor or MOSFET — and color + // Show whichever ESC temperature is hotter - capacitor or MOSFET - and color // it against that sensor's own thresholds (cap and MOSFET have different // limits). Skip a sensor that reads NaN (invalid); if both are invalid // escTemp stays NaN and the tile shows "-". @@ -461,47 +513,57 @@ void updateLvglMainScreen( lv_bar_set_value(battery_bar, (int)batteryPercent, LV_ANIM_OFF); // Set color based on percentage - lv_color_t batteryColor = LVGL_RED; + lv_color_t batteryColor = darkMode ? LVGL_DARK_RED : LVGL_RED; if (batteryPercent > bmsSOCThresholds.warnLow) { - batteryColor = LVGL_GREEN; + batteryColor = darkMode ? LVGL_DARK_GREEN : LVGL_GREEN; } else if (batteryPercent >= bmsSOCThresholds.critLow) { - batteryColor = LVGL_YELLOW; + batteryColor = darkMode ? LVGL_DARK_YELLOW : LVGL_YELLOW; } - lv_obj_set_style_bg_color(battery_bar, batteryColor, LV_PART_INDICATOR); + setBgColor(battery_bar, batteryColor, LV_PART_INDICATOR); // Update battery percentage text char buffer[10]; snprintf(buffer, sizeof(buffer), "%d%%", (int)batteryPercent); - lv_label_set_text(battery_label, buffer); - lv_obj_set_style_text_color(battery_label, LVGL_BLACK, 0); + setLabelText(battery_label, buffer); + setLabelTextColor(battery_label, darkMode ? LVGL_WHITE : LVGL_BLACK); } else if (escConnected) { // clear the battery bar, we handle voltage later lv_bar_set_value(battery_bar, 0, LV_ANIM_OFF); } else { lv_bar_set_value(battery_bar, 0, LV_ANIM_OFF); - lv_label_set_text(battery_label, "NO DATA"); - lv_obj_set_style_text_color(battery_label, LVGL_RED, 0); + setLabelText(battery_label, "NO DATA"); + setLabelTextColor(battery_label, LVGL_RED); } // Update left voltage (cell voltage) if (voltage_left_label != NULL) { // Check object exists + // Re-align only on source change: lv_obj_align() invalidates the label + // every call even when the resulting position is identical. if (bmsConnected) { char buffer[10]; snprintf(buffer, sizeof(buffer), "%2.2fv", lowestCellV); - lv_label_set_text(voltage_left_label, buffer); - - // Always use black text for better readability - lv_obj_set_style_text_color(voltage_left_label, LVGL_BLACK, 0); - // Restore default position when BMS is connected - lv_obj_align(voltage_left_label, LV_ALIGN_TOP_LEFT, 3, 12); + setLabelText(voltage_left_label, buffer); + + setLabelTextColor(voltage_left_label, + darkMode ? LVGL_WHITE : LVGL_BLACK); + if (lastVoltLeftMode != 0) { + // Restore default position when BMS is connected + lv_obj_align(voltage_left_label, LV_ALIGN_TOP_LEFT, 3, 12); + lastVoltLeftMode = 0; + } } else if (escConnected) { - lv_obj_set_style_text_color(voltage_left_label, LVGL_BLACK, 0); - lv_label_set_text(voltage_left_label, "NO\nBMS"); - // Move up by 10 pixels when showing NO BMS - lv_obj_align(voltage_left_label, LV_ALIGN_TOP_LEFT, 3, 2); + setLabelTextColor(voltage_left_label, + darkMode ? LVGL_WHITE : LVGL_BLACK); + setLabelText(voltage_left_label, "NO\nBMS"); + if (lastVoltLeftMode != 1) { + // Move up by 10 pixels when showing NO BMS + lv_obj_align(voltage_left_label, LV_ALIGN_TOP_LEFT, 3, 2); + lastVoltLeftMode = 1; + } } else { - lv_label_set_text(voltage_left_label, ""); + setLabelText(voltage_left_label, ""); + lastVoltLeftMode = 2; } } @@ -511,29 +573,38 @@ void updateLvglMainScreen( if (bmsConnected) { char buffer[10]; snprintf(buffer, sizeof(buffer), "%2.0fv", totalVolts); - lv_label_set_text(voltage_right_label, buffer); + setLabelText(voltage_right_label, buffer); // Ensure battery label shows percentage if BMS is connected if (batteryPercent >= 0) { char batt_buffer[10]; snprintf(batt_buffer, sizeof(batt_buffer), "%d%%", (int)batteryPercent); - lv_label_set_text(battery_label, batt_buffer); - lv_obj_set_style_text_color(battery_label, LVGL_BLACK, 0); + setLabelText(battery_label, batt_buffer); + setLabelTextColor(battery_label, + darkMode ? LVGL_WHITE : LVGL_BLACK); } } else if (escConnected) { - lv_label_set_text(voltage_right_label, ""); + setLabelText(voltage_right_label, ""); char buffer[10]; snprintf(buffer, sizeof(buffer), "%2.1fv", totalVolts); - lv_label_set_text(battery_label, buffer); - lv_obj_set_style_text_color(battery_label, LVGL_BLACK, 0); + setLabelText(battery_label, buffer); + setLabelTextColor(battery_label, + darkMode ? LVGL_WHITE : LVGL_BLACK); } else { - lv_label_set_text(voltage_right_label, ""); + setLabelText(voltage_right_label, ""); } } - // Update power display with individual character positions + // Update power display with individual character positions. + // Compute the desired text for every position first, then diff-apply: the + // old clear-then-set pattern invalidated all 4 labels twice per frame. if (power_char_labels[0] != NULL) { // Check if power display is initialized + const char* power_texts[4] = {"", "", "", ""}; + char power_tens_buf[12]; + char power_ones_buf[12]; + char power_tenths_buf[12]; + if (bmsConnected || escConnected) { float kWatts = unifiedBatteryData.power; @@ -545,11 +616,6 @@ void updateLvglMainScreen( kWatts = 0.0f; } - // Clear all positions first - for (int i = 0; i < 4; i++) { - lv_label_set_text(power_char_labels[i], ""); - } - // Carry-safe rounding to one decimal place (e.g., 9.95 -> 10.0) int tenths_total = static_cast(kWatts * 10.0f + 0.5f); int whole_part = tenths_total / 10; @@ -559,39 +625,35 @@ void updateLvglMainScreen( int tens = whole_part / 10; int ones = whole_part % 10; - // Populate character positions using static buffers - static char power_digit_buffers[4][12]; - // Tens digit (only show if >= 10kW) if (tens > 0) { - snprintf(power_digit_buffers[0], sizeof(power_digit_buffers[0]), "%d", tens); - lv_label_set_text(power_char_labels[0], power_digit_buffers[0]); + snprintf(power_tens_buf, sizeof(power_tens_buf), "%d", tens); + power_texts[0] = power_tens_buf; } // Ones digit (always show) - snprintf(power_digit_buffers[1], sizeof(power_digit_buffers[1]), "%d", ones); - lv_label_set_text(power_char_labels[1], power_digit_buffers[1]); + snprintf(power_ones_buf, sizeof(power_ones_buf), "%d", ones); + power_texts[1] = power_ones_buf; // Decimal point - lv_label_set_text(power_char_labels[2], "."); + power_texts[2] = "."; // Tenths digit - snprintf(power_digit_buffers[3], sizeof(power_digit_buffers[3]), "%d", decimal_part); - lv_label_set_text(power_char_labels[3], power_digit_buffers[3]); + snprintf(power_tenths_buf, sizeof(power_tenths_buf), "%d", decimal_part); + power_texts[3] = power_tenths_buf; // Unit label is static and already set to "kW" - } else { - // Clear all positions when no data - for (int i = 0; i < 4; i++) { - lv_label_set_text(power_char_labels[i], ""); - } - // Keep unit label visible even when no data + } + // else: all positions clear when no data; unit label stays visible + + for (int i = 0; i < 4; i++) { + setLabelText(power_char_labels[i], power_texts[i]); } } // Update performance mode - Re-added this section if (perf_mode_label != NULL) { // Check object exists - lv_label_set_text(perf_mode_label, deviceData.performance_mode == 0 ? "CHILL " : "SPORT"); + setLabelText(perf_mode_label, deviceData.performance_mode == 0 ? "CHILL " : "SPORT"); } // Update armed time @@ -603,19 +665,20 @@ void updateLvglMainScreen( const int sessionSeconds = (armedStartMillis > 0) ? ((_lastArmedMillis - armedStartMillis) / 1000) : 0; char timeBuffer[10]; snprintf(timeBuffer, sizeof(timeBuffer), "%02d:%02d", sessionSeconds / 60, sessionSeconds % 60); - lv_label_set_text(armed_time_label, timeBuffer); + setLabelText(armed_time_label, timeBuffer); } - // Update altitude - populate individual character positions + // Update altitude - compute the desired text for all 7 character positions + // first, then diff-apply so unchanged digits are not redrawn. (The old + // clear-then-set pattern invalidated all 7 labels twice per frame.) + const char* altitude_texts[7] = {"", "", "", "", "", "", ""}; + char altitude_digit_buffers[7][12]; + if (altitude == __FLT_MIN__) { // Show error in first few positions - lv_label_set_text(altitude_char_labels[0], "E"); - lv_label_set_text(altitude_char_labels[1], "R"); - lv_label_set_text(altitude_char_labels[2], "R"); - lv_label_set_text(altitude_char_labels[3], ""); - lv_label_set_text(altitude_char_labels[4], ""); - lv_label_set_text(altitude_char_labels[5], ""); - lv_label_set_text(altitude_char_labels[6], ""); + altitude_texts[0] = "E"; + altitude_texts[1] = "R"; + altitude_texts[2] = "R"; } else { if (deviceData.metric_alt) { // Display meters if metric altitude is enabled // Explicitly handle small negative values to avoid "-0.0" @@ -638,14 +701,6 @@ void updateLvglMainScreen( int tens = (whole_part / 10) % 10; int ones = whole_part % 10; - // Populate each character position using static character buffers - static char digit_buffers[7][12]; // Static buffers for single digits - - // Clear all positions first - for (int i = 0; i < 7; i++) { - lv_label_set_text(altitude_char_labels[i], ""); - } - // Determine the leftmost digit position needed int leftmost_pos = 3; // ones position (always needed) if (whole_part >= 10) leftmost_pos = 2; // tens @@ -654,43 +709,45 @@ void updateLvglMainScreen( // Place negative sign if needed (one position left of leftmost digit) if (isNegative && leftmost_pos > 0) { - lv_label_set_text(altitude_char_labels[leftmost_pos - 1], "-"); + altitude_texts[leftmost_pos - 1] = "-"; } // Thousands digit if (thousands > 0) { - snprintf(digit_buffers[0], sizeof(digit_buffers[0]), "%d", thousands); - lv_label_set_text(altitude_char_labels[0], digit_buffers[0]); + snprintf(altitude_digit_buffers[0], sizeof(altitude_digit_buffers[0]), "%d", thousands); + altitude_texts[0] = altitude_digit_buffers[0]; } // Hundreds digit if (thousands > 0 || hundreds > 0) { - snprintf(digit_buffers[1], sizeof(digit_buffers[1]), "%d", hundreds); - lv_label_set_text(altitude_char_labels[1], digit_buffers[1]); + snprintf(altitude_digit_buffers[1], sizeof(altitude_digit_buffers[1]), "%d", hundreds); + altitude_texts[1] = altitude_digit_buffers[1]; } // Tens digit if (whole_part >= 10) { - snprintf(digit_buffers[2], sizeof(digit_buffers[2]), "%d", tens); - lv_label_set_text(altitude_char_labels[2], digit_buffers[2]); + snprintf(altitude_digit_buffers[2], sizeof(altitude_digit_buffers[2]), "%d", tens); + altitude_texts[2] = altitude_digit_buffers[2]; } // Ones digit (always show) - snprintf(digit_buffers[3], sizeof(digit_buffers[3]), "%d", ones); - lv_label_set_text(altitude_char_labels[3], digit_buffers[3]); + snprintf(altitude_digit_buffers[3], sizeof(altitude_digit_buffers[3]), "%d", ones); + altitude_texts[3] = altitude_digit_buffers[3]; // Decimal point - lv_label_set_text(altitude_char_labels[4], "."); + altitude_texts[4] = "."; // Tenths digit - snprintf(digit_buffers[5], sizeof(digit_buffers[5]), "%d", decimal_part); - lv_label_set_text(altitude_char_labels[5], digit_buffers[5]); + snprintf(altitude_digit_buffers[5], sizeof(altitude_digit_buffers[5]), "%d", decimal_part); + altitude_texts[5] = altitude_digit_buffers[5]; - // Adjust width of position 4 back to narrow for meters (decimal point) + // Adjust width of position 4 back to narrow for meters (decimal point). + // lv_obj_set_size is internally change-detected, so this is free when + // the unit mode hasn't changed. lv_obj_set_size(altitude_char_labels[4], 8, 30); // decimal_width=8, char_height=30 // Unit - lv_label_set_text(altitude_char_labels[6], "m"); + altitude_texts[6] = "m"; } else { // For feet - no decimal point needed float feet_float = altitude * 3.28084f; @@ -704,16 +761,9 @@ void updateLvglMainScreen( int tens = (feet / 10) % 10; int ones = feet % 10; - static char digit_buffers_ft[7][12]; // Static buffers for feet - // Adjust width of position 4 for feet (should be normal width, not narrow) lv_obj_set_size(altitude_char_labels[4], 17, 30); // char_width=19, char_height=30 - // Clear all positions first - for (int i = 0; i < 7; i++) { - lv_label_set_text(altitude_char_labels[i], ""); - } - // Determine the leftmost digit position needed int leftmost_pos = 4; // ones position (always needed for feet) if (feet >= 10) leftmost_pos = 3; // tens @@ -723,117 +773,154 @@ void updateLvglMainScreen( // Place negative sign if needed (one position left of leftmost digit) if (isNegative && leftmost_pos > 0) { - lv_label_set_text(altitude_char_labels[leftmost_pos - 1], "-"); + altitude_texts[leftmost_pos - 1] = "-"; } // Ten-thousands digit in position 0 if (ten_thousands > 0) { - snprintf(digit_buffers_ft[0], sizeof(digit_buffers_ft[0]), "%d", ten_thousands); - lv_label_set_text(altitude_char_labels[0], digit_buffers_ft[0]); + snprintf(altitude_digit_buffers[0], sizeof(altitude_digit_buffers[0]), "%d", ten_thousands); + altitude_texts[0] = altitude_digit_buffers[0]; } // Thousands digit in position 1 if (ten_thousands > 0 || thousands > 0) { - snprintf(digit_buffers_ft[1], sizeof(digit_buffers_ft[1]), "%d", thousands); - lv_label_set_text(altitude_char_labels[1], digit_buffers_ft[1]); + snprintf(altitude_digit_buffers[1], sizeof(altitude_digit_buffers[1]), "%d", thousands); + altitude_texts[1] = altitude_digit_buffers[1]; } // Hundreds digit in position 2 if (ten_thousands > 0 || thousands > 0 || hundreds > 0) { - snprintf(digit_buffers_ft[2], sizeof(digit_buffers_ft[2]), "%d", hundreds); - lv_label_set_text(altitude_char_labels[2], digit_buffers_ft[2]); + snprintf(altitude_digit_buffers[2], sizeof(altitude_digit_buffers[2]), "%d", hundreds); + altitude_texts[2] = altitude_digit_buffers[2]; } // Tens digit in position 3 if (feet >= 10) { - snprintf(digit_buffers_ft[3], sizeof(digit_buffers_ft[3]), "%d", tens); - lv_label_set_text(altitude_char_labels[3], digit_buffers_ft[3]); + snprintf(altitude_digit_buffers[3], sizeof(altitude_digit_buffers[3]), "%d", tens); + altitude_texts[3] = altitude_digit_buffers[3]; } // Ones digit in position 4 (always show) - now has normal width - snprintf(digit_buffers_ft[4], sizeof(digit_buffers_ft[4]), "%d", ones); - lv_label_set_text(altitude_char_labels[4], digit_buffers_ft[4]); + snprintf(altitude_digit_buffers[4], sizeof(altitude_digit_buffers[4]), "%d", ones); + altitude_texts[4] = altitude_digit_buffers[4]; // Feet unit in position 6 (same as meters, with proper spacing) - lv_label_set_text(altitude_char_labels[6], "f"); + altitude_texts[6] = "f"; } } - // Update temperature labels + for (int i = 0; i < 7; i++) { + setLabelText(altitude_char_labels[i], altitude_texts[i]); + } + + // Update temperature labels. + // Tile background styles (normal/warning/critical) are applied only on + // level transitions: add/remove_style invalidates the tile on every call, + // which used to redraw active warning tiles every single frame. // -- Battery Temperature -- if (batt_temp_label != NULL && batt_letter_label != NULL) { // Check labels exist - lv_obj_remove_style(batt_temp_bg, &style_warning, 0); - lv_obj_remove_style(batt_temp_bg, &style_critical, 0); - + uint8_t battTempLevel = 0; // 0 = normal/no data, 1 = warning, 2 = critical if (bmsTelemetry.bmsState == TelemetryState::CONNECTED && hasValidBatteryTemp) { - lv_label_set_text_fmt(batt_temp_label, "%d", static_cast(batteryTemp)); + char buffer[12]; + snprintf(buffer, sizeof(buffer), "%d", static_cast(batteryTemp)); + setLabelText(batt_temp_label, buffer); if (batteryTemp >= bmsCellTempThresholds.critHigh) { + battTempLevel = 2; + } else if (batteryTemp >= bmsCellTempThresholds.warnHigh) { + battTempLevel = 1; + } + } else { + // No valid cell probe connected: show "-" instead of a fake low reading. + setLabelText(batt_temp_label, "-"); + } + + if (battTempLevel != lastBattTempLevel) { + lv_obj_remove_style(batt_temp_bg, &style_warning, 0); + lv_obj_remove_style(batt_temp_bg, &style_critical, 0); + if (battTempLevel == 2) { lv_obj_add_style(batt_temp_bg, &style_critical, 0); lv_obj_remove_flag(batt_temp_bg, LV_OBJ_FLAG_HIDDEN); - } else if (batteryTemp >= bmsCellTempThresholds.warnHigh) { + } else if (battTempLevel == 1) { lv_obj_add_style(batt_temp_bg, &style_warning, 0); lv_obj_remove_flag(batt_temp_bg, LV_OBJ_FLAG_HIDDEN); } else { lv_obj_add_flag(batt_temp_bg, LV_OBJ_FLAG_HIDDEN); } - } else { - // No valid cell probe connected: show "-" instead of a fake low reading. - lv_label_set_text(batt_temp_label, "-"); - lv_obj_add_flag(batt_temp_bg, LV_OBJ_FLAG_HIDDEN); + lastBattTempLevel = battTempLevel; } } // -- ESC Temperature -- if (esc_temp_label != NULL && esc_letter_label != NULL) { // Check labels exist - lv_obj_remove_style(esc_temp_bg, &style_warning, 0); - lv_obj_remove_style(esc_temp_bg, &style_critical, 0); - + uint8_t escTempLevel = 0; if (escTelemetry.escState == TelemetryState::CONNECTED && !isnan(escTemp)) { - lv_label_set_text_fmt(esc_temp_label, "%d", static_cast(escTemp)); - + char buffer[12]; + snprintf(buffer, sizeof(buffer), "%d", static_cast(escTemp)); + setLabelText(esc_temp_label, buffer); if (escTemp >= escTempThresholds->critHigh) { + escTempLevel = 2; + } else if (escTemp >= escTempThresholds->warnHigh) { + escTempLevel = 1; + } + } else { + setLabelText(esc_temp_label, "-"); + } + + if (escTempLevel != lastEscTempLevel) { + lv_obj_remove_style(esc_temp_bg, &style_warning, 0); + lv_obj_remove_style(esc_temp_bg, &style_critical, 0); + if (escTempLevel == 2) { lv_obj_add_style(esc_temp_bg, &style_critical, 0); lv_obj_remove_flag(esc_temp_bg, LV_OBJ_FLAG_HIDDEN); - } else if (escTemp >= escTempThresholds->warnHigh) { + } else if (escTempLevel == 1) { lv_obj_add_style(esc_temp_bg, &style_warning, 0); lv_obj_remove_flag(esc_temp_bg, LV_OBJ_FLAG_HIDDEN); } else { lv_obj_add_flag(esc_temp_bg, LV_OBJ_FLAG_HIDDEN); } - } else { - lv_label_set_text(esc_temp_label, "-"); - lv_obj_add_flag(esc_temp_bg, LV_OBJ_FLAG_HIDDEN); + lastEscTempLevel = escTempLevel; } } // -- Motor Temperature -- if (motor_temp_label != NULL && motor_letter_label != NULL) { // Check labels exist - lv_obj_remove_style(motor_temp_bg, &style_warning, 0); - lv_obj_remove_style(motor_temp_bg, &style_critical, 0); - + uint8_t motorTempLevel = 0; // Show motor temp only for a valid numeric reading while ESC is connected. if (escTelemetry.escState == TelemetryState::CONNECTED && !isnan(motorTemp)) { - lv_label_set_text_fmt(motor_temp_label, "%d", static_cast(motorTemp)); - + char buffer[12]; + snprintf(buffer, sizeof(buffer), "%d", static_cast(motorTemp)); + setLabelText(motor_temp_label, buffer); if (motorTemp >= motorTempThresholds.critHigh) { + motorTempLevel = 2; + } else if (motorTemp >= motorTempThresholds.warnHigh) { + motorTempLevel = 1; + } + } else { + setLabelText(motor_temp_label, "-"); + } + + if (motorTempLevel != lastMotorTempLevel) { + lv_obj_remove_style(motor_temp_bg, &style_warning, 0); + lv_obj_remove_style(motor_temp_bg, &style_critical, 0); + if (motorTempLevel == 2) { lv_obj_add_style(motor_temp_bg, &style_critical, 0); lv_obj_remove_flag(motor_temp_bg, LV_OBJ_FLAG_HIDDEN); - } else if (motorTemp >= motorTempThresholds.warnHigh) { + } else if (motorTempLevel == 1) { lv_obj_add_style(motor_temp_bg, &style_warning, 0); lv_obj_remove_flag(motor_temp_bg, LV_OBJ_FLAG_HIDDEN); } else { lv_obj_add_flag(motor_temp_bg, LV_OBJ_FLAG_HIDDEN); } - } else { - lv_label_set_text(motor_temp_label, "-"); - lv_obj_add_flag(motor_temp_bg, LV_OBJ_FLAG_HIDDEN); + lastMotorTempLevel = motorTempLevel; } } // Update armed indicator if (armed) { - // Set background to CYAN when armed, regardless of cruise state - lv_obj_set_style_bg_color(arm_indicator, LVGL_CYAN, LV_PART_MAIN); + // Keep the armed tile bright in light mode and glare/contrast safe in dark. + setBgColor(arm_indicator, + darkMode ? LVGL_DARK_CYAN : LVGL_CYAN, + LV_PART_MAIN); lv_obj_remove_flag(arm_indicator, LV_OBJ_FLAG_HIDDEN); } else { lv_obj_add_flag(arm_indicator, LV_OBJ_FLAG_HIDDEN); @@ -848,11 +935,24 @@ void updateLvglMainScreen( lv_obj_add_flag(cruise_icon_img, LV_OBJ_FLAG_HIDDEN); } // Restore original color after flashing is done - lv_obj_set_style_image_recolor(cruise_icon_img, original_cruise_icon_color, LV_PART_MAIN); + setImageRecolor(cruise_icon_img, original_cruise_icon_color); } // Update Charging Icon Visibility - only when BMS is connected and reports charging if (charging_icon_img != NULL) { // Check object exists + // Re-align to the live battery label. lv_obj_align_to() stamps an absolute + // position once and keeps no binding to the base object, but battery_label + // is centre-aligned and re-centres itself every time its text changes - so + // a position stamped at setup (when the label is still empty) leaves the + // icon sitting on top of the percentage digits. Only re-align when the + // width actually changed; the call invalidates the icon. + if (battery_label != NULL) { + const int32_t battW = lv_obj_get_width(battery_label); + if (battW != lastChargingIconBattW) { + lv_obj_align_to(charging_icon_img, battery_label, LV_ALIGN_OUT_RIGHT_MID, 3, 0); + lastChargingIconBattW = battW; + } + } bool showChargingIcon = (bmsTelemetry.bmsState == TelemetryState::CONNECTED) && bmsTelemetry.is_charging; if (showChargingIcon) { lv_obj_remove_flag(charging_icon_img, LV_OBJ_FLAG_HIDDEN); @@ -866,11 +966,11 @@ void updateLvglMainScreen( if (!isFlashingArmFailIcon && arm_fail_warning_icon_img != NULL) { lv_obj_add_flag(arm_fail_warning_icon_img, LV_OBJ_FLAG_HIDDEN); // Ensure color is reset if flashing ended abruptly elsewhere (though cb should handle it) - lv_obj_set_style_image_recolor(arm_fail_warning_icon_img, original_arm_fail_icon_color, LV_PART_MAIN); + setImageRecolor(arm_fail_warning_icon_img, original_arm_fail_icon_color); } // Keep the BLE icon synced from the UI task so missed callback updates recover. - // Pairing mode flash takes priority over the solid-connected state — the + // Pairing mode flash takes priority over the solid-connected state - the // flashing Bluetooth symbol communicates "ready to pair" for the entire 60s // window, even after the phone has connected. Once the window ends the icon // settles solid (if still connected) or hides. @@ -917,7 +1017,7 @@ void updateLvglMainScreen( climbRate = altitudeChange / timeChange; // m/s } } - updateClimbRateIndicator(climbRate); + updateClimbRateIndicator(climbRate, darkMode); lastAltitude = altitude; lastAltitudeTime = currentTime; } diff --git a/src/sp140/main.cpp b/src/sp140/main.cpp index 4c64584d..4bf98b8e 100644 --- a/src/sp140/main.cpp +++ b/src/sp140/main.cpp @@ -29,6 +29,8 @@ #include "../../inc/sp140/ble/fastlink_service.h" #include "../../inc/sp140/bms.h" #include "../../inc/sp140/esc.h" +#include "../../inc/sp140/esc_config_relay.h" +#include "../../inc/sp140/esc_flasher_relay.h" #include "../../inc/sp140/globals.h" // device config #include "../../inc/sp140/lvgl/lvgl_alerts.h" #include "../../inc/sp140/lvgl/lvgl_core.h" @@ -348,6 +350,10 @@ void bleNotifyTask(void *pvParameters) { publishFastLinkTelemetry(hub, currentState); } + // Push ESC config-relay status + result blob over notify (config-service + // GATT reads return null on this stack; notify is reliable). + pumpEscRelayNotify(); + if (!isOtaInProgress()) { setAndNotifyOnChange(pDeviceStateCharacteristic, static_cast(currentState), lastNotifiedState); @@ -469,10 +475,10 @@ void monitoringTask(void *pvParameters) { } } -// UI task: fixed 20 Hz refresh and snapshot publish +// UI task: fixed ~30 Hz refresh and snapshot publish void uiTask(void *pvParameters) { TickType_t lastWake = xTaskGetTickCount(); - const TickType_t uiTicks = pdMS_TO_TICKS(50); // 20 Hz + const TickType_t uiTicks = pdMS_TO_TICKS(33); // ~30 Hz, matches LV_DEF_REFR_PERIOD for (;;) { refreshDisplay(); lastUiRunMs = millis(); @@ -487,8 +493,23 @@ void bmsTask(void *pvParameters) { for (;;) { if (bmsCanInitialized) { updateBMSData(); - if (bms_can->isConnected()) { - bmsTelemetryData.bmsState = TelemetryState::CONNECTED; + // Coherent-snapshot gate: report CONNECTED only after the pack-voltage + // and cell-voltage frames have both arrived, so monitors and the UI + // never see the half-populated data a fresh link starts with. + // + // Latched on purpose. This orders the first few frames at link-up and + // has no legitimate work to do afterwards — re-evaluating it every cycle + // would let a live-but-faulted pack (one collapsed cell) read as "no + // data" and silently drop the BMS out of the alert system entirely. + // Genuine link loss is still caught by isConnected() below. + static bool bmsSnapshotEverCoherent = false; + if (bms_can->isConnected(BMS_LINK_TIMEOUT_MS)) { + if (!bmsSnapshotEverCoherent && bmsSnapshotCoherent(bmsTelemetryData)) { + bmsSnapshotEverCoherent = true; + } + bmsTelemetryData.bmsState = bmsSnapshotEverCoherent + ? TelemetryState::CONNECTED + : TelemetryState::NOT_CONNECTED; } else { bmsTelemetryData.bmsState = TelemetryState::NOT_CONNECTED; } @@ -563,7 +584,12 @@ void setupAnalogRead() { void setupWatchdog() { #ifndef OPENPPG_DEBUG - // Initialize Task Watchdog (reboot on timeout) + // Initialize Task Watchdog (reboot on timeout). The idle-task checks on both + // cores are deliberately DISABLED in sdkconfig + // (CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0/CPU1=n) so the watchdog scope is + // exactly the tasks that explicitly subscribe (throttleTask + watchdogTask). + // Otherwise any non-safety task (UI/BMS/BLE) monopolizing a core for >5 s + // would panic-reboot a flying device — the opposite of the intent. ESP_ERROR_CHECK(esp_task_wdt_init(WDT_TIMEOUT_SECONDS, true)); #endif // OPENPPG_DEBUG } @@ -998,6 +1024,14 @@ void toggleArm() { return; } + // Block arming while an ESC config-relay or firmware-relay session is in + // flight (the ESC may be mid-reboot / in the bootloader). Mirrors the OTA + // interlock above. + if (escConfigRelayIsActive() || escFlasherRelayIsActive()) { + USBSerial.println("Arm blocked: ESC config/firmware relay in progress"); + return; + } + // Check if enough time has passed since last disarm if (millis() - lastDisarmTime >= DISARM_COOLDOWN) { if (!throttleEngaged()) { @@ -1147,7 +1181,16 @@ void handleThrottle() { break; } - setESCThrottle(finalPwm); + // Suppress the ESC control/telemetry command during a config/firmware relay + // session. setESCThrottle() pings the ESC every cycle and the ESC answers with + // a burst of high-rate telemetry; that flood overruns the CAN RX buffer and the + // SaveConfig reply gets dropped, so the write times out. flash-qc works because + // its bus is quiet. The device is always DISARMED during a session, so there is + // no throttle to send anyway. readESCTelemetry() still runs — it pumps the bus + // and drives the relay state machine. + if (!escConfigRelayIsActive() && !escFlasherRelayIsActive()) { + setESCThrottle(finalPwm); + } // Read/Sync ESC Telemetry (runs in all armed states) readESCTelemetry(); diff --git a/src/sp140/simple_monitor.cpp b/src/sp140/simple_monitor.cpp index 6c7a2295..50752e4a 100644 --- a/src/sp140/simple_monitor.cpp +++ b/src/sp140/simple_monitor.cpp @@ -282,6 +282,18 @@ const char* sensorIDToAbbreviationWithLevel(SensorID id, AlertLevel level) { } return "BC-T4"; // Default + // Cell voltage monitors: suffix reflects the fired direction, not the + // monitor's name. A low-side fire on the high monitor used to display + // "BC-CV-H" for a 0 V (no data) reading. + case SensorID::BMS_High_Cell_Voltage: + case SensorID::BMS_Low_Cell_Voltage: + if (level == AlertLevel::WARN_HIGH || level == AlertLevel::CRIT_HIGH) { + return "BC-CV-H"; // Cell voltage high + } else if (level == AlertLevel::WARN_LOW || level == AlertLevel::CRIT_LOW) { + return "BC-CV-L"; // Cell voltage low + } + return "BC-CV"; // Default + // For all other sensors, use the standard abbreviation default: return sensorIDToAbbreviation(id); @@ -354,14 +366,37 @@ void checkAllSensorsWithData(const STR_ESC_TELEMETRY_140& escData, } } + // Grace period: a BMS that is itself still booting can emit sentinel/garbage + // readings in its first frames. Hold BMS monitors off briefly after the FIRST + // connect so half-baked data can never fire alerts. + // + // One-shot by design. Re-arming on every reconnect edge would mean each + // transient link drop — a chattering connector, or the SPI-mutex bail in + // updateBMSData() — blanks all BMS monitoring for another 2 s, right after + // the disconnect edge above already force-cleared every BMS alert. A real + // in-flight critical would vanish from the screen and could not be re-raised; + // flaps recurring faster than the grace would suppress it indefinitely. The + // booting-BMS garbage this protects against only happens once per power-on. + static uint32_t bmsGraceStartMs = 0; + static bool bmsGraceStarted = false; + static bool bmsGraceExpired = false; if (!prevBmsConnected && bmsConnected) { USBSerial.println("[MONITOR] BMS reconnected - resetting BMS monitor states"); + if (!bmsGraceStarted) { + bmsGraceStartMs = millis(); + bmsGraceStarted = true; + } for (auto* monitor : monitors) { if (monitor && monitor->getCategory() == SensorCategory::BMS) { monitor->resetState(); } } } + if (bmsGraceStarted && !bmsGraceExpired && + (millis() - bmsGraceStartMs >= BMS_ALERT_GRACE_MS)) { + bmsGraceExpired = true; + } + const bool bmsMonitorsArmed = bmsConnected && bmsGraceExpired; // Update previous connection states prevEscConnected = escConnected; @@ -383,7 +418,7 @@ void checkAllSensorsWithData(const STR_ESC_TELEMETRY_140& escData, shouldRun = escConnected; break; case SensorCategory::BMS: - shouldRun = bmsConnected; + shouldRun = bmsMonitorsArmed; break; case SensorCategory::ALTIMETER: case SensorCategory::INTERNAL: diff --git a/test/test_screenshots/CMakeLists.txt b/test/test_screenshots/CMakeLists.txt index a489df47..37e5cba5 100644 --- a/test/test_screenshots/CMakeLists.txt +++ b/test/test_screenshots/CMakeLists.txt @@ -59,6 +59,7 @@ target_compile_options(lvgl PRIVATE -w) # Project UI source files (the actual code under test) set(UI_SOURCES + ${PROJECT_ROOT}/src/sp140/lvgl/lvgl_splash.cpp ${PROJECT_ROOT}/src/sp140/lvgl/lvgl_main_screen.cpp ${PROJECT_ROOT}/src/sp140/lvgl/lvgl_updates.cpp ${PROJECT_ROOT}/src/sp140/lvgl/lvgl_alerts.cpp diff --git a/test/test_screenshots/build_and_run.sh b/test/test_screenshots/build_and_run.sh index 849f30b9..7655bcea 100755 --- a/test/test_screenshots/build_and_run.sh +++ b/test/test_screenshots/build_and_run.sh @@ -85,6 +85,11 @@ fi mkdir -p "$BUILD_DIR" +# --local uses RelWithDebInfo: optimized binary (5-10x faster renderer) with +# debug symbols. CI keeps Debug for faithful failure diagnostics. +BUILD_TYPE="Debug" +[ "$LOCAL_BUILD" = 1 ] && BUILD_TYPE="RelWithDebInfo" + # If the cached generator or build type no longer matches, clear the build dir once. if [ -f "$BUILD_DIR/CMakeCache.txt" ]; then cached_gen=$(grep '^CMAKE_GENERATOR:INTERNAL=' "$BUILD_DIR/CMakeCache.txt" 2>/dev/null | cut -d= -f2) @@ -102,10 +107,6 @@ cd "$BUILD_DIR" echo "" echo "--- Configuring CMake ---" -# --local uses RelWithDebInfo: optimized binary (5-10x faster renderer) with debug symbols. -# CI keeps Debug for faithful failure diagnostics. -BUILD_TYPE="Debug" -[ "$LOCAL_BUILD" = 1 ] && BUILD_TYPE="RelWithDebInfo" # shellcheck disable=SC2086 cmake "$SCRIPT_DIR" \ -DCMAKE_BUILD_TYPE="$BUILD_TYPE" \ diff --git a/test/test_screenshots/emulator_display.cpp b/test/test_screenshots/emulator_display.cpp index 307385f9..b0fce4a6 100644 --- a/test/test_screenshots/emulator_display.cpp +++ b/test/test_screenshots/emulator_display.cpp @@ -20,7 +20,6 @@ static uint8_t lvgl_buf1[SCREEN_WIDTH * SCREEN_HEIGHT * 2] __attribute__((aligne lv_display_t* main_display = nullptr; int8_t displayCS = -1; Adafruit_ST7735* tft_driver = nullptr; -uint32_t lvgl_last_update = 0; SemaphoreHandle_t spiBusMutex = nullptr; // Define lvglMutex from lvgl_updates.h diff --git a/test/test_screenshots/reference/main_armed_cruising_dark.bmp b/test/test_screenshots/reference/main_armed_cruising_dark.bmp index 80f7eb0f..4b3e5be6 100644 Binary files a/test/test_screenshots/reference/main_armed_cruising_dark.bmp and b/test/test_screenshots/reference/main_armed_cruising_dark.bmp differ diff --git a/test/test_screenshots/reference/main_armed_flying_dark.bmp b/test/test_screenshots/reference/main_armed_flying_dark.bmp index 79398c28..4075255e 100644 Binary files a/test/test_screenshots/reference/main_armed_flying_dark.bmp and b/test/test_screenshots/reference/main_armed_flying_dark.bmp differ diff --git a/test/test_screenshots/reference/main_ble_pairing_dark.bmp b/test/test_screenshots/reference/main_ble_pairing_dark.bmp index 0cce0ac3..8f619ac4 100644 Binary files a/test/test_screenshots/reference/main_ble_pairing_dark.bmp and b/test/test_screenshots/reference/main_ble_pairing_dark.bmp differ diff --git a/test/test_screenshots/reference/main_charging_dark.bmp b/test/test_screenshots/reference/main_charging_dark.bmp index 5e2674fe..37b30976 100644 Binary files a/test/test_screenshots/reference/main_charging_dark.bmp and b/test/test_screenshots/reference/main_charging_dark.bmp differ diff --git a/test/test_screenshots/reference/main_charging_light.bmp b/test/test_screenshots/reference/main_charging_light.bmp index 3a878544..9bee7237 100644 Binary files a/test/test_screenshots/reference/main_charging_light.bmp and b/test/test_screenshots/reference/main_charging_light.bmp differ diff --git a/test/test_screenshots/reference/main_critical_alerts_dark.bmp b/test/test_screenshots/reference/main_critical_alerts_dark.bmp index 2935d689..8f0d8dee 100644 Binary files a/test/test_screenshots/reference/main_critical_alerts_dark.bmp and b/test/test_screenshots/reference/main_critical_alerts_dark.bmp differ diff --git a/test/test_screenshots/reference/main_esc_disconnected_dark.bmp b/test/test_screenshots/reference/main_esc_disconnected_dark.bmp index 09e64a04..d36c2794 100644 Binary files a/test/test_screenshots/reference/main_esc_disconnected_dark.bmp and b/test/test_screenshots/reference/main_esc_disconnected_dark.bmp differ diff --git a/test/test_screenshots/reference/main_full_battery_dark.bmp b/test/test_screenshots/reference/main_full_battery_dark.bmp index ca1a7f5f..81cdb688 100644 Binary files a/test/test_screenshots/reference/main_full_battery_dark.bmp and b/test/test_screenshots/reference/main_full_battery_dark.bmp differ diff --git a/test/test_screenshots/reference/main_high_altitude_dark.bmp b/test/test_screenshots/reference/main_high_altitude_dark.bmp index bcd5fd3e..b459fae0 100644 Binary files a/test/test_screenshots/reference/main_high_altitude_dark.bmp and b/test/test_screenshots/reference/main_high_altitude_dark.bmp differ diff --git a/test/test_screenshots/reference/main_high_power_dark.bmp b/test/test_screenshots/reference/main_high_power_dark.bmp index f29eddb5..29e9376d 100644 Binary files a/test/test_screenshots/reference/main_high_power_dark.bmp and b/test/test_screenshots/reference/main_high_power_dark.bmp differ diff --git a/test/test_screenshots/reference/main_idle_dark.bmp b/test/test_screenshots/reference/main_idle_dark.bmp index 7c28ff81..5cc9784d 100644 Binary files a/test/test_screenshots/reference/main_idle_dark.bmp and b/test/test_screenshots/reference/main_idle_dark.bmp differ diff --git a/test/test_screenshots/reference/main_low_battery_dark.bmp b/test/test_screenshots/reference/main_low_battery_dark.bmp index 9fe1cfe1..1c786e5a 100644 Binary files a/test/test_screenshots/reference/main_low_battery_dark.bmp and b/test/test_screenshots/reference/main_low_battery_dark.bmp differ diff --git a/test/test_screenshots/reference/main_max_climb_dark.bmp b/test/test_screenshots/reference/main_max_climb_dark.bmp new file mode 100644 index 00000000..7443dd95 Binary files /dev/null and b/test/test_screenshots/reference/main_max_climb_dark.bmp differ diff --git a/test/test_screenshots/reference/main_max_climb_light.bmp b/test/test_screenshots/reference/main_max_climb_light.bmp new file mode 100644 index 00000000..9c79e797 Binary files /dev/null and b/test/test_screenshots/reference/main_max_climb_light.bmp differ diff --git a/test/test_screenshots/reference/main_max_descent_dark.bmp b/test/test_screenshots/reference/main_max_descent_dark.bmp new file mode 100644 index 00000000..0d3546d3 Binary files /dev/null and b/test/test_screenshots/reference/main_max_descent_dark.bmp differ diff --git a/test/test_screenshots/reference/main_max_descent_light.bmp b/test/test_screenshots/reference/main_max_descent_light.bmp new file mode 100644 index 00000000..4c03dda0 Binary files /dev/null and b/test/test_screenshots/reference/main_max_descent_light.bmp differ diff --git a/test/test_screenshots/reference/main_temp_critical_dark.bmp b/test/test_screenshots/reference/main_temp_critical_dark.bmp index 63961a01..f9f4bbfb 100644 Binary files a/test/test_screenshots/reference/main_temp_critical_dark.bmp and b/test/test_screenshots/reference/main_temp_critical_dark.bmp differ diff --git a/test/test_screenshots/reference/main_temp_warnings_dark.bmp b/test/test_screenshots/reference/main_temp_warnings_dark.bmp index a45873a5..fede4979 100644 Binary files a/test/test_screenshots/reference/main_temp_warnings_dark.bmp and b/test/test_screenshots/reference/main_temp_warnings_dark.bmp differ diff --git a/test/test_screenshots/reference/main_warning_alerts_dark.bmp b/test/test_screenshots/reference/main_warning_alerts_dark.bmp index cb3c4f6a..a85c1dd1 100644 Binary files a/test/test_screenshots/reference/main_warning_alerts_dark.bmp and b/test/test_screenshots/reference/main_warning_alerts_dark.bmp differ diff --git a/test/test_screenshots/reference/splash_dark.bmp b/test/test_screenshots/reference/splash_dark.bmp index 001d6d8a..495549f7 100644 Binary files a/test/test_screenshots/reference/splash_dark.bmp and b/test/test_screenshots/reference/splash_dark.bmp differ diff --git a/test/test_screenshots/reference/splash_light.bmp b/test/test_screenshots/reference/splash_light.bmp index 85ad8df0..645e4625 100644 Binary files a/test/test_screenshots/reference/splash_light.bmp and b/test/test_screenshots/reference/splash_light.bmp differ diff --git a/test/test_screenshots/test_screenshots.cpp b/test/test_screenshots/test_screenshots.cpp index 804436cc..81995374 100644 --- a/test/test_screenshots/test_screenshots.cpp +++ b/test/test_screenshots/test_screenshots.cpp @@ -8,6 +8,7 @@ #include "sp140/lvgl/lvgl_main_screen.h" #include "sp140/lvgl/lvgl_updates.h" #include "sp140/lvgl/lvgl_alerts.h" +#include "sp140/lvgl/lvgl_splash.h" #include "sp140/structs.h" #include "version.h" @@ -21,7 +22,11 @@ static bool file_exists(const char* path) { } static void ensure_output_dir() { +#ifdef _WIN32 + mkdir(OUTPUT_DIR); // MinGW mkdir has no mode argument +#else mkdir(OUTPUT_DIR, 0755); +#endif } // Create default device data for testing @@ -112,12 +117,16 @@ class ScreenshotTest : public ::testing::Test { const STR_BMS_TELEMETRY_140& bms, const UnifiedBatteryData& ubd, float altitude, bool armed, bool cruising, - unsigned int armedStartMillis = 0) { + unsigned int armedStartMillis = 0, + float climbRate = NAN) { emulator_init_display(darkMode); setupMainScreen(darkMode); // Apply data updateLvglMainScreen(dd, esc, bms, ubd, altitude, armed, cruising, armedStartMillis); + if (!std::isnan(climbRate)) { + updateClimbRateIndicator(climbRate, darkMode); + } // Render emulator_render_frame(); @@ -271,6 +280,46 @@ TEST_F(ScreenshotTest, MainScreen_HighAltitude_Dark) { 2456.8f, true, false, millis() - 900000); } +TEST_F(ScreenshotTest, MainScreen_MaxClimb_Light) { + auto dd = make_default_device_data(false); + auto esc = make_esc_connected(); + auto bms = make_bms_connected(); + auto ubd = make_unified_battery(65.0f, 86.0f, 8.5f); + + render_and_save("main_max_climb_light", false, dd, esc, bms, ubd, + 450.3f, true, false, millis() - 180000, 3.0f); +} + +TEST_F(ScreenshotTest, MainScreen_MaxClimb_Dark) { + auto dd = make_default_device_data(true); + auto esc = make_esc_connected(); + auto bms = make_bms_connected(); + auto ubd = make_unified_battery(65.0f, 86.0f, 8.5f); + + render_and_save("main_max_climb_dark", true, dd, esc, bms, ubd, + 450.3f, true, false, millis() - 180000, 3.0f); +} + +TEST_F(ScreenshotTest, MainScreen_MaxDescent_Light) { + auto dd = make_default_device_data(false); + auto esc = make_esc_connected(); + auto bms = make_bms_connected(); + auto ubd = make_unified_battery(65.0f, 86.0f, 8.5f); + + render_and_save("main_max_descent_light", false, dd, esc, bms, ubd, + 450.3f, true, false, millis() - 180000, -3.0f); +} + +TEST_F(ScreenshotTest, MainScreen_MaxDescent_Dark) { + auto dd = make_default_device_data(true); + auto esc = make_esc_connected(); + auto bms = make_bms_connected(); + auto ubd = make_unified_battery(65.0f, 86.0f, 8.5f); + + render_and_save("main_max_descent_dark", true, dd, esc, bms, ubd, + 450.3f, true, false, millis() - 180000, -3.0f); +} + TEST_F(ScreenshotTest, MainScreen_HighPower_Light) { auto dd = make_default_device_data(false); dd.performance_mode = 2; @@ -520,7 +569,7 @@ TEST_F(ScreenshotTest, MainScreen_CriticalAlerts_Light) { lv_showAlertTextWithLevel(SensorID::ESC_MOS_Temp, AlertLevel::WARN_HIGH, false); if (critical_border != NULL) { - lv_obj_set_style_border_opa(critical_border, LV_OPA_100, LV_PART_MAIN); + setCriticalBorderOpacity(LV_OPA_100); } emulator_render_frame(); @@ -547,7 +596,7 @@ TEST_F(ScreenshotTest, MainScreen_CriticalAlerts_Dark) { lv_showAlertTextWithLevel(SensorID::ESC_MOS_Temp, AlertLevel::WARN_HIGH, false); if (critical_border != NULL) { - lv_obj_set_style_border_opa(critical_border, LV_OPA_100, LV_PART_MAIN); + setCriticalBorderOpacity(LV_OPA_100); } emulator_render_frame(); @@ -597,43 +646,31 @@ TEST_F(ScreenshotTest, MainScreen_BLEPairing_Dark) { } // ============================================================ -// Splash screen tests (recreated from lvgl_core.cpp displayLvglSplash) -// Uses VERSION_MAJOR/VERSION_MINOR from version.h so references -// auto-update on rebuild after a version bump — just run -// build_and_run.sh --update-references after changing the version. +// Splash screen tests use the production builder. The compiled version text is +// asserted separately, then replaced with the stable v8.1 fixture value before +// pixel comparison so a version bump does not invalidate an otherwise-identical +// golden image. // ============================================================ // Helper to render a splash screen and save/compare static void render_splash(const char* name, bool darkMode) { - lv_obj_t* splash_screen = lv_obj_create(NULL); - lv_screen_load(splash_screen); - lv_obj_remove_flag(splash_screen, LV_OBJ_FLAG_SCROLLABLE); - lv_obj_set_style_bg_color(splash_screen, - darkMode ? lv_color_black() : lv_color_white(), - LV_PART_MAIN); - - lv_obj_t* title_label = lv_label_create(splash_screen); - lv_label_set_text(title_label, "OpenPPG"); - lv_obj_set_style_text_font(title_label, &lv_font_montserrat_28, 0); - lv_obj_set_style_text_color(title_label, - darkMode ? lv_color_white() : lv_color_black(), 0); - lv_obj_align(title_label, LV_ALIGN_TOP_MID, 0, 15); - - lv_obj_t* version_label = lv_label_create(splash_screen); - char version_str[10]; - snprintf(version_str, sizeof(version_str), "v%d.%d", VERSION_MAJOR, VERSION_MINOR); - lv_label_set_text(version_label, version_str); - lv_obj_set_style_text_font(version_label, &lv_font_montserrat_16, 0); - lv_obj_set_style_text_color(version_label, - darkMode ? lv_color_white() : lv_color_black(), 0); - lv_obj_align(version_label, LV_ALIGN_CENTER, 0, 0); - - lv_obj_t* time_label = lv_label_create(splash_screen); - lv_label_set_text(time_label, "02:05"); - lv_obj_set_style_text_font(time_label, &lv_font_montserrat_16, 0); - lv_obj_set_style_text_color(time_label, - darkMode ? lv_color_white() : lv_color_black(), 0); - lv_obj_align(time_label, LV_ALIGN_BOTTOM_MID, 0, -20); + auto dd = make_default_device_data(darkMode); + lv_obj_t* splash_screen = createLvglSplashScreen(dd); + + ASSERT_EQ(3u, lv_obj_get_child_count(splash_screen)); + lv_obj_t* version_label = lv_obj_get_child(splash_screen, 1); + char expected_version[10]; + snprintf(expected_version, sizeof(expected_version), "v%d.%d", VERSION_MAJOR, + VERSION_MINOR); + EXPECT_STREQ(expected_version, lv_label_get_text(version_label)); + + // Preserve visual coverage for the version label's position, font, color, + // and representative glyphs without coupling the golden to release metadata. + lv_label_set_text(version_label, "v8.1"); + + // Compare the stable, fully-visible splash state after the production title + // fade has completed. + lv_tick_inc(500); emulator_render_frame(); diff --git a/test/test_simplemonitor/test_simplemonitor.cpp b/test/test_simplemonitor/test_simplemonitor.cpp index 380f5538..1611c076 100644 --- a/test/test_simplemonitor/test_simplemonitor.cpp +++ b/test/test_simplemonitor/test_simplemonitor.cpp @@ -342,6 +342,100 @@ TEST(SimpleMonitor, BMSCellProbeSanitizerPassesThroughValidTemps) { EXPECT_FLOAT_EQ(out[3], 40.0f); } +// Regression: SensorMonitor fires at v <= critLow, and the high-cell monitor's +// critLow used to be 0.0 — so a zero-initialized (pre-data) reading fired a +// critical that displayed as "BC-CV-H" at every boot with a BMS connected. +TEST(SimpleMonitor, BMSHighCellVoltageZeroReadingDoesNotAlert) { + FakeLogger logger; + float fakeVoltage = 0.0f; + + SensorMonitor highCellMon( + SensorID::BMS_High_Cell_Voltage, + SensorCategory::BMS, + bmsHighCellVoltageThresholds, + [&]() { return fakeVoltage; }, + &logger); + + highCellMon.check(); + EXPECT_TRUE(logger.entries.empty()); + + // Genuine high readings still alert. + fakeVoltage = 4.21f; + highCellMon.check(); + ASSERT_EQ(logger.entries.size(), 1u); + EXPECT_EQ(logger.entries.back().lvl, AlertLevel::CRIT_HIGH); +} + +// A fresh BMS link populates its snapshot from several CAN frames; the state +// must not report CONNECTED until both basic frames have arrived. +TEST(SimpleMonitor, BmsSnapshotCoherentRequiresBothBasicFrames) { + STR_BMS_TELEMETRY_140 t = {}; + EXPECT_FALSE(bmsSnapshotCoherent(t)); // nothing received + + t.battery_voltage = 96.0f; // basic info 1 only + EXPECT_FALSE(bmsSnapshotCoherent(t)); + + t.battery_voltage = 0.0f; // basic info 2 only + t.highest_cell_voltage = 4.0f; + EXPECT_FALSE(bmsSnapshotCoherent(t)); + + t.battery_voltage = 96.0f; // both received + EXPECT_TRUE(bmsSnapshotCoherent(t)); +} + +// Regression: keying coherence on the LOWEST cell voltage made a shorted cell +// or broken sense lead (lowest -> 0.000 V on a healthy, still-transmitting +// pack) read as "no data", dropping the whole BMS to NOT_CONNECTED and +// silencing the low-cell and voltage-differential alerts that exist to catch +// exactly that fault. +TEST(SimpleMonitor, BmsSnapshotCoherentSurvivesCollapsedCell) { + STR_BMS_TELEMETRY_140 t = {}; + t.battery_voltage = 88.0f; + t.highest_cell_voltage = 3.95f; + + t.lowest_cell_voltage = 0.0f; // cell shorted / sense lead open + EXPECT_TRUE(bmsSnapshotCoherent(t)); + + t.lowest_cell_voltage = 0.30f; // collapsing cell + EXPECT_TRUE(bmsSnapshotCoherent(t)); +} + +// The low-cell monitor must still fire for a collapsed cell once the snapshot +// is considered coherent — this is the alert the gate must never suppress. +TEST(SimpleMonitor, BMSLowCellVoltageAlertsOnCollapsedCell) { + FakeLogger logger; + float lowestCell = 3.9f; + + SensorMonitor lowCellMon( + SensorID::BMS_Low_Cell_Voltage, + SensorCategory::BMS, + bmsLowCellVoltageThresholds, + [&]() { return lowestCell; }, + &logger); + + lowCellMon.check(); // healthy + EXPECT_TRUE(logger.entries.empty()); + + lowestCell = 0.30f; // collapsed cell + lowCellMon.check(); + ASSERT_EQ(logger.entries.size(), 1u); + EXPECT_EQ(logger.entries.back().lvl, AlertLevel::CRIT_LOW); +} + +// Before the first temperature frame, every probe reads NaN — that must be +// treated as "no data yet", not "all probes disconnected". +TEST(SimpleMonitor, BmsTempFrameSeenDetection) { + const float allNaN[BMS_CELL_PROBE_COUNT] = {NAN, NAN, NAN, NAN}; + EXPECT_FALSE(bmsTempFrameSeen(NAN, NAN, allNaN)); + + // Internal BMS sensors prove the frame arrived even with all probes out. + EXPECT_TRUE(bmsTempFrameSeen(32.0f, NAN, allNaN)); + EXPECT_TRUE(bmsTempFrameSeen(NAN, 30.0f, allNaN)); + + const float oneProbe[BMS_CELL_PROBE_COUNT] = {NAN, 27.0f, NAN, NAN}; + EXPECT_TRUE(bmsTempFrameSeen(NAN, NAN, oneProbe)); +} + TEST(SimpleMonitor, BMSCellProbeDisconnectTransitionTriggersAndClearsAlert) { FakeLogger logger; float sanitizedTemps[BMS_CELL_PROBE_COUNT] = {NAN, NAN, NAN, NAN};