cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
adventure789
Visitor
Visitor
499 Views
Registered: ‎07-06-2020

SG DMA

Hello All,

I'm new to Fpga family.working on ZCU102 evaluation board.i want to transfer data from pl-ps and ps-pl and need to do handshakes .Had hls-ip sends data in zynq need to process that data and send data to hls ip . Hls-ip reads that data and sends back that zynq. This will happen continuously. I Tried with simple mode dma its working (throughput issue). My question will it possible handleshakes and processing data for single single transfers with DMA SG mode. if possible suggest me example file provided by xilinx. Thanks in advance .

 

Thanks & Regards,
Pavan Kumar
Tags (3)
0 Kudos
3 Replies
savula
Moderator
Moderator
474 Views
Registered: ‎10-30-2017

Hi @adventure789 ,

what kind of handshake you are taking about. in general the AXI DMA in SG mode will transfer the data based on descriptors fetched from memory. The DMA will generates the interrupt after finishing the complete transfers. please set the interrupt for every descriptor and write 1 to IRQThreshold. this will make sure to generate the interrupt for every descriptor. you can then do a hand shake for every interrupt received.

 Best Regards,
Srikanth
----------------------------------------------------------------------------------------------
Kindly note- Please mark the Answer as "Accept as solution" if information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented.

0 Kudos
adventure789
Visitor
Visitor
449 Views
Registered: ‎07-06-2020

Hello srikanth,

I tried with SG-Poll example code and modified a little bit. Handshakes (lets suppose hls_ip(PL) is sending data (16bytes) PS need to receive data from S2MM port and process the data .After this i need to send data (100 bytes)(PS) from M2SS Port to hls-ip(PL). Like this i need to do so many times handshakes. In my code first i'm trying to receive data from PL ,process it then sending data to PS. Here im facing problem 16 bytes of data is receiving but its not sending 100 bytes data. my code is attached down any one tell me what mistakes i made. Thanks in advance.

//***********************************************************************************************************////

#include "xaxidma.h"
#include "xparameters.h"
#include "xdebug.h"

#ifdef __aarch64__
#include "xil_mmu.h"
#endif

#if defined(XPAR_UARTNS550_0_BASEADDR)
#include "xuartns550_l.h" /* to use uartns550 */
#endif

#if (!defined(DEBUG))
extern void xil_printf(const char *format, ...);
#endif

/******************** Constant Definitions **********************************/

/*
* Device hardware build related constants.
*/

#define DMA_DEV_ID XPAR_AXIDMA_0_DEVICE_ID

#ifdef XPAR_AXI_7SDDR_0_S_AXI_BASEADDR
#define DDR_BASE_ADDR XPAR_AXI_7SDDR_0_S_AXI_BASEADDR
#elif defined (XPAR_MIG7SERIES_0_BASEADDR)
#define DDR_BASE_ADDR XPAR_MIG7SERIES_0_BASEADDR
#elif defined (XPAR_MIG_0_BASEADDR)
#define DDR_BASE_ADDR XPAR_MIG_0_BASEADDR
#elif defined (XPAR_PSU_DDR_0_S_AXI_BASEADDR)
#define DDR_BASE_ADDR XPAR_PSU_DDR_0_S_AXI_BASEADDR
#endif

#ifndef DDR_BASE_ADDR
#warning CHECK FOR THE VALID DDR ADDRESS IN XPARAMETERS.H, \
DEFAULT SET TO 0x01000000
#define MEM_BASE_ADDR 0x01000000
#else
#define MEM_BASE_ADDR (DDR_BASE_ADDR + 0x1000000)
#endif

#define TX_BD_SPACE_BASE (MEM_BASE_ADDR)
#define TX_BD_SPACE_HIGH (MEM_BASE_ADDR + 0x00000FFF)
#define RX_BD_SPACE_BASE (MEM_BASE_ADDR + 0x00001000)
#define RX_BD_SPACE_HIGH (MEM_BASE_ADDR + 0x00001FFF)
#define TX_BUFFER_BASE (MEM_BASE_ADDR + 0x00100000)
#define RX_BUFFER_BASE (MEM_BASE_ADDR + 0x00300000)
#define RX_BUFFER_HIGH (MEM_BASE_ADDR + 0x004FFFFF)


#define MAX_PKT_LEN 2000
#define MARK_UNCACHEABLE 0x701

#define TEST_START_VALUE 0xC

/**************************** Type Definitions *******************************/


/***************** Macros (Inline Functions) Definitions *********************/


/************************** Function Prototypes ******************************/
#if defined(XPAR_UARTNS550_0_BASEADDR)
static void Uart550_Setup(void);
#endif

static int RxSetup(XAxiDma * AxiDmaInstPtr);
static int TxSetup(XAxiDma * AxiDmaInstPtr);
static int SendPacket(XAxiDma * AxiDmaInstPtr);
static int CheckData(void);
static int CheckDmaResult(XAxiDma * AxiDmaInstPtr);

/************************** Variable Definitions *****************************/
/*
* Device instance definitions
*/
XAxiDma AxiDma;

/*
* Buffer for transmit packet. Must be 32-bit aligned to be used by DMA.
*/
u32 *Packet = (u32 *) TX_BUFFER_BASE;

/*****************************************************************************/
/**
*
* Main function
*
* This function is the main entry of the tests on DMA core. It sets up
* DMA engine to be ready to receive and send packets, then a packet is
* transmitted and will be verified after it is received via the DMA loopback
* widget.
*
* @param None
*
* @return
* - XST_SUCCESS if test passes
* - XST_FAILURE if test fails.
*
* @note None.
*
******************************************************************************/
int main(void)
{
int Status;
XAxiDma_Config *Config;

#if defined(XPAR_UARTNS550_0_BASEADDR)

Uart550_Setup();

#endif

xil_printf("\r\n--- Entering main() --- \r\n");

#ifdef __aarch64__
Xil_SetTlbAttributes(TX_BD_SPACE_BASE, MARK_UNCACHEABLE);
Xil_SetTlbAttributes(RX_BD_SPACE_BASE, MARK_UNCACHEABLE);
#endif

Config = XAxiDma_LookupConfig(DMA_DEV_ID);
if (!Config) {
xil_printf("No config found for %d\r\n", DMA_DEV_ID);

return XST_FAILURE;
}

/* Initialize DMA engine */
Status = XAxiDma_CfgInitialize(&AxiDma, Config);
if (Status != XST_SUCCESS) {
xil_printf("Initialization failed %d\r\n", Status);
return XST_FAILURE;
}

if(!XAxiDma_HasSg(&AxiDma)) {
xil_printf("Device configured as Simple mode \r\n");

return XST_FAILURE;
}

Status = TxSetup(&AxiDma);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}

Status = RxSetup(&AxiDma);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}

/* Send a packet */
// Status = SendPacket(&AxiDma);
// if (Status != XST_SUCCESS) {
// return XST_FAILURE;
// }

// /* Check DMA transfer result */
// Status = CheckDmaResult(&AxiDma);

receive_data();
send_data(1);
receive_data();
// send_data(3);
// receive_data();

if (Status != XST_SUCCESS) {
xil_printf("AXI DMA SG Polling Example Failed\r\n");
return XST_FAILURE;
}

xil_printf("Successfully ran AXI DMA SG Polling Example\r\n");
xil_printf("--- Exiting main() --- \r\n");

if (Status != XST_SUCCESS) {
return XST_FAILURE;
}

return XST_SUCCESS;
}

#if defined(XPAR_UARTNS550_0_BASEADDR)
/*****************************************************************************/
/*
*
* Uart16550 setup routine, need to set baudrate to 9600, and data bits to 8
*
* @param None
*
* @return None
*
* @note None.
*
******************************************************************************/
static void Uart550_Setup(void)
{

/* Set the baudrate to be predictable
*/
XUartNs550_SetBaud(XPAR_UARTNS550_0_BASEADDR,
XPAR_XUARTNS550_CLOCK_HZ, 9600);

XUartNs550_SetLineControlReg(XPAR_UARTNS550_0_BASEADDR,
XUN_LCR_8_DATA_BITS);

}
#endif

/*****************************************************************************/
/**
*
* This function sets up RX channel of the DMA engine to be ready for packet
* reception
*
* @param AxiDmaInstPtr is the pointer to the instance of the DMA engine.
*
* @return XST_SUCCESS if the setup is successful, XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
static int RxSetup(XAxiDma * AxiDmaInstPtr)//dma-sg-example-function for setting up the rx bd ring
{
XAxiDma_BdRing *RxRingPtr;
int Delay = 0;
int Coalesce = 1;
int Status;
XAxiDma_Bd BdTemplate;
XAxiDma_Bd *BdPtr;
XAxiDma_Bd *BdCurPtr;
u32 BdCount;
u32 FreeBdCount;
UINTPTR RxBufferPtr;
int Index;

RxRingPtr = XAxiDma_GetRxRing(&AxiDma);

/* Disable all RX interrupts before RxBD space setup */

XAxiDma_BdRingIntDisable(RxRingPtr, XAXIDMA_IRQ_ALL_MASK);

/* Set delay and coalescing */
XAxiDma_BdRingSetCoalesce(RxRingPtr, Coalesce, Delay);

/* Setup Rx BD space */
BdCount = XAxiDma_BdRingCntCalc(XAXIDMA_BD_MINIMUM_ALIGNMENT,
RX_BD_SPACE_HIGH - RX_BD_SPACE_BASE + 1);

Status = XAxiDma_BdRingCreate(RxRingPtr, RX_BD_SPACE_BASE,
RX_BD_SPACE_BASE,
XAXIDMA_BD_MINIMUM_ALIGNMENT, BdCount);

if (Status != XST_SUCCESS) {
xil_printf("RX create BD ring failed %d\r\n", Status);

return XST_FAILURE;
}

/*
* Setup an all-zero BD as the template for the Rx channel.
*/
XAxiDma_BdClear(&BdTemplate);

Status = XAxiDma_BdRingClone(RxRingPtr, &BdTemplate);
if (Status != XST_SUCCESS) {
xil_printf("RX clone BD failed %d\r\n", Status);

return XST_FAILURE;
}

/* Attach buffers to RxBD ring so we are ready to receive packets */

FreeBdCount = XAxiDma_BdRingGetFreeCnt(RxRingPtr);

Status = XAxiDma_BdRingAlloc(RxRingPtr, FreeBdCount, &BdPtr);
if (Status != XST_SUCCESS) {
xil_printf("RX alloc BD failed %d\r\n", Status);
return XST_FAILURE;
}

BdCurPtr = BdPtr;
RxBufferPtr = RX_BUFFER_BASE;
for (Index = 0; Index < FreeBdCount; Index++) {
Status = XAxiDma_BdSetBufAddr(BdCurPtr, RxBufferPtr);

if (Status != XST_SUCCESS) {
xil_printf("Set buffer addr %x on BD %x failed %d\r\n",
(unsigned int)RxBufferPtr,
(UINTPTR)BdCurPtr, Status);

return XST_FAILURE;
}

Status = XAxiDma_BdSetLength(BdCurPtr, MAX_PKT_LEN,
RxRingPtr->MaxTransferLen);
if (Status != XST_SUCCESS) {
xil_printf("Rx set length %d on BD %x failed %d\r\n",
MAX_PKT_LEN, (UINTPTR)BdCurPtr, Status);

return XST_FAILURE;
}

/* Receive BDs do not need to set anything for the control
* The hardware will set the SOF/EOF bits per stream status
*/
XAxiDma_BdSetCtrl(BdCurPtr, 0);
XAxiDma_BdSetId(BdCurPtr, RxBufferPtr);

RxBufferPtr += MAX_PKT_LEN;
BdCurPtr = (XAxiDma_Bd *)XAxiDma_BdRingNext(RxRingPtr, BdCurPtr);
}

/* Clear the receive buffer, so we can verify data
*/
//memset((void *)RX_BUFFER_BASE, 0, MAX_PKT_LEN);

Status = XAxiDma_BdRingToHw(RxRingPtr, FreeBdCount,
BdPtr);
if (Status != XST_SUCCESS) {
xil_printf("RX submit hw failed %d\r\n", Status);

return XST_FAILURE;
}

/* Start RX DMA channel */
Status = XAxiDma_BdRingStart(RxRingPtr);
if (Status != XST_SUCCESS) {
xil_printf("RX start hw failed %d\r\n", Status);

return XST_FAILURE;
}

return XST_SUCCESS;
}

/*****************************************************************************/
/**
*
* This function sets up the TX channel of a DMA engine to be ready for packet
* transmission
*
* @param AxiDmaInstPtr is the instance pointer to the DMA engine.
*
* @return XST_SUCCESS if the setup is successful, XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
static int TxSetup(XAxiDma * AxiDmaInstPtr)//dma-sg-example-function for setting up the tx bd ring
{
XAxiDma_BdRing *TxRingPtr;
XAxiDma_Bd BdTemplate;
int Delay = 0;
int Coalesce = 1;
int Status;
u32 BdCount;

TxRingPtr = XAxiDma_GetTxRing(&AxiDma);

/* Disable all TX interrupts before TxBD space setup */

XAxiDma_BdRingIntDisable(TxRingPtr, XAXIDMA_IRQ_ALL_MASK);

/* Set TX delay and coalesce */
XAxiDma_BdRingSetCoalesce(TxRingPtr, Coalesce, Delay);

/* Setup TxBD space */
BdCount = XAxiDma_BdRingCntCalc(XAXIDMA_BD_MINIMUM_ALIGNMENT,
TX_BD_SPACE_HIGH - TX_BD_SPACE_BASE + 1);//here bd =64

Status = XAxiDma_BdRingCreate(TxRingPtr, TX_BD_SPACE_BASE,
TX_BD_SPACE_BASE,
XAXIDMA_BD_MINIMUM_ALIGNMENT, BdCount);// XAXIDMA_BD_MINIMUM_ALIGNMENT =64
if (Status != XST_SUCCESS) {
xil_printf("failed create BD ring in txsetup\r\n");

return XST_FAILURE;
}

/*
* We create an all-zero BD as the template.
*/
XAxiDma_BdClear(&BdTemplate);

Status = XAxiDma_BdRingClone(TxRingPtr, &BdTemplate);
if (Status != XST_SUCCESS) {
xil_printf("failed bdring clone in txsetup %d\r\n", Status);

return XST_FAILURE;
}

/* Start the TX channel */
Status = XAxiDma_BdRingStart(TxRingPtr);
if (Status != XST_SUCCESS) {
xil_printf("failed start bdring txsetup %d\r\n", Status);

return XST_FAILURE;
}

return XST_SUCCESS;
}

/*****************************************************************************/
/**
*
* This function transmits one packet non-blockingly through the DMA engine.
*
* @param AxiDmaInstPtr points to the DMA engine instance
*
* @return - XST_SUCCESS if the DMA accepts the packet successfully,
* - XST_FAILURE otherwise.
*
* @note None.
*
******************************************************************************/
static int SendPacket(XAxiDma * AxiDmaInstPtr)//dma-sg-example-function fro sending the data out from zynq
{
XAxiDma_BdRing *TxRingPtr;
u8 *TxPacket;
u8 Value;
XAxiDma_Bd *BdPtr;
int Status;
int Index;

TxRingPtr = XAxiDma_GetTxRing(AxiDmaInstPtr);

/* Create pattern in the packet to transmit */
TxPacket = (u8 *) Packet;

Value = TEST_START_VALUE;

for(Index = 0; Index < MAX_PKT_LEN; Index ++) {
TxPacket[Index] = Value;

Value = (Value + 1) & 0xFF;
}

/* Flush the buffers before the DMA transfer, in case the Data Cache
* is enabled
*/
Xil_DCacheFlushRange((UINTPTR)TxPacket, MAX_PKT_LEN);
Xil_DCacheFlushRange((UINTPTR)RX_BUFFER_BASE, MAX_PKT_LEN);

/* Allocate a BD */
Status = XAxiDma_BdRingAlloc(TxRingPtr,1,&BdPtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}

/* Set up the BD using the information of the packet to transmit */
Status = XAxiDma_BdSetBufAddr(BdPtr, (UINTPTR) Packet);
if (Status != XST_SUCCESS) {
xil_printf("Tx set buffer addr %x on BD %x failed %d\r\n",
(UINTPTR)Packet, (UINTPTR)BdPtr, Status);

return XST_FAILURE;
}

Status = XAxiDma_BdSetLength(BdPtr, MAX_PKT_LEN,
TxRingPtr->MaxTransferLen);
if (Status != XST_SUCCESS) {
xil_printf("Tx set length %d on BD %x failed %d\r\n",
MAX_PKT_LEN, (UINTPTR)BdPtr, Status);

return XST_FAILURE;
}

#if (XPAR_AXIDMA_0_SG_INCLUDE_STSCNTRL_STRM == 1)
Status = XAxiDma_BdSetAppWord(BdPtr,
XAXIDMA_LAST_APPWORD, MAX_PKT_LEN);

/* If Set app length failed, it is not fatal
*/
if (Status != XST_SUCCESS) {
xil_printf("Set app word failed with %d\r\n", Status);
}
#endif

/* For single packet, both SOF and EOF are to be set
*/
XAxiDma_BdSetCtrl(BdPtr, XAXIDMA_BD_CTRL_TXEOF_MASK |
XAXIDMA_BD_CTRL_TXSOF_MASK);

XAxiDma_BdSetId(BdPtr, (UINTPTR)Packet);

/* Give the BD to DMA to kick off the transmission. */
Status = XAxiDma_BdRingToHw(TxRingPtr, 1, BdPtr);
if (Status != XST_SUCCESS) {
xil_printf("to hw failed %d\r\n", Status);
return XST_FAILURE;
}

 

return XST_SUCCESS;
}

/*****************************************************************************/
/*
*
* This function checks data buffer after the DMA transfer is finished.
*
* @param None
*
* @return - XST_SUCCESS if validation is successful
* - XST_FAILURE if validation is failure.
*
* @note None.
*
******************************************************************************/
static int CheckData(void)////////////////this function is used to check the received data
{
u32 *RxPacket;
int Index = 0;
u8 Value;


RxPacket = (u32 *) RX_BUFFER_BASE;
Value = TEST_START_VALUE;

/* Invalidate the DestBuffer before receiving the data, in case the
* Data Cache is enabled
*/
Xil_DCacheInvalidateRange((UINTPTR)RxPacket,MAX_PKT_LEN/4);

for(Index = 0; Index < 2000; Index++) {
// if (RxPacket[Index] != Value) {
// xil_printf("Data error %d: %x/%x\r\n",
// Index, (unsigned int)RxPacket[Index],
// (unsigned int)Value);
//
// return XST_FAILURE;
// }
// Value = (Value + 1) & 0xFF;
xil_printf("RxPacket[%d] = %x \r\n",Index,RxPacket[Index]);
}

return XST_SUCCESS;
}

/*****************************************************************************/
/**
*
* This function waits until the DMA transaction is finished, checks data,
* and cleans up.
*
* @param None
*
* @return - XST_SUCCESS if DMA transfer is successful and data is correct,
* - XST_FAILURE if fails.
*
* @note None.
*
******************************************************************************/
static int CheckDmaResult(XAxiDma * AxiDmaInstPtr)
{
XAxiDma_BdRing *TxRingPtr;
XAxiDma_BdRing *RxRingPtr;
XAxiDma_Bd *BdPtr;
int ProcessedBdCount;
int FreeBdCount;
int Status;

TxRingPtr = XAxiDma_GetTxRing(AxiDmaInstPtr);
RxRingPtr = XAxiDma_GetRxRing(AxiDmaInstPtr);//--------------

/* Wait until the one BD TX transaction is done */
while ((ProcessedBdCount = XAxiDma_BdRingFromHw(TxRingPtr,
XAXIDMA_ALL_BDS,
&BdPtr)) == 0) {
}

/* Free all processed TX BDs for future transmission */
Status = XAxiDma_BdRingFree(TxRingPtr, ProcessedBdCount, BdPtr);
if (Status != XST_SUCCESS) {
xil_printf("Failed to free %d tx BDs %d\r\n",
ProcessedBdCount, Status);
return XST_FAILURE;
}

/* Wait until the data has been received by the Rx channel */
while ((ProcessedBdCount = XAxiDma_BdRingFromHw(RxRingPtr,
XAXIDMA_ALL_BDS,
&BdPtr)) == 0) {
}//---------------------------------------------------

/* Check received data */
if (CheckData() != XST_SUCCESS) {

return XST_FAILURE;
}

/* Free all processed RX BDs for future transmission */
Status = XAxiDma_BdRingFree(RxRingPtr, ProcessedBdCount, BdPtr);
if (Status != XST_SUCCESS) {
xil_printf("Failed to free %d rx BDs %d\r\n",
ProcessedBdCount, Status);
return XST_FAILURE;
}

/* Return processed BDs to RX channel so we are ready to receive new
* packets:
* - Allocate all free RX BDs
* - Pass the BDs to RX channel
*/
FreeBdCount = XAxiDma_BdRingGetFreeCnt(RxRingPtr);
Status = XAxiDma_BdRingAlloc(RxRingPtr, FreeBdCount, &BdPtr);
if (Status != XST_SUCCESS) {
xil_printf("bd alloc failed\r\n");
return XST_FAILURE;
}

Status = XAxiDma_BdRingToHw(RxRingPtr, FreeBdCount, BdPtr);
if (Status != XST_SUCCESS) {
xil_printf("Submit %d rx BDs failed %d\r\n", FreeBdCount, Status);
return XST_FAILURE;
}

return XST_SUCCESS;
}


void
receive_data()//this function is used to received data based on the max length i.e defined in macro
{
XAxiDma_BdRing *RxRingPtr;
XAxiDma_Bd *BdPtr;
int ProcessedBdCount;
Xil_DCacheFlushRange((UINTPTR)RX_BUFFER_BASE,MAX_PKT_LEN);
//XAxiDma_BdRingFree(RxRingPtr,XAXIDMA_ALL_BDS,BdPtr);
RxRingPtr = XAxiDma_GetRxRing(&AxiDma);
while ((ProcessedBdCount = XAxiDma_BdRingFromHw(RxRingPtr,
XAXIDMA_ALL_BDS,
&BdPtr)) == 0) {
}
xil_printf("processbdcount = %d",ProcessedBdCount);
CheckData();
// XAxiDma_BdRingFree(RxRingPtr,XAXIDMA_ALL_BDS,BdPtr);
// XAxiDma_BdRingAlloc(RxRingPtr,XAXIDMA_ALL_BDS,&BdPtr);
}

void
send_data(int constant)//this function is used to send data
{
XAxiDma_BdRing *TxRingPtr;
XAxiDma_BdRing *RxRingPtr;
u32 *TxPacket;
u8 Value;
int ProcessedBdCount;
XAxiDma_Bd *BdPtr;
int Index;
int Status;

TxRingPtr = XAxiDma_GetTxRing(&AxiDma);
XAxiDma_BdRingFree(TxRingPtr,XAXIDMA_ALL_BDS,BdPtr);
TxPacket = (u32 *) Packet;

//Value = 0x1;

for(Index = 0; Index < 100; Index ++) {
TxPacket[Index] = constant;

//Value = (Value + 1) & 0xFF;
}
Xil_DCacheFlushRange((UINTPTR)TxPacket,100);
xil_printf("Xil_DCacheFlushRange done");
Status = XAxiDma_BdRingAlloc(TxRingPtr,1, &BdPtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
xil_printf("alloc done");
/* Set up the BD using the information of the packet to transmit */
Status = XAxiDma_BdSetBufAddr(BdPtr, (UINTPTR) Packet);
if (Status != XST_SUCCESS) {
xil_printf("Tx set buffer addr %x on BD %x failed %d\r\n",
(UINTPTR)Packet, (UINTPTR)BdPtr, Status);

return XST_FAILURE;
}
xil_printf("XAxiDma_BdSetBufAddr done");
Status = XAxiDma_BdSetLength(BdPtr, 100,
TxRingPtr->MaxTransferLen);
if (Status != XST_SUCCESS) {
xil_printf("Tx set length %d on BD %x failed %d\r\n",
MAX_PKT_LEN, (UINTPTR)BdPtr, Status);

return XST_FAILURE;
}
xil_printf("XAxiDma_BdSetLength done");

Status = XAxiDma_BdSetAppWord(BdPtr,
XAXIDMA_LAST_APPWORD, 100);

XAxiDma_BdSetCtrl(BdPtr, XAXIDMA_BD_CTRL_TXEOF_MASK |
XAXIDMA_BD_CTRL_TXSOF_MASK);

XAxiDma_BdSetId(BdPtr, (UINTPTR)Packet);

/* Give the BD to DMA to kick off the transmission. */
Status = XAxiDma_BdRingToHw(TxRingPtr,1, BdPtr);
if (Status != XST_SUCCESS) {
xil_printf("to hw failed %d\r\n", Status);
return XST_FAILURE;
}
xil_printf("XAxiDma_BdRingToHw done");
}

Thanks & Regards,
Pavan Kumar
0 Kudos
adventure789
Visitor
Visitor
376 Views
Registered: ‎07-06-2020

Hi Srikanth,

First we tried in DMA Simple register mode due to more latency between the transfers , we moved to SG mode. We are sending continuous data for every 100 microseconds from PL to DMA(PS side). We modified the example code of dma sg poll provided by xilinx. In this we enabled the cyclic mode to reuse the Buffer Descriptors(BD) for receiving the continuous data into BD's.

Initially we will send two transfers(2) and then for every 100us we send three continuous data transfers(3,3,3....). We are able to receive 2+3 =5 transfer data correctly but while sending next three data transfers the data is missing in One of the BD's. We are attaching the code for your reference. Please help us to solve this problem.

NOTE: We are checking the data in the Receiving Side of DMA(S2MM).

For Example:

Let 1st data : 0x1111111

2nd data: 0x2222222,

3rd data : 0x3333333, 4th data : 0x4444444, 5th data : 0x5555555,

Now for every 100us 3rd to 5th data is repeated i.e.

3rd data : 0x3333333, 4th data : 0x4444444, 5th data : 0x5555555,

3rd data : 0x3333333, 4th data : 0x4444444, 5th data : 0x5555555,...



Result:

First 5 transfers,

1st data : 0x1111111

2nd data: 0x2222222

3rd data : 0x3333333,

4th data : 0x4444444,

5th data : 0x5555555,

For the second repetition of 3 data transfers,

3rd data : 0x0, 4th data : 0x4444444, 5th data : 0x5555555,

3rd data : 0x0, 4th data : 0x4444444, 5th data : 0x5555555,...

Regards,
Pavan kumar
Thanks & Regards,
Pavan Kumar
0 Kudos