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
43 changes: 40 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 @@ -195,10 +195,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
Comment thread
matiasgibbons marked this conversation as resolved.
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 +308,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 +524,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 +561,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