Board Support
🖥️ Board Support
Guide for adding new boards (ESP32-based with display + 2 buttons).
Supported Boards
| Board | Status | Environment name |
|---|---|---|
| LilyGo T-Display-S3 | ✅ Standard | t_display_s3 |
Adding a New Board (4 Steps)
Step 1: Create the Board File
Create src/boards/board_<name>.h:
#ifndef BOARD_<NAME>_H
#define BOARD_<NAME>_H
#include <Arduino.h>
// All GPIO numbers and display parameters of the board.
// Games and the engine must NEVER use direct GPIO numbers,
// only these constants.
namespace board {
// ---- Buttons ----
constexpr uint8_t PIN_BTN_A = 0; // first button (e.g. BOOT)
constexpr uint8_t PIN_BTN_B = 14; // second button
constexpr bool HAS_POWER_HOLD = true; // GPIO for display power
constexpr uint8_t PIN_POWER_ON = 15; // must stay HIGH
// ---- Button timing ----
constexpr uint32_t LONG_A_MS = 1200; // ms until Long for button A
constexpr uint32_t LONG_B_MS = 700; // ms until Long for button B
constexpr uint32_t DEBOUNCE_MS = 30; // debounce time in ms
// ---- Display geometry ----
// IMPORTANT: SCR_W/SCR_H in the rotation that TFT_ROTATION produces!
constexpr uint8_t TFT_ROTATION = 1; // 0=portrait, 1=landscape, ...
constexpr int16_t SCR_W = 320; // width in sketch orientation
constexpr int16_t SCR_H = 170; // height in sketch orientation
} // namespace board
#endif
Step 2: Include in board_config.h
Edit src/core/board_config.h:
#ifndef CORE_BOARD_CONFIG_H
#define CORE_BOARD_CONFIG_H
#include <Arduino.h>
#if defined(BOARD_TDISPLAY_S3)
#include "boards/board_tdisplay_s3.h"
#elif defined(BOARD_MY_BOARD) // <- NEW
#include "boards/board_my_board.h" // <- NEW
#else
#error "No board selected - set -D BOARD_<NAME> in platformio.ini"
#endif
#endif
Step 3: TFT_eSPI Setup (if needed)
If the board has a different display driver or different pins,
create include/tft_setup_<name>.h (or adapt an existing one):
#ifndef TFT_SETUP_<NAME>_H
#define TFT_SETUP_<NAME>_H
// Select the display driver (one of):
// #define ST7789_DRIVER // 240x320, common on ESP32 boards
// #define ILI9341_DRIVER // 240x320 SPI
// #define ST7735_DRIVER // 128x160 small
#define ST7789_DRIVER
#define TFT_WIDTH 240
#define TFT_HEIGHT 320
// Pins (adapt to the board!)
#define TFT_CS 5
#define TFT_DC 27
#define TFT_RST 33
#define TFT_BL 32
// For SPI displays:
#define TFT_MOSI 23
#define TFT_SCLK 18
#define TFT_MISO -1 // often not connected
// For 8-bit parallel (like the T-Display-S3):
// #define TFT_PARALLEL_8_BIT
// #define TFT_D0 39 ... TFT_D7 48
// #define TFT_WR 8
// #define TFT_RD 9
// SPI frequency (only for SPI displays)
#define SPI_FREQUENCY 40000000
#endif
Step 4: Create a PlatformIO Environment
Extend platformio.ini:
[platformio]
default_envs = t_display_s3
; Existing environment...
[env:t_display_s3]
; ...
; ============================================
; New board: My ESP32 Board
; ============================================
[env:my_board]
platform = espressif32@^6.5.0
board = esp32dev ; or esp32-s3-devkitc-1, etc.
framework = arduino
board_build.mcu = esp32 ; or esp32s3
board_build.f_cpu = 240000000L
monitor_speed = 115200
build_flags =
-std=gnu++17
-D BOARD_MY_BOARD ; <- define the board name
-D ARDUINO_USB_CDC_ON_BOOT=1
-I include
; lib_deps = ; adapt if the display differs
; bodmer/TFT_eSPI@2.5.43
Build & Flash for a New Board
# Build for a specific board
pio run -e my_board
# Build & flash
pio run -e my_board -t upload
# Serial monitor
pio device monitor
Board-Specific Details
Power-Hold (Display Power)
Many ESP32 boards with a display need a “power-hold” pin that must stay HIGH so the display gets power:
// In board_<name>.h:
constexpr bool HAS_POWER_HOLD = true;
constexpr uint8_t PIN_POWER_ON = 15; // GPIO number
The engine sets this pin in Engine::begin() before the display init:
// Automatically in Engine::begin():
boardPowerOn(); // GPIO15 HIGH + 10ms wait
⚠️ Important: Do not change this order, or the display stays black!
Buttons Active LOW vs. HIGH
Most boards have buttons active LOW (to GND). If active HIGH:
// buttons.h must then be adapted:
// bool raw = digitalRead(btn_.pin) == HIGH; // instead of LOW
All current boards are active LOW - please adapt ButtonTracker if a
board is active HIGH.
Pin Reference for Common Boards
LilyGo T-Display-S3 (Reference)
| Function | GPIO | Note |
|---|---|---|
| TFT 8-bit parallel | D0-D7: 39,40,41,42,45,46,47,48 | |
| TFT CS | 6 | |
| TFT DC | 7 | |
| TFT WR | 8 | |
| TFT RD | 9 | |
| TFT RST | 5 | |
| TFT Backlight | 38 | |
| Button A (BOOT) | 0 | active LOW |
| Button B | 14 | active LOW |
| Power-hold | 15 | must be HIGH |
| Battery ADC | 4 | unused |
Typical ESP32 DevKit (SPI Display)
| Function | GPIO | Note |
|---|---|---|
| TFT MOSI | 23 | VSPI default |
| TFT SCLK | 18 | VSPI default |
| TFT CS | 5 | |
| TFT DC | 27 | |
| TFT RST | 33 | |
| TFT BL | 32 | or 4 |
| Button A | 0 | BOOT (usually present) |
| Button B | 35 | or another free pin |
Checklist: Test a New Board
pio run -e <board>builds without errors- Display shows something after upload (not black/white)
- Both buttons respond (short + long)
- Backlight is on
pio device monitorshows serial output- Game switching works (wantsMenu)
- Deep sleep / restart works (if implemented)
Troubleshooting Board Support
| Problem | Solution |
|---|---|
| Black screen, backlight on | Check pin configuration in tft_setup.h; check driver (ST7789 vs ILI9341) |
| Black screen, backlight off | Check HAS_POWER_HOLD and PIN_POWER_ON |
| White/odd colors | Adjust TFT_INVERSION_ON or TFT_RGB_ORDER |
| Button A does not work | GPIO0 is BOOT - mind the flash BOOT+RST sequence |
| Build error “board not defined” | Check -D BOARD_<NAME> in platformio.ini |
| Display flickers | Reduce SPI frequency or use 8-bit parallel |