Skip to content

Add ESP32-S3 2.8 inch display board support#2500

Open
ch1n7u wants to merge 1 commit into
BruceDevices:mainfrom
ch1n7u:esp32s3-2p8-display-support
Open

Add ESP32-S3 2.8 inch display board support#2500
ch1n7u wants to merge 1 commit into
BruceDevices:mainfrom
ch1n7u:esp32s3-2p8-display-support

Conversation

@ch1n7u

@ch1n7u ch1n7u commented May 31, 2026

Copy link
Copy Markdown

Proposed Changes

This pull request adds support for an ESP32-S3 based board equipped with a 2.8" SPI TFT display. The implementation introduces a dedicated board configuration, display initialization, pin mappings, and PlatformIO environment while keeping existing board support unchanged.

The goal of this contribution is to expand Bruce Firmware compatibility to additional ESP32-S3 hardware platforms and provide a clean, maintainable implementation that follows the project's existing board architecture.

Types of Changes

  • New Feature
  • New Hardware/Board Support
  • PlatformIO Configuration Update

Verification

The following verification steps were performed:

  1. Built the new board environment successfully using PlatformIO.
  2. Flashed the firmware to physical ESP32-S3 hardware.
  3. Verified successful boot and initialization.
  4. Confirmed proper rendering of the Bruce user interface on the 2.8" TFT display.
  5. Verified that existing board environments continue to build successfully.

Testing

  • Tested on physical ESP32-S3 hardware with a 2.8" SPI TFT display.
  • Verified successful compilation of the newly added PlatformIO environment.
  • Performed basic functional testing of the user interface and display output.

No automated tests were added because this change primarily introduces hardware-specific support.

Linked Issues

None.

User-Facing Change

Added support for an ESP32-S3 based board featuring a 2.8" SPI TFT display.

Further Comments

This contribution was developed and tested on real hardware. The implementation is isolated to a dedicated board configuration to avoid affecting existing supported devices and to simplify future maintenance and enhancements.

Copilot AI review requested due to automatic review settings May 31, 2026 15:41

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR appears to revert or replace large portions of the codebase across many modules (WiFi, BLE, RFID, IR, NRF24, display core, board interfaces, build config, etc.). The net effect is the removal of many recently-added features (e.g., the structured ibutton menu, ducky_typer key queue, IR emulate mode, evil portal gateway IP setting, BLE stack teardown helpers, YModem support, WDGoWars upload, NetCut menu, AppsMenu, etc.) and the reintroduction of older, less-safe implementations. It also adds a new smoochiee-s3-2.8inch-ili9341 board variant and switches the default PlatformIO environment.

Changes:

  • Wide-scale revert of recent feature work across WiFi, BLE, RFID, IR, NRF24, audio, display, settings and serial commands modules.
  • Replaces many bounded-string APIs (snprintf, strlcpy) with unbounded equivalents (sprintf, strcpy) and removes input validation/escape handling in many keyboard prompts.
  • Adds a new Smoochiee S3 2.8" ILI9341 board variant and tweaks build configuration (default env, lib pinning, PlatformIO flags).

Reviewed changes

Copilot reviewed 107 out of 110 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/modules/bjs_interpreter/interpreter.h/.cpp Changes FS& parameter to FS by value.
src/core/startup_app.cpp Drops null-check on fs pointer returned from getScriptsFolder.
src/core/serial_commands/storage_commands.cpp Removes YModem support and reworks writeCallback argument handling.
src/core/type_convertion.cpp Shrinks temp buffer in decimalToHexString.
src/core/display.cpp Reworks status bar, removes Gif null guards, reverts playFrame logic, removes enabled option support, removes read16/32 initialization.
src/core/wifi/wg.cpp Replaces structured UI rendering with raw tft calls and a fixed 7s delay.
src/core/wifi/webInterface.cpp Reverts drawWebUiScreen to old layout, switches snprintfsprintf.
src/core/configPins.* / src/core/config.* / src/core/settings.* Removes PN532 bus config, evil portal gateway IP config, WDGoWars API key, TerminalLog flag.
src/core/sd_functions.* Removes folderExists, WDG upload entries, escape-cancel checks.
src/core/menu_items/* Adds AppsMenu, restructures MainMenu, reverts WifiMenu/FileMenu/EthernetMenu changes.
src/core/led_control.* Reorders LED effect enum values (renumbering breaks persisted configs).
src/core/app_launcher.* New JS app discovery/launcher.
src/modules/wifi/* Reverts evil portal DNS server lifetime, responder UI, tcp_utils UI, sniffer hardening, wifi_recover output, socks4 layout.
src/modules/ble/* Removes stopBLEStack and BLE↔WiFi mutual teardown logic.
src/modules/ir/ir_read.* Removes IR emulate mode and protocol parsing.
src/modules/NRF24/nrf_spectrum.* Rewrites spectrum analyzer with new modes and layout.
src/modules/NRF24/nrf_jammer.h Replaces jam-strategy struct fields with single useFlooding flag.
src/modules/others/ibutton.* Reverts structured ibutton menu and file I/O to older procedural version.
src/modules/others/audio.cpp Removes M5Unified path in _tone and frequency=0 delay handling in playTone.
src/modules/others/u2f.cpp Replaces virtual press helpers with direct digitalRead.
src/modules/badusb_ble/ducky_typer.cpp Removes the key-queue keyboard UI.
src/modules/bjs_interpreter/keyboard_js.cpp Removes ESC→empty-string handling.
boards/m5stack-cardputer/interface.cpp Reverts TCA8418 input handler to non-FIFO version, drops volatile from kb_interrupt.
boards/m5stack-sticks3/* Removes PSRAM/OPI config, simplifies codec setup.
boards/smoochiee-s3-2.8inch-ili9341/* Adds new board variant.
boards/lilygo-t-lora-pager/* Reverts to single-event input handler.
boards/lilygo-t-embed-cc1101/interface.cpp Removes encoder stale-step cleanup.
boards/marauder-touch/interface.cpp Removes encoder stale-step cleanup.
boards/pinouts/pins_arduino.h Adds new board and removes several existing ones.
platformio.ini Switches default env, downgrades NimBLE pin, removes LTO flags.
patch.py Removes HTTP request timeouts.
.gitignore Removes .idea and .ai entries.
.github/workflows/buil_parallel.yml Removes several boards from the matrix.
Comments suppressed due to low confidence (19)

src/modules/bjs_interpreter/interpreter.h:1

  • FS is an abstract base class (e.g. SD, LittleFS inherit from it), so passing it by value causes object slicing and removes the polymorphic behavior — calls into fs will not dispatch to the concrete filesystem. The original FS &fs reference signature should be preserved here and in interpreter.cpp.
    src/core/startup_app.cpp:1
  • fs is left uninitialized and the previous null-check after getScriptsFolder is removed. If getScriptsFolder does not set fs (e.g. when no filesystem is available) this dereferences an indeterminate pointer. Initialize fs = nullptr; and keep the if (fs == nullptr) return; guard.
    src/core/serial_commands/storage_commands.cpp:1
  • Both filepath and sizeStr are read from the same variable arg, and arg is no longer declared in this scope after the rename. This will not compile, and the intent is clearly to read filepathArg.getValue() and sizeArg.getValue() respectively.
    src/core/type_convertion.cpp:1
  • The previous comment explicitly noted the buffer was sized to 66 to accommodate the null terminator at index 65. Shrinking back to 65 reintroduces a one-byte out-of-bounds write when the routine null-terminates at the maximum index. Keep the size at 66.
    src/modules/wifi/sniffer.cpp:1
  • Replacing strlcpy(..., sizeof(...)) with unbounded strcpy removes bounds protection on the fixed-size wifi_config.ap.ssid/password buffers. Although the literals fit today, this regresses a defensive pattern; please retain strlcpy with the destination size.
    src/modules/wifi/sniffer.cpp:1
  • Replacing snprintf(buffer, sizeof(buffer), ...) with sprintf removes the size guard. The same pattern is being reintroduced in several other files in this PR (core/wifi/wifi_mac.cpp, core/net_utils.cpp, core/configPins.cpp, core/utils.cpp, core/connect/esp_connection.cpp, core/serial_commands/settings_commands.cpp, core/wifi/webInterface.cpp). Please keep snprintf to maintain bounds checking.
    src/core/display.cpp:1
  • gif is not initialized in the constructor (the gif member has no in-class initializer shown) and openGIF may fail before gif is assigned. The previous version null-guarded both close() and delete. Restore the null check, e.g. if (gif) { gif->close(); delete gif; gif = nullptr; }.
    src/core/display.cpp:1
  • When bSync is false (the documented “play next frame regardless of timing” path) this implementation returns 2 without ever advancing the GIF, and gif is not null-checked. Additionally delayMilliseconds is initialized to &zero, so the timing branch only fires when bSync is true and millis()-lTime >= 0, which makes the gating ineffective. Please null-check gif and call playFrame when bSync is false as well.
    src/core/display.cpp:1
  • Removing the zero-initialization here (and in read32 below) means partial-read failures (e.g. EOF on the SPI file) leave result with indeterminate bytes that are still returned to the caller. Keep uint16_t result = 0; / uint32_t result = 0;.
    src/modules/wifi/wifi_recover.cpp:1
  • total_time and seconds are computed but their only consumers are commented out, leaving dead code and unused-variable warnings. Either uncomment the padprintf calls or remove the computation.
    src/core/wifi/wg.cpp:1
  • local_ip is an IPAddress; Print::println does not have a direct overload that prints it as dotted-quad, so this either fails to compile or prints an unexpected representation. The previous code used local_ip.toString(). Please call .toString() explicitly.
    src/core/menu_items/AppsMenu.cpp:1
  • File::getNextFileName(bool*) is only available on recent arduino-esp32 cores; older targets in this repo (which platformio.ini still supports via multiple environments) may not have this overload. Consider using the portable openNextFile() iteration to avoid breaking builds on those board envs.
    src/core/led_control.h:1
  • Renumbering these macros silently changes the meaning of values already persisted in user configs (bruceConfig.ledEffect). Users upgrading will see the wrong effect activate (e.g. a stored 7 previously meant RAINBOW_BREATHE and will now mean DISCO). Either keep the original numbering or add a migration step in config load.
    src/modules/others/audio.cpp:1
  • Removing the frequency == 0 && duration > 0 delay branch breaks the common “silent rest” usage of playTone(0, duration) — callers now get an immediate return instead of waiting duration ms, which will desync any sequence of notes that uses rests. Keep the delay(duration) for the zero-frequency case.
    src/modules/wifi/evil_portal.cpp:1
  • This drops the user-configurable bruceConfig.evilPortalGatewayIp lookup and hardcodes 192.168.4.1, while the matching “Default” menu entry that re-applied the configured value is also removed. Users who previously set a custom gateway IP will silently have their configuration ignored. Restore the apGateway.fromString(bruceConfig.evilPortalGatewayIp) fallback.
    src/modules/ble/ble_common.cpp:1
  • is_ble_inited is declared at file scope here but is never referenced after the removal of stopBLEStack, and several call sites in core/wifi/wifi_common.cpp previously relied on stopBLEStack() for safe WiFi/BLE coexistence on no-PSRAM boards. Removing the teardown without an equivalent will cause radio init failures on those boards. Please either keep stopBLEStack and the FORCE_RADIO_TEARDOWN_ON_SWITCH paths or document the replacement.
    src/modules/wifi/tcp_utils.cpp:1
  • Removing the serverIP == \"\\x1B\" / portString == \"\\x1B\" checks means pressing ESC at either prompt now falls through to client.connect with whatever string is currently buffered, instead of cancelling. Many other files in this PR have the same regression (wifi_recover.cpp, wifi_atks.cpp, responder.cpp, RFID modules, IR module, qrcode_menu, ble_spam, wifi_mac, passwords, etc.). Please retain the ESC-cancel guard.
    src/core/menu_items/EthernetMenu.cpp:1
  • The icon-drawing function has been fully rewritten with magic numbers (e.g. iconCenterY - 25, iconH * 2, hardcoded 15 pin spacing) and no longer respects the scale parameter consistently (e.g. Y = iconCenterY - 25 ignores scale). The previous version derived all positions from scale, which made it work across screen sizes. Please scale the new layout the same way.
    src/main.cpp:1
  • Removing the setBrightness(bruceConfig.bright, false) re-apply after _post_setup_gpio() regresses the fix for boards whose backlight is reset inside post-setup (per the deleted comment). On those boards the configured brightness will be lost on boot. Please retain the re-apply.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

digitalWrite(5, HIGH);
}
volatile bool kb_interrupt = false;
bool kb_interrupt = false;
Comment thread patch.py
Comment on lines 106 to 107
{'input': js.read().decode('utf-8')},
timeout=10
)
Comment thread include/globals.h
Comment on lines 106 to 107
bool selected = false;
bool enabled = true;
bool (*hover)(void *hoverPointer, bool shouldRender);
board_build.flash_mode = qio
board_build.flash_size = 8MB
board_build.psram_type = opi
board_build.partitions = custom_8Mb.csv
Comment thread platformio.ini
mikalhart/TinyGPSPlus
tinyu-zhao/FFT@^0.0.1
h2zero/NimBLE-Arduino@2.5
h2zero/NimBLE-Arduino@^2.3.9
Comment thread include/VectorDisplay.h
Comment on lines +503 to 504
if (n > VECTOR_DISPLAY_MAX_STRING) n = VECTOR_DISPLAY_MAX_STRING;
strncpy(args.xyText.text, str, n);
ch1n7u

This comment was marked as duplicate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants