Three bugs and two UX defects found on review, plus hardening: - The control loop fed the task watchdog then slept exactly the watchdog period (both 10s), tripping the TWDT fractionally late on every single iteration. Sleep is now sliced 1s with a reset per slice. Also set CONFIG_ESP_TASK_WDT_PANIC=y - the sdkconfig comment claimed a hung task panics the chip, but nothing actually made that true. - The LVGL flush called draw_bitmap (which only queues the framebuffer switch) and released LVGL immediately, letting it render the next frame into the buffer still being scanned out - the exact PRD 8.2 race the double-buffer design exists to prevent. display_present_frame() now blocks on a vsync handshake until the swap has latched. - WiFi reconnect slept up to 30s inside the system event handler, stalling all queued WiFi/IP events. Moved to an esp_timer. - The setpoint label, arc, and mode/room lines rendered the control loop's copy of state, which refreshes every 10s - every knob detent looked dead for up to 10 seconds. The UI now reads settings live; when the fallback ladder clamps the setpoint it shows both values. Room-select focus now shows which room is being selected. - z2m ISO_8601_local timestamps carry a UTC offset the parser ignored, which would shift apparent reading age by the local offset (5-6h in the US) and permanently trip the fallback ladder. Offset is now honoured. - Suppressed the cosmetic "control loop stopped" fault in the window between relay_init and the control task's first call-in at boot. - Explicit pullups on the encoder A/B lines. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
96 lines
4.3 KiB
Plaintext
96 lines
4.3 KiB
Plaintext
# Rotary Thermostat — ESP32-S3, 16MB flash, 8MB octal PSRAM
|
|
#
|
|
# Several entries here are load-bearing for the RGB panel. Read the comments
|
|
# before changing any of them; PRD section 8.2 documents what each one costs.
|
|
|
|
CONFIG_IDF_TARGET="esp32s3"
|
|
|
|
# --- Flash -------------------------------------------------------------------
|
|
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
|
|
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
|
|
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
|
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
|
|
|
# --- PSRAM -------------------------------------------------------------------
|
|
# Octal (OPI) PSRAM. The vendor's Arduino build uses qio_opi; same thing.
|
|
CONFIG_SPIRAM=y
|
|
CONFIG_SPIRAM_MODE_OCT=y
|
|
CONFIG_SPIRAM_SPEED_80M=y
|
|
CONFIG_SPIRAM_USE_MALLOC=y
|
|
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384
|
|
CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y
|
|
#
|
|
# PRD 8.2: these two contend with the LCD for PSRAM bandwidth and produce a
|
|
# black screen plus stalled TLS handshakes. Elecrow's own ESPHome example sets
|
|
# both to 'y' — do not copy it. Left explicitly unset:
|
|
# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set
|
|
# CONFIG_SPIRAM_RODATA is not set
|
|
#
|
|
# 120MHz is the lever if artefacts appear at 480x480, but it drags flash to
|
|
# 120MHz with it and needs flash HPM plus a DC-aware bootloader. Not needed at
|
|
# this resolution — 480x480 is ~40% of the bandwidth 800x480 required.
|
|
|
|
# --- Cache -------------------------------------------------------------------
|
|
# Bigger data cache and 64-byte lines measurably help RGB panel DMA.
|
|
CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB=y
|
|
CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B=y
|
|
CONFIG_ESP32S3_DATA_CACHE_64KB=y
|
|
CONFIG_ESP32S3_DATA_CACHE_LINE_64B=y
|
|
|
|
# --- CPU / RTOS --------------------------------------------------------------
|
|
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
|
|
CONFIG_FREERTOS_HZ=1000
|
|
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192
|
|
|
|
# --- Console -----------------------------------------------------------------
|
|
# PRD 8.2: USB-Serial-JTAG is the ONLY console link on this board (native USB,
|
|
# no CH340), so it is made the PRIMARY console rather than the secondary one.
|
|
#
|
|
# Note the generated sdkconfig ends up with CONFIG_ESP_CONSOLE_SECONDARY_NONE=y,
|
|
# which looks like it contradicts PRD 8.2's warning. It does not. "Secondary
|
|
# console" only exists when the primary is UART; with USB-JTAG selected as
|
|
# primary there is no secondary slot to fill, and
|
|
# CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED=y confirms output still goes to
|
|
# the USB link. The warning was about the sibling board, where UART was primary
|
|
# and the secondary USB-JTAG console silently occupied GPIO19/20.
|
|
CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
|
|
|
|
# --- WiFi --------------------------------------------------------------------
|
|
# PRD 8.2: keep WiFi out of NVS. This project writes its own settings to NVS at
|
|
# runtime and we do not want WiFi adding uncontrolled flash writes on top.
|
|
CONFIG_ESP_WIFI_NVS_ENABLED=n
|
|
|
|
# --- LCD ---------------------------------------------------------------------
|
|
# RGB panel ISRs and callbacks run from IRAM so a flash operation cannot stall
|
|
# them. We use no bounce buffers (see drivers/display/display.c) which is what
|
|
# actually makes runtime NVS writes safe.
|
|
CONFIG_LCD_RGB_ISR_IRAM_SAFE=y
|
|
CONFIG_GDMA_CTRL_FUNC_IN_IRAM=y
|
|
|
|
# --- Watchdogs ---------------------------------------------------------------
|
|
# The task watchdog is part of the safety story: a hung control task panics the
|
|
# chip, and the reboot path de-asserts the relay within about a second.
|
|
# ESP_TASK_WDT_PANIC is what makes that true — without it the TWDT only logs a
|
|
# warning and a hung task keeps hanging. (The relay layer's own 30s watchdog
|
|
# has already dropped the heat call by then; this reboots the chip so the
|
|
# thermostat comes back instead of staying wedged.)
|
|
CONFIG_ESP_TASK_WDT_INIT=y
|
|
CONFIG_ESP_TASK_WDT_TIMEOUT_S=10
|
|
CONFIG_ESP_TASK_WDT_PANIC=y
|
|
CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=n
|
|
CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=n
|
|
CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y
|
|
|
|
# --- Logging -----------------------------------------------------------------
|
|
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
|
|
|
|
# --- LVGL --------------------------------------------------------------------
|
|
CONFIG_LV_COLOR_DEPTH_16=y
|
|
CONFIG_LV_USE_PERF_MONITOR=n
|
|
CONFIG_LV_FONT_MONTSERRAT_16=y
|
|
CONFIG_LV_FONT_MONTSERRAT_20=y
|
|
CONFIG_LV_FONT_MONTSERRAT_28=y
|
|
CONFIG_LV_FONT_MONTSERRAT_48=y
|
|
CONFIG_LV_MEM_SIZE_KILOBYTES=64
|