FRAME_BATTERY_ADC_GPIO was still at its off-by-default -1 in
sdkconfig.xiao despite the XIAO being the one board this was designed
for -- the status panel showed no battery line because the device never
sent a report at all. Sets it to GPIO0, matching the settled
shared-with-back-button design.
- version.txt + esp_app_desc_t version reporting (X-Frame-Version header);
new ota_update.c checks the server's advertised version against the
running one and streams+applies an update via esp_https_ota, gated by
bootloader rollback (marks the image valid only after a full successful
cycle, so a bad update can't brick a wall-mounted frame).
- Dual-OTA partition tables: partitions.csv (8MB dev board, 2MB slots) and
new partitions_xiao.csv (4MB XIAO, 1.875MB slots -- the dev board's
table doesn't fit the XIAO's flash). New build_for_board.sh gives each
board its own build dir + generated sdkconfig via SDKCONFIG_DEFAULTS
layering, so switching boards never clobbers the other's config.
- fetch_photo_info()/fetch_face_labels() were using the short
reachability-check timeout even though the manage-menu path can be the
first (cold, TLS-handshake-paying) request of a wake cycle -- switched
to the longer fetch timeout to stop spurious ESP_ERR_HTTP_CONNECT
failures.
- XIAO: the RF switch that selects onboard vs. external antenna
(GPIO3/14) isn't initialized by plain ESP-IDF the way Seeed's Arduino
package does it, leaving WiFi unable to reliably reach the antenna at
all -- new board_antenna.c powers the switch and selects the onboard
antenna, gated behind FRAME_XIAO_ANTENNA_INIT (on by default in
sdkconfig.xiao). Also remaps the EPD DC/RST/BUSY pins, since the dev
board's defaults (GPIO9/10/11) aren't physically exposed on the XIAO.