目录
四、zynq的HP口AXI时序实现读写DMA 1080P视频流
一、SPI配置接口要求
1. SPI(Sereial Peripheral Interface)串行外设接口,一般情况下有四根线(也有三线制的,感兴趣的同学可以仔细了解),时钟线(sck)、片选线(cs)、输入数据线(SDI)和输出数据线(SDO)。
2. 由图1-1可得SPI的配置时序要求先发LSB最后发MSB,这与zynq的PS端提供的驱动程序相反,所以在发送数据的时候要进行高低位对调操作。相应SDK的c代码如图1-2所示。
![](https://i-blog.csdnimg.cn/blog_migrate/e942b865bc93bcd84ba8702f02ee4750.png)
![](https://i-blog.csdnimg.cn/blog_migrate/76c4a25514508717d9685643447cc1c0.png)
3. 1080p模式需要如何配置寄存器可在芯片手册中进行查看,配置过程需要先进入Standby模式,配置完成后,再退出Standby模式。
二、IMX222 1080P 模式图像解析
1. 对输出的同步字和有效行场信号进行解析。
![](https://i-blog.csdnimg.cn/blog_migrate/ae045b29255d2622148dd25a9034af74.png)
![](https://i-blog.csdnimg.cn/blog_migrate/de13ac18fda0062935e8207d37fba542.png)
![](https://i-blog.csdnimg.cn/blog_migrate/b16e0aeae49c9f2be316213792c26d94.png)
2. 根据同步字和有效行场构成,设计出有效行和无效行的时序图,和状态机流程图如图2-4所示,使用Verilog代码实现。
![](https://i-blog.csdnimg.cn/blog_migrate/93f10ac1073b1e1f2f99bbf9a88ba76f.png)
3. (1)状态1的WAIT_INVLINE为图2-2的“6 Dummy for communication”部分;
(2)状态2和状态3WAIT_VLINE 、VSYNC_TIME为图2-2的“1Frame information line”部分,检测到有效行并产生vsync,此后便进入有效行;
(3)状态4 WAIT24_VLINE,在此转态需要等待24行不显示图像行,虽然这24行为validline区域,但是不显示图像,一般是为图像的算法处理留出空间;
(4)状态5 ACTIVE_LINE,正式进入可以显示图像的validline,启动列计数器,产生水平方向有效区域的精确标志:48~1969共1922个像素标识出来;
(5)若完成1082行的所有像素检测,跳回第一步,否则跳回第四步继续检测。
三、拜耳(Bayer)图像转TGB图像
1. 这里不详细介绍Bayer图像是什么,只介绍如何通过相关计算将Bayer图像转换为RGB格式。
如图3-1所示,Bayer转RGB的算法需要建立3x3的矩阵,为了不破坏图像的显示效果,这里多读出两行两列的的像素用于计算,1922*1082.
计算方法:
![](https://i-blog.csdnimg.cn/blog_migrate/398f5e119f72e832b2ac2ea9dc84c50a.png)
2.为了建立算法所需的3x3矩阵,采用两个(sfifo_2048x8)FIFO用来建立3*3的像素矩阵,如图3-2所示。
![](https://i-blog.csdnimg.cn/blog_migrate/ca737eb59ec4207766c548e673768ab4.png)
3. 在完成Verilog代码的时候,要注意:实现Bayer转RGB的算法所需3*3的矩阵,所以多读了两行两列的的像素,因此行、列计数器也会多出来2。但是判断奇偶行列进行实现Bayer转RGB各个分量的的计算时,只需要判断1920*1080,因此要对行列计数器进行适当的处理。
4. 关键标志信号:frame_valid, hor_valid, capture_hs_flag, frame_end_flag, calculate_en.
四、zynq的HP口AXI时序实现读写DMA 1080P视频流
(一)写DMA 1080P视频流
1. zynq的HP接口AXI写时序定义:
(1) HP 口用于传输高速数据流,最大位宽 64bit 同步时钟可以设置 250Mhz,本设计中使用64bit,200MHz。
(2)HP 口使用 AXI 协议最大突发长度可以设置 256 突发。
![](https://i-blog.csdnimg.cn/blog_migrate/5c8c3e2b0050946ae79c56d9d3d953e8.png)
2. DMA操作:直接存储器访问,用于传输高速数据流,可以直接访问内存。
这里要注意,由于DMA直接访问内存,而CPU高速数据处理时,是直接访问的cache,所以使用DMA直接访问DDR后,CPU并不知道DDR中数据改变,CPU任然会从cache中读取数据。所以我们在vivado 2018.3的SDK中观察不到内存中数据的变化。我们可以通过通知CPU的方法或者关掉cache的方法来解决,本设计中采用关掉cache的方法,但是带来的后果是数据传输效率一定程度的降低,c代码如图4-2所示。
![](https://i-blog.csdnimg.cn/blog_migrate/fd96fc841ecc7a9bdfa040038e0a8e0b.png)
3. 创建一个AXI4的IP,本设计创建的AXI4的IP数据位宽64bit,突发长度256,其他保持默认即可。HP接口遵循AXI3协议,可以调用samrtconnect模块完成协议转换。
4.根据图4-1的时序,和图4-3的结构框图自己设计改写生成vivado生成的AXI4的Verilog代码。AWADDR写地址的最终偏移量字节地址为:(1920x1080/2)x8,因为数据位宽是64bit,所以要除以2。因此最后一次256突发的起始地址为:(1920x1080/2)x8 - 256x8,在此之后地址便可清零。
5. 输入像素数据的时钟是74.25MHz(由imx222芯片手册得),数据位宽是24bit;AXI传输数据的时钟为200MHz,数据位宽为64bit,因此在这里引入一个异步FIFO,fifo的写入是32bit,读出是64bit;并且添加read_fifo_count,用于产生读fifo使能开始的标志和突发开始。
6. 要注意,要从第1行开始写入DDR,地址要准确清零,以保证显示的视频正常,不会出现上下偏移等问题。
7.关键标志信号:work_start_flag, detect_fv, burst_start, burst_cnt.
8.结构框图:
![](https://i-blog.csdnimg.cn/blog_migrate/5c51bc25b233276c0d9ee6e1bb6d71f0.png)
(二)读DMA 1080P视频流
1. 与写DMA 1080P视频流类似,在读DMA 1080P视频流中依然需要创建一个AXI4的IP,数据位宽64bit,突发长度256,其他保持默认即可。并根据图4-4 的时序和图4-5的结构框图自己设计改写生成vivado生成的AXI4的Verilog代码。
![](https://i-blog.csdnimg.cn/blog_migrate/e2da4bbbce4aa1112f7dfcc5a6620659.png)
![](https://i-blog.csdnimg.cn/blog_migrate/daf32a4546b0b15900079a7385a0ba31.png)
2. 当 FIFO 中不足 1 行图像数据时,从 AXI DDR 中读取数据填充 FIFO,HDMI 显示端第一次启动显示判断 FIFO 中大于等于 1 行图像数据就可以启动 HDMI 显示驱动时序。
3.图4-5中的读请求产生在后续的HDMI章节 介绍,这里通过判断fifo的rd_data_count的大小产生rd_fifo_en,从而将DDR中读回来的数据引出,使用ila进行分析验证。
4.关键信号:read_start(开始读DMA的标志)、burst_cnt、axi_rready(在读地址完成后拉高,读数据完成后拉低)。
5. axi_arvalid信号的拉高要避免在读地址和读数据区域,以防止重复读。
五、通过HDMI显示
使用Xilinx的7系列的Serdes(SERializer/DESerializer)的原语实现高速并转串,实现TMDS电平的HDMI的驱动器。
1.本设计的总体架构如图5-1所示,通过VGA处理后的R、G、B等相关信号用于后面8B/10B模块的输入信号,进而再完成并转串。8bit转10bit的模块以及并转串模块均可在vivado的语言模板中找到,只需要读懂代码的含义,并且根据自己的需求对相应的信号进行更改即可。
进行8bit转10bit是为了保证直流平衡,防止连续的0和1出现导致直流不平衡造成误码率升高。
![](https://i-blog.csdnimg.cn/blog_migrate/ac7d9e6d25fae3cade50fe33f2cfb271.png)
2. HDMI 1.4标准的连接架构如图5-2所示,在本设计中,只实现发送端(source)。应注意RGB与channel 0、1、2的对应关系。
![](https://i-blog.csdnimg.cn/blog_migrate/896b16ff529643d4ec7c0ccb2ad92049.png)
3. 至此,整个设计便完成了,理论上是可以正常显示摄像头拍到的图像。但是由于该设计具有一定的复杂度,可能每个模块设计出来后加以ila分析纠错后,可以正常运行,但是将多个模块互联到一起后,它们之间可能还会出现时序不匹配等一些奇奇怪怪的问题,仍需要逐步的有条理的耐心调试。
六、调试工作
1. 图像显示出现的问题:图像上下平移、显示器左边有一条竖直的无图像区域、拍摄浅色图像时显示颜色发紫。
2. 解决思路:本设计主要由Bayer -> RGB模块、AXI_DMA_WR模块、AXI_DMA_RD模块、HDMI显示模块组成。按次序逐一排除问题。本设计的最终目的是在显示器上完整稳定的显示摄像头拍摄到的画面,因此以图像正确显示为判断依据,从后往前逐一排查:
(1)检查HDMI显示模块的是否有问题。在这里,我另外生成了一个模块,用于产生HDMI显示模块需要的R、G、B信号,同步信号等,使显示器显示彩条。看这步操作是否有问题,若无问题,进入下一个模块的排查;若有问题,改正HDMI显示模块使其可以正确显示彩条后,放回整体设计中,看是否可以正确显示图像,若可以,设计完成,若不可以,进入下一个模块的排查。
(2)检查AXI_DMA_RD模块。在这里我在SDK中使用c代码在DDR的特定位置初始化一副彩条的图像,然后注释掉相应的代码,使AXI_DMA_WR模块不工作。执行该步操作,看显示器能否显示初始化的彩条。若可以显示,进入下一个模块的排查;若不可以显示,改正AXI_DMA_RD模块使其可以正确显示彩条后,放回整体设计中,看是否可以正确显示图像,若可以,设计完成,若不可以,进入下一个模块的排查。
(3)检查Bayer -> RGB模块。这个模块中包含了图像解析生成Sync和Bayer->RGB两个文件,由于图像解析生成sync模块相对简单,先对他进行检查,将RGB的值赋值成相同的值,图像变成了灰度图像。无误后再检查Bayer->RGB,发现是Bayer->RGB的算法在第0行就开始了,应该是在第2行开始,这个导致了图像的上下平移。也导致了AXI_DMA_WR模块缓冲数据的fifo写使能过早开启,导致显示器左边的无图像区域。
3. 一定注意时序的问题,信号和时钟有效的位置要配合好,切忌时钟还未开始,相关信号就来了,导致出现模块启动不了等错误。
4. 颜色异常的原因是Bayer->RGB的计算时,R、G、B的位宽不够,导致了数据的溢出。