Skip to content

feat(#283): UM FeatherS3D build env, TFT_eSPI and watchdog fixes (#284, #285), locked bench wiring (#282) - #288

Merged
Strycher merged 13 commits into
mainfrom
fc/283-um-feathers3-env
Sep 8, 2026
Merged

Strycher merged 13 commits into
mainfrom
fc/283-um-feathers3-env

Conversation

@Strycher

@Strycher Strycher commented Sep 8, 2026

Copy link
Copy Markdown
Owner

Closes #282, closes #283, closes #284, closes #285.

Stacked on fc/212-e4-screens (#280): this branch is #280's head plus the commits below, and this bench run is also band 4's hardware verification (#265).

What this is

The Field Compass bench moved to a UM FeatherS3D (Adafruit 6399) on 2026-09-05. This PR makes the firmware build for it, fixes two defects that no PlatformIO image had ever met because none had been flashed to hardware, and locks the bench wiring in the repo.

Issue Commit(s) What
#282 531eb62, 5bd1b55, 187a0cd, 62cd330, 6a0ba63, 68e351e, cbf170a The 2026-09-05 rewire record in docs/HARDWARE.md; the display module wire-by-wire table; docs/um-bench-wiring.md, the locked UM wire list (silkscreen labels only, owner-locked 2026-09-08 02:20); a warning that the Adafruit pin tables are not UM holes; CLAUDE.md pin assignments for both boards
#283 253f7af [env:um_feathers3]; shared settings in an [env] base section; src/fc_config.h selects the seven board-specific pins on ARDUINO_FEATHERS3 / ARDUINO_ADAFRUIT_FEATHER_ESP32S3 and errors on an unknown board; LDO2 (GPIO 39) driven HIGH on the UM board; vendored partitions/default_16MB.csv
#283 d6fa305 (part), 77ab753, f655868 Wire1 on the second STEMMA QT bus (16/15) and a dual-bus boot scan; an empty-scan diagnostic (idle line levels, swapped rescan, 10 kHz rescan); touch init logs the real CTP_INT
#284 8af7ce5, d6fa305 USE_FSPI_PORT: TFT_eSPI 2.5.43 resolved SPI_PORT to FSPI = 0 on the S3 and wrote its registers at address 0x10 (StoreProhibited in tft.init()). SD and FRAM now use TFT_eSPI's SPI instance so there is one driver per controller; the second driver hung the first SD mount
#285 8c2e690 Core 3.x starts the task watchdog at 5 s before setup(); esp_task_wdt_init(30 s) failed silently and the WiFi reconnect wait rebooted the board every ~70 s. Now esp_task_wdt_reconfigure, results checked, the timeout in force logged

Verified on hardware (um_feather, 2026-09-08, from the board's own boot log)

77ab753 flashed via pio-flash on the owner's GO. After the owner rewired from docs/um-bench-wiring.md, at 02:16 EDT: TFT + LVGL drawing; touch found at 0x38; OLED; SD 30436 MB with the serial log open; FRAM (mfg 0x04, prod 0x4803); RTC, then synced from GPS; GPS fix in 26 s; BME688/BSEC2 with state restored from SD; SHT41; LSM6DSOX + LIS3MDL; MAX17048; ten devices on I2C1; task watchdog 30 s with no resets; TFT sleep timeout confirmed by the owner. WiFi fails on the placeholder credentials, as expected (#99). Loop 44 Hz.

The Adafruit feather_s3 env builds unchanged in size and symbol set.

Builds on the tip

um_feathers3: 1,803,742 B flash / 74 KB RAM. feather_s3: 1,863,070 B / 103 KB RAM. pytest scripts/: 58 passed at 253f7af; the script suite is untouched since.

For the reviewer to decide

Records

docs/HARDWARE.md → UM FeatherS3 rewire (2026-09-05) and Corrections from the first boot; docs/um-bench-wiring.md; issue comments on #283/#284/#285 with the boot logs; C:\Dev\.field_compass\flash-history.jsonl for the four flashes.

🤖 Generated with Claude Code

…RE.md

The bench sheet, both header-by-header GPIO tables, the ten board-specific
defines and the caveats, copied verbatim from the 2026-09-05 session record
that was never written down. Adafruit 5477 tables unchanged. No firmware change.
A second [env:um_feathers3] for the UM FeatherS3[D] the bench was rewired
to on 2026-09-05 (#282). Shared settings move to an [env] base section;
each env carries board, memory, partitions, flash and its three TFT
control-line flags (UM: CS 17, DC 18, RST 14). src/fc_config.h selects the
other seven pins on the platform's board macro (UM: SD_CS 3, FRAM_CS 12,
TFT_BL 5, CTP_INT 6, BUTTON_A/B/C 1/38/33) and errors on an unknown board.
On the UM board setup() drives LDO2 (GPIO 39) HIGH before I2C, since it
feeds the vertical STEMMA QT connector. partitions/default_16MB.csv is a
byte-identical copy of the core's table.

Both envs build (feather_s3 1,856,814 B flash / 103,248 B RAM; um_feathers3
1,797,018 B / 74,032 B). The feather_s3 image keeps the same size and
defined-symbol set as the #280 build. pytest scripts/: 58 passed.
TFT_eSPI 2.5.43 sets SPI_PORT to FSPI on the S3, which Arduino core 3.x
defines as bus index 0; the IDF's REG_SPI_BASE(0) is 0, so every TFT
register pointer was NULL+offset and tft.init() panicked (StoreProhibited
at 0x10) on the first hardware run of any PlatformIO image. USE_FSPI_PORT
makes SPI_PORT 2 = GPSPI2, the controller the Arduino SPI object already
uses for SD and FRAM. Verified in both ELFs: writecommand now references
0x60024000/0x60024010; no NULL-based stores remain.

um_feathers3 1,802,134 B flash / 74,064 B RAM; feather_s3 1,862,006 B /
103,280 B.
…S3D (#283)

SD and FRAM now use TFT_eSPI's SPI instance instead of starting the Arduino
SPI object on the same controller: with USE_FSPI_PORT that was two SPIClass
drivers on GPSPI2, and the first SD mount on the UM board never returned.
The SD re-init path no longer ends/restarts the bus (it is the display's).

The FeatherS3D has two I2C buses (pinout card): I2C1 = header + first STEMMA
QT = 8/9, I2C2 = second STEMMA QT = 16/15 on LDO2. Wire1 is opened on I2C2
and the boot scan reports both buses.

docs/HARDWARE.md: header position 16 is LDO2 (switched 3.3 V), not a second
always-on 3V3 as the bench sheet said; MAX17048 is present on I2C1; named
holes verified against the card; first-boot results recorded.
Arduino core 3.x initialises the task watchdog at 5 s before setup(), so
esp_task_wdt_init(30 s) returned ESP_ERR_INVALID_STATE, the result went
unchecked, and the 5 s default stayed in force; the WiFi reconnect wait
then tripped it and rebooted the board every ~70 s on any board that
cannot join WiFi. Reconfigure the running watchdog instead, check both
results, and log the timeout actually in force.
…ls, rescan swapped and at 10 kHz

Temporary diagnostic for the dead I2C1 bus: one boot log says whether SDA/SCL
are held low, crossed, or too slow. To be removed once the cause is known.
…lank panel and dead I2C resolved

The dead I2C1 (SCL held low) and blank panel were display wires placed per
the retracted 05:46 table. Records the corrected holes per module pin, the
diagnostic that found it, and the 2026-09-08 01:13 state: TFT, OLED, RTC,
SD, GPS, nine I2C devices up; FRAM and touch still open; OLED glitch #286.
…at the Adafruit pin tables are not UM holes

Adafruit GPIO numbers collide with UM silkscreen numbers (14, 17, 18) and
that cost the 2026-09-08 bench session hours. um-bench-wiring.md is the
single list to wire from.
…oth boards

um-bench-wiring.md is the authoritative UM wire list (owner, 2026-09-08
02:20). HARDWARE.md points at it and marks the derivation tables record-only.
CLAUDE.md now lists both boards' GPIO views, names the UM board as the bench
board, and corrects the Adafruit GPS pins (38/39, not 5/6). Owner also
verified the TFT sleep timeout on the UM board.
@Strycher
Strycher force-pushed the fc/283-um-feathers3-env branch from cbf170a to 91fd9bc Compare September 8, 2026 06:30
@Strycher
Strycher changed the base branch from fc/212-e4-screens to main September 8, 2026 06:30
@Strycher
Strycher merged commit da4cb3a into main Sep 8, 2026
10 of 14 checks passed
@Strycher
Strycher deleted the fc/283-um-feathers3-env branch September 8, 2026 06:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant