We have been trying to figure out how to read and write data using the evaluation system on the ZC702 with the FMCOMMS4. Currently we are trying to get a loopback test working to verify that we can read/write data accurately. We have the RXA and TXA ports hooked up to each other. However, we're not getting the data we expect out of the loopback and so we're trying to understand how the read/write process works. We are using the 2014_R2 release from github:
(mostly because we were having Vivado versioning issues with 2015_R1 when building the hdl)
For writing, we defined DAC_DMA in main.c and then modified the sine_lut array in dac_core.c. We were able to verify with a spectrum analyzer that our signal was changing based on the sine_lut data we used. Looking at dac_init.c, there is a for loop that starts around line 227. It seems to pull out the I and Q data from sine_lut. From this code it appears that the first 16 elements in sine_lut are I, and the next 16 are Q. Then there are three lines to package and send the I and Q data to the correct memory location:
data_i1 = (sine_lut[index_i1 / 2] << 20);
data_q1 = (sine_lut[index_q1 / 2] << 4);
Xil_Out32(DAC_DDR_BASEADDR + index_mem * 4, data_i1 | data_q1);
So it looks like we can use this process to write data out to the FIFO when we want, instead of just at initialization. Is this correct? Also, why does the data need to be shifted << 20 and << 4 for the I and Q channels?
For reading, we are trying to use adc_capture in main.c. It seems like adc_capture writes DMA input data into the register fed into its second argument. This is the call:
We're not sure how the invalidate range works or when it should be called (after each read, before accessing the data?)
However, we should be able to then read that ADC_DDR_BASEADDR register (offset for each element we want) in order to get our read ADC data. So we used a loop:
rdata = Xil_In32(ADC_DDR_BASEADDR+(n*4));
SampleI = rdata & 0xFFFF;
SampleQ = (rdata >> 16) & 0xFFFF;
(and used console print to output our data to the console).
However, we're having trouble correlating the data we put into sine_lut with what we read out using adc_capture. For example, we set sine_lut to all 0x000, but when we read our ADC data, it comes back as variously low and high values.
In summary, our questions are:
1. How can we use the drivers to read the dma data?
2. How does the DAC output structure work?
3. How do we use the ADC capture option in main.c?
4. Are we generally expected to just do all this reading/writing from the FPGA?