Post Go back to editing

Continuous ADC data streaming from PL to PS (standalone - NO-OS)

Thread Summary

The user is experiencing data loss between transactions when using ADI AXI DMAC to stream data from PL to PS in a Vivado 2019.2 design. The issue occurs despite a sufficient FIFO size and slow write clock. The final answer indicates the thread was closed due to inactivity, with no definitive solution provided. The user was advised to share more details about the hardware and to review the AD7768 HDL design and no-OS project for potential insights.
AI Generated Content
Category: Hardware
Product Number: AD7768

Hi,

I facing issue with ADI AXI DMAC - data is lost between two transaction even though the FIFO size is sufficient and writing clock is slow.

I want to continuously stream the data from PL to PS using AXI DMAC, the data will further be sent on Ethernet (1Gbps). For getting acquainted with ADI AXI DMAC I have created a design in Vivado 2019.2.

The design has a 32-bit counter (500KHz), ADI AXI DMAC configured in FIFO-MM mode (scr:FIFO, dest:MM). 

FIFO size 8192 Bytes
FIFO width  32- bits
FIFO write clock 500KHz
AXI Clock 100MHz

In C program, the dma is first configured, then in while loop - dma is started, data is read from DDR and stored in internal buffer.

Data of approx. 400 Bytes is observed in between the end of one transaction and start of other transaction.

Am I missing any configuration? is there any limitation on dma? does it require resetting between two transactions ?

Below is the standalone code:

 

#include <xparameters.h>
#include "xil_cache.h"
#include "axi_dmac.h"
#include "no_os_print_log.h"
#include "no_os_gpio.h"
#include "no_os_delay.h"
#include "xilinx_spi.h"
#include "xilinx_gpio.h"
#include "no_os_error.h"
#include <xil_io.h>
#include <stdio.h>
#include "xtime_l.h"

#include "xil_exception.h"


#define DEV_DDR_BASEADDR      0x00100000
#define ENABLE_BASEADDR    XPAR_AXI_GPIO_0_BASEADDR

int main(void)
{

	/* Disable the instruction cache. */
	Xil_DCacheDisable();
	Xil_ICacheDisable();

	Xil_Out32(ENABLE_BASEADDR, 0x00000000);


	u32 b_DDR_Data = 0;
	u32 b_DDR_Addr = 0;

    XTime tStart, tEnd;
    double elapsed_time_us;


	struct axi_dmac *dma_desc;

	int ret;

	struct axi_dmac_init dma_initial = {
		.name = "ad7768_dma",
		.base = XPAR_AXI_DMAC_0_BASEADDR,
		.irq_option = IRQ_DISABLED
	};


	/* Initialize AXI DMAC */
	ret = axi_dmac_init(&dma_desc, &dma_initial);
	if (ret != 0){
		xil_printf("Failed - axi_dmac_init!\n\r");
	}


	struct axi_dma_transfer read_transfer = {
		// Number of bytes to write/read
		.size = 128,
		// Transfer done flag
		.transfer_done = 0,
		// Signal transfer mode
		.cyclic = NO,
		// Address of data source
		.src_addr = 0,
		// Address of data destination
		.dest_addr = (uintptr_t)DEV_DDR_BASEADDR
	};

	Xil_Out32(ENABLE_BASEADDR, 0x00000001);

	u32 data_buff[8192] = {0};
	int index_buff = 0;

	while(1){

	ret = axi_dmac_transfer_start(dma_desc, &read_transfer);
	if (ret != 0){
		xil_printf("Failed - axi_dmac_transfer_start!\n\r");
	}



	u32 DDR_Data = 0;
	u32 DDR_Addr = 0;


	for (int k = 0; k < 32; k++) {
			DDR_Addr = ( DEV_DDR_BASEADDR + (k*4) );
			DDR_Data = Xil_In32(DDR_Addr);

			data_buff[index_buff + k] = DDR_Data;


		}

	index_buff = index_buff + 32;

	if(index_buff == 8192)
		break;

	}

	xil_printf("Transfer Done!\n\r");

	for (int j = 0; j < 8192; j++){
		if( j != data_buff[j]){
			xil_printf("data[%d] = %d\n\r", j, data_buff[j]);
		}
	}

	//cleanup
	axi_dmac_remove(dma_desc);

}

Below is the vivado block diagram screenshot:

Thread Notes