Harmony鸿蒙南向驱动开发-MIPI DSI接口利用

打印 上一主题 下一主题

主题 860|帖子 860|积分 2584

功能简介

DSI(Display Serial Interface)是由移动行业处理器接口联盟(Mobile Industry Processor Interface (MIPI) Alliance)订定的规范,旨在低落移动设备中显示控制器的成本。它以串行的方式发送像素数据或指令给外设(通常是LCD或者雷同的显示设备),或从外设中读取状态信息或像素信息;它界说了主机、图像数据源和目标设备之间的串行总线和通信协议。
MIPI DSI具备高速模式和低速模式两种工作模式,全部数据通道都可以用于单向的高速传输,但只有第一个数据通道才可用于低速双向传输,附属端的状态信息、像素等是通过该数据通道返回。时钟通道专用于在高速传输数据的过程中传输同步时钟信号。
图1显示了简化的DSI接口。从概念上看,符合DSI的接口与基于DBI-2和DPI-2标准的接口具有相同的功能。它向外围设备传输像素或命令数据,并且可以从外围设备读取状态或像素信息。重要区别在于,DSI对全部像素数据、命令和事件举行序列化,而在传统接口中,这些像素数据、命令和事件通常必要附加控制信号才能在并行数据总线上传输。
图 1 DSI发送、吸取接口


DSI标准对应D-PHY、DSI、DCS规范,可分为四层:


  • PHY Layer
    PHY层指定传输介质(电导体)、输入/输出电路和从串行比特流中捕获“1”和“0”的时钟机制。这一部门的规范记录了传输介质的特性、信号的电气参数以及时钟与数据通道之间的时序关系。在DSI链路的发送端,并行数据、信号事件和命令按照包构造在协议层转换为包。协议层附加包协议信息和报头,然后通过Lane Management层向PHY发送完整的字节。数据由PHY举行序列化,并通过串行链路发送。DSI链路的吸取端实行与发送端相反的操作,将数据包分解为并行的数据、信号事件和命令。假如有多个Lane, Lane管理层将字节分配给单独的物理层,每个Lane一个PHY。
  • Lane Management层
    负责发送和网络数据流到每条Lane。数据Lane的三种操作模式 :espace mode,High-Speed(Burst) mode,Control mode。
  • Low Level Protocol层
    界说了怎样组帧和解析以及错误检测等。
  • Application层
    描述高层编码和解析数据流。这一层描述了数据流中包罗的数据的更高级的编码和表明。根据显示子系统架构的不同,它大概由具有指定格式的像素或编码的位流构成,或者由显示模块内的显示控制器表明的命令构成。DSI规范描述了像素值、位流、命令和命令参数到包集合中的字节的映射。
运作机制

MIPI DSI软件模块各分层的作用为:


  • 接口层:提供打开设备、写入数据和关闭设备的接口。
  • 焦点层:重要提供绑定设备、初始化设备以及释放设备的本事。
  • 适配层:实现别的详细的功能。
   阐明:
焦点层可以调用接口层的函数,焦点层通过钩子函数调用适配层函数,从而适配层可以间接的调用接口层函数,但是不可逆转接口层调用适配层函数。
  图 2 DSI无服务模式结构图


约束与限制

由于利用无服务模式,MIPI_DSI接口暂不支持用户态利用。
利用指导

场景先容

MIPI DSI重要用于毗连显示屏。
接口阐明

MIPI DSI模块提供的重要接口如表1所示,详细API详见//drivers/hdf_core/framework/include/platform/mipi_dsi_if.h。
表1 MIPI DSI API接口功能先容
功能分类接口名DevHandle MipiDsiOpen(uint8_t id)获取MIPI DSI操作句柄void MipiDsiClose(DevHandle handle)释放MIPI DSI操作句柄int32_t MipiDsiSetCfg(DevHandle handle, struct MipiCfg *cfg)设置MIPI DSI相关配置int32_t MipiDsiGetCfg(DevHandle handle, struct MipiCfg *cfg)获取当前MIPI DSI相关配置void MipiDsiSetLpMode(DevHandle handle)设置MIPI DSI进入Low power模式void MipiDsiSetHsMode(DevHandle handle)设置MIPI DSI进入High speed模式int32_t MipiDsiTx(DevHandle handle, struct DsiCmdDesc *cmd)DSI发送指令int32_t MipiDsiRx(DevHandle handle, struct DsiCmdDesc *cmd, int32_t readLen, uint8_t *out)MIPI DSI按期望长度回读数据 开发步骤

利用MIPI DSI的一般流程如下图所示。
图 3 MIPI DSI利用流程图


获取MIPI DSI操作句柄

在举行MIPI DSI举行通信前,首先要调用MipiDsiOpen获取操作句柄,该函数会返回指定通道ID的操作句柄。
  1. DevHandle MipiDsiOpen(uint8_t id);
复制代码
表 2 MipiDsiOpen的参数和返回值描述
参数参数描述iduint8_t类型,MIPI DSI通道ID返回值返回值描述NULL获取失败设备句柄获取到指令通道的操作句柄, 类型为DevHandle 假设系统中的MIPI DSI通道为0,获取该通道操作句柄的示例如下:
  1. DevHandle mipiDsiHandle = NULL;  // 设备句柄
  2. chnId = 0;                       // MIPI DSI通道ID
  3. // 获取操作句柄
  4. mipiDsiHandle = MipiDsiOpen(chnId);
  5. if (mipiDsiHandle == NULL) {
  6.     HDF_LOGE("MipiDsiOpen: mipi dsi open fail.\n");
  7.     return NULL;
  8. }
复制代码
MIPI DSI相应配置



  • 写入MIPI DSI配置
    1. int32_t MipiDsiSetCfg(DevHandle handle, struct MipiCfg *cfg);
    复制代码
    表 3 MipiDsiSetCfg的参数和返回值描述
       参数参数描述handleDevHandle类型,操作句柄cfg结构体指针类型,MIPI DSI相应配置buf 指针返回值返回值描述HDF_SUCCESS设置MIPI DSI配置成功负数设置MIPI DSI配置失败
    1. int32_t ret;
    2. struct MipiCfg cfg = {0};
    3. // 当前对接的屏幕配置如下
    4. cfg.lane = DSI_4_LANES;
    5. cfg.mode = DSI_CMD_MODE;
    6. cfg.burstMode = VIDEO_NON_BURST_MODE_SYNC_EVENTS;
    7. cfg.format = FORMAT_RGB_24_BIT;
    8. cfg.pixelClk = 174;
    9. cfg.phyDataRate = 384;
    10. cfg.timingInfo.hsaPixels = 50;
    11. cfg.timingInfo.hbpPixels = 55;
    12. cfg.timingInfo.hlinePixels = 1200;
    13. cfg.timingInfo.yResLines = 1800;
    14. cfg.timingInfo.vbpLines = 33;
    15. cfg.timingInfo.vsaLines = 76;
    16. cfg.timingInfo.vfpLines = 120;
    17. cfg.timingInfo.xResPixels = 1342;
    18. // 写入配置数据
    19. ret = MipiDsiSetCfg(mipiDsiHandle, &cfg);
    20. if (ret != HDF_SUCCESS) {
    21.     HDF_LOGE("MipiDsiSetCfg: set mipi cfg fail, ret:%d\n", ret);
    22.     return ret;
    23. }
    复制代码
  • 获取当前MIPI DSI的配置
    1. int32_t MipiDsiGetCfg(DevHandle handle, struct MipiCfg *cfg);
    复制代码
    表 4 MipiDsiGetCfg的参数和返回值描述
       参数参数描述handleDevHandle类型,操作句柄cfg结构体指针,MIPI DSI相应配置buf 指针返回值返回值描述HDF_SUCCESS获取当前MIPI DSI的配置成功负数获取当前MIPI DSI的配置失败
    1. int32_t ret;
    2. struct MipiCfg cfg;
    3. memset(&cfg, 0, sizeof(struct MipiCfg));
    4. ret = MipiDsiGetCfg(mipiDsiHandle, &cfg);
    5. if (ret != HDF_SUCCESS) {
    6.     HDF_LOGEMipiDsiGetCfg: get mipi cfg fail, ret:%d!\n", ret);
    7.     return ret;
    8. }
    复制代码
发送/回读控制指令



  • 发送指令
    1. int32_t MipiDsiTx(PalHandle handle, struct DsiCmdDesc *cmd);
    复制代码
    表 5 MipiDsiTx的参数和返回值描述
       参数参数描述handleDevHandle类型,操作句柄cmd结构体指针类型,必要发送的指令数据指针返回值返回值描述HDF_SUCCESS发送成功负数发送失败
    1. int32_t ret;
    2. struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc));
    3. if (cmd == NULL) {
    4.     return HDF_FAILURE;
    5. }
    6. cmd->dtype = DTYPE_DCS_WRITE;
    7. cmd->dlen = 1;
    8. cmd->payload = OsalMemCalloc(sizeof(uint8_t));
    9. if (cmd->payload == NULL) {
    10.     HdfFree(cmd);
    11.     return HDF_FAILURE;
    12. }
    13. *(cmd->payload) = DTYPE_GEN_LWRITE;
    14. MipiDsiSetLpMode(mipiHandle);
    15. ret = MipiDsiTx(mipiHandle, cmd);
    16. MipiDsiSetHsMode(mipiHandle);
    17. if (ret != HDF_SUCCESS) {
    18.     HDF_LOGE("MipiDsiTx: mipi dsi tx fail, ret:%d\n", ret);
    19.     HdfFree(cmd->payload);
    20.     HdfFree(cmd);
    21.     return ret;
    22. }
    23. HdfFree(cmd->payload);
    24. HdfFree(cmd);
    复制代码
  • 回读指令
    1. int32_t MipiDsiRx(DevHandle handle, struct DsiCmdDesc *cmd, uint32_t readLen, uint8_t *out);
    复制代码
    表 6 MipiDsiRx的参数和返回值描述
       参数参数描述handleDevHandle类型,操作句柄cmd结构体指针类型,必要回读的指令数据指针readLenuint32_t类型,期望回读的数据长度outuint8_t类型指针,回读的数据返回值返回值描述HDF_SUCCESS获取成功负数获取失败
    1. int32_t ret;
    2. uint8_t readVal = 0;
    3. struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc));
    4. if (cmdRead == NULL) {
    5.     return HDF_FAILURE;
    6. }
    7. cmdRead->dtype = DTYPE_DCS_READ;
    8. cmdRead->dlen = 1;
    9. cmdRead->payload = OsalMemCalloc(sizeof(uint8_t));
    10. if (cmdRead->payload == NULL) {
    11.     HdfFree(cmdRead);
    12.     return HDF_FAILURE;
    13. }
    14. *(cmdRead->payload) = DDIC_REG_STATUS;
    15. MipiDsiSetLpMode(mipiDsiHandle);
    16. ret = MipiDsiRx(mipiDsiHandle, cmdRead, sizeof(readVal), &readVal);
    17. MipiDsiSetHsMode(mipiDsiHandle);
    18. if (ret != HDF_SUCCESS) {
    19.     HDF_LOGE("MipiDsiRx: mipi dsi rx fail, ret:%d\n", ret);
    20.     HdfFree(cmdRead->payload);
    21.     HdfFree(cmdRead);
    22.     return HDF_FAILURE;
    23. }
    24. HdfFree(cmdRead->payload);
    25. HdfFree(cmdRead);
    复制代码
释放MIPI DSI操作句柄

MIPI DSI利用完成之后,必要释放操作句柄,释放句柄的函数如下所示:
  1. void MipiDsiClose(DevHandle handle);
复制代码
该函数会释放掉由MipiDsiOpen申请的资源。
表 7 MipiDsiClose的参数和返回值描述
参数参数描述handleDevHandle类型,MIPI DSI操作句柄
  1. MipiDsiClose(mipiHandle); // 释放掉MIPI DSI操作句柄
复制代码
利用实例

本例拟对Hi3516DV300开发板上MIPI DSI设备举行操作。
MIPI DSI完整的利用示例如下所示:
  1. #include "hdf_log.h"
  2. #include "mipi_dsi_if.h"
  3. #include "osal_mem.h"
  4. #define DTYPE_DCS_WRITE 0x05
  5. #define DTYPE_DCS_READ 0x06
  6. #define DTYPE_GEN_LWRITE 0x29
  7. #define DDIC_REG_STATUS 0x0A
  8. int32_t PalMipiDsiTestSample(void)
  9. {
  10.     uint8_t chnId;
  11.     int32_t ret;  
  12.     DevHandle mipiDsiHandle = NULL;
  13.    
  14.     // 设备通道编号
  15.     chnId = 0;
  16.     // 获取操作句柄
  17.     mipiDsiHandle = MipiDsiOpen(chnId);
  18.     if (mipiDsiHandle == NULL) {
  19.         HDF_LOGE("MipiDsiOpen: failed!\n");
  20.         return HDF_FAILURE;
  21.     }
  22.     // 配置相应参数
  23.     struct MipiCfg cfg = {0};
  24.     cfg.lane = DSI_2_LANES;
  25.     cfg.mode = DSI_VIDEO_MODE;
  26.     cfg.format = FORMAT_RGB_24_BIT;
  27.     cfg.burstMode = VIDEO_BURST_MODE;
  28.     cfg.timing.xPixels = 480;           // 480: width
  29.     cfg.timing.hsaPixels = 10;          // 10: horizontal sync porch
  30.     cfg.timing.hbpPixels = 20;          // 20: horizontal back porch
  31.     cfg.timing.hlinePixels = 530;       // 530: horizontal total width
  32.     cfg.timing.vsaLines = 2;            // 2: vertiacl sync width
  33.     cfg.timing.vbpLines = 14;           // 14: vertiacl back porch
  34.     cfg.timing.vfpLines = 16;           // 16: vertiacl front porch
  35.     cfg.timing.ylines = 960;            // 960: height
  36.     cfg.timing.edpiCmdSize = 0;         // 0 : no care
  37.     cfg.pixelClk = 31546;               // 31546: pixel clk   
  38.     cfg.phyDataRate = 379;              // 379: mipi clk
  39.     // 写入配置数据
  40.     ret = MipiDsiSetCfg(mipiDsiHandle, &cfg);
  41.     if (ret != 0) {
  42.         HDF_LOGE("PalMipiDsiTestSample: set mipi dsi cfg fail, ret:%d\n", ret);
  43.         return ret;
  44.     }
  45.     // 发送PANEL初始化指令
  46.     struct DsiCmdDesc *cmd = OsalMemCalloc(sizeof(struct DsiCmdDesc));
  47.     if (cmd == NULL) {
  48.         return -1;
  49.     }
  50.     cmd->dataType = DTYPE_DCS_WRITE;
  51.     cmd->dataLen = 1;
  52.     cmd->payload = OsalMemCalloc(sizeof(uint8_t));
  53.     if (cmd->payload == NULL) {
  54.         OsalMemFree(cmd);
  55.         return -1;
  56.     }
  57.     *(cmd->payload) = DTYPE_GEN_LWRITE;
  58.     MipiDsiSetLpMode(mipiDsiHandle);
  59.     ret = MipiDsiTx(mipiDsiHandle, cmd);
  60.     MipiDsiSetHsMode(mipiDsiHandle);
  61.     if (ret != HDF_SUCCESS) {
  62.         HDF_LOGE("PalMipiDsiTestSample: mipi dsi tx fail, ret:%d\n", ret);
  63.         OsalMemFree(cmd->payload);
  64.         OsalMemFree(cmd);
  65.         return ret;
  66.     }
  67.     OsalMemFree(cmd->payload);
  68.     OsalMemFree(cmd);
  69.     // 回读panel状态寄存器
  70.     uint8_t readVal = 0;
  71.     struct DsiCmdDesc *cmdRead = OsalMemCalloc(sizeof(struct DsiCmdDesc));
  72.     if (cmdRead == NULL) {
  73.         return -1;
  74.     }
  75.     cmdRead->dataType = DTYPE_DCS_READ;
  76.     cmdRead->dataLen = 1;
  77.     cmdRead->payload = OsalMemCalloc(sizeof(uint8_t));
  78.     if (cmdRead->payload == NULL) {
  79.         OsalMemFree(cmdRead);
  80.         return -1;
  81.     }
  82.     *(cmdRead->payload) = DDIC_REG_STATUS;
  83.     MipiDsiSetLpMode(mipiDsiHandle);
  84.     ret = MipiDsiRx(mipiDsiHandle, cmdRead, sizeof(readVal), &readVal);
  85.     MipiDsiSetHsMode(mipiDsiHandle);
  86.     if (ret != HDF_SUCCESS) {
  87.         HDF_LOGE("PalMipiDsiTestSample: mipi dsi rx fail, ret:%d\n", ret);
  88.         OsalMemFree(cmdRead->payload);
  89.         OsalMemFree(cmdRead);
  90.         return ret;
  91.     }
  92.     OsalMemFree(cmdRead->payload);
  93.     OsalMemFree(cmdRead);
  94.     HDF_LOGD("PalMipiDsiTestSample: mipi dsi tests end");
  95.     // 释放MIPI DSI设备句柄
  96.     MipiDsiClose(mipiDsiHandle);
  97.     return ret;
  98. }
复制代码
最后

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道必要重点把握哪些鸿蒙应用开发知识点?而且学习时频仍踩坑,终极浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有必要的。 
这份鸿蒙(HarmonyOS NEXT)资料包罗了鸿蒙开发必把握的焦点知识要点,内容包罗了ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。
希望这一份鸿蒙学习资料能够给大家带来资助,有必要的小伙伴自行领取,限时开源,先到先得~无套路领取!!
获取这份完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料
鸿蒙(HarmonyOS NEXT)最新学习路线




  •  HarmonOS基础技能



  • HarmonOS就业必备技能 

  •  HarmonOS多媒体技术



  • 鸿蒙NaPi组件进阶



  • HarmonOS高级技能



  • 初识HarmonOS内核 

  • 实战就业级设备开发

有了路线图,怎么能没有学习资料呢,小编也预备了一份连合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)鸿蒙(OpenHarmony )开发入门教学视频,内容包罗:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。
获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料
《鸿蒙 (OpenHarmony)开发入门教学视频》


《鸿蒙生态应用开发V2.0白皮书》


《鸿蒙 (OpenHarmony)开发基础到实战手册》

OpenHarmony北向、南向开发环境搭建

 《鸿蒙开发基础》



  • ArkTS语言
  • 安装DevEco Studio
  • 运用你的第一个ArkTS应用
  • ArkUI声明式UI开发
  • .……

 《鸿蒙开发进阶》



  • Stage模型入门
  • 网络管理
  • 数据管理
  • 电话服务
  • 分布式应用开发
  • 通知与窗口管理
  • 多媒体技术
  • 安全技能
  • 使命管理
  • WebGL
  • 国际化开发
  • 应用测试
  • DFX面向未来筹划
  • 鸿蒙系统移植和裁剪定制
  • ……

《鸿蒙进阶实战》



  • ArkTS实践
  • UIAbility应用
  • 网络案例
  • ……

 获取以上完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料
总结

总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑衅,也是一个时机。只有积极应对变革,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。 


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

王國慶

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表