MI PSPI API
REVISION HISTORY¶
Revision No. | Description |
Date |
---|---|---|
1.00 | 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可应用于以下场景:
-
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_liner
和PSPI_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_pspi
、reset.sh
和dev0_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] 接收数据缓冲区 -
相关数据类型及接口
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输入图像数据的高 -
相关数据类型及接口
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_laneu8TeMode 是否使用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 -
相关数据类型及接口
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;
-
注意事项
- 在选择Auto+Vsync trigger 模式的时候需要sensor 有Vsync 信号支持。
- 在选择Auto trigger 模式的时候会丢掉前两帧的数据。
- 默认选择Auto trigger 模式。
-
相关数据类型及接口
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。
-
相关数据类型及接口
3.7. MI_PSPI_DEV¶
-
说明
定义芯片内部的PSPI编号。
-
定义
typedef MI_S32 MI_PSPI_DEV;
-
注意事项
这个参数的值可设置为0或1,分别代表芯片内部的PSPI0和PSPI1。注意PSPI0和PSPI1都无法同时用于RX和TX。
-
相关数据类型及接口
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 } ] }