@@ -80,9 +80,20 @@ static bool dma_trans_done_cb(dw_gdma_channel_handle_t chan, const dw_gdma_trans
8080{
8181 bool yield_needed = false;
8282 esp_lcd_dpi_panel_t * dpi_panel = (esp_lcd_dpi_panel_t * )user_data ;
83+ mipi_dsi_hal_context_t * hal = & dpi_panel -> bus -> hal ;
8384 uint8_t fb_index = dpi_panel -> cur_fb_index ;
8485 dw_gdma_link_list_handle_t link_list = dpi_panel -> link_lists [fb_index ];
8586
87+ // clear the interrupt status
88+ uint32_t error_status = mipi_dsi_brg_ll_get_interrupt_status (hal -> bridge );
89+ mipi_dsi_brg_ll_clear_interrupt_status (hal -> bridge , error_status );
90+ if (unlikely (error_status & MIPI_DSI_LL_EVENT_UNDERRUN )) {
91+ // when an underrun happens, the LCD display may already becomes blue
92+ // it's too late to recover the display, so we just print an error message
93+ // as a hint to the user that he should optimize the memory bandwidth (with AXI-ICM)
94+ ESP_DRAM_LOGE (TAG , "can't fetch data from external memory fast enough, underrun happens" );
95+ }
96+
8697 // restart the DMA transfer, keep refreshing the LCD
8798 dw_gdma_block_markers_t markers = {
8899 .is_valid = true,
@@ -440,6 +451,10 @@ static esp_err_t dpi_panel_init(esp_lcd_panel_t *panel)
440451 mipi_dsi_brg_ll_enable_dpi_output (hal -> bridge , true);
441452 mipi_dsi_brg_ll_update_dpi_config (hal -> bridge );
442453
454+ // enable the underrun interrupt, we use this as a signal of bandwidth shortage
455+ // note, we opt to not install a dedicated interrupt handler just for this error condition, instead, we check it in the DMA callback
456+ mipi_dsi_brg_ll_enable_interrupt (hal -> bridge , MIPI_DSI_LL_EVENT_UNDERRUN , true);
457+
443458 return ESP_OK ;
444459}
445460
0 commit comments