@@ -38,7 +38,7 @@ struct esp_lcd_dpi_panel_t {
3838 uint32_t h_pixels ; // Horizontal pixels
3939 uint32_t v_pixels ; // Vertical pixels
4040 size_t frame_buffer_size ; // Frame buffer size
41- size_t bytes_per_pixel ; // Bytes per pixel
41+ size_t bits_per_pixel ; // Bits per pixel
4242 lcd_color_rgb_pixel_format_t pixel_format ; // RGB Pixel format
4343 dw_gdma_channel_handle_t dma_chan ; // DMA channel
4444 dw_gdma_link_list_handle_t link_lists [DPI_PANEL_MAX_FB_NUM ]; // DMA link list
@@ -118,7 +118,7 @@ static esp_err_t dpi_panel_create_dma_link(esp_lcd_dpi_panel_t *dpi_panel)
118118 .handshake_type = DW_GDMA_HANDSHAKE_HW ,
119119 .num_outstanding_requests = 2 ,
120120 },
121- .flow_controller = DW_GDMA_FLOW_CTRL_DST , // the DSI bridge as the DMA flow controller
121+ .flow_controller = DW_GDMA_FLOW_CTRL_SELF , // DMA as the flow controller
122122 .chan_priority = 1 ,
123123 };
124124 ESP_RETURN_ON_ERROR (dw_gdma_new_channel (& dma_alloc_config , & dma_chan ), TAG , "create DMA channel failed" );
@@ -161,6 +161,22 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
161161 }
162162 ESP_RETURN_ON_FALSE (num_fbs <= DPI_PANEL_MAX_FB_NUM , ESP_ERR_INVALID_ARG , TAG , "num_fbs not within [1,%d]" , DPI_PANEL_MAX_FB_NUM );
163163
164+ size_t bits_per_pixel = 0 ;
165+ switch (panel_config -> pixel_format ) {
166+ case LCD_COLOR_PIXEL_FORMAT_RGB565 :
167+ bits_per_pixel = 16 ;
168+ break ;
169+ case LCD_COLOR_PIXEL_FORMAT_RGB666 :
170+ // RGB data in the memory must be constructed in 6-6-6 (18 bits) for each pixel
171+ bits_per_pixel = 18 ;
172+ break ;
173+ case LCD_COLOR_PIXEL_FORMAT_RGB888 :
174+ bits_per_pixel = 24 ;
175+ break ;
176+ }
177+ ESP_RETURN_ON_FALSE (panel_config -> video_timing .h_size * panel_config -> video_timing .v_size * bits_per_pixel % 8 == 0 ,
178+ ESP_ERR_INVALID_ARG , TAG , "frame buffer size not aligned to byte boundary" );
179+
164180 int bus_id = bus -> bus_id ;
165181 mipi_dsi_hal_context_t * hal = & bus -> hal ;
166182
@@ -172,22 +188,10 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
172188 dpi_panel -> num_fbs = num_fbs ;
173189
174190 // allocate frame buffer from PSRAM
175- size_t bytes_per_pixel = 0 ;
176- switch (panel_config -> pixel_format ) {
177- case LCD_COLOR_PIXEL_FORMAT_RGB565 :
178- bytes_per_pixel = 2 ;
179- break ;
180- case LCD_COLOR_PIXEL_FORMAT_RGB666 :
181- bytes_per_pixel = 3 ;
182- break ;
183- case LCD_COLOR_PIXEL_FORMAT_RGB888 :
184- bytes_per_pixel = 3 ;
185- break ;
186- }
187191 uint32_t cache_line_size = cache_hal_get_cache_line_size (CACHE_LL_LEVEL_EXT_MEM , CACHE_TYPE_DATA );
188192 // DMA doesn't have requirement on the buffer alignment, but the cache does
189193 uint32_t alignment = cache_line_size ;
190- size_t frame_buffer_size = panel_config -> video_timing .h_size * panel_config -> video_timing .v_size * bytes_per_pixel ;
194+ size_t frame_buffer_size = panel_config -> video_timing .h_size * panel_config -> video_timing .v_size * bits_per_pixel / 8 ;
191195 uint8_t * frame_buffer = NULL ;
192196 for (int i = 0 ; i < num_fbs ; i ++ ) {
193197 frame_buffer = heap_caps_aligned_calloc (alignment , 1 , frame_buffer_size , MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT );
@@ -202,7 +206,7 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
202206 err , TAG , "cache write back failed" );
203207 }
204208 dpi_panel -> frame_buffer_size = frame_buffer_size ;
205- dpi_panel -> bytes_per_pixel = bytes_per_pixel ;
209+ dpi_panel -> bits_per_pixel = bits_per_pixel ;
206210 dpi_panel -> h_pixels = panel_config -> video_timing .h_size ;
207211 dpi_panel -> v_pixels = panel_config -> video_timing .v_size ;
208212
@@ -274,10 +278,10 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
274278 panel_config -> video_timing .vsync_back_porch ,
275279 panel_config -> video_timing .v_size ,
276280 panel_config -> video_timing .vsync_front_porch );
277- mipi_dsi_brg_ll_set_num_pixel_bits (hal -> bridge , panel_config -> video_timing .h_size * panel_config -> video_timing .v_size * bytes_per_pixel * 8 );
281+ mipi_dsi_brg_ll_set_num_pixel_bits (hal -> bridge , panel_config -> video_timing .h_size * panel_config -> video_timing .v_size * bits_per_pixel );
278282 mipi_dsi_brg_ll_set_underrun_discard_count (hal -> bridge , panel_config -> video_timing .h_size );
279- // let the DSI bridge as the DMA flow controller
280- mipi_dsi_brg_ll_set_flow_controller (hal -> bridge , MIPI_DSI_LL_FLOW_CONTROLLER_BRIDGE );
283+ // use the DW_GDMA as the flow controller
284+ mipi_dsi_brg_ll_set_flow_controller (hal -> bridge , MIPI_DSI_LL_FLOW_CONTROLLER_DMA );
281285 mipi_dsi_brg_ll_set_burst_len (hal -> bridge , 256 );
282286 mipi_dsi_brg_ll_set_empty_threshold (hal -> bridge , 1024 - 256 );
283287 // enable DSI bridge
@@ -416,7 +420,7 @@ static esp_err_t dpi_panel_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int
416420 uint8_t * frame_buffer = dpi_panel -> fbs [cur_fb_index ];
417421 uint8_t * draw_buffer = (uint8_t * )color_data ;
418422 size_t frame_buffer_size = dpi_panel -> frame_buffer_size ;
419- size_t bytes_per_pixel = dpi_panel -> bytes_per_pixel ;
423+ size_t bits_per_pixel = dpi_panel -> bits_per_pixel ;
420424
421425 // clip to boundaries
422426 int h_res = dpi_panel -> h_pixels ;
@@ -443,8 +447,8 @@ static esp_err_t dpi_panel_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int
443447 if (!do_copy ) { // no copy, just do cache memory write back
444448 ESP_LOGD (TAG , "draw buffer is in frame buffer memory range, do cache write back only" );
445449 // only write back the LCD lines that updated by the draw buffer
446- uint8_t * cache_sync_start = dpi_panel -> fbs [draw_buf_fb_index ] + (y_start * dpi_panel -> h_pixels ) * bytes_per_pixel ;
447- size_t cache_sync_size = (y_end - y_start ) * dpi_panel -> h_pixels * bytes_per_pixel ;
450+ uint8_t * cache_sync_start = dpi_panel -> fbs [draw_buf_fb_index ] + (y_start * dpi_panel -> h_pixels ) * bits_per_pixel / 8 ;
451+ size_t cache_sync_size = (y_end - y_start ) * dpi_panel -> h_pixels * bits_per_pixel / 8 ;
448452 // the buffer to be flushed is still within the frame buffer, so even an unaligned address is OK
449453 esp_cache_msync (cache_sync_start , cache_sync_size , ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED );
450454
@@ -456,18 +460,18 @@ static esp_err_t dpi_panel_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int
456460 } else if (!dpi_panel -> fbcpy_handle ) { // copy by CPU
457461 ESP_LOGD (TAG , "copy draw buffer by CPU" );
458462 const uint8_t * from = draw_buffer ;
459- uint8_t * to = frame_buffer + (y_start * dpi_panel -> h_pixels + x_start ) * bytes_per_pixel ;
460- uint32_t copy_bytes_per_line = (x_end - x_start ) * bytes_per_pixel ;
461- uint32_t bytes_per_line = bytes_per_pixel * dpi_panel -> h_pixels ;
463+ uint8_t * to = frame_buffer + (y_start * dpi_panel -> h_pixels + x_start ) * bits_per_pixel / 8 ;
464+ uint32_t copy_bytes_per_line = (x_end - x_start ) * bits_per_pixel / 8 ;
465+ uint32_t bytes_per_line = bits_per_pixel * dpi_panel -> h_pixels / 8 ;
462466 // please note, we assume the user provided draw_buffer is compact,
463467 // but the destination is a sub-window of the frame buffer, so we need to skip the stride
464468 for (int y = y_start ; y < y_end ; y ++ ) {
465469 memcpy (to , from , copy_bytes_per_line );
466470 to += bytes_per_line ;
467471 from += copy_bytes_per_line ;
468472 }
469- uint8_t * cache_sync_start = frame_buffer + (y_start * dpi_panel -> h_pixels ) * bytes_per_pixel ;
470- size_t cache_sync_size = (y_end - y_start ) * dpi_panel -> h_pixels * bytes_per_pixel ;
473+ uint8_t * cache_sync_start = frame_buffer + (y_start * dpi_panel -> h_pixels ) * bits_per_pixel / 8 ;
474+ size_t cache_sync_size = (y_end - y_start ) * dpi_panel -> h_pixels * bits_per_pixel / 8 ;
471475 // the buffer to be flushed is still within the frame buffer, so even an unaligned address is OK
472476 esp_cache_msync (cache_sync_start , cache_sync_size , ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED );
473477 // invoke the trans done callback
@@ -482,7 +486,7 @@ static esp_err_t dpi_panel_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int
482486
483487 // write back the user's draw buffer, so that the DMA can see the correct data
484488 // Note, the user draw buffer should be 1D array, and contiguous in memory, no stride
485- size_t color_data_size = (x_end - x_start ) * (y_end - y_start ) * bytes_per_pixel ;
489+ size_t color_data_size = (x_end - x_start ) * (y_end - y_start ) * bits_per_pixel / 8 ;
486490 esp_cache_msync (draw_buffer , color_data_size , ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED );
487491
488492 esp_async_fbcpy_trans_desc_t fbcpy_trans_config = {
0 commit comments