44 * SPDX-License-Identifier: Apache-2.0
55 */
66#include <sys/param.h>
7- #include "freertos/FreeRTOS.h"
8- #include "freertos/task.h"
9- #include "freertos/semphr.h"
10- #include "soc/soc_caps.h"
11- #include "esp_check.h"
127#include "esp_lcd_panel_interface.h"
138#include "esp_lcd_mipi_dsi.h"
149#include "esp_clk_tree.h"
1712#include "esp_async_fbcpy.h"
1813#include "esp_memory_utils.h"
1914#include "esp_private/dw_gdma.h"
20- #include "esp_private/esp_clk_tree_common.h"
21- #include "hal/cache_hal.h"
22- #include "hal/cache_ll.h"
2315#include "hal/color_hal.h"
2416
25- static const char * TAG = "lcd.dsi.dpi" ;
26-
2717typedef struct esp_lcd_dpi_panel_t esp_lcd_dpi_panel_t ;
2818
2919static esp_err_t dpi_panel_del (esp_lcd_panel_t * panel );
@@ -77,8 +67,7 @@ static bool async_fbcpy_done_cb(esp_async_fbcpy_handle_t mcp, esp_async_fbcpy_ev
7767 return need_yield ;
7868}
7969
80- IRAM_ATTR
81- static bool dma_trans_done_cb (dw_gdma_channel_handle_t chan , const dw_gdma_trans_done_event_data_t * event_data , void * user_data )
70+ bool mipi_dsi_dma_trans_done_cb (dw_gdma_channel_handle_t chan , const dw_gdma_trans_done_event_data_t * event_data , void * user_data )
8271{
8372 bool yield_needed = false;
8473 esp_lcd_dpi_panel_t * dpi_panel = (esp_lcd_dpi_panel_t * )user_data ;
@@ -152,7 +141,7 @@ static esp_err_t dpi_panel_create_dma_link(esp_lcd_dpi_panel_t *dpi_panel)
152141
153142 // register DMA ISR callbacks
154143 dw_gdma_event_callbacks_t dsi_dma_cbs = {
155- .on_full_trans_done = dma_trans_done_cb ,
144+ .on_full_trans_done = mipi_dsi_dma_trans_done_cb ,
156145 };
157146 ESP_RETURN_ON_ERROR (dw_gdma_channel_register_event_callbacks (dma_chan , & dsi_dma_cbs , dpi_panel ), TAG , "register DMA callbacks failed" );
158147
@@ -177,28 +166,42 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
177166 }
178167 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 );
179168
180- size_t bits_per_pixel = 0 ;
181- switch (panel_config -> pixel_format ) {
182- case LCD_COLOR_PIXEL_FORMAT_RGB565 :
183- bits_per_pixel = 16 ;
184- break ;
185- case LCD_COLOR_PIXEL_FORMAT_RGB666 :
186- // RGB data in the memory must be constructed in 6-6-6 (18 bits) for each pixel
187- bits_per_pixel = 18 ;
188- break ;
189- case LCD_COLOR_PIXEL_FORMAT_RGB888 :
190- bits_per_pixel = 24 ;
191- break ;
192- }
193- lcd_color_format_t in_color_format = COLOR_TYPE_ID (COLOR_SPACE_RGB , panel_config -> pixel_format );
194- // if user sets the in_color_format, it can override the pixel format setting
169+ // by default, use RGB888 as the input color format
170+ lcd_color_format_t in_color_format = LCD_COLOR_FMT_RGB888 ;
171+ size_t bits_per_pixel = 24 ;
172+ // the deprecated way to set the pixel format
173+ #pragma GCC diagnostic push
174+ #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
175+ bool has_pixel_fmt = panel_config -> pixel_format != 0 ;
176+ bool has_in_fmt = panel_config -> in_color_format != 0 ;
177+ ESP_RETURN_ON_FALSE (has_pixel_fmt ^ has_in_fmt , ESP_ERR_INVALID_ARG , TAG ,
178+ "must set exactly one of pixel_format or in_color_format" );
179+ if (panel_config -> pixel_format ) {
180+ switch (panel_config -> pixel_format ) {
181+ case LCD_COLOR_PIXEL_FORMAT_RGB565 :
182+ bits_per_pixel = 16 ;
183+ break ;
184+ case LCD_COLOR_PIXEL_FORMAT_RGB666 :
185+ // RGB data in the memory must be constructed in 6-6-6 (18 bits) for each pixel
186+ bits_per_pixel = 18 ;
187+ break ;
188+ case LCD_COLOR_PIXEL_FORMAT_RGB888 :
189+ bits_per_pixel = 24 ;
190+ break ;
191+ }
192+ in_color_format = COLOR_TYPE_ID (COLOR_SPACE_RGB , panel_config -> pixel_format );
193+ }
194+ #pragma GCC diagnostic pop
195+ // the recommended way to set the input color format
195196 if (panel_config -> in_color_format ) {
197+ in_color_format = panel_config -> in_color_format ;
198+ // if user sets the in_color_format, it can override the pixel format setting
196199 color_space_pixel_format_t in_color_id = {
197- .color_type_id = panel_config -> in_color_format ,
200+ .color_type_id = in_color_format ,
198201 };
199202 bits_per_pixel = color_hal_pixel_format_get_bit_depth (in_color_id );
200- in_color_format = panel_config -> in_color_format ;
201203 }
204+ // by default, out_color_format is the same as in_color_format (i.e. no color format conversion)
202205 lcd_color_format_t out_color_format = in_color_format ;
203206 if (panel_config -> out_color_format ) {
204207 out_color_format = panel_config -> out_color_format ;
@@ -218,20 +221,16 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
218221 dpi_panel -> num_fbs = num_fbs ;
219222
220223 // allocate frame buffer from PSRAM
221- uint32_t cache_line_size = cache_hal_get_cache_line_size (CACHE_LL_LEVEL_EXT_MEM , CACHE_TYPE_DATA );
222- // DMA doesn't have requirement on the buffer alignment, but the cache does
223- uint32_t alignment = cache_line_size ;
224224 size_t fb_size = panel_config -> video_timing .h_size * panel_config -> video_timing .v_size * bits_per_pixel / 8 ;
225- uint8_t * frame_buffer = NULL ;
226225 for (int i = 0 ; i < num_fbs ; i ++ ) {
227- frame_buffer = heap_caps_aligned_calloc ( alignment , 1 , fb_size , MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT );
226+ uint8_t * frame_buffer = heap_caps_calloc ( 1 , fb_size , MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT | MALLOC_CAP_DMA );
228227 ESP_GOTO_ON_FALSE (frame_buffer , ESP_ERR_NO_MEM , err , TAG , "no memory for frame buffer" );
229228 dpi_panel -> fbs [i ] = frame_buffer ;
230229 ESP_LOGD (TAG , "fb[%d] @%p" , i , frame_buffer );
231230 // preset the frame buffer with black color
232- // the frame buffer address alignment is ensured by `heap_caps_aligned_calloc `
231+ // the frame buffer address alignment is ensured by `heap_caps_calloc `
233232 // while the value of the fb_size may not be aligned to the cache line size
234- // but that's not a problem because the `heap_caps_aligned_calloc ` internally allocated a buffer whose size is aligned up to the cache line size
233+ // but that's not a problem because the `heap_caps_calloc ` internally allocated a buffer whose size is aligned up to the cache line size
235234 ESP_GOTO_ON_ERROR (esp_cache_msync (frame_buffer , fb_size , ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED ),
236235 err , TAG , "cache write back failed" );
237236 }
@@ -264,7 +263,7 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
264263 uint32_t dpi_div = mipi_dsi_hal_host_dpi_calculate_divider (hal , dpi_clk_src_freq_hz / 1000 / 1000 , panel_config -> dpi_clock_freq_mhz );
265264 ESP_GOTO_ON_ERROR (esp_clk_tree_enable_src ((soc_module_clk_t )dpi_clk_src , true), err , TAG , "clock source enable failed" );
266265 // set the clock source, set the divider, and enable the dpi clock
267- DSI_CLOCK_SRC_ATOMIC () {
266+ PERIPH_RCC_ATOMIC () {
268267 mipi_dsi_ll_set_dpi_clock_source (bus_id , dpi_clk_src );
269268 mipi_dsi_ll_set_dpi_clock_div (bus_id , dpi_div );
270269 mipi_dsi_ll_enable_dpi_clock (bus_id , true);
@@ -283,7 +282,7 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
283282 ESP_GOTO_ON_ERROR (dpi_panel_create_dma_link (dpi_panel ), err , TAG , "initialize DMA link failed" );
284283
285284 mipi_dsi_host_ll_dpi_set_vcid (hal -> host , panel_config -> virtual_channel );
286- mipi_dsi_hal_host_dpi_set_color_coding (hal , out_color_format , 0 );
285+ mipi_dsi_host_ll_dpi_set_color_coding (hal -> host , out_color_format , 0 );
287286 // these signals define how the DPI interface interacts with the controller
288287 mipi_dsi_host_ll_dpi_set_timing_polarity (hal -> host , false, false, false, false, false);
289288
@@ -321,8 +320,9 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
321320 panel_config -> video_timing .vsync_front_porch );
322321 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 );
323322 mipi_dsi_brg_ll_set_underrun_discard_count (hal -> bridge , panel_config -> video_timing .h_size );
324- // set input color space
325- mipi_dsi_brg_ll_set_input_color_space (hal -> bridge , COLOR_SPACE_TYPE (in_color_format ));
323+ // set the in/out color formats in the DSI bridge
324+ mipi_dsi_brg_ll_set_input_color_format (hal -> bridge , in_color_format );
325+ mipi_dsi_brg_ll_set_output_color_format (hal -> bridge , out_color_format , 0 );
326326 // use the DW_GDMA as the flow controller
327327 mipi_dsi_brg_ll_set_flow_controller (hal -> bridge , MIPI_DSI_LL_FLOW_CONTROLLER_DMA );
328328 mipi_dsi_brg_ll_set_multi_block_number (hal -> bridge , DPI_PANEL_MIN_DMA_NODES_PER_LINK );
@@ -352,7 +352,7 @@ static esp_err_t dpi_panel_del(esp_lcd_panel_t *panel)
352352 int bus_id = bus -> bus_id ;
353353 mipi_dsi_hal_context_t * hal = & bus -> hal ;
354354 // disable the DPI clock
355- DSI_CLOCK_SRC_ATOMIC () {
355+ PERIPH_RCC_ATOMIC () {
356356 mipi_dsi_ll_enable_dpi_clock (bus_id , false);
357357 }
358358 // disable the DSI bridge
@@ -574,6 +574,7 @@ esp_err_t esp_lcd_dpi_panel_set_color_conversion(esp_lcd_panel_handle_t panel, c
574574 if (dpi_panel -> in_color_format == COLOR_TYPE_ID (COLOR_SPACE_YUV , COLOR_PIXEL_YUV422 )
575575 && COLOR_SPACE_TYPE (dpi_panel -> out_color_format ) == LCD_COLOR_SPACE_RGB ) {
576576 // YUV422->RGB
577+ mipi_dsi_brg_ll_set_input_color_range (hal -> bridge , config -> in_color_range );
577578 mipi_dsi_brg_ll_set_yuv_convert_std (hal -> bridge , config -> spec .yuv .conv_std );
578579 mipi_dsi_brg_ll_set_yuv422_pack_order (hal -> bridge , config -> spec .yuv .yuv422 .in_pack_order );
579580 } else {
@@ -611,7 +612,7 @@ esp_err_t esp_lcd_dpi_panel_register_event_callbacks(esp_lcd_panel_handle_t pane
611612{
612613 ESP_RETURN_ON_FALSE (panel && cbs , ESP_ERR_INVALID_ARG , TAG , "invalid argument" );
613614 esp_lcd_dpi_panel_t * dpi_panel = __containerof (panel , esp_lcd_dpi_panel_t , base );
614- #if CONFIG_LCD_DSI_ISR_IRAM_SAFE
615+ #if CONFIG_LCD_DSI_ISR_HANDLER_IN_IRAM
615616 if (cbs -> on_color_trans_done ) {
616617 ESP_RETURN_ON_FALSE (esp_ptr_in_iram (cbs -> on_color_trans_done ), ESP_ERR_INVALID_ARG , TAG , "on_color_trans_done callback not in IRAM" );
617618 }
@@ -621,7 +622,7 @@ esp_err_t esp_lcd_dpi_panel_register_event_callbacks(esp_lcd_panel_handle_t pane
621622 if (user_ctx ) {
622623 ESP_RETURN_ON_FALSE (esp_ptr_internal (user_ctx ), ESP_ERR_INVALID_ARG , TAG , "user context not in internal RAM" );
623624 }
624- #endif // CONFIG_LCD_RGB_ISR_IRAM_SAFE
625+ #endif // CONFIG_LCD_DSI_ISR_HANDLER_IN_IRAM
625626 dpi_panel -> on_color_trans_done = cbs -> on_color_trans_done ;
626627 dpi_panel -> on_refresh_done = cbs -> on_refresh_done ;
627628 dpi_panel -> user_ctx = user_ctx ;
0 commit comments