Skip to content

fix(esp_lvgl_port): support CONFIG_LCD_RGB_ISR_IRAM_SAFE for RGB panels (BSP-787)#732

Open
matiasgibbons wants to merge 4 commits intoespressif:masterfrom
matiasgibbons:fix/rgb-iram-safe-callback
Open

fix(esp_lvgl_port): support CONFIG_LCD_RGB_ISR_IRAM_SAFE for RGB panels (BSP-787)#732
matiasgibbons wants to merge 4 commits intoespressif:masterfrom
matiasgibbons:fix/rgb-iram-safe-callback

Conversation

@matiasgibbons
Copy link
Copy Markdown

@matiasgibbons matiasgibbons commented Mar 10, 2026

Problem

On ESP32-S3 with RGB LCD panels in bounce buffer mode, enabling
CONFIG_LCD_RGB_ISR_IRAM_SAFE=y causes a LoadProhibited crash at boot:

The root cause is that lvgl_port_flush_rgb_vsync_ready_callback() calls
lv_display_get_driver_data(), which resides in flash. When SPI flash
operations disable the cache, the ISR tries to execute from flash → crash.

Without CONFIG_LCD_RGB_ISR_IRAM_SAFE, the callback works but DMA underruns
can occur during flash operations, causing visible white horizontal lines on
the display (tearing artifacts).

Solution

When CONFIG_LCD_RGB_ISR_IRAM_SAFE is enabled:

  1. Mark the callback with IRAM_ATTR
  2. Pass disp_ctx (already in SRAM) directly as user_ctx instead of
    disp_drv (lv_display_t*), avoiding the need to call
    lv_display_get_driver_data() from ISR context
  3. Access disp_ctx->trans_sem directly (xSemaphoreGiveFromISR is always in IRAM)

When CONFIG_LCD_RGB_ISR_IRAM_SAFE is not set, behavior is 100% unchanged.

Testing

  • ESP32-S3 + ST7277 RGB 800×480 panel, bounce buffer mode, PSRAM canvas
  • Verified no crash with CONFIG_LCD_RGB_ISR_IRAM_SAFE=y
  • Verified white line artifacts eliminated during SPI flash operations
  • Verified backward compatibility without the config option

Note

Medium Risk
Touches ISR callback wiring and memory placement for display contexts, which can impact stability on constrained targets if allocation/callback assumptions differ across IDF versions. Changes are gated by CONFIG_LCD_RGB_ISR_IRAM_SAFE and otherwise preserve existing behavior.

Overview
Fixes ESP32-S3 RGB panel ISR crashes/tearing when CONFIG_LCD_RGB_ISR_IRAM_SAFE is enabled by making the RGB vsync/bounce-buffer callback IRAM-safe and avoiding flash-resident LVGL access.

When the config is on, RGB panel event callbacks now receive disp_ctx directly as user_ctx, lvgl_port_flush_rgb_vsync_ready_callback() is built with IRAM_ATTR and no longer calls lv_display_get_driver_data() from ISR context, and the display context allocation is forced into internal RAM via heap_caps_malloc(..., MALLOC_CAP_INTERNAL); behavior is unchanged when the config is off.

Reviewed by Cursor Bugbot for commit 5b71d1f. Bugbot is set up for automated code reviews on this repo. Configure here.

When CONFIG_LCD_RGB_ISR_IRAM_SAFE is enabled on ESP32-S3, the VSYNC/bounce
buffer callback must be placed in IRAM. The current implementation calls
lv_display_get_driver_data() from the callback, which resides in flash.
When SPI flash operations disable cache, this causes a LoadProhibited crash.

Fix: when CONFIG_LCD_RGB_ISR_IRAM_SAFE is set, pass the disp_ctx struct
directly as user_ctx instead of the lv_display_t pointer. This avoids
any flash function calls from the ISR context.

Without CONFIG_LCD_RGB_ISR_IRAM_SAFE the behavior is unchanged.
Copilot AI review requested due to automatic review settings March 10, 2026 12:37
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Mar 10, 2026

CLA assistant check
All committers have signed the CLA.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the ESP LVGL port’s RGB panel VSYNC/bounce-buffer callback path to support CONFIG_LCD_RGB_ISR_IRAM_SAFE on ESP32-S3 by ensuring the callback can run safely with cache disabled (e.g., during SPI flash operations).

Changes:

  • Adds an IRAM-safe variant of lvgl_port_flush_rgb_vsync_ready_callback() guarded by CONFIG_LCD_RGB_ISR_IRAM_SAFE.
  • Passes disp_ctx as the RGB panel callback user_ctx when IRAM-safe mode is enabled to avoid calling lv_display_get_driver_data() from ISR context.
  • Keeps the existing behavior unchanged when CONFIG_LCD_RGB_ISR_IRAM_SAFE is disabled.

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

Comment thread components/esp_lvgl_port/src/lvgl9/esp_lvgl_port_disp.c
Comment thread components/esp_lvgl_port/src/lvgl9/esp_lvgl_port_disp.c Outdated
@github-actions github-actions bot changed the title fix(esp_lvgl_port): support CONFIG_LCD_RGB_ISR_IRAM_SAFE for RGB panels fix(esp_lvgl_port): support CONFIG_LCD_RGB_ISR_IRAM_SAFE for RGB panels (BSP-787) Mar 10, 2026
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Free Tier Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Comment thread components/esp_lvgl_port/src/lvgl9/esp_lvgl_port_disp.c Outdated
- Replace assert() with null-check + early return in IRAM callback
  (assert references flash strings, defeating IRAM safety)
- Allocate disp_ctx from internal RAM (MALLOC_CAP_INTERNAL) when
  CONFIG_LCD_RGB_ISR_IRAM_SAFE is enabled, ensuring the struct
  remains accessible when cache is disabled during SPI flash ops
…it compliance

Use heap_caps_malloc with MALLOC_CAP_DEFAULT in the non-IRAM-safe path
instead of plain malloc(). Functionally equivalent but satisfies the
ESP-IDF pre-commit hook that forbids bare malloc() calls.
Having IRAM_ATTR on both the forward declaration and the definition of
lvgl_port_flush_rgb_vsync_ready_callback caused conflicting section
attributes (.iram1.0 vs .iram1.1) at link time on some IDF versions.
The attribute on the definition is sufficient to place the function in
IRAM.
@matiasgibbons matiasgibbons force-pushed the fix/rgb-iram-safe-callback branch from ca691a2 to 5b71d1f Compare April 16, 2026 04:29
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.

4 participants