# MIPI DSI Interfaced LCD

[中文]

1. Create a DSI bus, and it will initialize the D-PHY as well.

   >     esp_lcd_dsi_bus_handle_t mipi_dsi_bus = NULL;
   >     esp_lcd_dsi_bus_config_t bus_config = {
   >         .bus_id = 0, // index from 0, specify the DSI host to use
   >         .num_data_lanes = 2, // Number of data lanes to use, can't set a value that exceeds the chip's capability
   >         .lane_bit_rate_mbps = EXAMPLE_MIPI_DSI_LANE_BITRATE_MBPS, // Bit rate of the data lanes, in Mbps
   >     };
   >     ESP_ERROR_CHECK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));

2. Derive the DBI interface from the DSI bus. The DBI interface mostly is used as the control IO layer in the esp_lcd component. This interface provides the functions to read or write the configuration registers inside the LCD device. In this step, you need to provide the following information:

   > - `esp_lcd_dbi_io_config_t::virtual_channel` sets the virtual channel number to use. The virtual channel is a logical channel that is used to multiplex the data from different sources. If you only have one LCD connected, you can set this to `0`.

   > - `esp_lcd_dbi_io_config_t::lcd_cmd_bits` and `esp_lcd_dbi_io_config_t::lcd_param_bits` set the bit width of the command and parameter that recognized by the LCD controller chip. This is chip specific, you should refer to your LCD spec in advance.

   >     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,   // according to the LCD spec
   >         .lcd_param_bits = 8, // according to the LCD spec
   >     };
   >     ESP_ERROR_CHECK(esp_lcd_new_panel_io_dbi(mipi_dsi_bus, &dbi_config, &mipi_dbi_io));

3. Install the LCD controller driver. The LCD controller driver is responsible for sending the commands and parameters to the LCD controller chip. In this step, you need to specify the MIPI DBI IO handle that allocated in the last step, and some panel specific configurations:

   > - `esp_lcd_panel_dev_config_t::bits_per_pixel` sets the bit width of each pixel. The LCD driver uses this value to calculate the number of bytes to send to the LCD controller chip.

   > - `esp_lcd_panel_dev_config_t::reset_gpio_num` sets the GPIO number of the reset pin. If the LCD controller chip does not have a reset pin, you can set this value to `-1`.

   > - `esp_lcd_panel_dev_config_t::rgb_ele_order` sets the RGB element order of the pixel data, it can be RGB or 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 usually uses 24 bit (i.e., RGB888) per pixel
   >         .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));

4. With the LCD control panel that returned in the last step, you can reset the LCD device followed by a basic initialization. After that, you can turn on the display.

   >     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));

5. However, you still can't send pixel data to the MIPI LCD with the control panel, because MIPI LCD has a high resolution and there's no GRAM in the LCD controller. We need to maintain the LCD frame buffer and flush it to the LCD via the MIPI DSI DPI interface. To allocate a DPI data panel, you need to provide many essential parameters, including the DPI clock frequency, the pixel format, the video timing, and so on.

   > - `esp_lcd_dpi_panel_config_t::virtual_channel` sets the virtual channel number to use. Like the DBI interface, we also need to set the virtual channel for the DPI interface. If you only have one LCD connected, you can set this to `0`.

   > - `esp_lcd_dpi_panel_config_t::dpi_clk_src` sets the clock source for the DPI interface. The available clock sources are listed in `mipi_dsi_dpi_clock_source_t`.

   > - `esp_lcd_dpi_panel_config_t::dpi_clock_freq_mhz` sets the DPI clock frequency in MHz. Higher pixel clock frequency results in higher refresh rate, but may cause flickering if the DMA bandwidth is not sufficient or the LCD controller chip does not support high pixel clock frequency.

   > - `esp_lcd_dpi_panel_config_t::in_color_format` sets the pixel format of the input pixel data. The available pixel formats are listed in `lcd_color_format_t`. We usually use RGB888 for MIPI LCD to get the best color depth.

   > - `esp_lcd_dpi_panel_config_t::video_timing` sets the LCD panel specific timing parameters. All required parameters are listed in the `esp_lcd_video_timing_t`, including the LCD resolution and blanking porches. Please fill them according to the datasheet of your LCD.

   >     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,
   >         .in_color_format = LCD_COLOR_FMT_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,
   >         },
   >     };
   >     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));

6. Configure draw bitmap hook function (optional)

   > If you want to use DMA2D to implement draw bitmap, the driver has already implemented the DMA2D draw bitmap hook function, you only need to call `esp_lcd_dpi_panel_enable_dma2d()` to enable it.

   >     ESP_ERROR_CHECK(esp_lcd_dpi_panel_enable_dma2d(mipi_dpi_panel));

   > Note

   > Due to hardware limitation, if external memory encryption is enabled, DMA2D can only access address and length that are aligned to 16 bytes. You need to ensure that your draw buffer's address and length are aligned to 16 bytes. peripherals/lcd/mipi_dsi shows how to use LVGL to constrain the redrawn area to ensure alignment.

   > If you need more advanced applications, you can add a custom hook for draw bitmap, such as using PPA to implement rotation, scaling, etc.

   >     esp_lcd_panel_hooks_t hooks = {
   >         .draw_bitmap_hook = custom_draw_bitmap_hook,
   >     };
   >     ESP_ERROR_CHECK(esp_lcd_dpi_panel_register_hooks(mipi_dpi_panel, &hooks, &user_ctx));

## Power Supply for MIPI DPHY

The MIPI DPHY on ESP32-P4 requires a dedicated 2.5V power supply. Please refer to your schematic and ensure that the power pin (often labeled `VDD_MIPI_DPHY`) is properly connected to a 2.5V power source before using the MIPI DSI driver.

On ESP32-P4, the MIPI DPHY can be powered by the internal adjustable LDO. Connect the output pin of the LDO channel to the MIPI DPHY power pin. Before initializing the DSI driver, use the API provided in Low Dropout Voltage Regulator (LDO) to configure the LDO output voltage to 2.5V.

## API Reference

### Header File

- components/esp_lcd/dsi/include/esp_lcd_mipi_dsi.h

- 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 on `esp_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.

  Parameters:

    - bus_config -- [in] Bus configuration

    - ret_bus -- [out] Returned bus handle

  Returns:

    - 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.

  Parameters:

    bus -- [in] MIPI DSI bus handle, returned from `esp_lcd_new_dsi_bus`

  Returns:

    - 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.

  Note

  Although we call it "DBI", internally the driver is using a co-called "generic" interface for transmitting/receiving LCD commands and parameters.

  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

  Returns:

    - 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.

  Parameters:

    - 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

  Returns:

    - 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.

  Parameters:

    - 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

  Returns:

    - 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.

  Parameters:

    - dpi_panel -- [in] MIPI DPI panel handle, returned from esp_lcd_new_panel_dpi()

    - pattern -- [in] Pattern type

  Returns:

    - 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_set_yuv_conversion(esp_lcd_panel_handle_t dpi_panel, const esp_lcd_color_conv_yuv_config_t *config)

  Set color conversion (YUV<->RGB) configuration for DPI panel.

  Parameters:

    - dpi_panel -- [in] MIPI DPI panel handle, returned from esp_lcd_new_panel_dpi()

    - config -- [in] Color conversion configuration

  Returns:

    - 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_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.

  Parameters:

    - 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

  Returns:

    - ESP_ERR_INVALID_ARG: Register callbacks failed because of invalid argument

    - ESP_OK: Register callbacks successfully

esp_err_t esp_lcd_dpi_panel_register_hooks(esp_lcd_panel_handle_t dpi_panel, const esp_lcd_panel_hooks_t *hooks, void *hook_ctx)

  Register panel hooks to the DPI panel.

  Note

  You can register panel hooks to implement custom operations like scaling, rotation, color space conversion, etc. with hardware accelerators like PPA or DMA2D. The hook will be overridden when this function is called multiple times.

  Parameters:

    - dpi_panel -- [in] LCD DPI panel handle, which is returned from esp_lcd_new_panel_dpi()

    - hooks -- [in] Panel hooks

    - hook_ctx -- [in] Hook context

  Returns:

    - ESP_OK: Register hooks successfully

    - Other error codes on failure

esp_err_t esp_lcd_dpi_panel_enable_dma2d(esp_lcd_panel_handle_t dpi_panel)

  Enable DMA2D for DPI panel.

  Note

  The function will register a built-in DMA2D draw bitmap hook to perform draw bitmap operations using DMA2D.

  Parameters:

    dpi_panel -- [in] LCD DPI panel handle, which is returned from esp_lcd_new_panel_dpi()

  Returns:

    - ESP_OK: Enable DMA2D successfully

    - Other error codes on failure

esp_err_t esp_lcd_dpi_panel_disable_dma2d(esp_lcd_panel_handle_t dpi_panel)

  Disable DMA2D for DPI panel.

  Note

  The function will unregister the built-in DMA2D draw bitmap hook.

  Parameters:

    dpi_panel -- [in] LCD DPI panel handle, which is returned from esp_lcd_new_panel_dpi()

  Returns:

    - ESP_OK: Disable DMA2D successfully

    - Other error codes on failure

### 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_pllref_clock_source_t phy_clk_src

    The clock source for the PHY PLL

  float lane_bit_rate_mbps

    Lane bit rate in Mbps

  struct esp_lcd_dsi_bus_config_t::extra_dsi_bus_flags flags

    Extra configuration flags

  struct extra_dsi_bus_flags

    Extra configuration flags for MIPI DSI bus.

    Public Members

    uint32_t clock_lane_force_hs

      Force the clock lane to high speed mode

struct esp_lcd_dbi_io_config_t

  Panel IO configuration structure, for MIPI DSI command interface.

  Public Members

  uint8_t virtual_channel

    Virtual channel ID, index from 0

  int lcd_cmd_bits

    Bit-width of LCD command

  int lcd_param_bits

    Bit-width of LCD parameter

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

  float dpi_clock_freq_mhz

    Pixel clock frequency in MHz

  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

  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.

    Public Members

    uint32_t disable_lp

      Disable low-power for DPI

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

struct esp_lcd_draw_bitmap_hook_data_t

  Type of draw bitmap hook data.

  Public Members

  void *dst_data

    Destination buffer (usually frame buffer)

  int dst_x_size

    Destination bitmap width

  int dst_y_size

    Destination bitmap height

  int dst_x_start

    Destination start x coordinate

  int dst_y_start

    Destination start y coordinate

  int dst_x_end

    Destination end x coordinate (exclusive)

  int dst_y_end

    Destination end y coordinate (exclusive)

  const void *src_data

    Source bitmap data

  int src_x_size

    Source bitmap width

  int src_y_size

    Source bitmap height

  int src_x_start

    Source start x coordinate

  int src_y_start

    Source start y coordinate

  int src_x_end

    Source end x coordinate (exclusive)

  int src_y_end

    Source end y coordinate (exclusive)

  int bits_per_pixel

    Bits per pixel

  bool (*on_hook_end)(esp_lcd_panel_handle_t panel)

    Callback to be invoked when the hook completes its operation

struct esp_lcd_panel_hooks_t

  Type of LCD panel hooks.

  Public Members

  esp_lcd_panel_draw_bitmap_hook_t draw_bitmap_hook

    Draw bitmap hook function

### 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.

typedef esp_err_t (*esp_lcd_panel_draw_bitmap_hook_t)(esp_lcd_panel_handle_t panel, const esp_lcd_draw_bitmap_hook_data_t *hook_data, void *hook_ctx)

  draw bitmap hook function type for custom pixel processing operations

  This hook allows users to implement custom operations like scaling, rotation, color space conversion, etc. using hardware accelerators like PPA or DMA2D.

  Note

  The hook should ensure the synchronization of draw operations on its own.

  Param panel:

    [in] LCD panel handle

  Param hook_data:

    [in] Hook data

  Param hook_ctx:

    [in] Hook context

  Return:

    - ESP_OK on success

    - Other error codes on failure

Was this page helpful?

- Thank you! We received your feedback.
- If you have any comments, fill in Espressif Documentation Feedback Form.

- We value your feedback.
- Let us know how we can improve this page by filling in Espressif Documentation Feedback Form.