MIPI DSI 接口的 LCD
创建 DSI 总线,并对 D-PHY 进行初始化设置。
esp_lcd_dsi_bus_handle_t mipi_dsi_bus = NULL; esp_lcd_dsi_bus_config_t bus_config = { .bus_id = 0, // 从 0 开始编号,指定要使用的 DSI 主机 .num_data_lanes = 2, // 要使用的数据通道数,不能超过芯片支持的数量 .phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT, // DPHY 的时钟源 .lane_bit_rate_mbps = EXAMPLE_MIPI_DSI_LANE_BITRATE_MBPS, // 数据通道的比特率 (Mbps) }; ESP_ERROR_CHECK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));
从 DSI 总线派生 DBI 接口。DBI 接口主要用作 esp_lcd 组件中的控制 IO 层。使用该接口可读写 LCD 设备内部的配置寄存器。在此步骤中,需要提供以下信息:
esp_lcd_dbi_io_config_t::virtual_channel
设置虚拟通道号。虚拟通道是一种逻辑通道,用于从不同来源多路复用数据。如果只连接了一个 LCD,则将此值设置为0
。esp_lcd_dbi_io_config_t::lcd_cmd_bits
和esp_lcd_dbi_io_config_t::lcd_param_bits
分别设置 LCD 控制器芯片可识别的命令及参数的位宽。不同芯片对位宽要求不同,请提前参阅 LCD 规格书。
esp_lcd_panel_io_handle_t mipi_dbi_io = NULL; esp_lcd_dbi_io_config_t dbi_config = { .virtual_channel = 0, .lcd_cmd_bits = 8, // 依据 LCD 规格书说明来设置 .lcd_param_bits = 8, // 依据 LCD 规格书说明来设置 }; ESP_ERROR_CHECK(esp_lcd_new_panel_io_dbi(mipi_dsi_bus, &dbi_config, &mipi_dbi_io));
安装 LCD 控制器驱动程序。LCD 控制器驱动程序负责向 LCD 控制器芯片发送命令和参数。在此步骤中,需要指定上一步骤中分配到的 MIPI DBI IO 设备句柄以及一些面板特定配置:
esp_lcd_panel_dev_config_t::bits_per_pixel
设置每个像素的位宽。LCD 驱动程序使用此值计算要发送到 LCD 控制器芯片的字节数。esp_lcd_panel_dev_config_t::reset_gpio_num
设置复位管脚的 GPIO 编号。如果 LCD 控制器芯片没有硬件复位管脚,则将此设置为-1
。esp_lcd_panel_dev_config_t::rgb_ele_order
设置像素数据的 RGB 元素顺序,可以是 RGB 或 BGR。
esp_lcd_panel_handle_t ili9881c_ctrl_panel = NULL; esp_lcd_panel_dev_config_t lcd_dev_config = { .bits_per_pixel = 24, // MIPI LCD 上通常每像素使用 24 位(即 RGB888) .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB, .reset_gpio_num = EXAMPLE_PIN_NUM_LCD_RST, }; ESP_ERROR_CHECK(esp_lcd_new_panel_ili9881c(mipi_dbi_io, &lcd_dev_config, &ili9881c_ctrl_panel));
使用上一步骤中返回的 LCD 控制面板,在基本初始化完成后可以重置 LCD 设备。之后,可以打开显示器。
ESP_ERROR_CHECK(esp_lcd_panel_reset(ili9881c_ctrl_panel)); ESP_ERROR_CHECK(esp_lcd_panel_init(ili9881c_ctrl_panel)); ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(ili9881c_ctrl_panel, true));
此时仍然无法使用控制面板向 MIPI LCD 发送像素数据,因为 MIPI LCD 具有高分辨率,而 LCD 控制器中没有 GRAM。因此需要维护 LCD 帧 buffer,并通过 MIPI DSI DPI 接口将其刷新到 LCD 屏幕上。分配 DPI 数据面板需要许多基本参数,例如 DPI 时钟频率、像素格式、视频时序等。
esp_lcd_dpi_panel_config_t::virtual_channel
设置虚拟通道号。与 DBI 接口类似,DPI 接口也需要设置虚拟通道。如果只连接了一个 LCD,则将此值设置为0
。esp_lcd_dpi_panel_config_t::dpi_clk_src
设置 DPI 接口的时钟源。可用的时钟源列表见mipi_dsi_dpi_clock_source_t
。esp_lcd_dpi_panel_config_t::dpi_clock_freq_mhz
设置 DPI 时钟频率 (MHz)。像素时钟频率越高,刷新率越高,但如果 DMA 带宽不足或 LCD 控制器芯片不支持高像素时钟频率,则可能会导致闪烁。esp_lcd_dpi_panel_config_t::pixel_format
设置像素数据的像素格式。可用的像素格式见lcd_color_rgb_pixel_format_t
。MIPI LCD 通常使用 RGB888 来获得最佳色彩深度。esp_lcd_dpi_panel_config_t::video_timing
设置 LCD 面板的特定时序参数。包括 LCD 分辨率和消隐间隔在内的必要参数列表见esp_lcd_video_timing_t
,请依据 LCD 技术规格书填写参数。esp_lcd_dpi_panel_config_t::extra_dpi_panel_flags::use_dma2d
设置是否用 2D DMA 将用户数据异步复制到帧 buffer 中。
esp_lcd_panel_handle_t mipi_dpi_panel = NULL; esp_lcd_dpi_panel_config_t dpi_config = { .virtual_channel = 0, .dpi_clk_src = MIPI_DSI_DPI_CLK_SRC_DEFAULT, .dpi_clock_freq_mhz = 1 * 1000, .pixel_format = LCD_COLOR_PIXEL_FORMAT_RGB888, .video_timing = { .h_size = EXAMPLE_MIPI_DSI_LCD_H_RES, .v_size = EXAMPLE_MIPI_DSI_LCD_V_RES, .hsync_back_porch = EXAMPLE_MIPI_DSI_LCD_HBP, .hsync_pulse_width = EXAMPLE_MIPI_DSI_LCD_HSYNC, .hsync_front_porch = EXAMPLE_MIPI_DSI_LCD_HFP, .vsync_back_porch = EXAMPLE_MIPI_DSI_LCD_VBP, .vsync_pulse_width = EXAMPLE_MIPI_DSI_LCD_VSYNC, .vsync_front_porch = EXAMPLE_MIPI_DSI_LCD_VFP, }, .flags.use_dma2d = true, }; ESP_ERROR_CHECK(esp_lcd_new_panel_dpi(mipi_dsi_bus, &dpi_config, &mipi_dpi_panel)); ESP_ERROR_CHECK(esp_lcd_panel_init(mipi_dpi_panel));
API 参考
Header File
This header file can be included with:
#include "esp_lcd_mipi_dsi.h"
This header file is a part of the API provided by the
esp_lcd
component. To declare that your component depends onesp_lcd
, add the following to your CMakeLists.txt:REQUIRES esp_lcd
or
PRIV_REQUIRES esp_lcd
Functions
-
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)
Create MIPI DSI bus handle.
- 参数
bus_config -- [in] Bus configuration
ret_bus -- [out] Returned bus handle
- 返回
ESP_OK: Create MIPI DSI bus successfully
ESP_ERR_INVALID_ARG: Create MIPI DSI bus failed because of invalid argument
ESP_ERR_NO_MEM: Create MIPI DSI bus failed because of out of memory
ESP_ERR_NOT_FOUND: Create MIPI DSI bus failed because no more free DSI hardware instance
ESP_FAIL: Create MIPI DSI bus failed because of other error
-
esp_err_t esp_lcd_del_dsi_bus(esp_lcd_dsi_bus_handle_t bus)
Destroy MIPI DSI bus handle.
- 参数
bus -- [in] MIPI DSI bus handle, returned from
esp_lcd_new_dsi_bus
- 返回
ESP_OK: Destroy MIPI DSI bus successfully
ESP_ERR_INVALID_ARG: Destroy MIPI DSI bus failed because of invalid argument
ESP_FAIL: Destroy MIPI DSI bus failed because of other error
-
esp_err_t esp_lcd_new_panel_io_dbi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dbi_io_config_t *io_config, esp_lcd_panel_io_handle_t *ret_io)
Create LCD panel IO, for MIPI DSI DBI interface.
备注
Although we call it "DBI", internally the driver is using a co-called "generic" interface for transmitting/receiving LCD commands and parameters.
- 参数
bus -- [in] MIPI DSI bus handle, returned from
esp_lcd_new_dsi_bus
io_config -- [in] IO configuration
ret_io -- [out] Returned panel IO handle
- 返回
ESP_OK: Create MIPI DSI command IO successfully
ESP_ERR_INVALID_ARG: Create MIPI DSI command IO failed because of invalid argument
ESP_ERR_NO_MEM: Create MIPI DSI command IO failed because of out of memory
ESP_FAIL: Create MIPI DSI command IO failed because of other error
-
esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_panel_config_t *panel_config, esp_lcd_panel_handle_t *ret_panel)
Create LCD panel for MIPI DSI DPI interface.
- 参数
bus -- [in] MIPI DSI bus handle, returned from
esp_lcd_new_dsi_bus
panel_config -- [in] DSI data panel configuration
ret_panel -- [out] Returned LCD panel handle
- 返回
ESP_OK: Create MIPI DSI data panel successfully
ESP_ERR_INVALID_ARG: Create MIPI DSI data panel failed because of invalid argument
ESP_ERR_NO_MEM: Create MIPI DSI data panel failed because of out of memory
ESP_ERR_NOT_SUPPORTED: Create MIPI DSI data panel failed because of unsupported feature
ESP_FAIL: Create MIPI DSI data panel failed because of other error
-
esp_err_t esp_lcd_dpi_panel_get_frame_buffer(esp_lcd_panel_handle_t dpi_panel, uint32_t fb_num, void **fb0, ...)
Get the address of the frame buffer(s) that allocated by the driver.
- 参数
dpi_panel -- [in] MIPI DPI panel handle, returned from esp_lcd_new_panel_dpi()
fb_num -- [in] Number of frame buffer(s) to get. This value must be the same as the number of the followed parameters.
fb0 -- [out] Address of the frame buffer 0 (first frame buffer)
... -- [out] List of other frame buffers if any
- 返回
ESP_ERR_INVALID_ARG: Get frame buffer address failed because of invalid argument
ESP_OK: Get frame buffer address successfully
-
esp_err_t esp_lcd_dpi_panel_set_pattern(esp_lcd_panel_handle_t dpi_panel, mipi_dsi_pattern_type_t pattern)
Set pre-defined pattern to the screen for testing or debugging purpose.
- 参数
dpi_panel -- [in] MIPI DPI panel handle, returned from esp_lcd_new_panel_dpi()
pattern -- [in] Pattern type
- 返回
ESP_OK: Set pattern successfully
ESP_ERR_INVALID_ARG: Set pattern failed because of invalid argument
ESP_FAIL: Set pattern failed because of other error
-
esp_err_t esp_lcd_dpi_panel_register_event_callbacks(esp_lcd_panel_handle_t dpi_panel, const esp_lcd_dpi_panel_event_callbacks_t *cbs, void *user_ctx)
Register LCD DPI panel callbacks.
- 参数
dpi_panel -- [in] LCD DPI panel handle, which is returned from esp_lcd_new_panel_dpi()
cbs -- [in] structure with all LCD panel callbacks
user_ctx -- [in] User private data, passed directly to callback's user_ctx
- 返回
ESP_ERR_INVALID_ARG: Register callbacks failed because of invalid argument
ESP_OK: Register callbacks successfully
Structures
-
struct esp_lcd_dsi_bus_config_t
MIPI DSI bus configuration structure.
Public Members
-
int bus_id
Select which DSI controller, index from 0
-
uint8_t num_data_lanes
Number of data lanes, if set to 0, the driver will fallback to use maximum number of lanes
-
mipi_dsi_phy_clock_source_t phy_clk_src
MIPI DSI PHY clock source
-
uint32_t lane_bit_rate_mbps
Lane bit rate in Mbps
-
int bus_id
-
struct esp_lcd_dbi_io_config_t
Panel IO configuration structure, for MIPI DSI command interface.
-
struct esp_lcd_dpi_panel_config_t
MIPI DSI DPI panel configuration structure.
Public Members
-
uint8_t virtual_channel
Virtual channel ID, index from 0
-
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
-
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
-
struct esp_lcd_dpi_panel_config_t::extra_dpi_panel_flags flags
Extra configuration flags
-
struct extra_dpi_panel_flags
Extra configuration flags for MIPI DSI DPI panel.
-
uint8_t virtual_channel
-
struct esp_lcd_dpi_panel_event_data_t
Type of LCD DPI panel event data.
-
struct esp_lcd_dpi_panel_event_callbacks_t
Type of LCD DPI panel callbacks.
Public Members
-
esp_lcd_dpi_panel_color_trans_done_cb_t on_color_trans_done
Invoked when user's color buffer copied to the internal frame buffer. This is an indicator that the draw buffer can be recycled safely. But doesn't mean the draw buffer finishes the refreshing to the screen.
-
esp_lcd_dpi_panel_refresh_done_cb_t on_refresh_done
Invoked when the internal frame buffer finishes refreshing to the screen
-
esp_lcd_dpi_panel_color_trans_done_cb_t on_color_trans_done
Type Definitions
-
typedef struct esp_lcd_dsi_bus_t *esp_lcd_dsi_bus_handle_t
Type of MIPI DSI bus handle
-
typedef bool (*esp_lcd_dpi_panel_general_cb_t)(esp_lcd_panel_handle_t panel, esp_lcd_dpi_panel_event_data_t *edata, void *user_ctx)
A general function callback prototype for DPI panel driver.
- Param panel
[in] LCD panel handle, which is created by factory API like esp_lcd_new_panel_dpi()
- Param edata
[in] DPI panel event data, fed by driver
- Param user_ctx
[in] User data
- Return
Whether a high priority task has been waken up by this function
-
typedef esp_lcd_dpi_panel_general_cb_t esp_lcd_dpi_panel_color_trans_done_cb_t
Declare the prototype of the function that will be invoked when driver finishes coping user's color buffer to frame buffer.
-
typedef esp_lcd_dpi_panel_general_cb_t esp_lcd_dpi_panel_refresh_done_cb_t
Declare the prototype of the function that will be invoked when driver finishes refreshing the frame buffer to the screen.