1# MIPI CSI 2 3## 概述 4 5### 功能简介 6 7CSI(Camera Serial Interface)是由MIPI联盟下Camera工作组指定的接口标准。CSI-2是MIPI CSI第二版,主要由应用层、协议层、物理层组成,最大支持4通道数据传输、单线传输速度高达1Gb/s。 8 9物理层支持HS(High Speed)和LP(Low Speed)两种工作模式。HS模式下采用低压差分信号,功耗较大,但数据传输速率可以很高(数据速率为80M~1Gbps);LP模式下采用单端信号,数据速率很低(<10Mbps),但是相应的功耗也很低。两种模式的结合保证了MIPI总线在需要传输大量数据(如图像)时可以高速传输,而在不需要传输大数据量时又能够减少功耗。 10 11图1显示了简化的CSI接口。D-PHY采用1对源同步的差分时钟和1~4对差分数据线来进行数据传输。数据传输采用DDR方式,即在时钟的上下边沿都有数据传输。 12 13**图1** CSI发送、接收接口<a name="fig1_MIPI_CSIDes"></a> 14![](figures/CSI发送-接收接口.png) 15 16MIPI CSI标准分为应用层、协议层与物理层,协议层又细分为像素字节转换层、低级协议层、Lane管理层。 17 18- 物理层(PHY Layer) 19 20 PHY层指定了传输媒介,在电气层面从串行bit流中捕捉“0”与“1”,同时生成SoT与EoT等信号。 21 22- 协议层(Protocol Layer) 23 24 协议层由三个子层组成,每个子层有不同的职责。CSI-2协议能够在host侧处理器上用一个单独的接口处理多条数据流。协议层规定了多条数据流该如何标记和交织起来,以便每条数据流能够被正确地恢复出来。 25 26 - 像素字节转换层(Pixel/Byte Packing/Unpacking Layer) 27 28 CSI-2规范支持多种不同像素格式的图像应用。在发送方中,本层在发送数据到Low Level Protocol层之前,将来自应用层的像素封包为字节数据。在接收方中,本层在发送数据到应用层之前,将来自Low Level Protocol层的字节数据解包为像素。8位的像素数据在本层中传输时保持不变。 29 30 - 低级协议层(Low Level Protocol) 31 32 LLP主要包含了在SoT和EoT事件之间的bit和byte级别的同步方法,以及和下一层传递数据的方法。LLP最小数据粒度是1个字节。LLP也包含了一个字节内的bit值解析,即Endian(大小端里的Endian的意思)的处理。 33 34 - Lane管理层(Lane Management) 35 36 CSI-2的Lane是可扩展的。具体的数据Lane的数量规范并没有给出限制,具体根据应用的带宽需求而定。发送侧分发(distributor功能)来自出口方向数据流的字节到1条或多条Lane上。接收侧则从一条或多条Lane中收集字节并合并(merge功能)到一个数据流上,复原出原始流的字节顺序。对于C-PHY物理层来说,本层专门分发字节对(16 bits)到数据Lane或从数据Lane中收集字节对。基于每Lane的扰码功能是可选特性。 37 38 协议层的数据组织形式是包(packet)。接口的发送侧会增加包头(header)和错误校验(error-checking)信息到即将被LLP发送的数据上。接收侧在LLP将包头剥掉,包头会被接收器中对应的逻辑所解析。错误校验信息可以用来做入口数据的完整性检查。 39 40- 应用层(Application Layer) 41 42 本层描述了更高层级的应用对于数据中的数据的处理,规范并不涵盖应用层。CSI-2规范只给出了像素值和字节的映射关系。 43 44### 运作机制 45 46MIPI CSI模块各分层的作用为:接口层提供打开设备、写入数据和关闭设备的接口。核心层主要提供绑定设备、初始化设备以及释放设备的能力。适配层实现其它具体的功能。 47 48![](../public_sys-resources/icon-note.gif) **说明:**<br>核心层可以调用接口层的函数,核心层通过钩子函数调用适配层函数,从而适配层可以间接的调用接口层函数,但是不可逆转接口层调用适配层函数。 49 50**图2**CSI无服务模式结构图 51 52![image](figures/无服务模式结构图.png "CSI无服务模式结构图") 53 54### 约束与限制 55 56由于使用无服务模式,MIPI_CSI接口暂不支持用户态使用。 57 58## 使用指导 59 60### 场景介绍 61 62MIPI CSI主要用于连接摄像头组件。 63 64### 接口说明 65 66MIPI CSI模块提供的主要接口如表1所示,具体API详见//drivers/hdf_core/framework/include/platform/mipi_csi_if.h。 67 68**表1** ComboDevAttr结构体介绍 69 70<a name="table1_MIPI_CSIDes"></a> 71 72| 名称 | 描述 | 73| --------- | ----------------------------------------------------- | 74| devno | 设备号 | 75| inputMode | 输入模式:MIPI/LVDS/SUBSLVDS/HISPI/DC | 76| dataRate | Mipi Rx,SLVS输入速率 | 77| imgRect | MIPI Rx设备裁剪区域(与原始传感器输入图像大小相对应) | 78| MIPIAttr | Mipi设备属性 | 79| lvdsAttr | LVDS/SubLVDS/HiSPi设备属性 | 80 81**表2** ExtDataType结构体介绍 82 83<a name="table2_MIPI_CSIDes"></a> 84 85| 名称 | 描述 | 86| --------------- | ------------------------------- | 87| devno | 设备号 | 88| num | Sensor号 | 89| extDataBitWidth | 图片的位深 | 90| extDataType | 定义YUV和原始数据格式以及位深度 | 91 92**表3** MIPI CSI API接口功能介绍 93 94<a name="table3_MIPI_CSIDes"></a> 95 96| 接口名 | 接口描述 | 97| -------- | -------- | 98| DevHandle MipiCsiOpen(uint8_t id) | 获取MIPI_CSI控制器操作句柄 | 99| void MipiCsiClose(DevHandle handle) | 释放MIPI_CSI控制器操作句柄 | 100| int32_t MipiCsiSetComboDevAttr(DevHandle handle, ComboDevAttr \*pAttr) | 设置MIPI,CMOS或者LVDS相机的参数给控制器,参数包括工作模式,图像区域,图像深度,数据速率和物理通道等 | 101| int32_t MipiCsiSetExtDataType(DevHandle handle, ExtDataType \*dataType) | 设置YUV和RAW数据格式和位深(可选) | 102| int32_t MipiCsiSetHsMode(DevHandle handle, LaneDivideMode laneDivideMode) | 设置MIPI RX的Lane分布。根据硬件连接的形式选择具体的mode | 103| int32_t MipiCsiSetPhyCmvmode(DevHandle handle, uint8_t devno, PhyCmvMode cmvMode) | 设置共模电压模式 | 104| int32_t MipiCsiResetSensor(DevHandle handle, uint8_t snsResetSource) | 复位Sensor | 105| int32_t MipiCsiUnresetSensor(DevHandle handle, uint8_t snsResetSource) | 撤销复位Sensor | 106| int32_t MipiCsiResetRx(DevHandle handle, uint8_t comboDev) | 复位MIPI RX。不同的s32WorkingViNum有不同的enSnsType | 107| int32_t MipiCsiUnresetRx(DevHandle handle, uint8_t comboDev) | 撤销复位MIPI RX | 108| int32_t MipiCsiEnableClock(DevHandle handle, uint8_t comboDev) | 使能MIPI的时钟。根据上层函数电泳传递的enSnsType参数决定是用MIPI还是LVDS | 109| int32_t MipiCsiDisableClock(DevHandle handle, uint8_t comboDev) | 关闭MIPI设备的时钟 | 110| int32_t MipiCsiEnableSensorClock(DevHandle handle, uint8_t snsClkSource) | 使能MIPI上的Sensor时钟 | 111| int32_t MipiCsiDisableSensorClock(DevHandle handle, uint8_t snsClkSource) | 关闭Sensor的时钟 | 112 113 114## 开发步骤 115 116#### 使用流程 117 118使用MIPI CSI的一般流程如图3所示。 119 120**图3** MIPI CSI使用流程图 121 122 123![](figures/MIPI-CSI使用流程图.png) 124 125#### 获取MIPI CSI控制器操作句柄 126 127在进行MIPI CSI进行通信前,首先要调用MipiCsiOpen获取控制器操作句柄,该函数会返回指定通道ID的控制器操作句柄。 128 129```c 130DevHandle MipiCsiOpen(uint8_t id); 131``` 132 133**表4** MipiCsiOpen的参数和返回值描述 134 135| 参数 | 参数描述 | 136| ---------- | ----------------------------------------------- | 137| id | MIPI CSI通道ID | 138| **返回值** | **返回值描述** | 139| NULL | 获取失败 | 140| 设备句柄 | 获取到指令通道的控制器操作句柄,类型为DevHandle | 141 142假设系统中的MIPI CSI通道为0,获取该通道控制器操作句柄的示例如下: 143 144```c 145DevHandle MipiCsiHandle = NULL; /* 设备句柄 */ 146id = 0; /* MIPI CSI通道ID */ 147 148/* 获取控制器操作句柄 */ 149MipiCsiHandle = MipiCsiOpen(id); 150if (MipiCsiHandle == NULL) { 151 HDF_LOGE("MipiCsiOpen: failed\n"); 152 return; 153} 154``` 155 156#### 进行MIPI CSI相应配置 157 158- 写入MIPI CSI配置 159 160 ```c 161 int32_t MipiCsiSetComboDevAttr(DevHandle handle, ComboDevAttr *pAttr); 162 ``` 163 164 **表5** MipiCsiSetComboDevAttr的参数和返回值描述 165 166 <a name="table5_MIPI_CSIDes"></a> 167 168 | 参数 | 参数描述 | 169 | ---------- | -------------------------- | 170 | handle | 控制器操作句柄 | 171 | pAttr | MIPI CSI相应配置结构体指针 | 172 | **返回值** | **返回值描述** | 173 | 0 | 设置成功 | 174 | 负数 | 设置失败 | 175 176 ```c 177 int32_t ret; 178 struct ComboDevAttr attr; 179 180 /* 当前配置如下 */ 181 (void)memset_s(&attr, sizeof(ComboDevAttr), 0, sizeof(ComboDevAttr)); 182 attr.devno = 0; /* 设备0 */ 183 attr.inputMode = INPUT_MODE_MIPI; /* 输入模式为MIPI */ 184 attr.dataRate = MIPI_DATA_RATE_X1; /* 每时钟输出1像素 */ 185 attr.imgRect.x = 0; /* 0: 图像传感器左上位置 */ 186 attr.imgRect.y = 0; /* 0: 图像传感器右上位置 */ 187 attr.imgRect.width = 2592; /* 2592: 图像传感器宽度大小 */ 188 attr.imgRect.height = 1944; /* 1944: 图像传感器高度尺寸 */ 189 /* 写入配置数据 */ 190 ret = MipiCsiSetComboDevAttr(MipiCsiHandle, &attr); 191 if (ret != 0) { 192 HDF_LOGE("%s: MipiCsiSetComboDevAttr fail! ret=%d\n", __func__, ret); 193 return -1; 194 } 195 ``` 196 197- 设置YUV和RAW数据格式和位深 198 199 ```c 200 int32_t MipiCsiSetExtDataType(DevHandle handle, ExtDataType* dataType); 201 ``` 202 203 **表6** MipiCsiSetExtDataType的参数和返回值描述 204 205 <a name="table6_MIPI_CSIDes"></a> 206 207 | 参数 | 参数描述 | 208 | ---------- | ------------------------------- | 209 | handle | 控制器操作句柄 | 210 | dataType | 定义YUV和原始数据格式以及位深度 | 211 | **返回值** | **返回值描述** | 212 | 0 | 设置成功 | 213 | 负数 | 设置失败 | 214 215 ```c 216 int32_t ret; 217 struct ExtDataType dataType; 218 219 /* 配置YUV和RAW数据格式和位深参数 */ 220 dataType.devno = 0; /* 设备0 */ 221 dataType.num = 0; /* Sensor 0 */ 222 dataType.extDataBitWidth[0] = 12; /* 位深数组元素0 */ 223 dataType.extDataBitWidth[1] = 12; /* 位深数组元素1 */ 224 dataType.extDataBitWidth[2] = 12; /* 位深数组元素2 */ 225 226 dataType.extDataType[0] = 0x39; /* 定义YUV和原始数据格式以及位深度元素0 */ 227 dataType.extDataType[1] = 0x39; /* 定义YUV和原始数据格式以及位深度元素1 */ 228 dataType.extDataType[2] = 0x39; /* 定义YUV和原始数据格式以及位深度元素2 */ 229 /* 设置YUV和RAW数据格式和位深 */ 230 ret = MipiCsiSetExtDataType(MipiCsiHandle, &dataType); 231 if (ret != 0) { 232 HDF_LOGE("%s: MipiCsiSetExtDataType fail! ret=%d\n", __func__, ret); 233 return -1; 234 } 235 ``` 236 237- 设置MIPI RX的Lane分布 238 239 ```c 240 int32_t MipiCsiSetHsMode(DevHandle handle, LaneDivideMode laneDivideMode); 241 ``` 242 243 **表7** MipiCsiSetHsMode的参数和返回值描述 244 245 | 参数 | 参数描述 | 246 | -------------- | -------------- | 247 | handle | 控制器操作句柄 | 248 | laneDivideMode | Lane模式参数 | 249 | **返回值** | **返回值描述** | 250 | 0 | 设置成功 | 251 | 负数 | 设置失败 | 252 253 ```c 254 int32_t ret; 255 enum LaneDivideMode mode; 256 257 /* Lane模式参数为0 */ 258 mode = LANE_DIVIDE_MODE_0; 259 /* 设置MIPI RX的 Lane分布 */ 260 ret = MipiCsiSetHsMode(MipiCsiHandle, mode); 261 if (ret != 0) { 262 HDF_LOGE("%s: MipiCsiSetHsMode fail! ret=%d\n", __func__, ret); 263 return -1; 264 } 265 ``` 266 267- 设置共模电压模式 268 269 ```c 270 int32_t MipiCsiSetPhyCmvmode(DevHandle handle, uint8_t devno, PhyCmvMode cmvMode); 271 ``` 272 273 **表8** MipiCsiSetPhyCmvmode的参数和返回值描述 274 275 | 参数 | 参数描述 | 276 | ---------- | ---------------- | 277 | handle | 控制器操作句柄 | 278 | cmvMode | 共模电压模式参数 | 279 | devno | 设备编号 | 280 | **返回值** | **返回值描述** | 281 | 0 | 设置成功 | 282 | 负数 | 设置失败 | 283 284 ```c 285 int32_t ret; 286 enum PhyCmvMode mode; 287 uint8_t devno; 288 289 /* 共模电压模式参数为0 */ 290 mode = PHY_CMV_GE1200MV; 291 /* 设备编号为0 */ 292 devno = 0; 293 /* 设置共模电压模式 */ 294 ret = MipiCsiSetPhyCmvmode(MipiCsiHandle, devno, mode); 295 if (ret != 0) { 296 HDF_LOGE("%s: MipiCsiSetPhyCmvmode fail! ret=%d\n", __func__, ret); 297 return -1; 298 } 299 ``` 300 301#### 复位/撤销复位Sensor 302 303- 复位Sensor 304 305 ```c 306 int32_t MipiCsiResetSensor(DevHandle handle, uint8_t snsResetSource); 307 ``` 308 309 **表9** MipiCsiResetSensor的参数和返回值描述 310 311 | 参数 | 参数描述 | 312 | -------------- | ------------------------------------------------ | 313 | handle | 控制器操作句柄 | 314 | snsResetSource | 传感器的复位信号线号,在软件中称为传感器的复位源 | 315 | **返回值** | **返回值描述** | 316 | 0 | 复位成功 | 317 | 负数 | 复位失败 | 318 319 ```c 320 int32_t ret; 321 uint8_t snsResetSource; 322 323 /* 传感器复位信号线号为0 */ 324 snsResetSource = 0; 325 /* 复位Sensor */ 326 ret = MipiCsiResetSensor(MipiCsiHandle, snsResetSource); 327 if (ret != 0) { 328 HDF_LOGE("%s: MipiCsiResetSensor fail! ret=%d\n", __func__, ret); 329 return -1; 330 } 331 ``` 332 333- 撤销复位Sensor 334 335 ```c 336 int32_t MipiCsiUnresetSensor(DevHandle handle, uint8_t snsResetSource); 337 ``` 338 339 **表10** MipiCsiUnresetSensor的参数和返回值描述 340 341 | 参数 | 参数描述 | 342 | -------------- | ------------------------------------------------ | 343 | handle | 控制器操作句柄 | 344 | snsResetSource | 传感器的复位信号线号,在软件中称为传感器的复位源 | 345 | **返回值** | **返回值描述** | 346 | 0 | 撤销复位成功 | 347 | 负数 | 撤销复位失败 | 348 349 ```c 350 int32_t ret; 351 uint8_t snsResetSource; 352 353 /* 传感器撤销复位信号线号为0 */ 354 snsResetSource = 0; 355 /* 撤销复位Sensor */ 356 ret = MipiCsiUnresetSensor(MipiCsiHandle, snsResetSource); 357 if (ret != 0) { 358 HDF_LOGE("%s: MipiCsiUnresetSensor fail! ret=%d\n", __func__, ret); 359 return -1; 360 } 361 ``` 362 363#### 复位/撤销复位MIPI RX 364 365- 复位MIPI RX 366 367 ```c 368 int32_t MipiCsiResetRx(DevHandle handle, uint8_t comboDev); 369 ``` 370 371 **表11** MipiCsiResetRx的参数和返回值描述 372 373 | 参数 | 参数描述 | 374 | ---------- | --------------------- | 375 | handle | 控制器操作句柄 | 376 | comboDev | MIPI RX或LVDS通路序号 | 377 | **返回值** | **返回值描述** | 378 | 0 | 复位成功 | 379 | 负数 | 复位失败 | 380 381 ```c 382 int32_t ret; 383 uint8_t comboDev; 384 385 /* 通路序号为0 */ 386 comboDev = 0; 387 /* 复位MIPI RX */ 388 ret = MipiCsiResetRx(MipiCsiHandle, comboDev); 389 if (ret != 0) { 390 HDF_LOGE("%s: MipiCsiResetRx fail! ret=%d\n", __func__, ret); 391 return -1; 392 } 393 ``` 394 395- 撤销复位MIPI RX 396 397 ```c 398 int32_t MipiCsiUnresetRx(DevHandle handle, uint8_t comboDev); 399 ``` 400 401 **表12** MipiCsiUnresetRx的参数和返回值描述 402 403 | 参数 | 参数描述 | 404 | ---------- | --------------------- | 405 | handle | 控制器操作句柄 | 406 | comboDev | MIPI RX或LVDS通路序号 | 407 | **返回值** | **返回值描述** | 408 | 0 | 撤销复位成功 | 409 | 负数 | 撤销复位失败 | 410 411 ```c 412 int32_t ret; 413 uint8_t comboDev; 414 415 /* 通路序号为0 */ 416 comboDev = 0; 417 /* 撤销复位MIPI RX */ 418 ret = MipiCsiUnresetRx(MipiCsiHandle, comboDev); 419 if (ret != 0) { 420 HDF_LOGE("%s: MipiCsiUnresetRx fail! ret=%d\n", __func__, ret); 421 return -1; 422 } 423 ``` 424 425#### 使能/关闭MIPI的时钟 426 427- 使能MIPI的时钟 428 429 ```c 430 int32_t MipiCsiEnableClock(DevHandle handle, uint8_t comboDev); 431 ``` 432 433 **表13** MipiCsiEnableClock的参数和返回值描述 434 435 <a name="table13_MIPI_CSIDes"></a> 436 437 | 参数 | 参数描述 | 438 | ---------- | -------------- | 439 | handle | 控制器操作句柄 | 440 | comboDev | 通路序号 | 441 | **返回值** | **返回值描述** | 442 | 0 | 使能成功 | 443 | 负数 | 使能失败 | 444 445 ```c 446 int32_t ret; 447 uint8_t comboDev; 448 449 /* 通路序号为0 */ 450 comboDev = 0; 451 /* 使能MIPI的时钟 */ 452 ret = MipiCsiEnableClock(MipiCsiHandle, comboDev); 453 if (ret != 0) { 454 HDF_LOGE("%s: MipiCsiEnableClock fail! ret=%d\n", __func__, ret); 455 return -1; 456 } 457 ``` 458 459- 关闭MIPI的时钟 460 461 ```c 462 int32_t MipiCsiDisableClock(DevHandle handle, uint8_t comboDev); 463 ``` 464 465 **表14** MipiCsiDisableClock的参数和返回值描述 466 467 <a name="table14_MIPI_CSIDes"></a> 468 469 | 参数 | 参数描述 | 470 | ---------- | -------------- | 471 | handle | 控制器操作句柄 | 472 | comboDev | 通路序号 | 473 | **返回值** | **返回值描述** | 474 | 0 | 关闭成功 | 475 | 负数 | 关闭失败 | 476 477 ```c 478 int32_t ret; 479 uint8_t comboDev; 480 481 /* 通路序号为0 */ 482 comboDev = 0; 483 /* 关闭MIPI的时钟 */ 484 ret = MipiCsiDisableClock(MipiCsiHandle, comboDev); 485 if (ret != 0) { 486 HDF_LOGE("%s: MipiCsiDisableClock fail! ret=%d\n", __func__, ret); 487 return -1; 488 } 489 ``` 490 491#### 使能/关闭MIPI上的Sensor时钟<a name="section2.7_MIPI_CSIDes"></a> 492 493- 使能MIPI上的Sensor时钟 494 495 ```c 496 int32_t MipiCsiEnableSensorClock(DevHandle handle, uint8_t snsClkSource); 497 ``` 498 499 **表15** MipiCsiEnableSensorClock的参数和返回值描述 500 501 <a name="table15_MIPI_CSIDes"></a> 502 503 | 参数 | 参数描述 | 504 | ------------ | ------------------------------------------------ | 505 | handle | 控制器操作句柄 | 506 | snsClkSource | 传感器的时钟信号线号,在软件中称为传感器的时钟源 | 507 | **返回值** | **返回值描述** | 508 | 0 | 使能成功 | 509 | 负数 | 使能失败 | 510 511 ```c 512 int32_t ret; 513 uint8_t snsClkSource; 514 515 /* 传感器的时钟信号线号为0 */ 516 snsClkSource = 0; 517 /* 使能MIPI上的Sensor时钟 */ 518 ret = MipiCsiEnableSensorClock(MipiCsiHandle, snsClkSource); 519 if (ret != 0) { 520 HDF_LOGE("%s: MipiCsiEnableSensorClock fail! ret=%d\n", __func__, ret); 521 return -1; 522 } 523 ``` 524 525- 关闭MIPI上的Sensor时钟 526 527 ```c 528 int32_t MipiCsiDisableSensorClock(DevHandle handle, uint8_t snsClkSource); 529 ``` 530 531 **表16** MipiCsiDisableSensorClock的参数和返回值描述 532 533 <a name="table16_MIPI_CSIDes"></a> 534 535 | 参数 | 参数描述 | 536 | ------------ | ------------------------------------------------ | 537 | handle | 控制器操作句柄 | 538 | snsClkSource | 传感器的时钟信号线号,在软件中称为传感器的时钟源 | 539 | **返回值** | **返回值描述** | 540 | 0 | 关闭成功 | 541 | 负数 | 关闭失败 | 542 543 ```c 544 int32_t ret; 545 uint8_t snsClkSource; 546 547 /* 传感器的时钟信号线号为0 */ 548 snsClkSource = 0; 549 /* 关闭MIPI上的Sensor时钟 */ 550 ret = MipiCsiDisableSensorClock(MipiCsiHandle, snsClkSource); 551 if (ret != 0) { 552 HDF_LOGE("%s: MipiCsiDisableSensorClock fail! ret=%d\n", __func__, ret); 553 return -1; 554 } 555 ``` 556 557#### 释放MIPI CSI控制器操作句柄<a name="section2.8_MIPI_CSIDes"></a> 558 559MIPI CSI使用完成之后,需要释放控制器操作句柄,释放句柄的函数如下所示: 560 561```c 562void MipiCsiClose(DevHandle handle); 563``` 564 565该函数会释放掉由MipiCsiOpen申请的资源。 566 567**表17** MipiCsiClose的参数和返回值描述 568 569<a name="table17_MIPI_CSIDes"></a> 570 571| 参数 | 参数描述 | 572| ------------ | ------------------------------------------------ | 573| handle | MIPI CSI控制器操作句柄 | 574 575```c 576MipiCsiClose(MIPIHandle); /* 释放掉MIPI CSI控制器操作句柄 */ 577``` 578 579## 使用实例<a name="section3_MIPI_CSIDes"></a> 580 581本例拟对Hi3516DV300开发板上MIPI CSI设备进行操作。 582 583MIPI CSI完整的使用示例如下所示: 584 585```c 586#include "hdf.h" 587#include "MIPI_csi_if.h" 588 589void PalMipiCsiTestSample(void) 590{ 591 uint8_t id; 592 int32_t ret; 593 uint8_t comboDev; 594 uint8_t snsClkSource; 595 uint8_t devno; 596 enum LaneDivideMode mode; 597 enum PhyCmvMode mode; 598 struct ComboDevAttr attr; 599 struct ExtDataType dataType; 600 DevHandle MipiCsiHandle = NULL; 601 602 /* 控制器ID号 */ 603 id = 0; 604 /* 获取控制器操作句柄 */ 605 MipiCsiHandle = MipiCsiOpen(id); 606 if (MipiCsiHandle == NULL) { 607 HDF_LOGE("MipiCsiOpen: failed!\n"); 608 return; 609 } 610 611 /* Lane模式参数为0 */ 612 mode = LANE_DIVIDE_MODE_0; 613 /* 设置MIPI RX的Lane分布 */ 614 ret = MipiCsiSetHsMode(MipiCsiHandle, mode); 615 if (ret != 0) { 616 HDF_LOGE("%s: MipiCsiSetHsMode fail! ret=%d\n", __func__, ret); 617 return; 618 } 619 620 /* 通路序号为0 */ 621 comboDev = 0; 622 /* 使能MIPI的时钟 */ 623 ret = MipiCsiEnableClock(MipiCsiHandle, comboDev); 624 if (ret != 0) { 625 HDF_LOGE("%s: MipiCsiEnableClock fail! ret=%d\n", __func__, ret); 626 return; 627 } 628 629 /* 复位MIPI RX */ 630 ret = MipiCsiResetRx(MipiCsiHandle, comboDev); 631 if (ret != 0) { 632 HDF_LOGE("%s: MipiCsiResetRx fail! ret=%d\n", __func__, ret); 633 return; 634 } 635 636 /* 传感器的时钟信号线号为0 */ 637 snsClkSource = 0; 638 /* 使能MIPI上的Sensor时钟 */ 639 ret = MipiCsiEnableSensorClock(MipiCsiHandle, snsClkSource); 640 if (ret != 0) { 641 HDF_LOGE("%s: MipiCsiEnableSensorClock fail! ret=%d\n", __func__, ret); 642 return; 643 } 644 645 /* 复位Sensor */ 646 ret = MipiCsiResetSensor(MipiCsiHandle, snsResetSource); 647 if (ret != 0) { 648 HDF_LOGE("%s: MipiCsiResetSensor fail! ret=%d\n", __func__, ret); 649 return; 650 } 651 652 /* MIPI参数配置如下 */ 653 (void)memset_s(&attr, sizeof(ComboDevAttr), 0, sizeof(ComboDevAttr)); 654 attr.devno = 0; /* 设备0 */ 655 attr.inputMode = INPUT_MODE_MIPI; /* 输入模式为MIPI */ 656 attr.dataRate = MIPI_DATA_RATE_X1; /* 每时钟输出1像素 */ 657 attr.imgRect.x = 0; /* 0: 图像传感器左上位置 */ 658 attr.imgRect.y = 0; /* 0: 图像传感器右上位置 */ 659 attr.imgRect.width = 2592; /* 2592: 图像传感器宽度大小 */ 660 attr.imgRect.height = 1944; /* 1944: 图像传感器高度尺寸 */ 661 /* 写入配置数据 */ 662 ret = MipiCsiSetComboDevAttr(MipiCsiHandle, &attr); 663 if (ret != 0) { 664 HDF_LOGE("%s: MipiCsiSetComboDevAttr fail! ret=%d\n", __func__, ret); 665 return; 666 } 667 668 /* 共模电压模式参数为0 */ 669 mode = PHY_CMV_GE1200MV; 670 /* 设备编号为0 */ 671 devno = 0; 672 /* 设置共模电压模式 */ 673 ret = MipiCsiSetPhyCmvmode(MipiCsiHandle, devno, mode); 674 if (ret != 0) { 675 HDF_LOGE("%s: MipiCsiSetPhyCmvmode fail! ret=%d\n", __func__, ret); 676 return; 677 } 678 679 /* 通路序号为0 */ 680 comboDev = 0; 681 /* 撤销复位MIPI RX */ 682 ret = MipiCsiUnresetRx(MipiCsiHandle, comboDev); 683 if (ret != 0) { 684 HDF_LOGE("%s: MipiCsiUnresetRx fail! ret=%d\n", __func__, ret); 685 return; 686 } 687 688 /* 关闭MIPI的时钟 */ 689 ret = MipiCsiDisableClock(MipiCsiHandle, comboDev); 690 if (ret != 0) { 691 HDF_LOGE("%s: MipiCsiDisableClock fail! ret=%d\n", __func__, ret); 692 return; 693 } 694 695 /* 传感器撤销复位信号线号为0 */ 696 snsResetSource = 0; 697 /* 撤销复位Sensor */ 698 ret = MipiCsiUnresetSensor(MipiCsiHandle, snsResetSource); 699 if (ret != 0) { 700 HDF_LOGE("%s: MipiCsiUnresetSensor fail! ret=%d\n", __func__, ret); 701 return; 702 } 703 704 /* 关闭MIPI上的Sensor时钟 */ 705 ret = MipiCsiDisableSensorClock(MipiCsiHandle, snsClkSource); 706 if (ret != 0) { 707 HDF_LOGE("%s: MipiCsiDisableSensorClock fail! ret=%d\n", __func__, ret); 708 return; 709 } 710 711 /* 释放MIPI DSI设备句柄 */ 712 MipiCsiClose(MipiCsiHandle); 713} 714``` 715 716