目录
1、前言
本设计采用OV5640摄像头MIPI模式作为输入,分辨率为1280x720@60Hz,MIPI解码方案采用Xilinx官方提供的MIPI CSI-2 RX Subsystem IP解码MIPI视频,通过DP接口输出视频。
FPGA图像采集领域目前协议最复杂、技术难度最高的应该就是MIPI协议了,MIPI解码难度之高,令无数英雄竞折腰,以至于Xilinx官方不得不推出专用的IP核供开发者使用,不然太高端的操作直接吓退一大批FPGA开发者,就没人玩儿了。
本文详细描述了设计方案,工程代码编译通过后上板调试验证,可直接项目移植,适用于在校学生、研究生项目开发,也适用于在职工程师做项目开发,可应用于医疗、军工等行业的数字成像和图像传输领域;
提供完整的、跑通的工程源码和技术支持;
工程源码和技术支持的获取方式放在了文章末尾,请耐心看到最后;
关于MIPI协议,请自行搜索,csdn就有很多大佬讲得很详细,我就不多写这块了;
本设计只针对2line的MIPI相机;
2、我这里已有的 MIPI 编解码方案
我这里目前已有丰富的基于FPGA的MIPI编解码方案,主要是MIPI解码的,既有纯vhdl实现的MIPI解码,也有调用Xilinx官方IP实现的MIPI解码,既有2line的MIPI解码,也有4line的MIPI解码,既有4K分辨率的MIPI解码,也有小到720P分辨率的MIPI解码,既有基于Xilinx平台FPGA的MIPI解码也有基于Altera平台FPGA的MIPI解码,还有基于Lattice平台FPGA的MIPI解码,后续还将继续推出更过国产FPGA的MIPI解码方案,毕竟目前国产化方案才是未来主流,后续也将推出更多MIPI编码的DSI方案,努力将FPGA的MIPI编解码方案做成白菜价。。。
基于此,我专门建了一个MIPI编解码的专栏,并将MIPI编解码的博客都放到了专栏里整理,对FPGA编解码MIPI有项目需求或学习兴趣的兄弟可以去我的专栏看看,专栏地址如下:
点击直接前往专栏
3、设计思路和架构
工程采用两个 lane 的 MIPI 输入,MIPI 摄像头配置为 RAW10 输出。通过mipi_csi2_rx_subsystem 模块进行协议解析并转换成 AXIS 流数据,并通过Sensor Demosaic模块将RAW 转换成 RGB 数据,之后经过 Gammer 校正等模块,进入 VDMA,之后进入 HP 口。
设计架构如下:
先配置 ZYNQ 核,100MHz 用于数据传输,200MHz 用于 MIPI 模块参考时钟,如下图:
配置 i2c 为 EMIO,用于配置摄像头寄存器,GPIO EMIO 设置为 1,用于配置摄像头使能,如下图:
添加 mipi_csi2_rx_subsystem IP,用于 MIPI 数据的接收与解析,转成 axi-stream 接口。
配置如下,数据格式选择 RAW10,选择 2 lane,Line Rate 配置为 1000Mbps,指的是最大支持的速率,也可以根据自己的需求填写,范围为 80-2500;Pixels Per Clock 默认配置为1,表示 1 个周期为 1 个像素;如下图:
自此,输入MIPI视频就以完成了解码,输出为AXIS视频流;后面就是图像数据格式转换和VDMA缓存以及vitis软件配置了。
4、vivado工程详解
提供2套工程源码,对应2种fpga,其他型号的fpga只需在vivado里更改fpga型号,然后重新编译即可,很简单,不多说;
工程1:
输入:OV5640摄像头MIPI模式,1280x720@60Hz;
FPGA型号:Zynq UltraScale Xczu4ev;
开发环境:vivado2020.2;
输出:DP,1280x720@60Hz;
工程2:
输入:OV5640摄像头MIPI模式,1280x720@60Hz;
FPGA型号:Zynq UltraScale Xczu2cg;
开发环境:vivado2020.2;
输出:DP,1280x720@60Hz;
以工程1为例,vivado工程BD如下:
综合后的代码架构如下:
vitis软件配置部分c代码主函数源码如下:
int main(void)
{
int Status;
int i ;
Xil_DCacheDisable();
Xil_ICacheDisable();
for (i = 0; i < DISPLAY_NUM_FRAMES; i++)
{
pFrames[i] = frameBuf[i];
memset(pFrames[i], 0, DEMO_MAX_FRAME);
}
PsGpioSetup() ;
XGpioPs_WritePin(&Gpio, CAM_EMIO, 0) ;
usleep(1000000);
XGpioPs_WritePin(&Gpio, CAM_EMIO, 1) ;
usleep(1000000);
i2c_init(&ps_i2c0, XPAR_XIICPS_0_DEVICE_ID,100000);
xil_printf("DPDMA Generic Video Example Test \r\n");
Status = DpdmaVideoExample(&RunCfg, pFrames[0]);
if (Status != XST_SUCCESS) {
xil_printf("DPDMA Video Example Test Failed\r\n");
return XST_FAILURE;
}
gamma_lut_init();
demosaic_init();
vdma_write_init(XPAR_AXIVDMA_0_DEVICE_ID,HORSIZE,VERSIZE,DEMO_STRIDE,(unsigned int)pFrames[0]);
sensor_init(&ps_i2c0);
return 0;
}
5、工程移植说明
vivado版本不一致处理
1:如果你的vivado版本与本工程vivado版本一致,则直接打开工程;
2:如果你的vivado版本低于本工程vivado版本,则需要打开工程后,点击文件–>另存为;但此方法并不保险,最保险的方法是将你的vivado版本升级到本工程vivado的版本或者更高版本;
3:如果你的vivado版本高于本工程vivado版本,解决如下:
打开工程后会发现IP都被锁住了,如下:
此时需要升级IP,操作如下:
FPGA型号不一致处理
如果你的FPGA型号与我的不一致,则需要更改FPGA型号,操作如下:
更改FPGA型号后还需要升级IP,升级IP的方法前面已经讲述了;
其他注意事项
1:由于每个板子的DDR不一定完全一样,所以MIG IP需要根据你自己的原理图进行配置,甚至可以直接删掉我这里原工程的MIG并重新添加IP,重新配置;
2:根据你自己的原理图修改引脚约束,在xdc文件中修改即可;
3:纯FPGA移植到Zynq需要在工程中添加zynq软核;
6、上板调试验证
由于某些不可抗力和高层次复杂因素,不便展示调试结果,请见谅;
7、福利:工程代码的获取
福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料获取方式:私,或者文章末尾的V名片。
网盘资料如下: