diff --git a/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c b/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c index 7fa3e1dc94..ac6dd9a501 100644 --- a/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c +++ b/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c @@ -15,7 +15,7 @@ static const char *TAG = "lcd.dsi.bus"; #define MIPI_DSI_DEFAULT_TIMEOUT_CLOCK_FREQ_MHZ 10 // TxClkEsc frequency must be configured between 2 and 20 MHz -#define MIPI_DSI_DEFAULT_ESCAPE_CLOCK_FREQ_MHZ 10 +#define MIPI_DSI_DEFAULT_ESCAPE_CLOCK_FREQ_MHZ 18 esp_err_t esp_lcd_new_dsi_bus(const esp_lcd_dsi_bus_config_t *bus_config, esp_lcd_dsi_bus_handle_t *ret_bus) { diff --git a/components/esp_lcd/dsi/esp_lcd_panel_dpi.c b/components/esp_lcd/dsi/esp_lcd_panel_dpi.c index 2abcc1f81e..4d6d7c3f3c 100644 --- a/components/esp_lcd/dsi/esp_lcd_panel_dpi.c +++ b/components/esp_lcd/dsi/esp_lcd_panel_dpi.c @@ -79,9 +79,20 @@ static bool dma_trans_done_cb(dw_gdma_channel_handle_t chan, const dw_gdma_trans { bool yield_needed = false; esp_lcd_dpi_panel_t *dpi_panel = (esp_lcd_dpi_panel_t *)user_data; + mipi_dsi_hal_context_t *hal = &dpi_panel->bus->hal; uint8_t fb_index = dpi_panel->cur_fb_index; dw_gdma_link_list_handle_t link_list = dpi_panel->link_lists[fb_index]; + // clear the interrupt status + uint32_t error_status = mipi_dsi_brg_ll_get_interrupt_status(hal->bridge); + mipi_dsi_brg_ll_clear_interrupt_status(hal->bridge, error_status); + if (unlikely(error_status & MIPI_DSI_LL_EVENT_UNDERRUN)) { + // when an underrun happens, the LCD display may already becomes blue + // it's too late to recover the display, so we just print an error message + // as a hint to the user that he should optimize the memory bandwidth (with AXI-ICM) + ESP_DRAM_LOGE(TAG, "can't fetch data from external memory fast enough, underrun happens"); + } + // restart the DMA transfer, keep refreshing the LCD dw_gdma_block_markers_t markers = { .is_valid = true, @@ -438,6 +449,10 @@ static esp_err_t dpi_panel_init(esp_lcd_panel_t *panel) mipi_dsi_brg_ll_enable_dpi_output(hal->bridge, true); mipi_dsi_brg_ll_update_dpi_config(hal->bridge); + // enable the underrun interrupt, we use this as a signal of bandwidth shortage + // note, we opt to not install a dedicated interrupt handler just for this error condition, instead, we check it in the DMA callback + mipi_dsi_brg_ll_enable_interrupt(hal->bridge, MIPI_DSI_LL_EVENT_UNDERRUN, true); + return ESP_OK; } diff --git a/components/hal/esp32p4/include/hal/mipi_dsi_host_ll.h b/components/hal/esp32p4/include/hal/mipi_dsi_host_ll.h index ec52570334..0a54f719ef 100644 --- a/components/hal/esp32p4/include/hal/mipi_dsi_host_ll.h +++ b/components/hal/esp32p4/include/hal/mipi_dsi_host_ll.h @@ -82,7 +82,7 @@ static inline void mipi_dsi_host_ll_power_on_off(dsi_host_dev_t *dev, bool on) */ static inline void mipi_dsi_host_ll_set_timeout_clock_division(dsi_host_dev_t *dev, uint32_t div) { - HAL_FORCE_MODIFY_U32_REG_FIELD(dev->clkmgr_cfg, to_clk_division, div - 1); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->clkmgr_cfg, to_clk_division, div); } /** @@ -95,7 +95,8 @@ static inline void mipi_dsi_host_ll_set_timeout_clock_division(dsi_host_dev_t *d */ static inline void mipi_dsi_host_ll_set_escape_clock_division(dsi_host_dev_t *dev, uint32_t div) { - HAL_FORCE_MODIFY_U32_REG_FIELD(dev->clkmgr_cfg, tx_esc_clk_division, div - 1); + HAL_ASSERT(div > 1 && div < 256); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->clkmgr_cfg, tx_esc_clk_division, div); } /** diff --git a/examples/peripherals/lcd/mipi_dsi/main/idf_component.yml b/examples/peripherals/lcd/mipi_dsi/main/idf_component.yml index b445b5e83e..fe1207b157 100644 --- a/examples/peripherals/lcd/mipi_dsi/main/idf_component.yml +++ b/examples/peripherals/lcd/mipi_dsi/main/idf_component.yml @@ -1,4 +1,4 @@ dependencies: - lvgl/lvgl: "9.2.0" + lvgl/lvgl: "9.2.2" esp_lcd_ili9881c: "^1.0.0" esp_lcd_ek79007: "^1.0.0"