前面我们完成了一个PCIE中断采集图像的方案,但是很多应用中我们需要采集分析ADC的数据,本文就是提供这么一个PCIE中断采集ADC的方案。 首先我们要理解下XDMA的中断类型,以及控制时序: 1)、Legacy Interrupts: 对于Legacy Interrupts中断,当user_irq_ack 第一次为1的时候usr_irq_req可以清0,当user_irq_ack 第二次为1的时候,可以重新设置usr_irq_req发起中断。 在PCI总线里面INTx中断是由四条可选的中断线决定的,这种中断方式是共享式的,所有的pci设备把中断信号在一条中短线上相与,再上报给cpu,cpu收到中断以后再查询具体是哪个设备产生了中断。 2)、MSI Interrupts: MSI 发出usr_irq_req 中断请求后,user_irq_ack 为1只是说明中断已经北主机接收了,但是不代表已经处理,软件或者驱动层可以去清零usr_irq_req。 MSI中断和MSI-X都是往配置的CPU中断寄存器里进行memory写操作,来产生中断,效率比INTx是共享式高,其中MSI最多支持32个中断向量,而MSI-X最多支持2048个中断向量。 3)、MSI-X Interrupts: 当usr_irq_req 中断请求后,只要user_irq_ack为1 就可以清零usr_irq_req,但是没说明说明时候可以置1,重启下次中断。 经过以上所有中断方式测试,发现,MSI-X中断,会导致系统非常慢,估计是底层频繁中断导致,软件非常卡反而影响了传输效率,Legacy和MSI 对于usr_irq_req的清除,对于大数据量的传输,比如一幅图像的传图,只要确保usr_irq_req足够长的时间,中断就能被响应。 或者当软件收到中断后,通过AXI-LITE接口清除usr_irq_req。 usr_irq_req清除后可以重新置位响应中断。 本文就是采用了增加AXI-lite接口来控制清除usr_irq_req中断信号。 先看下整体的BD设计: 可以看到XDMA支持8条中断信号输入,而且我们增加了2个axi-gpio的IP,其中axi_gpio_0用于清除中断请求,axi-gpio_1用于控制FDMA控制器部分的复位(启停)。 展开XDMA的IP看下IP的设置,在中断部分,使用MIS中断,支持8个中断向量 和前面做的图像采集的方案类似,我们需要修改下FDMA的控制代码部分,由于ADC不需要类似视频的场同步,ADC一直以数据流的方式,写入DDR就可以。以下FDMA控制代码部分的修改,接口参数中,每次AXI burst的大小为256x128bit=4096bytes,FDMA每次busrt的大小为2048X4bytes=8192bytes 所以一次传输需要2次的AXIburst.FMDA的调用接口如下图: 再来看下FMDA控制代码部分fdma_ctr_irq代码中,如下图,当一帧图像传输完成后,设置了W0_irq位1 以下代码中,根据时序要求,先对W0_Fbuf寄存一次,这样才能确保设置中断请求的相关位置是刚刚完成写内存的指向位置。由于是异步采样,对于清除中断请求的信号,xdma_irq_ack需要三次缓存。 最后通过设置xdma_irq_req的相关位为1请求PCIE中断,以及清除xdma_irq_req的相关位为0,以便下次中断请求。 通过逻辑代码分析可以看出如果上位机无法及时响应中断,会出现丢中断的情况。对于不允许数据丢失的应用场合,在增加多缓存的情况下仍然无法满足要求的,只有通过增加PCIE带宽和PC的处理能力来解决。
ADC采集部分采用的是DAQ7606数据卡,这个数据卡具有8通道每个通道采样率200kbps,我们本次只采集其中的2个通道,作为演示demo。关键的信号如下,通过ad_data_valid信号,把AD采集的值写入到FDMA控制器的FIFO中 再来看下FMDA控制代码部分fdma_ctr_irq代码中,如下图,当一帧图像传输完成后,设置了W0_irq位1 以下代码中,根据时序要求,先对W0_Fbuf寄存一次,这样才能确保设置中断请求的相关位置是刚刚完成写内存的指向位置。由于是异步采样,对于清除中断请求的信号,xdma_irq_ack需要三次缓存。 最后通过设置xdma_irq_req的相关位为1请求PCIE中断,以及清除xdma_irq_req的相关位为0,以便下次中断请求。 通过逻辑代码分析可以看出如果上位机无法及时响应中断,会出现丢中断的情况。对于不允许数据丢失的应用场合,在增加多缓存的情况下仍然无法满足要求的,只有通过增加PCIE带宽和PC的处理能力来解决。
ADC采集部分采用的是DAQ7606数据卡,这个数据卡具有8通道每个通道采样率200kbps,我们本次只采集其中的2个通道,作为演示demo。关键的信号如下,通过ad_data_valid信号,把AD采集的值写入到FDMA控制器的FIFO中 中断部分响应。 ADC采集数据 FDMA的数据传输 上位机采集波形显示
以下是等待中断响应,中断响应后并且清除FMDA的中断部分。 设置的定时器中断,每过一定时间,会调用updatedataSlot函数,这个函数中,每次读取8192个bytes正好是2048个32bit 数据,我们的ADC就是分别在高16bit和低16bit.我来访问ADC数据方便,我们还设计了一个简单的数据结构: struct daq7606 { short ad0; short ad1; }; 通过这个数据接口把ad0通道和ad1通道非常方便的分开。 当我们取出2048个数据点,并且完成显示后,在下次一的显示中,我们再调用c2h_transfer(8192)从FPGA的DDR中取出数据。 本文后期我们会整理好,发布到2020版本的教程中,敬请关注! |
扫描关注,了解最新资讯