MI PSPI API


REVISION HISTORY

Revision No.
Description
Date
1.00
  • Initial release
  • 25/09/2020
    2.00
  • 完善概述说明
  • 18/04/2025

    1. 概述

    1.1. 模块说明

    PSPI基于SPI通信协议,为实现Sensor和Panel间的通信而设计。

    PSPI作为Slave时,可与Sensor通信,Vsync是Sensor给PSPI的指示信号,表示Sensor已经准备好发送一帧图像,其有效信号为高电平。

    PSPI作为Master时,可与Panel通信,Te是Panel给PSPI的指示信号,表示Panel已经开始将所有内部buffer刷新到显示屏上,其有效信号为高电平。

    1.2. 基本结构

    PSPI目前没有与MI其他模块对接,功能实现主要通过应用层的开发。

    当硬件接上Pannel时,Pannel的初始化由应用层调用函数MI_PSPI_Transfer()传入屏参实现,之后应用层不断传入图片数据到PSPI Master;

    当硬件接上Sensor时,Sensor的初始化由应用层调用函数MI_PSPI_Enable()实现,会触发sensor已设定好的init flow,之后通过PSPI Slave获取sensor数据。

    1.3. 功能介绍

    • 支持SPI时钟(SCLK)的极性和相位配置

    • 支持片选(SS)信号的极性切换

    • 单次传输字长可选3~32Bit

    • 允许片选 (SS) 信号在字传输之间保持有效

    • 支持FIFO模式和DMA模式

    • 支持通过BDMA在DMA模式下进行双通道/四通道模式读写

    • 支持在DMA模式下对RGB565和BRG565进行单通道/双通道写入

    • 支持TE信号和VSYNC信号的接收

    • 支持跳过TE信号次数,次数可选0到15

    • 支持TE信号的极性切换

    1.4. 应用场景

    PSPI可应用于以下场景:

    1. Pure linux场景

      在linux环境下基于PSPI提供的API接口进行开发

    1.5. 芯片差异

    PSPI在不同芯片上的差异主要表现在不同的PAD MODE设定影响不同的通讯功能,以下列表中1表示支持,0表示不支持

    本文的所描述芯片为Pcupid

    1.5.1. Ikayaki

    CHIP PAD MODE MODE INDEX 3wire mode 4wire mode dual mod equal mod master tx master rx slave tx slave rx
    Ikayaki reg_pspi0_g_mode mode 1 1 0 0 0 1 1 1 1
    mode 2 1 0 1 1 1 1 1 1
    reg_pspi0_sr_mode mode 1 1 0 1 1 1 0 0 1
    mode 2 1 0 1 1 1 0 0 1
    mode 3 1 0 1 0 1 0 0 1
    mode 4 1 0 1 0 1 0 0 1
    mode 5 1 0 0 0 1 0 0 1
    mode 6 1 0 0 0 1 0 0 1
    reg_pspi1_g_mode mode 1 1 0 0 0 1 1 1 1
    mode 2 1 0 1 1 1 1 1 1
    reg_pspi1_pl_mode mode 1 1 0 1 0 1 0 0 1
    mode 2 1 0 1 0 1 0 0 1
    mode 3 1 0 1 0 1 0 0 1
    mode 4 1 0 1 0 1 0 0 1
    mode 5 1 0 1 0 1 0 0 1
    mode 6 1 0 0 0 1 0 0 1

    1.5.2. Opera

    CHIP PAD MODE MODE INDEX 3wire mode 4wire mode dual mod equal mod master tx master rx slave tx slave rx
    Opera reg_pspi0_g_mode mode 1 1 0 1 1 1 1 1 1
    reg_pspi0_sensor_mode mode 1 1 0 1 0 1 0 0 1
    mode 2 1 0 1 1 1 0 0 1
    mode 3 1 0 0 0 1 0 0 1
    reg_pspi1_g_mode mode 1 1 0 1 1 1 1 1 1
    reg_pspi0_pannel_mode mode 1 1 0 1 0 1 0 0 1
    mode 2 1 0 1 0 1 0 0 1

    1.5.3. Pcupid

    CHIP PAD MODE MODE INDEX 3wire mode 4wire mode dual mod equal mod master tx master rx slave tx slave rx
    Pcupid reg_pspi0_g_mode mode 1 1 1 1 1 1 1 1 1
    reg_pspi0_mode mode 1 1 0 1 1 1 0 1 1
    mode 2 1 0 1 1 1 0 1 1
    mode 3 1 0 1 0 1 0 1 1
    mode 4 1 0 1 0 1 0 1 1
    mode 5 1 0 0 0 1 0 1 1
    reg_pspi1_g_mode mode 1 1 1 1 1 1 1 1 1
    reg_pspi1_mode mode 1 1 0 1 0 1 0 1 1
    mode 2 1 0 1 0 1 0 1 1
    mode 3 1 1 0 0 1 1 1 1
    mode 4 1 0 1 1 1 0 1 1
    mode 5 1 0 1 1 1 1 1 0

    1.6. 工作原理

    PSPI基于SPI通信协议,因此SPI通信特性都具备,本质也是数据的收发,因此仅说明PSPI特殊的通信模式

    1.6.1. TE Mode

    一般Pannel都可以通过操作TE Line On/Off命令动态启停同步信号,PSPI可以接收到TE信号用作信号同步,防止画面撕裂。

    除此之外PSPI支持跳过 0~15 个TE信号,以便在TE信号触发时延迟启动 PSPI。

    例如:如果将跳过次数设置为2,PSPI每次接收一个TE信号后,后续两个TE信号会被跳过。

    1.6.2. Quad/Dual Mode Read Data Format

    PSPI支持Quad Mode/Dual Mode下的位顺序反转

    Quad Mode常规读取如下所示:

    Quad Mode位顺序反转读取如下所示:

    Duad Mode常规读取如下所示:

    Duad Mode位顺序反转读取如下所示:

    1.7. 开发流程

    1.7.1. 编译配置

    默认KO

    选择defconfig,进入project目录,make menuconfig打开MI_PSPI

    Sdk Config-->
        [*] Interface Compile Config -->
            [*] pspi -->
                [*] nhal_pspi
                [*] mi_pspi
                (bf3901.ko gc032a.ko) PSPIDEV List
                (bf3901.ko) PSPIDEV0
                (pspi_id=1 pspi_slave=0x6e) PSPIDEV0 Opt
    

    编译并成功烧录后,启动时会自动加载mi_pspi.ko模块和pspi device模块

    PSPIDEV List:选择pspi device,源码位于sdk/driver/PspiDriver/drv目录下,比如bf301型号的sensor,源码命名为drv_pspi_bf3901.c,加入List后,会编译生成bf3901.ko

    PSPIDEV0:选择成功烧录启动后自动insmod的pspi device模块,按照上述的内容,启动后程序会先insmod mi_pspi.ko然后再insmod drv_pspi_bf3901.ko

    PSPIDEV0 Opt:选择insmod device ko时的传入参数,pspi_id=1说明将bf3901与pspi bus1绑定,pspi_slave=0x6e填入此sensor的slave address = 0x6e

    自定义KO

    在目录sdk/driver/PspiDriver/drv下添加文件,命名方式固定为drv_pspi_xxx.ko,其中xxx为设备型号,可参考drv_pspi_bf3901.c,完善xxx_linerPSPI_SENSOR_InitTable两部分结构体信息即可

    bf3901_linear描述sensor的pixel array和fps

    static struct {
        struct _senout{
            s32 width, height, min_fps, max_fps;
        }senout;
    
        struct _senstr{
            const char* strResDesc;
        }senstr;
    
    }bf3901_linear[] = {
        { {240, 320, 0, 30}, {"240x320@30fps"}},
    };
    

    PSPI_SENSOR_InitTable按寄存器和数值的格式填充sensor初始化命令,如果设定某个寄存器后需要delay一段时间,可将数值填写成0xffff

    const static IIC_ARRAY_t PSPI_SENSOR_InitTable[] =
    {
        {0x12, 0x80},
        {0x11, 0xb0},
        {0x1b, 0x80},
        {0x6b, 0x01},
        {0x12, 0x20},
        {0x3a, 0x00},
        ......
        {0x13, 0x05},
        {0x6a, 0x81},
        {0x23, 0x00},
        {0x01, 0x08},
        {0x02, 0x08},
    };
    

    1.7.2. PADMUX配置

    以PSPI0连接Sensor为例:

    进入kernel/driver/arch/arm64/boot/dts/sstar/chipname-xxx-padmux.dtsi,配置PSPI0 MODE1

    <PAD_OUTP_RX0_CH0        PINMUX_FOR_PSPI0_MODE_1          MDRV_PUSE_PSPI1_CS>,
    <PAD_OUTN_RX0_CH0        PINMUX_FOR_PSPI0_MODE_1          MDRV_PUSE_PSPI1_VSYNC>,
    <PAD_OUTP_RX0_CH1        PINMUX_FOR_PSPI0_MODE_1          MDRV_PUSE_PSPI1_CLK>,
    <PAD_OUTN_RX0_CH1        PINMUX_FOR_PSPI0_MODE_1          MDRV_PUSE_PSPI1_MISO0>,
    <PAD_OUTP_RX0_CH2        PINMUX_FOR_PSPI0_MODE_1          MDRV_PUSE_PSPI1_MISO1>,
    <PAD_OUTN_RX0_CH2        PINMUX_FOR_PSPI0_MODE_1          MDRV_PUSE_PSPI1_MISO2>,
    <PAD_OUTP_RX0_CH3        PINMUX_FOR_PSPI0_MODE_1          MDRV_PUSE_PSPI1_MISO3>,
    <PAD_GPIOB_02            PINMUX_FOR_SR00_MCLK_MODE_2      MDRV_PUSE_SR00_MCLK>,
    

    以PSPI1连接Pannel为例:

    进入kernel/driver/arch/arm64/boot/dts/sstar/chipname-xxx-padmux.dtsi,配置PSPI1 MODE1

    <PAD_GPIOA_12                PINMUX_FOR_PSPI1_MODE_1      MDRV_PUSE_PSPI1_CS>,
    <PAD_GPIOA_13                PINMUX_FOR_PSPI1_MODE_1      MDRV_PUSE_PSPI1_CLK>,
    <PAD_GPIOA_14                PINMUX_FOR_PSPI1_MODE_1      MDRV_PUSE_PSPI1_MOSI0>,
    <PAD_GPIOA_15                PINMUX_FOR_PSPI1_MODE_1      MDRV_PUSE_PSPI1_MOSI1>,
    <PAD_GPIOA_16                PINMUX_FOR_PSPI1_TE_MODE_1   MDRV_PUSE_PSPI1_TE>,
    

    1.7.3. 运行环境说明

    硬件连接注意事项

    PSPI1 MODE1的PIN脚都集中在JP114,请注意接线正确

    将JP24的档位切换到3.3V

    UT程序运行说明

    首先确保板端启动时有加载mi_pspi.ko文件,移植prog_pspireset.shdev0_sensor_datalane2_auto.json文件到板端,输入命令运行UT程序:

    prog_pspi -i dev0_sensor_datalane2_auto.json -t 50000
    

    -i 指定json文件; -t 指定程序运行时间,以毫秒为单位

    传入panel的画面数据默认使用红绿蓝,如果修改, 可在sdk/verify/mi_demo/source/pspi/ut_pspi_main.c中修改:

    1.8. 实例介绍

    1.8.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;
    }
    

    1.8.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");
            }
        }
    }
    

    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. 错误码

    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 设备未使能

    5. PROCFS介绍

    5.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 最大时钟频率

    5.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

    6. MODPARAM.json介绍

    进入目录sdk/verify/mi_demo/source/pspi/case_json,修改其中的文件reset.sh和适配json文件:

    PSPIl连接Pannel时,reset.sh需要填入作为reset pin的GPIO INDEX ID,

    ./gpio.sh -i 67 -w 0
    sleep 1
    ./gpio.sh -i 67 -w 1
    
    id 67就是PAD_GPIOA_17作为reset pin与panel连接。
    

    json文件的适配以dev0_sensor_datalane2_auto.json为例:

    {
        "pspi":[
            {
                "enable":0,   //disable
                "devid" : 0,  //pspi0
                "devtype": "sensor"
            },
            {
                "enable":1,  //enable pspi1连接的panel
                "devid" : 1, //pspi1
                "devtype": "panel"
            }
    
        ],
    
        ......
    
        "panel":[
            {
                "devId" : 1,
                "autoTrig":1, //使能auto trig,实时刷新画面
                "temode":1,   //使能TE mode,保证画面不撕裂
                "datalane":2  //根据panel可选1-单线、2-双线、4-四线传输
            },
            {
                "devId" : 0,
                "autoTrig":1,
                "temode":1,
                "datalane":2
            }
        ]
    
    }