MIPI DSI

Overview

  • The Display Serial Interface (DSI) is a specification stipulated by the Mobile Industry Processor Interface (MIPI) Alliance, aiming to reduce the cost of display controllers in a mobile device. It defines a serial bus and communication protocol among the host, the source of image data, and the target device. In this way, the DSI can send pixel data or commands to peripherals (usually LCDs or similar display devices) in serial mode, or reads information such as status and pixel from the peripherals.

  • MIPI DSI is capable of working in both high speed (HS) mode and low power (LP) mode. All data lanes can only travel from the DSI host to a peripheral in HS mode, except the first data lane, which can also receive data such as status information and pixels from the peripheral in LP mode. The clock lane is dedicated to transmitting synchronization clock signals in HS mode.

  • Figure 1 shows a simplified DSI interface. Conceptually, a DSI-compliant interface has the same features as interfaces complying with DBI-2 and DPI-2 standards. It sends pixels or commands to a peripheral and can read status or pixel information from the peripheral. The main difference is that the DSI serializes all pixel data, commands, and events that, in traditional interfaces, are conveyed to and from the peripheral on a parallel data bus with additional control signals.

    Figure 1 DSI transmitting and receiving interface

Available APIs

Table 1 APIs for MIPI DSI

Capability

Function

Description

Setting/Obtaining MIPI DSI configuration parameters

MipiDsiSetCfg

Sets configuration parameters for a MIPI DSI device.

MipiDsiGetCfg

Obtains configuration parameters of a MIPI DSI device.

Obtaining /Releasing device handles

MipiDsiOpen

Obtains a MIPI DSI device handle.

MipiDsiClose

Releases a specified MIPI DSI device handle.

Setting the LP or HS mode

MipiDsiSetLpMode

Sets LP mode for a MIPI DSI device.

MipiDsiSetHsMode

Sets HS mode for a MIPI DSI device.

Reading/Sending commands

MipiDsiTx

Sends a display command set (DCS) command for sending data.

MipiDsiRx

Receives a DCS command for reading data with the specified length.

NOTE: All functions described in this document can be called only in kernel space.

Usage Guidelines

How to Use

Figure 2 shows the process of using a MIPI DSI device.

Figure 2 Process of using a MIPI DSI device

Obtains a MIPI DSI device handle.

Before performing MIPI DSI communication, obtain a MIPI DSI device handle by calling MipiDsiOpen. This function returns a MIPI DSI device handle with a specified channel ID.

DevHandle MipiDsiOpen(uint8_t id);

Table 2 Description of MipiDsiOpen

Parameter

Description

id

MIPI DSI channel ID.

Return Value

Description

NULL

Failed to receive the specified command.

Device handle

MIPI DSI device handle with a specified channel ID, whose data type is DevHandle.

The following example shows how to obtain a MIPI DSI device handle with the channel ID 0:

DevHandle mipiDsiHandle = NULL;  /* Device handle */
chnId = 0;      /* MIPI DSI channel ID */

/* Obtain the MIPI DSI device handle based on a specified channel ID. */
mipiDsiHandle = MipiDsiOpen(chnId);
if (mipiDsiHandle == NULL) {
    HDF_LOGE("MipiDsiOpen: failed\n");
    return;
}

Setting MIPI DSI Configuration Parameters

  • Set MIPI DSI configuration parameters by calling the following function:

int32_t MipiDsiSetCfg(DevHandle handle, struct MipiCfg *cfg);

Table 3 Description of MipiDsiSetCfg

Parameter

Description

handle

MIPI DSI device handle.

cfg

Pointer to MIPI DSI configuration parameters.

Return Value

Description

0

Succeeded in setting MIPI DSI configuration parameters.

Negative value

Failed to set MIPI DSI configuration parameters.

int32_t ret;
struct MipiCfg cfg = {0};

/* Configuration parameters of the connected device are as follows: */
cfg.lane = DSI_4_LANES;
cfg.mode = DSI_CMD_MODE;
cfg.burstMode = VIDEO_NON_BURST_MODE_SYNC_EVENTS;
cfg.format = FORMAT_RGB_24_BIT;
cfg.pixelClk = 174;
cfg.phyDataRate = 384;
cfg.timingInfo.hsaPixels = 50;
cfg.timingInfo.hbpPixels = 55;
cfg.timingInfo.hlinePixels = 1200;
cfg.timingInfo.yResLines = 1800;
cfg.timingInfo.vbpLines = 33;
cfg.timingInfo.vsaLines = 76;
cfg.timingInfo.vfpLines = 120;
cfg.timingInfo.xResPixels = 1342;
/* Set MIPI DSI configuration parameters. */
ret = MipiDsiSetCfg(g_handle, &cfg);
if (ret != 0) {
    HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret);
    return -1;
}
  • Obtain MIPI DSI configuration parameters by calling the following function:

int32_t MipiDsiGetCfg(DevHandle handle, struct MipiCfg *cfg);

Table 4 Description of MipiDsiGetCfg

Parameter

Description

handle

MIPI DSI device handle.

cfg

Pointer to MIPI DSI configuration parameters.

Return Value

Description

0

Succeeded in receiving the specified command.

Negative value

Failed to receive the specified command.

int32_t ret;
struct MipiCfg cfg;
memset(&cfg, 0, sizeof(struct MipiCfg));
ret = MipiDsiGetCfg(g_handle, &cfg);
if (ret != HDF_SUCCESS) {
    HDF_LOGE("%s: GetMipiCfg fail!\n", __func__);
    return HDF_FAILURE;
}

Sending/Receiving the Pointer to a Command

  • Send the pointer to a specified command by calling the following function:

int32_t MipiDsiTx(PalHandle handle, struct DsiCmdDesc *cmd);

Table 5 Description of MipiDsiTx

Parameter

Description

handle

MIPI DSI device handle.

cmd

Pointer to the command to be sent.

Return Value

Description

0

Succeeded in sending the specified command.

Negative value

Failed to send the specified command.

int32_t ret;
struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc));
if (cmd == NULL) {
    return HDF_FAILURE;
}
cmd->dtype = DTYPE_DCS_WRITE;
cmd->dlen = 1;
cmd->payload = OsalMemCalloc(sizeof(uint8_t));
if (cmd->payload == NULL) {
    HdfFree(cmd);
    return HDF_FAILURE;
}
*(cmd->payload) = DTYPE_GEN_LWRITE;
MipiDsiSetLpMode(mipiHandle);
ret = MipiDsiTx(mipiHandle, cmd);
MipiDsiSetHsMode(mipiHandle);
if (ret != HDF_SUCCESS) {
    HDF_LOGE("%s: PalMipiDsiTx fail! ret=%d\n", __func__, ret);
    HdfFree(cmd->payload);
    HdfFree(cmd);
    return HDF_FAILURE;
}
HdfFree(cmd->payload);
HdfFree(cmd);
  • Receive a specified command by calling the following function:

int32_t MipiDsiRx(DevHandle handle, struct DsiCmdDesc *cmd, uint32_t readLen, uint8_t *out);

Table 6 Description of MipiDsiRx

Parameter

Description

handle

MIPI DSI device handle.

cmd

Pointer to the command to be received.

readLen

Length of the data to read.

out

Pointer to the read data.

Return Value

Description

0

Succeeded in receiving the specified command.

Negative value

Failed to receive the specified command.

int32_t ret;
uint8_t readVal = 0;

struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc));
if (cmdRead == NULL) {
    return HDF_FAILURE;
}
cmdRead->dtype = DTYPE_DCS_READ;
cmdRead->dlen = 1;
cmdRead->payload = OsalMemCalloc(sizeof(uint8_t));
if (cmdRead->payload == NULL) {
    HdfFree(cmdRead);
    return HDF_FAILURE;
}
*(cmdRead->payload) = DDIC_REG_STATUS;
MipiDsiSetLpMode(g_handle);
ret = MipiDsiRx(g_handle, cmdRead, sizeof(readVal), &readVal);
MipiDsiSetHsMode(g_handle);
if (ret != HDF_SUCCESS) {
    HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret);
    HdfFree(cmdRead->payload);
    HdfFree(cmdRead);
    return HDF_FAILURE;
}
HdfFree(cmdRead->payload);
HdfFree(cmdRead);

Releasing the MIPI DSI Device Handle

After the MIPI DSI communication, release the MIPI DSI device handle by calling the following function:

void MipiDsiClose(DevHandle handle);

This function releases the resources requested by MipiDsiOpen.

Table 7 Description of MipiDsiClose

Parameter

Description

handle

MIPI DSI device handle.

MipiDsiClose(mipiHandle); /* Release the MIPI DSI device handle */

Usage Example

The following is an example of using a MIPI DSI device:

#include "hdf.h"
#include "mipi_dsi_if.h"

void PalMipiDsiTestSample(void)
{
    uint8_t chnId;
    int32_t ret;  
    DevHandle handle = NULL;
    
    /* Device channel ID */
    chnId = 0; 
    /* Obtain the MIPI DSI device handle based on a specified channel ID. */
    handle = MipiDsiOpen(chnId);
    if (handle == NULL) {
        HDF_LOGE("MipiDsiOpen: failed!\n");
        return;
    }
    /* MIPI DSI configuration parameters */
    struct MipiCfg cfg = {0};
    cfg.lane = DSI_4_LANES;
    cfg.mode = DSI_CMD_MODE;
    cfg.burstMode = VIDEO_NON_BURST_MODE_SYNC_EVENTS;
    cfg.format = FORMAT_RGB_24_BIT;
    cfg.pixelClk = 174;                      
    cfg.phyDataRate = 384;                 
    cfg.timingInfo.hsaPixels = 50;
    cfg.timingInfo.hbpPixels = 55;
    cfg.timingInfo.hlinePixels = 1200;
    cfg.timingInfo.yResLines = 1800;
    cfg.timingInfo.vbpLines = 33;
    cfg.timingInfo.vsaLines = 76;
    cfg.timingInfo.vfpLines = 120;
    cfg.timingInfo.xResPixels = 1342;
    /* Set MIPI DSI configuration parameters. */
    ret = MipiDsiSetCfg(g_handle, &cfg);
    if (ret != 0) {
        HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret);
        return;
    }
    /* Send the command for initializing the PANEL register. */
    struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc));
    if (cmd == NULL) {
        return;
    }
    cmd->dtype = DTYPE_DCS_WRITE;
    cmd->dlen = 1;
    cmd->payload = OsalMemCalloc(sizeof(uint8_t));
    if (cmd->payload == NULL) {
        HdfFree(cmd);
        return;
    }
    *(cmd->payload) = DTYPE_GEN_LWRITE;
    MipiDsiSetLpMode(mipiHandle);
    ret = MipiDsiTx(mipiHandle, cmd);
    MipiDsiSetHsMode(mipiHandle);
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("%s: MipiDsiTx fail! ret=%d\n", __func__, ret);
        HdfFree(cmd->payload);
        HdfFree(cmd);
        return;
    }
    HdfFree(cmd->payload);
    HdfFree(cmd);
    /* Pointer to the register that reads the PANEL status */
    uint8_t readVal = 0;
    struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc));
    if (cmdRead == NULL) {
        return;
    }
    cmdRead->dtype = DTYPE_DCS_READ;
    cmdRead->dlen = 1;
    cmdRead->payload = OsalMemCalloc(sizeof(uint8_t));
    if (cmdRead->payload == NULL) {
        HdfFree(cmdRead);
        return;
    }
    *(cmdRead->payload) = DDIC_REG_STATUS;
    MipiDsiSetLpMode(g_handle);
    ret = MipiDsiRx(g_handle, cmdRead, sizeof(readVal), &readVal);
    MipiDsiSetHsMode(g_handle);
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret);
        HdfFree(cmdRead->payload);
        HdfFree(cmdRead);
        return;
    }
    HdfFree(cmdRead->payload);
    HdfFree(cmdRead);
    /* Release the MIPI DSI device handle. */
    MipiDsiClose(handle); 
}