我们选用的cmos sensor是安森美半导体公司的python 5000,价格较贵,但是帧率相对较高,能够提供较高的精度,全景时能出来2592*2048@100Hz的视频图像,可以通过降低分辨率 进一步提高帧率。驱动该摄像头的工作主要分为两部分,寄存器配置和LVDS解串。
1,寄存器配置
PFGA需要给cmos sensor供应时钟和配置寄存器。有两种方式提供时钟,一种是提供72M的单端时钟,再经过sensor里PLL倍频后产生288M;第二种是直接提供288M的差分时钟; 两种方式效果一样,我们提供的72M单端时钟。
FPGA通过spi接口去配置cmos sensor的寄存器,分辨率,帧率以及ROI都可以通过寄存器配置以达到相应的需求。参照安森美 官网提供的文档 NOIP1SN5000A的Figure 20的读写时序即可, 需要注意是SPI时钟应小于10M, 需要配置的寄存器有100多个, 配成的寄存器列表由FAE提供了。
配置通常是在上电后立即完成,有一下几种方式可以检验是否将数据成功写到寄存器中。
a, 上电后开始计数,记到5--10s后状态机从IDLE状态跳转到configure状态,即可根据相应的触发条件在mosi上抓出相应的数据; 配置完成后可以跳到读状态,如果配置成功,即可在miso上抓到相应的数据。
b. 配置完成后读出相应的寄存器,并把读出来的数据存到相应的寄存器中,用Chipscope scope抓寄存器的值即可。 在做这个验证 的时候我遇到了两个问题。 (1)根据时序图,读寄存器的值是在下降沿采样,需要额外用到一个always语句;(2)第二 个问题比较尴尬了,cmos sensor是插在一个插糟里的,mosi和mosi分别连接在了FPGA的pin的P端和N端。抓数据发现mosi和 mosi两个信号相等,(为何相等原因解释不清楚,可能跟FPGA结构有关)。即最后抓到的值始终等于要写进去的值,误导我以 为配置没问题,而去调试后面lvds解串的问题了。 偶然发现其实插糟没插紧,从LVDS传过来的数据都是错误的。
2. LVDS解串
驱动高速摄像头的难点是LVDS解串,python5000以LVDS串行的方式传输数据到FPGA端,相对于LVDS并行, 解析LVDS串行的数据需要理解bitslip这个信号,因此难度相对大一些(之前调试的时候对这个信号理解不透彻耽误了较多时间)。10对LVDS差分数据即8data+1sync+1clk以源同步的形式、288M(双边沿采样)的速度传输到FPGA,
由于xilinx_fpga时钟结构的限制,从cmos sensor过来的差分时钟不能进到两个selectio中,于是重写了selectio这个模块,模块接口如下,lvds差分信号进到这个模块后,可以把相应的data和sync数据解析出来。
关于selectio模块需要注意数据的高低位,如果反了的话,就会一直给bitslip信号,导致数据不对。要根据sensor发来的数据的高低位先后顺序,相应地在selectio中修改。
为了满足时序,在这个模块里面可以修改data和clk的延迟以满足建立时间和保持时间,bitslip也是由为重要,为了产生bitslip信号,单独用了一个模块。另外发现加不加时序约束语句影响不大。
配置相应 的测试模式寄存器,参照下图,解析出来的8data数据和1syn正确。根据sync信息,可以将视频数据的行场信号提取出来。
后面要做的是数据解析和算法相关的了,博客会继续更新。