Skip to content

Add LTDC display and GT911 touch drivers for STM32H7 boards#407

Open
nuraci wants to merge 4 commits intolvgl:masterfrom
Copper-And-Code:master
Open

Add LTDC display and GT911 touch drivers for STM32H7 boards#407
nuraci wants to merge 4 commits intolvgl:masterfrom
Copper-And-Code:master

Conversation

@nuraci
Copy link
Copy Markdown

@nuraci nuraci commented Mar 29, 2026

Summary

Add a generic LTDC display driver and GT911 I2C touch driver for STM32H7,
along with board-specific BSP files for three boards (DEV190806042,
FK743M5-XIH6, STM32H7_CORE).

LTDC driver (driver/stm32/st_ltdc/)

  • st_ltdc.c — MicroPython C module exposing the st_ltdc.LTDC class:
    configurable timing parameters, polarity flags, RGB565/RGB888/ARGB8888
    color formats, double-buffered VSYNC-synced flush (DIRECT/FULL mode)
    and DMA2D-accelerated partial updates (PARTIAL mode).
    Framebuffer MPU region is configured as Write-Through so LTDC reads
    are always coherent without manual cache maintenance.
    AXI QoS priorities are tuned to prevent LTDC starvation.
  • touch_i2c.c — MicroPython C module exposing touch_i2c.TP class
    for GT9xx touch controllers, supporting both hardware I2C and SoftI2C.
  • Python layerst_ltdc_utils.py (init helper), boards.py (pin
    configs per board), panels.py (display timing presets), display_conf.py
    (auto-selects board/panel from build config), display_driver.py
    (one-line boot).

Board-specific BSP (driver/stm32/{BOARD}/bsp_ltdc.c)

Each file implements HAL_LTDC_MspInit() / HAL_LTDC_MspDeInit() with
the correct PLL3 pixel-clock setup and GPIO alternate-function mapping
for that board's LTDC wiring. The build system (micropython.mk)
automatically picks the right BSP based on the BOARD variable.

Supported configurations

Board Display Touch I2C
DEV190806042 RGB 24-bit (Port I/J/K) GT911 SoftI2C
FK743M5-XIH6 RGB 24-bit (mixed ports) GT911 SoftI2C
STM32H7_CORE V1.0 RGB (scattered pins) GT911 HW I2C4
STM32H7_CORE V1.3 RGB (scattered pins) GT911 SoftI2C

Test plan

  • Build with LVGL enabled for each board variant
  • Verify display initializes and shows LVGL content without flickering
  • Verify touch input works (GT911 detected, coordinates reported)
  • Verify double-buffered DIRECT mode (no tearing)
  • Verify PARTIAL render mode with DMA2D
  • Test soft-reset cycle (Ctrl-D): display deinits cleanly and reinits
  • Test lv.deinit() / lv.init() cycle without crash

Boards docs and photos

https://github.com/Copper-And-Code/stm32h7-boards-docs

micropython sample code and tools

https://github.com/Copper-And-Code/lv_micropython_code_and_tools


Summary by cubic

Add a generic LTDC display driver and GT911 I2C touch driver for STM32H7 boards with LVGL integration. Adds BSPs for DEV190806042, FK743M5-XIH6, and STM32H7_CORE, plus safer init/deinit and config validation.

  • New Features

    • st_ltdc.LTDC driver: configurable timings/polarity, RGB565/RGB888/ARGB8888, tear‑free double buffering with VSYNC‑synced flush, DMA2D‑accelerated partial updates.
    • Framebuffer set write‑through via MPU; AXI QoS tuned to avoid LTDC starvation.
    • touch_i2c.TP for GT9xx (GT911) via hardware I2C or SoftI2C; BSPs and auto board/panel selection via boards.py/panels.py/display_conf.py; display_driver.py for one‑line init; LVGL lv_conf.h; example updated.
  • Bug Fixes

    • Zero‑initialize the display object to avoid picking the wrong backlight path; guard deinit() when the handle was never initialized.
    • Validate panel timings (width/height/hsync/vsync) and raise ValueError for unsupported BOARD/VERSION/PANEL in display_conf.py.

Written for commit b6fce8e. Summary will update on new commits.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

4 issues found across 14 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="driver/stm32/st_ltdc/modules/st_ltdc.c">

<violation number="1" location="driver/stm32/st_ltdc/modules/st_ltdc.c:264">
P2: Backlight selector fields are not fully initialized before use, so init/deinit may read indeterminate `bl_pin`/`bl_led` values and take the wrong backlight path.</violation>

<violation number="2" location="driver/stm32/st_ltdc/modules/st_ltdc.c:482">
P2: `deinit()` lacks an initialization-state guard and unconditionally calls LTDC HAL operations, allowing out-of-sequence calls to operate on an uninitialized `hltdc` handle.</violation>

<violation number="3" location="driver/stm32/st_ltdc/modules/st_ltdc.c:520">
P2: LTDC timing and geometry inputs are not range-validated, allowing unsigned underflow/wrap in register calculations.</violation>
</file>

<file name="driver/stm32/st_ltdc/display_conf.py">

<violation number="1" location="driver/stm32/st_ltdc/display_conf.py:13">
P2: Unsupported BOARD/VERSION/PANEL values can leave `board`/`panel` undefined, causing runtime import failure instead of a clear configuration error.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

- Zero-initialize ltdc_display_obj_t to prevent indeterminate
  bl_pin/bl_led fields from selecting the wrong backlight path
- Guard deinit() against out-of-sequence calls on uninitialized handle
- Validate LTDC timing parameters (width, height, hsync, vsync > 0)
  before computing register values to prevent unsigned underflow
- Raise ValueError for unsupported BOARD/VERSION/PANEL in display_conf.py
  instead of leaving variables undefined
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="driver/stm32/st_ltdc/modules/st_ltdc.c">

<violation number="1" location="driver/stm32/st_ltdc/modules/st_ltdc.c:470">
P1: `deinit()` can become a no-op after LVGL display delete because it keys off a global that is cleared outside `deinit`, skipping LTDC/backlight teardown.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
@nuraci
Copy link
Copy Markdown
Author

nuraci commented Apr 3, 2026

The CI failure is unrelated to this PR — it's a pre-existing issue in the ESP32 port. This PR only touches STM32 board definitions and the LTDC driver.

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.

1 participant