MI PSPI API


REVISION HISTORY

Revision No.
Description
Date
1.00
  • Initial release
  • 09/25/2020
    2.00
  • Initial release
  • 10/27/2022

    1. 概述

    1.1. 模块说明

    通过PSPI从sensor获取图像数据,或将图像数据通过PSPI传输到panel。

    注意:目前sensor只能接PSPI0,panel只能接PSPI1。

    1.2. 流程框图

    芯片可以将PSPI0设置为从机,然后通过PSPI从sensor获取数据,同时搭配有一个BDMA用来将获取到的数据写入内存;

    芯片可以将PSPI1设置为主机,然后通过PSPI将数据发送到panel,内部搭配有一个BDMA用来读取内存中的数据。

    2. API 参考

    2.1. API功能模块

    API名 功能
    MI_PSPI_CreateDevice 创建PSPI设备并配置PSPI属性
    MI_PSPI_DestroyDevice 销毁PSPI设备
    MI_PSPI_Transfer 给PSPI设备发送参数信息,对外部所接设备的参数进行配置
    MI_PSPI_SetDevAttr 设置PSPI属性
    MI_PSPI_SetOutputAttr 设置PSPI输出端口属性
    MI_PSPI_Enable 启用PSPI设备
    MI_PSPI_Disable 禁用PSPI设备

    2.2. MI_PSPI_CreateDevice

    • 描述

      创建PSPI设备并配置其属性。

    • 语法

      MI_S32 MI_PSPI_CreateDevice (MI_PSPI_DEV PspiDev, MI_PSPI_Param_t *pstPspiParam);
      
    • 参数

      参数名称 描述 输入/输出
      PspiDev PSPI具体设备 输入
      pstPspiParam PSPI设备的具体属性 输入
    • 返回值

      • MI_PSPI_SUCCESS:成功。

      • 非MI_PSPI_SUCCESS:失败,具体见错误码

    • 需求

      • 头文件:mi_pspi.h、mi_pspi_datatype.h

      • 库文件:libmi_pspi.a / libmi_pspi.so

    • 注意

      • 同一PSPI设备不能连续创建两次,如果要再修改PSPI的属性,可以通过MI_PSPI_SetDevAttr进行修改。

    2.3. MI_PSPI_DestroyDevice

    • 描述

      销毁PSPI设备。

    • 语法

      MI_S32 MI_PSPI_DestroyDevice(MI_PSPI_DEV PspiDev);
      
    • 参数

      参数名称 描述 输入/输出
      PspiDev 需要销毁的PSPI设备。 输入
    • 返回值

      • MI_PSPI_SUCCESS:成功。

      • 非MI_PSPI_SUCCESS:失败,具体见错误码

    • 需求

      • 头文件:mi_pspi.h、mi_pspi_datatype.h

      • 库文件:libmi_pspi.a / libmi_pspi.so

    2.4. MI_PSPI_Transfer

    • 描述

      给PSPI外部所接设备发送参数信息,对外部所接设备的参数进行配置。

    • 语法

      MI_S32 MI_PSPI_Transfer(MI_PSPI_DEV PspiDev, MI_PSPI_Msg_t *pstMsg)
      
    • 参数

      参数名称 描述 输入/输出
      PspiDev PSPI具体设备 输入
      pstMsg 发送给从机设备的具体参数 输入
    • 返回值

      • MI_PSPI_SUCCESS:成功。

      • 非MI_PSPI_SUCCESS:失败,具体见错误码

    • 需求

      • 头文件:mi_pspi.h、mi_pspi_datatype.h

      • 库文件:libmi_pspi.a / libmi_pspi.so

    • 注意

      • 这个函数是用来通过PSPI向从机发送数据来控制从机的,如使用PSPI点亮panel时,在向panel发送具体的图像数据前需要对panel发送一些控制参数,这些控制参数就可以通过这个函数进行发送。一次性发送参数的数量可以由 mi_pspi_datatype.h 中的 PSPI_ PARAM_BUFF_SIZE 宏来进行控制。

    2.5. MI_PSPI_SetDevAttr

    • 描述

      配置PSPI属性。

    • 语法

      MI_S32 MI_PSPI_SetDevAttr(MI_PSPI_DEV PspiDev, MI_PSPI_Param_t * pstPspiParam);
      
    • 参数

      参数名称 描述 输入/输出
      PspiDev PSPI具体设备 输入
      pstPspiParam 即将要进行配置的具体属性 输入
    • 返回值

      • MI_PSPI_SUCCESS:成功。

      • 非MI_PSPI_SUCCESS:失败,具体见错误码

    • 需求

      • 头文件:mi_pspi.h、mi_pspi_datatype.h

      • 库文件:libmi_pspi.a / libmi_pspi.so

    • 注意

      • 这个函数是用来对PSPI的属性进行修改,如果不需要修改,可不调用。

    2.6. MI_PSPI_SetOutputAttr

    • 描述

      设置PSPI输出端口的属性。

    • 语法

      MI_S32 MI_PSPI_SetOutputAttr(MI_PSPI_OutputAttr_t * pstOutputAttr);
      
    • 参数

      参数名称 描述 输入/输出
      pstOutputAttr 即将要进行配置的属性 输入
    • 返回值

      • MI_PSPI_SUCCESS:成功。

      • 非MI_PSPI_SUCCESS:失败,具体见错误码

    • 需求

      • 头文件:mi_pspi.h、mi_pspi_datatype.h

      • 库文件:libmi_pspi.a / libmi_pspi.so

    • 注意

      • 这个函数是用来对存储sensor 数据的buffer 属性进行设置,在接panel时这个函数无作用。其中sensor的输出通道的默认属性为640 * 480, YUV 422 格式。

    2.7. MI_PSPI_Enable

    • 描述

      启用PSPI设备。

    • 语法

      MI_S32 MI_PSPI_Enable(MI_PSPI_DEV PspiDev);
      
    • 参数

      参数名称 描述 输入/输出
      PspiDev 要启用的PSPI设备 输入
    • 返回值

      • MI_PSPI_SUCCESS:成功。

      • 非MI_PSPI_SUCCESS:失败,具体见错误码

    • 需求

      • 头文件:mi_pspi.h、mi_pspi_datatype.h

      • 库文件:libmi_pspi.a / libmi_pspi.so

    • 注意

      • 在使用mi_sys的相关接口操作PSPI前,必须调用这个函数进行使能。

    2.8. MI_PSPI_Disable

    • 描述

      禁用PSPI设备。

    • 语法

      MI_S32 MI_PSPI_Disable(MI_PSPI_DEV PspiDev);
      
    • 参数

      参数名称 描述 输入/输出
      PspiDev 要禁用的PSPI设备 输入
    • 返回值

      • MI_PSPI_SUCCESS:成功。

      • 非MI_PSPI_SUCCESS:失败,具体见错误码

    • 需求

      • 头文件:mi_pspi.h、mi_pspi_datatype.h

      • 库文件:libmi_pspi.a / libmi_pspi.so

    • 注意

      • 在不需要再使用PSPI时,必须调用这个函数禁用PSPI。

    3. PSPI 数据类型

    3.1. 模块相关数据类型定义

    数据类型 定义
    MI_PSPI_Msg_t 定义传输给外部连接的PSPI设备参数的数据帧
    MI_PSPI_OutputAttr_t 定义PSPI输出端口属性
    MI_PSPI_Param_t 定义PSPI属性
    MI_PSPI_TriggerMode_e 定义PSPI Trigger 模式
    MI_PSPI_Type_e 定义PSPI的设备类型
    MI_PSPI_DEV 定义PSPI的设备编号

    3.2. MI_PSPI_Msg_t

    • 说明

      定义使用PSPI向外部设备传输参数时的数据帧。

    • 定义

      typedef struct MI_PSPI_Msg_s
      {
          MI_U16 u16TxSize;
          MI_U16 u16RxSize;
          MI_U8  u8TxBitCount;
          MI_U8  u8RxBitCount;
          MI_U16 au16TxBuf[PSPI_PARAM_BUFF_SIZE];
          MI_U16 au16RxBuf[PSPI_PARAM_BUFF_SIZE];
      } MI_PSPI_Msg_t;
      
    • 注意事项

      • 每次传输的最大数据个数是由宏 PSPI_PARAM_BUFF_SIZE 来控制的。
    • 成员

      成员名称 描述
      u16TxSize 发送数据数目(MI_U16类型大小)
      u16RxSize 接收数据数目(MI_U16类型大小)
      u8TxBitCount 发送时一次传输的bit数目
      u8RxBitCount 接收时一次传输的bit数目
      au16TxBuf[PSPI_PARAM_BUFF_SIZE] 发送数据缓冲区
      au16RxBuf[PSPI_PARAM_BUFF_SIZE] 接收数据缓冲区
    • 相关数据类型及接口

      MI_PSPI_Transfer

    3.3. MI_PSPI_OutputAttr_t

    • 说明

      定义PSPI输出端口属性。由于只有当PSPI接sensor时才有输出端口,所以这个目前是用来描述所接sensor的属性。

    • 定义

      typedef struct MI_PSPI_OutputAttr_s
      {
          MI_SYS_PixelFormat_e ePixelFormat;
          MI_U16               u16Width;
          MI_U16               u16Height;
      } MI_PSPI_OutputAttr_t;
      
    • 成员

      成员名称 描述
      ePixelFormat 定义sensor输入数据的格式
      u16Width 定义sensor输入图像数据的宽
      u16Height 定义sensor输入图像数据的高
    • 相关数据类型及接口

      MI_PSPI_SetOutputAttr

    3.4. MI_PSPI_Param_t

    • 说明

      定义PSPI属性

    • 定义

      typedef struct MI_PSPI_Param_s
      {
          MI_U32                u32MaxSpeedHz;
          MI_U16                u16DelayCycle; /* cs is inactive*/
          MI_U16                u16WaitCycle;  /* cs is active  */
          MI_U16                u16PspiMode;
          MI_U8                 u8DataLane;    /* cs count      */
          MI_U8                 u8BitsPerWord; /* The number of bitsin an SPI transmission*/
          MI_U8                 u8RgbSwap;     /* for panel     */
          MI_U8                 u8TeMode;      /* for panel     */
          MI_U8                 u8ChipSelect;
          MI_PSPI_Type_e        ePspiType;
          MI_PSPI_TriggerMode_e eTriggerMode;  /* select trigger mode*/
      } MI_PSPI_Param_t;
      
    • 成员

      成员名称 描述 可选值
      u32MaxSpeedHz 最大时钟频率 1000000~54000000
      u16DelayCycle SPI_SSCTL没有设置时,两次传送数据之间的延时 0x0000~0xFFFF,单位为时钟周期
      u16WaitCycle SPI_SSCTL有设置时,两次传送数据之间的延时 0x0000~0xFFFF,单位为时钟周期
      u16PspiMode PSPI模式配置 0:主机模式,MSB,上升沿接收,下降沿发送,片选信号低电平有效,两次数据传送期间片选信号有效。
      SPI_CPHA:上升沿发送,下降沿接收
      SPI_CPOL:上升沿发送,下降沿接收
      SPI_CPHA|SPI_CPOL:上升沿接收,下降沿发送。
      SPI_SLAVE:PSPI作为从机
      SPI_LSB:PSPI LSB先行
      SPI_SSPOL:片选信号极性控制,设置则高电平有效。
      SPI_SSCTL:控制PSPI传送两次数据之间片选信号是否继续保持有效。设置则两次数据传送期间片选信号无效。
      u8DataLane 发送时的数据线条数 DATA_SINGLE:单线
      DATA_DUAL:双线
      DATA_QUAD:四线
      u8BitsPerWord 每次发送的bit数 可以配置为3~32
      u8RgbSwap 给panel发送数据时的格式和数据线条数 RGB_SINGLE:RGB格式,单线发送
      RGB_DUAL:RGB格式,双线发送
      BGR_SINGLE:BGR格式,单线发送
      BGR_DUAL:BGR格式,双向发送
      注意:需要同步配置data_lane
      u8TeMode 是否使用TE模式 1:使用TE模式;0:不使用TE模式
      u8ChipSelect PSPI片选信号 MI_PSPI_SELECT_0; MI_PSPI_SELECT_1
      ePspiType PSPI设备类型 TX or RX
      eTriggerMode PSPI trigger 模式 Auto trigger 或者 Auto+Vsync trigger
    • 相关数据类型及接口

      MI_PSPI_CreateDevice

      MI_PSPI_SetDevAttr

    3.5. MI_PSPI_TriggerMode_e

    • 说明

      定义PSPI trigger 的模式。

    • 定义

      typedef enum
          {
              E_MI_PSPI_TRIGGER_MODE_NA = 0,
              E_MI_PSPI_TRIGGER_MODE_AUTO,
              E_MI_PSPI_TRIGGER_MODE_AUTO_VSYNC,
              E_MI_PSPI_TRIGGER_MODE_MAX,
          } MI_PSPI_TriggerMode_e;
      
    • 注意事项

      1. 在选择Auto+Vsync trigger 模式的时候需要sensor 有Vsync 信号支持。
      2. 在选择Auto trigger 模式的时候会丢掉前两帧的数据。
      3. 默认选择Auto trigger 模式。
    • 相关数据类型及接口

      MI_PSPI_CreateDevice

      MI_PSPI_SetDevAttr

    3.6. MI_PSPI_Type_e

    • 说明

      定义PSPI的设备类型。例如:接senor选择RX;接panel选择TX。

    • 定义

      typedef enum
      {
          E_MI_PSPI_INVALID_TYPE = 0,
          E_MI_PSPI_TYPE_RX      = 1,
          E_MI_PSPI_TYPE_TX      = 2,
          E_MI_PSPI_TYPE_MAX,
      } MI_PSPI_Type_e;
      
    • 注意事项

      默认选择RX。

    • 相关数据类型及接口

      MI_PSPI_CreateDevice

      MI_PSPI_SetDevAttr

    3.7. MI_PSPI_DEV

    4. 程序例程

    4.1. Sensor例程

    int main(int argc, char *argv[])
    {
        int fd = 0
        MI_PSPI_DEV   pspi_dev = 0;
        MI_PSPI_Param_t  pspi_para;
        MI_PSPI_OutputAttr_t stOutputAttr;
        MI_SYS_ChnPort_t stChnPort;
        MI_SYS_BufInfo_t stBufInfo;
        MI_SYS_BUF_HANDLE hSysBuf;
        memset(&stChnPort, 0x0, sizeof(MI_SYS_ChnPort_t));
        memset(&stBufInfo, 0x0, sizeof(MI_SYS_BufInfo_t));
        memset(&hSysBuf, 0x0, sizeof(MI_SYS_BUF_HANDLE));
        memset(&pspi_para, 0x0, sizeof(MI_PSPI_SpiParam_t));
        stChnPort.eModId    = E_MI_MODULE_ID_PSPI;
        stChnPort.u32DevId  = 0;
        stChnPort.u32ChnId  = 0;
        stChnPort.u32PortId = 0;
        stOutputAttr.u16Width   = 1920;
        stOutputAttr.u16Width   = 1080;
        stOutputAttr.ePixelFormat = E_MI_SYS_PIXEL_FRAME_YUV_SEMIPLANAR_420;
        pspi_para.u8BitsPerWord    = 8;
        pspi_para.u8DataLane        = DATA_DUAL;
        pspi_para.u16DelayCycle      = 0;
        pspi_para.u16WaitCycle       = 0;
        pspi_para.u8RgbSwap         = 0;
        pspi_para.u32MaxSpeedHz     = 1000000;
        pspi_para.u16PspiMode         = SPI_SLAVE;
        pspi_para.u8ChipSelect      = MI_PSPI_SELECT_0;
        pspi_para.ePspiType      =  E_MI_PSPI_TYPE_RX;
        pspi_para.eTriggerMode      = E_MI_PSPI_TRIGGER_MODE_AUTO;
        /***
        通过I2C等手段向sensor发送命令
        ***/
        MI_SYS_Init();
        MI_PSPI_CreateDevice(pspi_dev, &pspi_para);
        MI_PSPI_SetOutputAttr(&stOutputAttr);  //修改sensor输入图像的属性
        MI_PSPI_Enable(pspi_dev);//为了减小篇幅去掉了对函数调用的返回值进行判断
        MI_SYS_SetChnOutputPortDepth(&stChnPort,3,4);
    GET_OUT_BUF:
        if (MI_SUCCESS != MI_SYS_ChnOutputPortGetBuf(&stChnPort, &stBufInfo, &hSysBuf))
        {
            goto GET_OUT_BUF;
        }
        fd = open(“picture”, O_RDWR|O_CREAT|O_TRUNC, 0777);
        write(fd, tBufInfo.stFrameData.pVirAddr[0], stBufInfo.stFrameData.u32BufSize));
        sync();
        close(fd);
    PUT_OUT_BUF:
        if (MI_SUCCESS != MI_SYS_ChnOutputPortPutBuf(hSysBuf))
        {
            goto PUT_OUT_BUF;
        }
        MI_SYS_SetChnOutputPortDepth(&stChnPort,0,3);
        MI_PSPI_Disable(pspi_dev);
        MI_PSPI_DestroyDevice(pspi_dev);
        MI_SYS_Exit();
        Return 0;
    }
    

    4.2. Panel例程

    int main(int argc, char *argv[])
    {
        MI_S32 s32Ret = 0;
        MI_U16 * buff = NULL;
        MI_U32 size = 0;
        MI_PSPI_Msg_t  pspi_msg;
        MI_PSPI_Param_t  pspi_para;
        MI_PSPI_DEV   pspi_dev = 1;
        MI_SYS_ChnPort_t  stChnPort;
        MI_SYS_BUF_HANDLE  stHandle;
        MI_SYS_BufInfo_t   stBufInfo;
        MI_SYS_BufConf_t  stBufConf;
        pspi_para.u8BitsPerWord    = 9;
        pspi_para.u8DataLane       = DATA_SINGLE;
        pspi_para.u16DelayCycle    = 2;
        pspi_para.u16WaitCycle     = 2;
        pspi_para.u8RgbSwap        = 0;
        pspi_para.u32MaxSpeedHz    = 1000000;
        pspi_para.u16PspiMode      = 0;
        pspi_para.u8ChipSelect     = MI_PSPI_SELECT_0;
        pspi_para.u8TeMode         = 0;
        MI_PSPI_CreateDevice(pspi_dev, &pspi_para);//为了减小篇幅去掉了对函数调用的返回值进行判断
        memset(&pspi_msg, 0 ,sizeof(MI_PSPI_Msg_t));
        pspi_msg.u8TxBitCount = 9;//可根据panel的不同选择不同的数值
        pspi_msg.u8RxBitCount = 8;
        pspi_msg.u8TxSize = 1;
        //0xDA   //根据panel的型号发送对应的控制命令,视panel型号而定
        pspi_msg.au16TxBuf[0] = 0xDA;
        MI_PSPI_Transfer(pspi_dev,  & pspi_msg);
        /****    向panel发送命令   *****/
        memset(&stChnPort, 0, sizeof(MI_SYS_ChnPort_t));
        memset(&stBufConf, 0, sizeof(MI_SYS_BufConf_t));
        memset(&stBufInfo, 0, sizeof(MI_SYS_BufInfo_t));
        memset(&stHandle, 0, sizeof(MI_SYS_BUF_HANDLE));
        stChnPort.eModId = E_MI_MODULE_ID_PSPI;
        stChnPort.u32DevId = 1;
        stChnPort.u32ChnId = 0;
        stChnPort.u32PortId = 0;
        stBufConf.eBufType = E_MI_SYS_BUFDATA_FRAME;
        stBufConf.stFrameCfg.u16Height = 240;
        stBufConf.stFrameCfg.u16Width  = 320;//这些参数视情况而定
        stBufConf.stFrameCfg.eFrameScanMode = E_MI_SYS_FRAME_SCAN_MODE_PROGRESSIVE;
        stBufConf.stFrameCfg.eFormat    = E_MI_SYS_PIXEL_FRAME_RGB565;
        MI_PSPI_Enable(pspi_dev);
        while(1)
        {
            getBuff1:
            if (MI_SYS_ChnInputPortGetBuf(&stChnPort,&stBufConf,&stBufInfo,&stHandle,4000)!= MI_SUCCESS)
            {
                printf("get input port buf red failed\n");
                goto getBuff1;
            }
            else
            {
                printf("MI_SYS_ChnInputPortGetBuf success 1\n");
                buff =  (MI_U16 *)stBufInfo.stFrameData.pVirAddr[0];
                size = stBufInfo.stFrameData.u32BufSize/2;
                for(i = 0; i < size ; i++)
                {
                    buff[i] = 0xf800;
                }
            putbuff1:
                if(MI_SYS_ChnInputPortPutBuf(stHandle, &stBufInfo, FALSE) != MI_SUCCESS)
                {
                    printf("writter frame err 1\n");
                    goto putbuff1;
                }
                else
                    printf("written a frame red to screen success\n");
            }
        }
    }
    

    5. 错误码

    PSPI API 错误码如下表所示:

    错误代码 宏定义 描述
    0xA02B201F MI_PSPI_FAIL 函数运行失败
    0xA02B2003 MI_ERR_PSPI_ILLEGAL_PARAM 传入非法的、不恰当的参数
    0xA02B2006 MI_ERR_PSPI_NULL_PTR 传入空指针
    0xA02B200C MI_ERR_PSPI_NO_MEM 申请内存失败
    0xA02B2010 MI_ERR_PSPI_SYS_NOTREADY SYS未就绪
    0xA02B2015 MI_ERR_PSPI_DEV_NOT_INIT 设备未初始化
    0xA02B2016 MI_ERR_PSPI_DEV_HAVE_INITED 设备已初始化
    0xA02B2017 MI_ERR_PSPI_NOT_ENABLE 设备未使能

    6. PROCFS介绍

    6.1. Pspi cat

    • 调试信息

      # cat /proc/mi_modules/mi_pspi/mi_pspi0
      

    • 调试信息分析

      记录当前PSPI的使用状况以及Irq(中断)属性、device属性、设备参数属性,可以动态地获取到这些信息,方便调试和测试。

    • 参数说明

      参数 描述
      Irq Info IrqNum 中断号
      IrqCnt 产生中断次数
      IrqCnt/Ms 在一定时间内的中断发生次数,单位是毫秒
      Ips 每秒中断发生的次数
      MasIv/MinIv 一定时间内已完成Task的最大与最小间隔时间,单位是微秒
      Dev Info DevId 设备号
      DevEnable 设备是否使能
      ReadyTaskCnt 预先分配Task数量
      EnqueTaskCnt 每秒中断发生的次数
      FinishTaskCnt 完成Task数量
      DropTaskCnt 丢弃Task数量
      BindStatus 绑定状态
      DevType 设备类型
      UseMode 当前使用的trigger模式
      Attrbute ChipSelect PSPI片选信号
      Te_mode 设备是否使能TE模式
      Bit_per_word 每次发送的bit数
      rgb_swap 给panel发送数据时的格式和数据线条数
      data_lane 发送数据时数据线条数
      delay_cycle SPI_SSCTL没有设置时,两次传送数据之间的延时
      wait_cycle SPI_SSCTL有设置时,两次传送数据之间的延时
      spi_mode 设备模式
      Max_speed_hz 最大时钟频率

    6.2. Pspi echo

    功能
    获取当前PSPI所支持的echo命令及其具体使用形式
    命令 echo help > /proc/mi_modules/mi_pspi/mi_pspi0
    参数说明
    举例 echo help > /proc/mi_modules/mi_pspi/mi_pspi0
    功能
    dump frame data
    命令 echo dumpframe [path] > /proc/mi_modules/mi_pspi/mi_pspi0
    参数说明 [path] dump出来的数据的存储路径
    举例 echo dumpframe /mnt/pspiSensorData > /proc/mi_modules/mi_pspi/mi_pspi0