Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 45 additions & 3 deletions components/esp_lvgl_port/src/lvgl9/esp_lvgl_port_disp.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,14 @@ static lv_display_t *lvgl_port_add_disp_priv(const lvgl_port_display_cfg_t *disp
static bool lvgl_port_flush_io_ready_callback(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata,
void *user_ctx);
#if CONFIG_IDF_TARGET_ESP32S3 && ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
#if CONFIG_LCD_RGB_ISR_IRAM_SAFE
static IRAM_ATTR bool lvgl_port_flush_rgb_vsync_ready_callback(esp_lcd_panel_handle_t panel_io,
const esp_lcd_rgb_panel_event_data_t *edata, void *user_ctx);
#else
static bool lvgl_port_flush_rgb_vsync_ready_callback(esp_lcd_panel_handle_t panel_io,
const esp_lcd_rgb_panel_event_data_t *edata, void *user_ctx);
#endif
#endif
#if (CONFIG_IDF_TARGET_ESP32P4 && ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0))
static bool lvgl_port_flush_dpi_panel_ready_callback(esp_lcd_panel_handle_t panel_io,
esp_lcd_dpi_panel_event_data_t *edata, void *user_ctx);
Expand Down Expand Up @@ -195,10 +200,18 @@ lv_display_t *lvgl_port_add_disp_rgb(const lvgl_port_display_cfg_t *disp_cfg,
#endif
};

/* When LCD_RGB_ISR_IRAM_SAFE is enabled, the callback must be in IRAM and
* cannot call lv_display_get_driver_data() (which resides in flash).
* Pass disp_ctx directly as user_ctx to avoid flash access from ISR. */
#if CONFIG_LCD_RGB_ISR_IRAM_SAFE
void *cb_user_ctx = disp_ctx;
#else
void *cb_user_ctx = disp_ctx->disp_drv;
#endif
if (rgb_cfg->flags.bb_mode && (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 2))) {
ESP_ERROR_CHECK(esp_lcd_rgb_panel_register_event_callbacks(disp_ctx->panel_handle, &bb_cbs, disp_ctx->disp_drv));
ESP_ERROR_CHECK(esp_lcd_rgb_panel_register_event_callbacks(disp_ctx->panel_handle, &bb_cbs, cb_user_ctx));
} else {
ESP_ERROR_CHECK(esp_lcd_rgb_panel_register_event_callbacks(disp_ctx->panel_handle, &vsync_cbs, disp_ctx->disp_drv));
ESP_ERROR_CHECK(esp_lcd_rgb_panel_register_event_callbacks(disp_ctx->panel_handle, &vsync_cbs, cb_user_ctx));
}
#else
ESP_RETURN_ON_FALSE(false, NULL, TAG, "RGB is supported only on ESP32S3 and from IDF 5.0!");
Expand Down Expand Up @@ -300,7 +313,14 @@ static lv_display_t *lvgl_port_add_disp_priv(const lvgl_port_display_cfg_t *disp
}

/* Display context */
lvgl_port_display_ctx_t *disp_ctx = malloc(sizeof(lvgl_port_display_ctx_t));
#if CONFIG_LCD_RGB_ISR_IRAM_SAFE
/* When ISR IRAM safety is enabled, the display context is passed directly
* to the ISR callback as user_ctx. It must reside in internal RAM so it
* remains accessible when the cache is disabled during SPI flash operations. */
lvgl_port_display_ctx_t *disp_ctx = heap_caps_malloc(sizeof(lvgl_port_display_ctx_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
#else
lvgl_port_display_ctx_t *disp_ctx = heap_caps_malloc(sizeof(lvgl_port_display_ctx_t), MALLOC_CAP_DEFAULT);
#endif
ESP_GOTO_ON_FALSE(disp_ctx, ESP_ERR_NO_MEM, err, TAG, "Not enough memory for display context allocation!");
memset(disp_ctx, 0, sizeof(lvgl_port_display_ctx_t));
disp_ctx->io_handle = disp_cfg->io_handle;
Expand Down Expand Up @@ -509,6 +529,27 @@ static bool lvgl_port_flush_dpi_vsync_ready_callback(esp_lcd_panel_handle_t pane
#endif

#if CONFIG_IDF_TARGET_ESP32S3 && ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
#if CONFIG_LCD_RGB_ISR_IRAM_SAFE
/* When LCD_RGB_ISR_IRAM_SAFE is enabled, this callback runs from IRAM.
* user_ctx is lvgl_port_display_ctx_t* to avoid calling lv_display_get_driver_data()
* which resides in flash and would crash when cache is disabled (e.g. during SPI flash ops). */
static IRAM_ATTR bool lvgl_port_flush_rgb_vsync_ready_callback(esp_lcd_panel_handle_t panel_io,
const esp_lcd_rgb_panel_event_data_t *edata, void *user_ctx)
{
BaseType_t need_yield = pdFALSE;

lvgl_port_display_ctx_t *disp_ctx = (lvgl_port_display_ctx_t *)user_ctx;
if (disp_ctx == NULL) {
return false;
}

if (disp_ctx->trans_sem) {
xSemaphoreGiveFromISR(disp_ctx->trans_sem, &need_yield);
}

return (need_yield == pdTRUE);
}
#else
static bool lvgl_port_flush_rgb_vsync_ready_callback(esp_lcd_panel_handle_t panel_io,
const esp_lcd_rgb_panel_event_data_t *edata, void *user_ctx)
{
Expand All @@ -525,6 +566,7 @@ static bool lvgl_port_flush_rgb_vsync_ready_callback(esp_lcd_panel_handle_t pane

return (need_yield == pdTRUE);
}
#endif /* CONFIG_LCD_RGB_ISR_IRAM_SAFE */
#endif
#endif

Expand Down