MIPI CSI

Overview

Defined by the Mobile Industry Processor Interface (MIPI) Alliance, the Camera Serial Interface (CSI) is a specification that allows data to be transmitted from the camera to the host processor on mobile platforms. As the second release, the MIPI CSI-2 consists of the application layer, protocol layer, and physical layer. It supports a maximum of four-lane data transmission and a single-lane transmission rate of 1 Gbit/s.

The physical layer supports the high speed (HS) and low speed (LS) modes. Using low-voltage differential signaling (LVDS), the HS mode delivers 80 Mbit/s to 1 Gbit/s transmission speed but high power consumption. The unidirectional LS mode provides lower power consumption but lower transmission speed (< 10 Mbit/s). The blend of the two modes ensures high-speed transmission of massive data (such as images) and minimized power consumption when less data is transmitted.

The figure below shows a simplified CSI. The D-PHY transmits data by using one pair of source-synchronized differential clocks and one to four pairs of differential data lanes. Data is transmitted in Double Data Rate (DDR) mode, that is, data is transmitted on both the rising and falling edges of the clock.

Figure 1 CSI TX and RX interfaces

ComboDevAttr Structure

Table 1 ComboDevAttr structure

Name Description
devno Device number.
inputMode Input mode, which can be MIPI, LVDS, sub-LVDS, HiSPI, or DC.
dataRate Input rate of the MIPI RX scalable low voltage signaling (SLVS).
imgRect Crop area of the MIPI RX device (same as the size of the input image of the sensor).
MIPIAttr Attributes of the MIPI device.
lvdsAttr Attributes of the LVDS, sub-LVDS, or HiSPi device.

ExtDataType Structure

Table 2 ExtDataType structure

Name Description
devno Device number.
num Sensor number.
extDataBitWidth Bit depth of an image.
extDataType Pointer to the YUV, raw data format, and bit depth.

Available APIs

Table 3 MIPI CSI APIs

Category API
Opening or closing the MIPI CSI controller operation handle MipiCsiOpen: opens the MIPI CSI controller operation handle.
MipiCsiClose: closes the MIPI CSI controller operation handle.
Setting MIPI CSI attributes MipiCsiSetComboDevAttr: sets attributes of the MIPI, CMOS, or LVDS camera to the controller. The attributes include the working mode, image area, image depth, data rate, and physical channel.
MipiCsiSetExtDataType (optional): sets the YUV and RAW data formats and bit depths.
MipiCsiSetHsMode: sets the MIPI RX lane distribution. Set the mode based on the hardware connection.
MipiCsiSetPhyCmvmode: sets the common-mode voltage (CMV) mode.
Resetting a sensor or deasserting the reset of a sensor MipiCsiResetSensor: resets a sensor.
MipiCsiUnresetSensor: deasserts the reset of a sensor.
Resetting the MIPI RX or deasserting the reset of the MIPI RX MipiCsiResetRx: resets the MIPI&nbsp;RX. The value of enSnsType varies depending on the value of s32WorkingViNum.
MipiCsiUnresetRx: deasserts the reset on the MIPI&nbsp;RX.
Enabling or disabling the MIPI clock MipiCsiEnableClock: enables the MIPI clock. The enSnsType passed by the upper-layer function during electrophoresis determines whether MIPI or LVDS is used.
MipiCsiDisableClock: disables the MIPI clock.
Enabling or disabling the MIPI sensor clock MipiCsiEnableSensorClock: enables the MIPI sensor clock.
MipiCsiDisableSensorClock: disables the MIPI sensor clock.

Usage Guidelines

How to Use

The figure below illustrates the general development process.

Figure 2 Using MIPI CSI driver APIs

Opening a MIPI CSI Controller Operation Handle

Before starting MIPI CSI communication, call MipiCsiOpen to open the MIPI CSI device handle. This function returns the MIPI CSI device handle with the specified lane ID.

DevHandle MipiCsiOpen(uint8_t id);

Table 4 Description of MipiCsiOpen

Parameter Description
id MIPI CSI lane ID.
Return Value Description
NULL The operation failed.
Device handle The operation is successful. The MIPI CSI device handle with the specified lane ID is returned. The data type is DevHandle.

For example, open the controller operation handle of MIPI CSI lane 0:

DevHandle mipiCsiHandle = NULL;  /* Device handle */
id = 0; /* MIPI CSI lane ID */

/* Open the controller operation handle. */
MipiCsiHandle = MipiCsiOpen(id);
if (MipiCsiHandle == NULL) {
    HDF_LOGE("MipiCsiOpen: failed\n");
    return;
}

Setting MIPI CSI Attributes

  • Set MIPI CSI attributes.

    int32_t MipiCsiSetComboDevAttr(DevHandle handle, ComboDevAttr *pAttr);
    

    Table 5 Description of MipiCsiSetComboDevAttr

Parameter Description
handle Controller operation handle.
pAttr Pointer to the MIPI CSI structure.
Return Value Description
0 The operation is successful.
Negative value The operation failed.
```c
int32_t ret;
struct ComboDevAttr attr;

/* The current configuration is as follows: */
(void)memset_s(&attr, sizeof(ComboDevAttr), 0, sizeof(ComboDevAttr));
attr.devno = 0; /* Device 0 */
attr.inputMode = INPUT_MODE_MIPI; /* The input mode is MIPI. */
attr.dataRate = MIPI_DATA_RATE_X1; /* The data rate is 1 pixel per clock cycle. */
attr.imgRect.x = 0; /* The value 0 indicates the upper left position of the image sensor. */
attr.imgRect.y = 0; /* The value 0 indicates the upper right position of the image sensor. */
attr.imgRect.width = 2592; /* The width of the image sensor is 2592. */
attr.imgRect.height = 1944; /* The height of the image sensor is 1944. */
/* Write the MIPI CSI configuration. */
ret = MipiCsiSetComboDevAttr(MipiCsiHandle, &attr);
if (ret != 0) {
    HDF_LOGE("%s: MipiCsiSetComboDevAttr fail! ret=%d\n", __func__, ret);
    return -1;
}
```
  • Set the YUV, RAW data format, and bit depth.

    int32_t MipiCsiSetExtDataType(DevHandle handle, ExtDataType* dataType);
    

    Table 6 Description of MipiCsiSetExtDataType

Parameter Description
handle Controller operation handle.
dataType Pointer to the YUV, raw data format, and bit depth.
Return Value Description
0 The operation is successful.
Negative value The operation failed.
```c
int32_t ret;
struct ExtDataType dataType;

/* Set the YUV, raw data format, and bit depth. */
dataType.devno = 0; /* Device 0 */
dataType.num = 0;   /* sensor 0 */
dataType.extDataBitWidth[0] = 12; /* Bit depth array element 0 */
dataType.extDataBitWidth[1] = 12; /* Bit depth array element 1 */
dataType.extDataBitWidth[2] = 12; /* Bit depth array element 2 */

dataType.extDataType[0] = 0x39; /* Define YUV, raw data format, and bit depth element 0. */
dataType.extDataType[1] = 0x39; /* Define YUV, raw data format, and bit depth element 1. */
dataType.extDataType[2] = 0x39; /* Define YUV, raw data format, and bit depth element 2. */
/* Set the YUV, raw data format, and bit depth. */
ret = MipiCsiSetExtDataType(MipiCsiHandle, &dataType);
if (ret != 0) {
    HDF_LOGE("%s: MipiCsiSetExtDataType fail! ret=%d\n", __func__, ret);
    return -1;
}
```
  • Set the MIPI RX lane distribution.

    int32_t MipiCsiSetHsMode(DevHandle handle, LaneDivideMode laneDivideMode);
    

    Table 7 Description of MipiCsiSetHsMode

Parameter Description
handle Controller operation handle.
laneDivideMode Lane mode.
Return Value Description
0 The operation is successful.
Negative value The operation failed.
```c
int32_t ret;
enum LaneDivideMode mode;

/* Set the lane mode to 0. */
mode = LANE_DIVIDE_MODE_0;
/* Set the MIPI RX lane distribution. */
ret = MipiCsiSetHsMode(MipiCsiHandle, mode);
if (ret != 0) {
    HDF_LOGE("%s: MipiCsiSetHsMode fail! ret=%d\n", __func__, ret);
    return -1;
}
```
  • Set the CMV mode.

    int32_t MipiCsiSetPhyCmvmode(DevHandle handle, uint8_t devno, PhyCmvMode cmvMode);
    

    Table 8 Description of MipiCsiSetPhyCmvmode

Parameter Description
handle Controller operation handle.
cmvMode CMV mode.
devno Device number.
Return Value Description
0 The operation is successful.
Negative value The operation failed.
```c
int32_t ret;
enum PhyCmvMode mode;
uint8_t devno;

/* Set the CMV mode to 0. */
mode = PHY_CMV_GE1200MV;
/* The device number is 0. */
devno = 0;
/* Set the CMV mode. */
ret = MipiCsiSetPhyCmvmode(MipiCsiHandle, devno, mode);
if (ret != 0) {
    HDF_LOGE("%s: MipiCsiSetPhyCmvmode fail! ret=%d\n", __func__, ret);
    return -1;
}
```

Resetting a Sensor or Deasserting the Reset of a Sensor

  • Reset a sensor.

    int32_t MipiCsiResetSensor(DevHandle handle, uint8_t snsResetSource);
    

    Table 9 Description of MipiCsiResetSensor

Parameter Description
handle Controller operation handle.
snsResetSource Sensor's reset signal cable number, which is called "sensor reset source" in software.
Return Value Description
0 The operation is successful.
Negative value The operation failed.
```c
int32_t ret;
uint8_t snsResetSource;

/* The sensor's reset signal cable number is 0. */
snsResetSource = 0;
/* Reset the sensor. */
ret = MipiCsiResetSensor(MipiCsiHandle, snsResetSource);
if (ret != 0) {
    HDF_LOGE("%s: MipiCsiResetSensor fail! ret=%d\n", __func__, ret);
    return -1;
}
```
  • Deassert the reset of a sensor.

    int32_t MipiCsiUnresetSensor(DevHandle handle, uint8_t snsResetSource);
    

    Table 10 Description of MipiCsiUnresetSensor

Parameter Description
handle Controller operation handle.
snsResetSource Sensor's reset signal cable number, which is called "sensor reset source" in software.
Return Value Description
0 The operation is successful.
Negative value The operation failed.
```c
int32_t ret;
uint8_t snsResetSource;

/* The sensor's reset signal cable number is 0. */
snsResetSource = 0;
/* Deassert the reset of the sensor. */
ret = MipiCsiUnresetSensor(MipiCsiHandle, snsResetSource);
if (ret != 0) {
    HDF_LOGE("%s: MipiCsiUnresetSensor fail! ret=%d\n", __func__, ret);
    return -1;
}
```

Resetting the MIPI RX or Deasserting the Reset of the MIPI RX

  • Reset the MIPI RX.

    int32_t MipiCsiResetRx(DevHandle handle, uint8_t comboDev);
    

    Table 11 Description of MipiCsiResetRx

Parameter Description
handle Controller operation handle.
comboDev MIPI RX or LVDS channel number.
Return Value Description
0 The operation is successful.
Negative value The operation failed.
```c
int32_t ret;
uint8_t comboDev;

/* The channel number is 0.*/
comboDev = 0;
/* Reset the MIPI RX. */
ret = MipiCsiResetRx(MipiCsiHandle, comboDev);
if (ret != 0) {
    HDF_LOGE("%s: MipiCsiResetRx fail! ret=%d\n", __func__, ret);
    return -1;
}
```
  • Deassert the reset of the MIPI RX.

    int32_t MipiCsiUnresetRx(DevHandle handle, uint8_t comboDev);
    

    Table 12 Description of MipiCsiUnresetRx

Parameter Description
handle Controller operation handle.
comboDev MIPI RX or LVDS channel number.
Return Value Description
0 The operation is successful.
Negative value The operation failed.
```c
int32_t ret;
uint8_t comboDev;

/* The channel number is 0.*/
comboDev = 0;
/* Deassert the reset of the MIPI RX. */
ret = MipiCsiUnresetRx(MipiCsiHandle, comboDev);
if (ret != 0) {
    HDF_LOGE("%s: MipiCsiUnresetRx fail! ret=%d\n", __func__, ret);
    return -1;
}
```

Enabling or Disabling the MIPI Clock

  • Enable the MIPI clock.

    int32_t MipiCsiEnableClock(DevHandle handle, uint8_t comboDev);
    

    Table 13 Description of MipiCsiEnableClock

Parameter Description
handle Controller operation handle.
comboDev Channel number.
Return Value Description
0 The operation is successful.
Negative value The operation failed.
```c
int32_t ret;
uint8_t comboDev;

/* The channel number is 0.*/
comboDev = 0;
/* Enable the MIPI clock. */
ret = MipiCsiEnableClock(MipiCsiHandle, comboDev);
if (ret != 0) {
    HDF_LOGE("%s: MipiCsiEnableClock fail! ret=%d\n", __func__, ret);
    return -1;
}
```
  • Disable the MIPI clock.

    int32_t MipiCsiDisableClock(DevHandle handle, uint8_t comboDev);
    

    Table 14 Description of MipiCsiDisableClock

Parameter Description
handle Controller operation handle.
comboDev Channel number.
Return Value Description
0 The operation is successful.
Negative value The operation failed.
```c
int32_t ret;
uint8_t comboDev;

/* The channel number is 0.*/
comboDev = 0;
/* Disable the MIPI clock. */
ret = MipiCsiDisableClock(MipiCsiHandle, comboDev);
if (ret != 0) {
    HDF_LOGE("%s: MipiCsiDisableClock fail! ret=%d\n", __func__, ret);
    return -1;
}
```

Enabling or Disabling the MIPI Sensor Clock

  • Enable the MIPI sensor clock.

    int32_t MipiCsiEnableSensorClock(DevHandle handle, uint8_t snsClkSource);
    

    Table 15 Description of MipiCsiEnableSensorClock

Parameter Description
handle Controller operation handle.
snsClkSource Sensor's clock signal cable number, which is called clock source of the sensor in software.
Return Value Description
0 The operation is successful.
Negative value The operation failed.
```c
int32_t ret;
uint8_t snsClkSource;

/* The sensor's clock signal cable number is 0. */
snsClkSource = 0;
/* Enable the MIPI sensor clock. */
ret = MipiCsiEnableSensorClock(MipiCsiHandle, snsClkSource);
if (ret != 0) {
    HDF_LOGE("%s: MipiCsiEnableSensorClock fail! ret=%d\n", __func__, ret);
    return -1;
}
```
  • Disable the MIPI sensor clock.

    int32_t MipiCsiDisableSensorClock(DevHandle handle, uint8_t snsClkSource);
    

    Table 16 Description of MipiCsiDisableSensorClock

Parameter Description
handle Controller operation handle.
snsClkSource Sensor's clock signal cable number, which is called clock source of the sensor in software.
Return Value Description
0 The operation is successful.
Negative value The operation failed.
```c
int32_t ret;
uint8_t snsClkSource;

/* The sensor's clock signal cable number is 0. */
snsClkSource = 0;
/* Disable the MIPI sensor clock. */
ret = MipiCsiDisableSensorClock(MipiCsiHandle, snsClkSource);
if (ret != 0) {
    HDF_LOGE("%s: MipiCsiDisableSensorClock fail! ret=%d\n", __func__, ret);
    return -1;
}
```

Closing a MIPI CSI Controller Operation Handle

Call MipiCsiClose() to close the MIPI CSI controller handle after the MIPI CSI communication is complete.

void MipiCsiClose(DevHandle handle);

This function releases the resources requested by MipiCsiOpen.

Table 17 Description of MipiCsiClose

Parameter Description
handle MIPI CSI controller operation handle.
MipiCsiClose(MIPIHandle); /* Close the operation handle of the MIPI CSI controller. */

Example

The sample code is as follows:

#include "hdf.h"
#include "MIPI_csi_if.h"

void PalMipiCsiTestSample(void)
{
    uint8_t id;
    int32_t ret;
    uint8_t comboDev;
    uint8_t snsClkSource;
    uint8_t devno;
    enum LaneDivideMode mode;
    enum PhyCmvMode mode;
    struct ComboDevAttr attr;
    struct ExtDataType dataType;
    DevHandle MipiCsiHandle = NULL;
    
    /* Controller ID */
    id = 0; 
    /* Open the controller operation handle. */
    MipiCsiHandle = MipiCsiOpen(id);
    if (MipiCsiHandle == NULL) {
        HDF_LOGE("MipiCsiOpen: failed!\n");
        return;
    }
    
    /* Set the lane mode to 0. */
    mode = LANE_DIVIDE_MODE_0;
    /* Set the MIPI RX lane distribution. */
    ret = MipiCsiSetHsMode(MipiCsiHandle, mode);
    if (ret != 0) {
        HDF_LOGE("%s: MipiCsiSetHsMode fail! ret=%d\n", __func__, ret);
        return;
    }

    /* The channel number is 0.*/
    comboDev = 0;
    /* Enable the MIPI clock. */
    ret = MipiCsiEnableClock(MipiCsiHandle, comboDev);
    if (ret != 0) {
        HDF_LOGE("%s: MipiCsiEnableClock fail! ret=%d\n", __func__, ret);
        return;
    }
    
    /* Reset the MIPI RX. */
    ret = MipiCsiResetRx(MipiCsiHandle, comboDev);
    if (ret != 0) {
        HDF_LOGE("%s: MipiCsiResetRx fail! ret=%d\n", __func__, ret);
        return;
    }

    /* The sensor's clock signal cable number is 0. */
    snsClkSource = 0;
    /* Enable the MIPI sensor clock. */
    ret = MipiCsiEnableSensorClock(MipiCsiHandle, snsClkSource);
    if (ret != 0) {
        HDF_LOGE("%s: MipiCsiEnableSensorClock fail! ret=%d\n", __func__, ret);
        return;
    }
    
    /* Reset the sensor. */
    ret = MipiCsiResetSensor(MipiCsiHandle, snsResetSource);
    if (ret != 0) {
        HDF_LOGE("%s: MipiCsiResetSensor fail! ret=%d\n", __func__, ret);
        return;
    }
    
    /* Set MIPI parameters. */
    (void)memset_s(&attr, sizeof(ComboDevAttr), 0, sizeof(ComboDevAttr));
    attr.devno = 0; /* Device 0 */
    attr.inputMode = INPUT_MODE_MIPI; /* The input mode is MIPI. */
    attr.dataRate = MIPI_DATA_RATE_X1; /* The data rate is 1 pixel per clock cycle. */
    attr.imgRect.x = 0; /* The value 0 indicates the upper left position of the image sensor. */
    attr.imgRect.y = 0; /* The value 0 indicates the upper right position of the image sensor. */
    attr.imgRect.width = 2592; /* The width of the image sensor is 2592. */
    attr.imgRect.height = 1944; /* The height of the image sensor is 1944. */
    /* Write the MIPI CSI configuration. */
    ret = MipiCsiSetComboDevAttr(MipiCsiHandle, &attr);
    if (ret != 0) {
        HDF_LOGE("%s: MipiCsiSetComboDevAttr fail! ret=%d\n", __func__, ret);
        return;
    }
    
    /* Set the CMV mode to 0. */
    mode = PHY_CMV_GE1200MV;
    /* The device number is 0. */
    devno = 0;
    /* Set the CMV mode. */
    ret = MipiCsiSetPhyCmvmode(MipiCsiHandle, devno, mode);
    if (ret != 0) {
        HDF_LOGE("%s: MipiCsiSetPhyCmvmode fail! ret=%d\n", __func__, ret);
        return;
    }
    
    /* The channel number is 0.*/
    comboDev = 0;
    /* Deassert the reset of the MIPI RX. */
    ret = MipiCsiUnresetRx(MipiCsiHandle, comboDev);
    if (ret != 0) {
        HDF_LOGE("%s: MipiCsiUnresetRx fail! ret=%d\n", __func__, ret);
        return;
    }
    
    /* Disable the MIPI clock. */
    ret = MipiCsiDisableClock(MipiCsiHandle, comboDev);
    if (ret != 0) {
        HDF_LOGE("%s: MipiCsiDisableClock fail! ret=%d\n", __func__, ret);
        return;
    }
    
    /* The sensor's reset signal cable number is 0. */
    snsResetSource = 0;
    /* Deassert the reset of the sensor. */
    ret = MipiCsiUnresetSensor(MipiCsiHandle, snsResetSource);
    if (ret != 0) {
        HDF_LOGE("%s: MipiCsiUnresetSensor fail! ret=%d\n", __func__, ret);
        return;
    }
    
    /* Disable the MIPI sensor clock. */
    ret = MipiCsiDisableSensorClock(MipiCsiHandle, snsClkSource);
    if (ret != 0) {
        HDF_LOGE("%s: MipiCsiDisableSensorClock fail! ret=%d\n", __func__, ret);
        return;
    }
    
    /* Close the MIPI CSI device handle. */
    MipiCsiClose(MipiCsiHandle); 
}