mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-30 19:19:21 +00:00
feat(lcd): support color conversion for mipi dsi driver
This commit is contained in:
@@ -16,7 +16,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)
|
||||
{
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include "esp_private/esp_clk_tree_common.h"
|
||||
#include "hal/cache_hal.h"
|
||||
#include "hal/cache_ll.h"
|
||||
#include "hal/color_hal.h"
|
||||
|
||||
static const char *TAG = "lcd.dsi.dpi";
|
||||
|
||||
@@ -40,7 +41,8 @@ struct esp_lcd_dpi_panel_t {
|
||||
uint32_t v_pixels; // Vertical pixels
|
||||
size_t fb_size; // Frame buffer size, in bytes
|
||||
size_t bits_per_pixel; // Bits per pixel
|
||||
lcd_color_rgb_pixel_format_t pixel_format; // RGB Pixel format
|
||||
lcd_color_format_t in_color_format; // Input color format
|
||||
lcd_color_format_t out_color_format; // Output color format
|
||||
dw_gdma_channel_handle_t dma_chan; // DMA channel
|
||||
dw_gdma_link_list_handle_t link_lists[DPI_PANEL_MAX_FB_NUM]; // DMA link list
|
||||
esp_async_fbcpy_handle_t fbcpy_handle; // Use DMA2D to do frame buffer copy
|
||||
@@ -175,6 +177,19 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
|
||||
bits_per_pixel = 24;
|
||||
break;
|
||||
}
|
||||
lcd_color_format_t in_color_format = COLOR_TYPE_ID(COLOR_SPACE_RGB, panel_config->pixel_format);
|
||||
// if user sets the in_color_format, it can override the pixel format setting
|
||||
if (panel_config->in_color_format) {
|
||||
color_space_pixel_format_t in_color_id = {
|
||||
.color_type_id = panel_config->in_color_format,
|
||||
};
|
||||
bits_per_pixel = color_hal_pixel_format_get_bit_depth(in_color_id);
|
||||
in_color_format = panel_config->in_color_format;
|
||||
}
|
||||
lcd_color_format_t out_color_format = in_color_format;
|
||||
if (panel_config->out_color_format) {
|
||||
out_color_format = panel_config->out_color_format;
|
||||
}
|
||||
ESP_RETURN_ON_FALSE(panel_config->video_timing.h_size * panel_config->video_timing.v_size * bits_per_pixel % 8 == 0,
|
||||
ESP_ERR_INVALID_ARG, TAG, "frame buffer size not aligned to byte boundary");
|
||||
|
||||
@@ -184,7 +199,8 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
|
||||
dpi_panel = heap_caps_calloc(1, sizeof(esp_lcd_dpi_panel_t), DSI_MEM_ALLOC_CAPS);
|
||||
ESP_GOTO_ON_FALSE(dpi_panel, ESP_ERR_NO_MEM, err, TAG, "no memory for DPI panel");
|
||||
dpi_panel->virtual_channel = panel_config->virtual_channel;
|
||||
dpi_panel->pixel_format = panel_config->pixel_format;
|
||||
dpi_panel->in_color_format = in_color_format;
|
||||
dpi_panel->out_color_format = out_color_format;
|
||||
dpi_panel->bus = bus;
|
||||
dpi_panel->num_fbs = num_fbs;
|
||||
|
||||
@@ -253,7 +269,7 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
|
||||
ESP_GOTO_ON_ERROR(dpi_panel_create_dma_link(dpi_panel), err, TAG, "initialize DMA link failed");
|
||||
|
||||
mipi_dsi_host_ll_dpi_set_vcid(hal->host, panel_config->virtual_channel);
|
||||
mipi_dsi_hal_host_dpi_set_color_coding(hal, panel_config->pixel_format, 0);
|
||||
mipi_dsi_hal_host_dpi_set_color_coding(hal, out_color_format, 0);
|
||||
// these signals define how the DPI interface interacts with the controller
|
||||
mipi_dsi_host_ll_dpi_set_timing_polarity(hal->host, false, false, false, false, false);
|
||||
|
||||
@@ -291,6 +307,8 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
|
||||
panel_config->video_timing.vsync_front_porch);
|
||||
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);
|
||||
mipi_dsi_brg_ll_set_underrun_discard_count(hal->bridge, panel_config->video_timing.h_size);
|
||||
// set input color space
|
||||
mipi_dsi_brg_ll_set_input_color_space(hal->bridge, COLOR_SPACE_TYPE(in_color_format));
|
||||
// use the DW_GDMA as the flow controller
|
||||
mipi_dsi_brg_ll_set_flow_controller(hal->bridge, MIPI_DSI_LL_FLOW_CONTROLLER_DMA);
|
||||
mipi_dsi_brg_ll_set_multi_block_number(hal->bridge, DPI_PANEL_MIN_DMA_NODES_PER_LINK);
|
||||
@@ -343,7 +361,7 @@ static esp_err_t dpi_panel_del(esp_lcd_panel_t *panel)
|
||||
esp_async_fbcpy_uninstall(dpi_panel->fbcpy_handle);
|
||||
}
|
||||
if (dpi_panel->draw_sem) {
|
||||
vSemaphoreDelete(dpi_panel->draw_sem);
|
||||
vSemaphoreDeleteWithCaps(dpi_panel->draw_sem);
|
||||
}
|
||||
if (dpi_panel->pm_lock) {
|
||||
esp_pm_lock_release(dpi_panel->pm_lock);
|
||||
@@ -515,9 +533,8 @@ static esp_err_t dpi_panel_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int
|
||||
.copy_size_x = x_end - x_start,
|
||||
.copy_size_y = y_end - y_start,
|
||||
.pixel_format_unique_id = {
|
||||
.color_space = COLOR_SPACE_RGB,
|
||||
.pixel_format = dpi_panel->pixel_format,
|
||||
},
|
||||
.color_type_id = dpi_panel->in_color_format,
|
||||
}
|
||||
};
|
||||
ESP_RETURN_ON_ERROR(esp_async_fbcpy(dpi_panel->fbcpy_handle, &fbcpy_trans_config, async_fbcpy_done_cb, dpi_panel), TAG, "async memcpy failed");
|
||||
}
|
||||
@@ -525,6 +542,24 @@ static esp_err_t dpi_panel_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_lcd_dpi_panel_set_color_conversion(esp_lcd_panel_handle_t panel, const esp_lcd_color_conv_config_t *config)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(panel, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
esp_lcd_dpi_panel_t *dpi_panel = __containerof(panel, esp_lcd_dpi_panel_t, base);
|
||||
esp_lcd_dsi_bus_handle_t bus = dpi_panel->bus;
|
||||
mipi_dsi_hal_context_t *hal = &bus->hal;
|
||||
|
||||
if (dpi_panel->in_color_format == COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV422)
|
||||
&& COLOR_SPACE_TYPE(dpi_panel->out_color_format) == LCD_COLOR_SPACE_RGB) {
|
||||
// YUV422->RGB
|
||||
mipi_dsi_brg_ll_set_yuv_convert_std(hal->bridge, config->spec.yuv.conv_std);
|
||||
mipi_dsi_brg_ll_set_yuv422_pack_order(hal->bridge, config->spec.yuv.yuv422.in_pack_order);
|
||||
} else {
|
||||
ESP_RETURN_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, TAG, "unsupported conversion mode");
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_lcd_dpi_panel_set_pattern(esp_lcd_panel_handle_t panel, mipi_dsi_pattern_type_t pattern)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(panel, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
|
@@ -84,6 +84,10 @@ typedef struct {
|
||||
mipi_dsi_dpi_clock_source_t dpi_clk_src; /*!< MIPI DSI DPI clock source */
|
||||
uint32_t dpi_clock_freq_mhz; /*!< DPI clock frequency in MHz */
|
||||
lcd_color_rgb_pixel_format_t pixel_format; /*!< Pixel format that used by the MIPI LCD device */
|
||||
lcd_color_format_t in_color_format; /*!< Format of the input data (color space and pixel format),
|
||||
which is the format stored in the frame buffer */
|
||||
lcd_color_format_t out_color_format; /*!< Format of the output data (color space and pixel format),
|
||||
which is the format that the panel can accept */
|
||||
uint8_t num_fbs; /*!< Number of screen-sized frame buffers that allocated by the driver
|
||||
By default (set to either 0 or 1) only one frame buffer will be created */
|
||||
esp_lcd_video_timing_t video_timing; /*!< Video timing */
|
||||
@@ -134,6 +138,18 @@ esp_err_t esp_lcd_dpi_panel_get_frame_buffer(esp_lcd_panel_handle_t dpi_panel, u
|
||||
*/
|
||||
esp_err_t esp_lcd_dpi_panel_set_pattern(esp_lcd_panel_handle_t dpi_panel, mipi_dsi_pattern_type_t pattern);
|
||||
|
||||
/**
|
||||
* @brief Set color conversion configuration for DPI panel
|
||||
*
|
||||
* @param[in] dpi_panel MIPI DPI panel handle, returned from esp_lcd_new_panel_dpi()
|
||||
* @param[in] config Color conversion configuration
|
||||
* @return
|
||||
* - ESP_OK: Set color conversion configuration successfully
|
||||
* - ESP_ERR_INVALID_ARG: Set color conversion configuration failed because of invalid argument
|
||||
* - ESP_FAIL: Set color conversion configuration failed because of other error
|
||||
*/
|
||||
esp_err_t esp_lcd_dpi_panel_set_color_conversion(esp_lcd_panel_handle_t dpi_panel, const esp_lcd_color_conv_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Type of LCD DPI panel event data
|
||||
*/
|
||||
|
Reference in New Issue
Block a user