# MIPI DSI - [概述](#section16806142183217) - [接口说明](#section12720125432316) - [使用指导](#section037231715335) - [使用流程](#section49299119344) - [获取MIPI-DSI操作句柄](#section5126155683811) - [MIPI-DSI相应配置](#section201164274344) - [发送/回读控制指令](#section199401342173415) - [释放MIPI-DSI操作句柄](#section161011610357) - [使用实例](#section17470126123520) ## 概述 - DSI(Display Serial Interface)是由移动行业处理器接口联盟(Mobile Industry Processor Interface \(MIPI\) Alliance)制定的规范,旨在降低移动设备中显示控制器的成本。它以串行的方式发送像素数据或指令给外设\(通常是LCD或者类似的显示设备\),或从外设中读取状态信息或像素信息;它定义了主机、图像数据源和目标设备之间的串行总线和通信协议。 - MIPI-DSI具备高速模式和低速模式两种工作模式,全部数据通道都可以用于单向的高速传输,但只有第一个数据通道才可用于低速双向传输,从属端的状态信息、像素等是通过该数据通道返回。时钟通道专用于在高速传输数据的过程中传输同步时钟信号。 - 图1显示了简化的DSI接口。从概念上看,符合DSI的接口与基于DBI-2和DPI-2标准的接口具有相同的功能。它向外围设备传输像素或命令数据,并且可以从外围设备读取状态或像素信息。主要区别在于,DSI对所有像素数据、命令和事件进行序列化,而在传统接口中,这些像素数据、命令和事件通常需要附加控制信号才能在并行数据总线上传输。 **图 1** DSI发送、接收接口 ![](figures/DSI发送-接收接口.png "DSI发送-接收接口") ## 接口说明 **表 1** MIPI-DSI API接口功能介绍

功能分类

接口名

描述

设置/获取当前MIPI-DSI相关配置

MipiDsiSetCfg

设置MIPI-DSI相关配置

MipiDsiGetCfg

获取当前MIPI-DSI相关配置

获取/释放MIPI-DSI操作句柄

MipiDsiOpen

获取MIPI-DSI操作句柄

MipiDsiClose

释放MIPI-DSI操作句柄

设置MIPI-DSI进入Low power模式/High speed模式

MipiDsiSetLpMode

设置MIPI-DSI进入Low power模式

MipiDsiSetHsMode

设置MIPI-DSI进入High speed模式

MIPI-DSI发送/回读指令

MipiDsiTx

MIPI-DSI发送相应指令的接口

MipiDsiRx

MIPI-DSI按期望长度回读的接口

>![](../public_sys-resources/icon-note.gif) **说明:** >本文涉及的所有接口,仅限内核态使用,不支持在用户态使用 ## 使用指导 ### 使用流程 使用MIPI-DSI的一般流程如[图2](#fig129103491241)所示。 **图 2** MIPI-DSI使用流程图 ![](figures/MIPI-DSI使用流程图.png) ### 获取MIPI-DSI操作句柄 在进行MIPI-DSI进行通信前,首先要调用MipiDsiOpen获取操作句柄,该函数会返回指定通道ID的操作句柄。 DevHandle MipiDsiOpen\(uint8\_t id\); **表 2** MipiDsiOpen的参数和返回值描述

参数

参数描述

id

MIPI DSI通道ID

返回值

返回值描述

NULL

获取失败

设备句柄

获取到指令通道的操作句柄, 类型为DevHandle

假设系统中的MIPI-DSI通道为0,获取该通道操作句柄的示例如下: ``` DevHandle mipiDsiHandle = NULL; /* 设备句柄 */ chnId = 0; /* MIPI-DSI通道ID */ /* 获取操作句柄 */ mipiDsiHandle = MipiDsiOpen(chnId); if (mipiDsiHandle == NULL) { HDF_LOGE("MipiDsiOpen: failed\n"); return; } ``` ### MIPI-DSI相应配置 - 写入MIPI-DSI配置 int32\_t MipiDsiSetCfg\(DevHandle handle, struct MipiCfg \*cfg\); **表 3** MipiDsiSetCfg的参数和返回值描述

参数

参数描述

handle

操作句柄

cfg

MIPI-DSI相应配置buf 指针

返回值

返回值描述

0

设置成功

负数

设置失败

``` int32_t ret; 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; /* 写入配置数据 */ ret = MipiDsiSetCfg(mipiDsiHandle, &cfg); if (ret != 0) { HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret); return -1; } ``` - 获取当前MIPI-DSI的配置 int32\_t MipiDsiGetCfg\(DevHandle handle, struct MipiCfg \*cfg\); **表 4** MipiDsiGetCfg的参数和返回值描述

参数

参数描述

handle

操作句柄

cfg

MIPI-DSI相应配置buf 指针

返回值

返回值描述

0

获取成功

负数

获取失败

``` int32_t ret; struct MipiCfg cfg; memset(&cfg, 0, sizeof(struct MipiCfg)); ret = MipiDsiGetCfg(mipiDsiHandle, &cfg); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: GetMipiCfg fail!\n", __func__); return HDF_FAILURE; } ``` ### 发送/回读控制指令 - 发送指令 int32\_t MipiDsiTx\(PalHandle handle, struct DsiCmdDesc \*cmd\); **表 5** MipiDsiTx的参数和返回值描述

参数

参数描述

handle

操作句柄

cmd

需要发送的指令数据指针

返回值

返回值描述

0

发送成功

负数

发送失败

``` 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); ``` - 回读指令 int32\_t MipiDsiRx\(DevHandle handle, struct DsiCmdDesc \*cmd, uint32\_t readLen, uint8\_t \*out\); **表 6** MipiDsiRx的参数和返回值描述

参数

参数描述

handle

操作句柄

cmd

需要回读的指令数据指针

readLen

期望回读的数据长度

out

回读的数据buf指针

返回值

返回值描述

0

获取成功

负数

获取失败

``` 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(mipiDsiHandle); ret = MipiDsiRx(mipiDsiHandle, cmdRead, sizeof(readVal), &readVal); MipiDsiSetHsMode(mipiDsiHandle); 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); ``` ### 释放MIPI-DSI操作句柄 MIPI-DSI使用完成之后,需要释放操作句柄,释放句柄的函数如下所示: void MipiDsiClose\(DevHandle handle\); 该函数会释放掉由MipiDsiOpen申请的资源。 **表 7** MipiDsiClose的参数和返回值描述

参数

参数描述

handle

MIPI-DSI操作句柄

``` MipiDsiClose(mipiHandle); /* 释放掉MIPI-DSI操作句柄 */ ``` ## 使用实例 MIPI-DSI完整的使用示例如下所示: ``` #include "hdf.h" #include "mipi_dsi_if.h" void PalMipiDsiTestSample(void) { uint8_t chnId; int32_t ret; DevHandle mipiDsiHandle = NULL; /* 设备通道编号 */ chnId = 0; /* 获取操作句柄 */ mipiDsiHandle = MipiDsiOpen(chnId); if (mipiDsiHandle == NULL) { HDF_LOGE("MipiDsiOpen: failed!\n"); return; } /* 配置相应参数 */ 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; /* 写入配置数据 */ ret = MipiDsiSetCfg(mipiDsiHandle, &cfg); if (ret != 0) { HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret); return; } /* 发送PANEL初始化指令 */ 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); /* 回读panel状态寄存器 */ 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(mipiDsiHandle); ret = MipiDsiRx(mipiDsiHandle, cmdRead, sizeof(readVal), &readVal); MipiDsiSetHsMode(mipiDsiHandle); 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); /* 释放MIPI DSI设备句柄 */ MipiDsiClose(handle); } ```