Skip to content

ESP32S3-4827S043C Board Support Package (BSP)

ESP32S3-4827S043C Board Support Package (BSP)

Section titled “ESP32S3-4827S043C Board Support Package (BSP)”

The esp32s3_4827s043c_bsp module is the hardware abstraction layer for the ESP32S3-4827S043C board — a 4.3-inch capacitive touch display panel driven by an ILI9485 controller over a 16-bit RGB parallel interface. It initialises every hardware peripheral needed by the pendant firmware, wires LVGL to the RGB panel and the GT911 touch controller, and registers the board-specific custom control events that the UI layer consumes.


  1. Module Overview
  2. Hardware Specifications
  3. GPIO Pin Reference
  4. Architecture
  5. Component Breakdown
  6. Initialization Flow
  7. Display Subsystem
  8. Touch Subsystem
  9. Control Events System
  10. Snapshot Feature
  11. FreeRTOS Task Layout
  12. Public API
  13. Build System Integration
  14. Compile-Time Feature Flags
  15. Sibling Modules and References

ItemValue
Board nameESP32S3-4827S043C
Board versionv1.0
MCUESP32-S3
DisplayILI9485, 16-bit RGB parallel, 480×272 physical
TouchGT911 capacitive, I2C
Physical controlsNone (encoder, buttons, switch, potentiometer are all emulated through the UI)
Source directoryboards/esp32s3_4827s043c/components/bsp/
Key source filesboard_init.c, control_types.c
Key header filesboard_init.h, board_config.h, control_event.h, control_types.h, tasks_def.h, disp_ili9485_def.h, touch_gt911_def.h, disp_backlight_def.h

The BSP is the only place in the firmware where hardware I/O details live for this board. The rest of the firmware (UI, GCode host, communication transports) is hardware-agnostic and addresses the board only through the public API exposed by board_init.h and the LVGL handles returned by this module.


ParameterValue
ControllerILI9485
Interface16-bit RGB565 parallel (no SPI)
Physical size4.3 inch
Physical resolution480 × 272 px
Mounting in enclosureRotated 90° — portrait physical orientation maps to landscape logical view
Logical resolution (Portrait mode)272 × 480 (LVGL canvas)
Logical resolution (Landscape mode)480 × 272 (LVGL canvas)
Confirmed working orientationPORTRAIT_INVERTED (confirmed 2026-08-05/07)
Pixel clock (normal)8 MHz
Pixel clock (FS access)6 MHz (hardware workaround)
Color formatRGB565
Byte swap requiredNo (DISPLAY_SWAP_COLOR_FLAG = 0)
Frame buffer locationPSRAM (fb_in_psram = true)
LVGL draw bufferDouble, 1/4 screen height each, allocated in SPIRAM
ParameterValue
GPIOGPIO 2
ControlPWM (LEDC)
ActiveHigh
Default level20 %
PWM timerTimer 0, Channel 0
PWM frequency5 kHz
PWM resolution8-bit
ParameterValue
ControllerGT911 (capacitive)
InterfaceI2C
I2C portI2C_NUM_0
I2C SDAGPIO 19
I2C SCLGPIO 20
I2C frequency400 kHz
I2C addresses probed0x5D, 0x14
Reset pinGPIO 38
Interrupt pinNC by default (GPIO 18 with HARDWARE_MOD_GT911_INT)
Max X/YAuto-detected from device firmware
ParameterValue
PortUART_NUM_0
TXGPIO 43
RXGPIO 44
Default baud rate115 200
Flow controlNone
RX buffer512 bytes
ParameterValue
SPI hostSPI2_HOST
MISOGPIO 13
MOSIGPIO 11
CLKGPIO 12
CSGPIO 10
Card detectNC
Frequency20 MHz

All physical control GPIOs are set to GPIO_NUM_NC — there are no physical buttons, encoder, switch, or potentiometer on this board. The control events framework is retained so that upper UI layers (which are shared across all boards) compile without modification and handle emulated input through the touch UI.


┌─────────────────────────────────────────────────────────┐
│ ESP32S3-4827S043C GPIO Map │
├──────────┬────────────┬─────────────────────────────────┤
│ GPIO │ Direction │ Function │
├──────────┼────────────┼─────────────────────────────────┤
│ GPIO 1 │ Output │ D4 – RGB data bus (B4) │
│ GPIO 2 │ Output │ Backlight PWM │
│ GPIO 3 │ Output │ D1 – RGB data bus (B1) │
│ GPIO 4 │ Output │ D10 – RGB data bus (G5) │
│ GPIO 5 │ Output │ D5 – RGB data bus (G0) │
│ GPIO 6 │ Output │ D6 – RGB data bus (G1) │
│ GPIO 7 │ Output │ D7 – RGB data bus (G2) │
│ GPIO 8 │ Output │ D0 – RGB data bus (B0) │
│ GPIO 9 │ Output │ D3 – RGB data bus (B3) │
│ GPIO 10 │ Output │ SD CS │
│ GPIO 11 │ Bidir │ SD MOSI │
│ GPIO 12 │ Output │ SD CLK │
│ GPIO 13 │ Input │ SD MISO │
│ GPIO 14 │ Output │ D15 – RGB data bus (R4) │
│ GPIO 15 │ Output │ D8 – RGB data bus (G3) │
│ GPIO 16 │ Output │ D9 – RGB data bus (G4) │
│ GPIO 18 │ Input │ Touch INT (opt: HARDWARE_MOD_GT911_INT) │
│ GPIO 19 │ Bidir │ I2C SDA (touch GT911) │
│ GPIO 20 │ Bidir │ I2C SCL (touch GT911) │
│ GPIO 21 │ Output │ D14 – RGB data bus (R3) │
│ GPIO 38 │ Output │ Touch RST (GT911) │
│ GPIO 39 │ Output │ HSYNC │
│ GPIO 40 │ Output │ DE │
│ GPIO 41 │ Output │ VSYNC │
│ GPIO 42 │ Output │ PCLK │
│ GPIO 43 │ Output │ UART0 TX (CNC serial) │
│ GPIO 44 │ Input │ UART0 RX (CNC serial) │
│ GPIO 45 │ Output │ D11 – RGB data bus (R0) │
│ GPIO 46 │ Output │ D2 – RGB data bus (B2) │
│ GPIO 47 │ Output │ D13 – RGB data bus (R2) │
│ GPIO 48 │ Output │ D12 – RGB data bus (R1) │
└──────────┴────────────┴─────────────────────────────────┘

UI_Framework

Core_Platform

ESP-IDF / FreeRTOS

Hardware_Peripheral_Drivers

esp32s3_4827s043c_bsp

configures

configures

configures

uses

registers VSYNC callback

creates tick timer

calls

logs via

snapshot hook in flush

creates lv_display_t

creates lv_indev_t

registers custom events

acquires lock, calls lv_timer_handler

calls board_init

board_init.c

control_types.c

control_event.h

disp_ili9485

disp_backlight

touch_gt911

bus_i2c

esp_lcd_rgb_panel

esp_timer

ledc / PWM

i2c driver

activity_manager

esp3d_log

esp3d_snapshot

LVGL

UIManager / tftUI task

Semaphores

LVGL Task - Core 1

ISR Context (VSYNC)

Take sem_gui_ready

Give sem_vsync_end

Give sem_gui_ready

Wait sem_vsync_end

esp_lcd_panel_draw_bitmap

lv_tick_inc every 20ms

touch_gt911_read

activity_process_event

disp_on_vsync_event

lvgl_flush_cb

increase_lvgl_tick

touch_read_cb

sem_gui_ready

sem_vsync_end

RGB Panel DMA

LVGL core timer

GT911 driver

activity_manager


The central initialization source file. Contains all internal state and all callback functions needed to drive LVGL on this board.

VariableTypePurpose
lvgl_api_lock_lock_tMutex protecting LVGL API calls from multiple threads
lvgl_displaylv_display_t *LVGL display handle
lvgl_buf1lv_color16_t *Primary LVGL draw buffer (SPIRAM)
lvgl_buf2lv_color16_t *Secondary draw buffer (SPIRAM, double-buffer mode)
lvgl_tick_timeresp_timer_handle_tPeriodic timer driving lv_tick_inc()
touch_indevlv_indev_t *LVGL input device handle for the GT911
disp_panelesp_lcd_panel_handle_tESP-LCD RGB panel handle
sem_vsync_endSemaphoreHandle_tBinary semaphore: VSYNC ISR signals flush completion
sem_gui_readySemaphoreHandle_tBinary semaphore: flush signals readiness to VSYNC ISR
FunctionScopeDescription
board_init()PublicTop-level entry point: initialises activity manager, backlight, ILI9485, GT911, LVGL, and control events
init_lvgl()StaticCreates LVGL display, allocates draw buffers, registers flush callback, starts tick timer, creates touch indev
init_touch_controller()StaticInitialises shared I2C bus, then configures GT911
lvgl_flush_cb()StaticLVGL flush callback: optional snapshot write, VSYNC sync, esp_lcd_panel_draw_bitmap(), lv_display_flush_ready()
disp_on_vsync_event()Static (ISR)RGB panel VSYNC ISR callback — synchronises with lvgl_flush_cb via semaphores
touch_read_cb()StaticLVGL indev read callback — reads GT911, maps coords, handles activity wakeup suppression
increase_lvgl_tick()Staticesp_timer callback — calls lv_tick_inc(LVGL_TICK_PERIOD_MS) every 20 ms
bsp_accessFs()Public (conditional)Reduces pixel clock to 6 MHz before flash/SD access
bsp_releaseFs()Public (conditional)Restores pixel clock to 8 MHz after flash/SD access
get_lvgl_display()PublicReturns lvgl_display handle for use by ESP3DXUi
get_lvgl_lock()PublicReturns &lvgl_api_lock for thread-safe LVGL access
get_touch_indev()PublicReturns touch_indev handle
board_get_name()PublicReturns "ESP32S3-4827S043C"
board_get_version()PublicReturns "v1.0"

Defines the control_event_t structure — the common payload dispatched through the LVGL event system for all hardware controls on this board.

typedef struct {
lv_indev_t *indev; // LVGL input device that generated the event
uint32_t btn_id; // Button / control index
lv_indev_type_t type; // LVGL indev type (pointer, button, encoder…)
control_family_t family_id; // Which hardware family generated the event
int32_t steps; // Encoder step count (signed)
uint32_t press_duration; // How long the control was held (ms)
} control_event_t;

Because this board has no physical encoder, buttons, switch, or potentiometer (GPIO_NUM_NC for all), control_event_t events with those family IDs will only be generated by the emulated UI virtual controls defined in the upper layers.

Declares and registers three custom LVGL event codes beyond the built-in set. These must be registered after lv_init(), which board_init() guarantees by calling control_events_init() at the end of its initialisation sequence.

EventPurpose
LV_EVENT_SWITCH_PRESSED4-position switch moved to a new position
LV_EVENT_SWITCH_RELEASED4-position switch released
LV_EVENT_POTENTIOMETER_CHANGEDPotentiometer value changed

The control_family_t enum defines five input families relevant across all boards:

ValueIDDescription
CONTROL_FAMILY_BUTTONS0Physical push buttons
CONTROL_FAMILY_SWITCH14-position rotary switch
CONTROL_FAMILY_TOUCH2Touchscreen (future use)
CONTROL_FAMILY_ENCODER3Rotary encoder
CONTROL_FAMILY_POTENTIOMETER4Analog potentiometer

All hardware constants live in dedicated *_def.h headers so that board_init.c stays free of magic numbers.

HeaderContents
board_config.hAll GPIO assignments, pixel clock, resolution, I2C freq, UART pins, SD pins, touch axis flags — the single authoritative source for this board’s wiring
tasks_def.hFreeRTOS task stack sizes, core affinities, priorities, and LVGL tick period
disp_ili9485_def.hComplete disp_ili9485_config_t struct wired from board_config.h, including RGB timing parameters
touch_gt911_def.hComplete touch_gt911_config_t struct wired from board_config.h, axis swap/mirror flags per orientation
disp_backlight_def.hbacklight_config_t wired from board_config.h, PWM timer/channel/freq/resolution
lv_conf.hLVGL configuration overrides for this board
sd_def.hSD card configuration
serial_def.hUART configuration

control_events_init()init_lvgl()touch_gt911_configure()bus_i2c_init()init_touch_controller()disp_ili9485_configure()backlight_configure()activity_manager_init()board_init()app_main / ESP3DX::begin()control_events_init()init_lvgl()touch_gt911_configure()bus_i2c_init()init_touch_controller()disp_ili9485_configure()backlight_configure()activity_manager_init()board_init()app_main / ESP3DX::begin()board_init()activity_manager_init()ESP_OKbacklight_configure(&backlight_cfg)ESP_OKbacklight_set(0)disp_ili9485_configure(&disp_ili9485_default_config, &disp_panel)disp_panel handleinit_touch_controller()bus_i2c_init(I2C_NUM_0, SDA=19, SCL=20, 400kHz)ESP_OKtouch_gt911_configure(&touch_gt911_default_config)ESP_OKESP_OKinit_lvgl()lv_init()xSemaphoreCreateBinary() x2esp_lcd_rgb_panel_register_event_callbacks(disp_on_vsync_event)lv_display_create(W, H)heap_caps_malloc(SPIRAM) x2 (draw buffers)lv_display_set_buffers(buf1, buf2)lv_display_set_flush_cb(lvgl_flush_cb)esp_timer_create(increase_lvgl_tick, 20ms)lv_indev_create() + lv_indev_set_read_cb(touch_read_cb)ESP_OKbacklight_set(20%)control_events_init()lv_event_register_id() x3ESP_OK

The ILI9485 is driven through the ESP32-S3’s esp_lcd_rgb_panel driver. The panel connects via a 16-bit parallel data bus carrying RGB565 pixel data directly — no SPI command overhead after initialisation.

The physical glass is 480×272 and is mounted rotated 90° in the pendant enclosure. The ILI9485 driver’s swap_xy orientation capability transposes logical (portrait) LVGL coordinates into the physical landscape scan grid on every flush. This is the RGB-parallel equivalent of SPI panels’ MADCTL byte.

Important: DISPLAY_WIDTH_PX / DISPLAY_HEIGHT_PX in board_config.h are the logical (rotated) LVGL canvas dimensions, not the physical scan resolution. Use DISPLAY_PANEL_PHYSICAL_WIDTH_PX (480) and DISPLAY_PANEL_PHYSICAL_HEIGHT_PX (272) only for RGB timing configuration.

RGB panels stream pixel data continuously from a single shared frame buffer. Without synchronization, LVGL’s partial-buffer writes could race the ongoing LCD scan, causing visible tearing or a vertical shift artifact.

The BSP solves this with a dual semaphore handshake between the VSYNC ISR and the LVGL flush callback:

RGB Panel DMAdisp_on_vsync_event (ISR)lvgl_flush_cb (Core 1)RGB Panel DMAdisp_on_vsync_event (ISR)lvgl_flush_cb (Core 1)GUI ready - waiting for VSYNCSafe blanking window confirmedoptional snapshot writeoptional byte swapxSemaphoreGive(sem_gui_ready)VSYNC interruptxSemaphoreTakeFromISR(sem_gui_ready)xSemaphoreGiveFromISR(sem_vsync_end)xSemaphoreTake(sem_vsync_end, portMAX_DELAY)esp_lcd_panel_draw_bitmap(...)lv_display_flush_ready()

This ensures pixel data is written into the frame buffer only during the safe blanking period, preventing scan-line corruption on real hardware.

ParameterValue
Number of buffers2 (double buffering)
Buffer sizeDISPLAY_WIDTH_PX × DISPLAY_HEIGHT_PX / 4 pixels = 1/4 screen
StorageSPIRAM (MALLOC_CAP_SPIRAM)
Render modeLV_DISPLAY_RENDER_MODE_PARTIAL
Color formatLV_COLOR_FORMAT_RGB565
Byte swapNone — direct RGB565 parallel, no endian mismatch

A 1/4-screen partial buffer balances flush latency against SPIRAM bandwidth: smaller buffers mean more flushes per frame but each VSYNC wait is shorter.

The board supports four orientations, selected at compile time via the DEFAULT_ORIENTATION CMake variable (see esp32s3_4827s043c_build_scripts.md):

DEFAULT_ORIENTATIONDISPLAY_WIDTH_PXDISPLAY_HEIGHT_PXILI9485 driver constantTouch confirmed
PORTRAIT272480DISP_ILI9485_ORIENTATION_PORTRAITNot yet confirmed
PORTRAIT_INVERTED272480DISP_ILI9485_ORIENTATION_PORTRAIT_INVERTEDYes — 2026-08-05/07
LANDSCAPE480272DISP_ILI9485_ORIENTATION_LANDSCAPEYes — 2026-08-09
LANDSCAPE_INVERTED480272DISP_ILI9485_ORIENTATION_LANDSCAPE_INVERTEDNot yet confirmed

Touch axis mapping flags in board_config.h must be validated independently for each orientation — they cannot be derived algebraically from the display orientation. See the inline comments in board_config.h for the per-orientation confirmed values.

For the general display driver architecture and the swap_xy / mirror semantics, see docs/architecture/display_drivers.md.

The ESP32-S3’s RGB LCD DMA and the flash/PSRAM memory bus share internal bandwidth. At the normal 8 MHz pixel clock, flash or SD writes cause a visible vertical shift/drift artifact on the display (confirmed on real hardware, 2026-08-05).

The workaround is implemented via two public functions gated by ESP3D_PATCH_FS_ACCESS_RELEASE:

RGB Panel DMAbsp_accessFs / bsp_releaseFsESP3DFlash / ESP3DSdRGB Panel DMAbsp_accessFs / bsp_releaseFsESP3DFlash / ESP3DSdbsp_accessFs()esp_lcd_rgb_panel_set_pclk(6 MHz)vTaskDelay(40 ms)ESP_OKflash / SD read or writebsp_releaseFs()esp_lcd_rgb_panel_set_pclk(8 MHz)vTaskDelay(40 ms)ESP_OK

The 40 ms delay after each clock change allows the RGB panel PLL to stabilise and the DMA pipeline to flush before the display returns to normal operation.


The GT911 is configured via touch_gt911_configure() using the touch_gt911_default_config instance from touch_gt911_def.h. Key parameters:

  • I2C address: Auto-detected from the {0x5D, 0x14} probe list
  • Resolution: Auto-detected from GT911 device firmware (not hardcoded)
  • Axis mapping: swap_xy, invert_x, invert_y set per orientation (see board_config.h)

In touch_read_cb, the raw GT911 coordinates (native resolution) are mapped to the LVGL display resolution:

uint16_t x = touch_data.x * DISPLAY_WIDTH_PX / touch_gt911_get_x_max();
uint16_t y = touch_data.y * DISPLAY_HEIGHT_PX / touch_gt911_get_y_max();

The LVGL indev read timer is set to 10 ms (twice the LVGL tick period) for responsive touch tracking.

The touch callback integrates directly with the activity_manager to implement screen-wake-from-sleep behaviour:

No

No

Yes

Yes

No

Yes

No, first press

screen active

screen sleeping

Yes, held

Yes

No

touch_read_cb called

touch_gt911_read

is_pressed?

last_pressed_state?

data->state = RELEASED

touch_consumed

for_wakeup?

clear flag

activity_process_event

last_pressed_state = false

data->state = RELEASED

last_pressed_state?

activity_process_event

data->state = PRESSED

coords mapped to LVGL

consumed_for_wakeup = true

data->state = RELEASED

consumed

for_wakeup?

data->state = RELEASED

update coords

data->state = PRESSED

This ensures the first touch after the screen wakes is consumed for the wake-up action and is not forwarded to LVGL widgets, preventing unintended button activations.


The BSP defines the custom LVGL event infrastructure used by all UI screens. Three events are registered at runtime (IDs assigned by lv_event_register_id() after lv_init()):

Extern variableTrigger
LV_EVENT_SWITCH_PRESSED4-position switch activated
LV_EVENT_SWITCH_RELEASED4-position switch deactivated
LV_EVENT_POTENTIOMETER_CHANGEDPotentiometer value changed

These events carry a control_event_t payload (via lv_event_get_param()) with the full context needed by any screen handler:

family_id

control_event_t

+lv_indev_t* indev

+uint32_t btn_id

+lv_indev_type_t type

+control_family_t family_id

+int32_t steps

+uint32_t press_duration

«enumeration»

control_family_t

CONTROL_FAMILY_BUTTONS = 0

CONTROL_FAMILY_SWITCH

CONTROL_FAMILY_TOUCH

CONTROL_FAMILY_ENCODER

CONTROL_FAMILY_POTENTIOMETER

control_events_init() is called after lv_init() inside board_init() — this ordering is mandatory. Calling it before lv_init() would cause lv_event_register_id() to return LV_EVENT_ALL for all three IDs, making them indistinguishable.


When ESP3D_SNAPSHOT_FEATURE is enabled, lvgl_flush_cb intercepts every partial-buffer write and appends the raw pixel data to a file opened in g_snapshot. The capture logic runs under g_snapshot.mutex to avoid races with the snapshot controller:

  • Pixels are written in 120-byte chunks to avoid large stack allocations
  • Capture tracks captured_pixels vs expected_pixels (full-frame count)
  • On any fwrite error, g_snapshot.error is set and g_snapshot.ongoing cleared
  • fflush() is called after each successful chunk to ensure durability
  • Snapshot capture is transparent to VSYNC sync — the byte swap and semaphore handshake still execute normally after the snapshot write

For the snapshot state type see main/display/esp3d_snapshot.h (snapshot_state_t).


Core 1

tftUI - LVGL

Stack: 12288 B / Prio: 15

esp3d_gcode_host_task

Stack: 4096 B / Prio: 14

esp3d_rendering_rx_task

Stack: 4096 B / Prio: 5

tftStream

Stack: 8192 B / Prio: 0

Core 0

tftNetwork

Stack: 4096 B / Prio: 0

esp3d_serial_rx_task

Stack: 4096 B / Prio: 10

esp3d_socket_rx_task

Stack: 4096 B / Prio: 5

esp3d_socket_client_rx

Stack: 8192 B / Prio: 5

TaskCorePriorityStack (bytes)Notes
tftUI11512 288LVGL handler — highest priority on Core 1
esp3d_gcode_host_task1144 096GCode stream manager
esp3d_rendering_rx_task154 096Rendering pipeline
tftStream108 192Stream I/O; chunk size scales with PSRAM
esp3d_serial_rx_task0104 096UART RX for CNC serial
tftNetwork004 096Network orchestration
esp3d_socket_rx_task054 096Socket server RX
esp3d_socket_client_rx058 192Socket client RX

LVGL runs exclusively on Core 1. No LVGL API calls are permitted from Core 0 tasks or from ISRs. The lvgl_api_lock returned by get_lvgl_lock() must be held by any non-UI-task code that calls into LVGL.

Stream chunk size adapts to installed PSRAM:

PSRAMSTREAM_CHUNK_SIZE
>= 8 MB8 192 bytes
>= 4 MB4 096 bytes
>= 2 MB2 048 bytes
< 2 MB1 024 bytes

Declared in board_init.h:

/* Always available */
esp_err_t board_init(void);
const char *board_get_name(void);
const char *board_get_version(void);
/* Requires ESP3D_DISPLAY_FEATURE */
lv_display_t *get_lvgl_display(void);
_lock_t *get_lvgl_lock(void);
/* Requires ESP3D_DISPLAY_FEATURE && ESP3D_TOUCH_FEATURE */
lv_indev_t *get_touch_indev(void);
/* Requires ESP3D_PATCH_FS_ACCESS_RELEASE */
esp_err_t bsp_accessFs(void);
esp_err_t bsp_releaseFs(void);

board_init() must be called once, early in ESP3DX::begin(), before any other subsystem that requires the display, touch, or LVGL infrastructure.


The BSP is an ESP-IDF component registered in CMakeLists.txt:

Source files: board_init.c control_types.c
Include dirs: . (exposes all headers in the bsp/ directory)
IDF component dependencies:
esp_timer -- periodic LVGL tick timer
esp3d_log -- logging macros
nvs_flash -- settings persistence (transitive)
driver -- GPIO, I2C, LEDC
esp_lcd -- RGB panel driver
disp_backlight -- PWM backlight abstraction
disp_ili9485 -- ILI9485 RGB parallel driver
touch_gt911 -- GT911 capacitive touch driver
bus_i2c -- shared I2C bus abstraction
lvgl -- LVGL graphics library
esp3d_activity_manager -- screen-wake / inactivity tracking

For build variant selection, sdkconfig management, and multi-variant compilation see esp32s3_4827s043c_build_scripts.md.


FlagEffect when enabled
ESP3D_DISPLAY_FEATURECompiles all display and LVGL code
ESP3D_TOUCH_FEATURECompiles GT911 init and touch_read_cb
ESP3D_BRIGHTNESS_CONTROL_FEATUREEnables backlight PWM control via backlight_configure()
ESP3D_PATCH_FS_ACCESS_RELEASEEnables bsp_accessFs() / bsp_releaseFs() pixel-clock throttle
ESP3D_SNAPSHOT_FEATUREEnables in-flush screen capture to file
DISPLAY_USE_DOUBLE_BUFFER_FLAGAllocates second LVGL draw buffer in SPIRAM (set to 1 on this board)
HARDWARE_MOD_GT911_INTRoutes GT911 INT to GPIO 18 instead of NC
ESP3D_ORIENTATION_PORTRAIT272x480 canvas, portrait orientation
ESP3D_ORIENTATION_PORTRAIT_INVERTED272x480 canvas, portrait inverted (confirmed default)
ESP3D_ORIENTATION_LANDSCAPE480x272 canvas, landscape (confirmed 2026-08-09)
ESP3D_ORIENTATION_LANDSCAPE_INVERTED480x272 canvas, landscape inverted

ModuleDescription
esp32s3_4827s043c_factory.mdFactory test application (standalone, does not use this BSP)
esp32s3_4827s043c_build_scripts.mdBuild scripts, variant definitions, sdkconfig management
ModuleUsed by this BSP
display_drivers_rgb.mddisp_ili9485 (RGB parallel) and disp_backlight
touch_controllers.mdtouch_gt911
bus_drivers.mdbus_i2c (shared I2C bus for GT911)

Comparable BSP Modules (RGB parallel + VSYNC pattern)

Section titled “Comparable BSP Modules (RGB parallel + VSYNC pattern)”
ModuleDisplayNotable difference
esp32s3_8048s043c.mdST7262, 800x480, GT911Also implements bsp_accessFs/bsp_releaseFs
esp32s3_8048s050c.mdST7262, 800x480, GT911Same pattern, 5-inch panel
esp32s3_8048s070c_bsp.mdRGB, 800x480, GT9117-inch panel with SD shared access
esp32s3_8048_touch_lcd_7.mdRGB, 800x480, GT9117-inch touch LCD with bsp_accessFs
DocumentRelevance
docs/architecture/display_drivers.mdRGB parallel vs SPI driver architecture, swap_xy semantics, orientation math
docs/architecture/screens_architecture.mdLVGL screen management built on top of this BSP
docs/guides/esp32_memory_constraints.mdSPIRAM, DRAM constraints, stream chunk sizing
docs/guides/esp3d_log_guide.mdesp3d_log / esp3d_log_e usage in this module
ModuleUsage
bsp_board_initialization.mdCross-board BSP patterns and LVGL integration overview
bsp_control_events.mdControl event framework shared across all boards
Hardware_Abstraction_Layer.mdOverall HAL architecture this BSP fits into

components/bsp/lv_conf.h was regenerated from the LVGL 9.6.0 template (Configuration file for v9.6.0), and the sdkconfig files set CONFIG_LV_CONF_SKIP=n so this file is actually used (see Board_Support_Packages.md). The project values are kept (LV_MEM_SIZE 48 KB, monitors positions), LV_USE_COLOR_FILTER is 0 (color filters are not used: pressed feedback is a darker local style, see ui_components.md). LV_COLOR_DEPTH is no longer set in the file: LVGL takes CONFIG_LV_COLOR_DEPTH, or 16 by default.