UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Observer surabhiagp
Observer
365 Views
Registered: ‎12-08-2017

DMA SG fails to free BDs and collect new data in cyclic mode

Hi,

 

I have 2 concerns regarding the DMA API.

My design is setup such that the DMA receives data from a custom IP in the PL and outputs it on the console. 

I have used the multipacket SG example xaxidma_example_poll_multi_pkts.c file and modified it to receive data only.

It functions fine, the data received is as expected but I have a peculiar problem right after the data is read.

 

1) (See code below) The parameter ProcessedBdCount is 64 whereas NUMBER_OF_PACKETS is 32 (fixed value).

Is that right? Shouldn't it wait until all 64 BDs are processed?

In my case as soon as ProcessedBdCount reaches > 32 it leaves the loop... but that means the actual number provided to the function XAxiDma_BdRingFree(RxRingPtr, ProcessedBdCount, BdPtr) is incorrect (should be 64)... which is why I always get 'bd failed to free error'. Am I doing something incorrect?

 

/* Wait until the data has been received by the Rx channel */
	ProcessedBdCount = 0;

	while (ProcessedBdCount < NUMBER_OF_PACKETS) { 

		ProcessedBdCount += XAxiDma_BdRingFromHw(RxRingPtr,
					       XAXIDMA_ALL_BDS, &BdPtr);
	}
	/* Check received data */
	if (CheckData() != XST_SUCCESS) {

		return XST_FAILURE;
	}

	/* Free all processed RX BDs for future transmission */
	Status = XAxiDma_BdRingFree(RxRingPtr, ProcessedBdCount, BdPtr); //Fails here if ProcessedBdCount!=64
	if (Status != XST_SUCCESS) {
		xil_printf("free bd failed\r\n");
		return XST_FAILURE;
	}

2) I can't get the cyclic mode to function. I am not sure which functions can be repeated without requiring a reset/refresh... 

This is my current flow

 

RxSetup() //This function includes XAxiDma_BdRingCreate, XAxiDma_BdRingToHw, XAxiDma_BdRingStart

 

CheckDmaResult() //This function is written below

 

 

static int CheckDmaResult(XAxiDma * AxiDmaInstPtr)
{
	XAxiDma_BdRing *RxRingPtr;
	XAxiDma_Bd *BdPtr;
	u32 ProcessedBdCount = 0;
	u32 FreeBdCount;
	int Status;

	RxRingPtr = XAxiDma_GetRxRing(AxiDmaInstPtr);

	/* Wait until the data has been received by the Rx channel */
	ProcessedBdCount = 0;

	while (ProcessedBdCount < NUMBER_OF_PACKETS*2) {  

		ProcessedBdCount += XAxiDma_BdRingFromHw(RxRingPtr,
					       XAXIDMA_ALL_BDS, &BdPtr);
	}


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

		return XST_FAILURE;
	}

	/* Free all processed RX BDs for future transmission */
	Status = XAxiDma_BdRingFree(RxRingPtr, ProcessedBdCount, BdPtr); //Cyclic mode fails here
	if (Status != XST_SUCCESS) {
		xil_printf("free bd failed\r\n");
		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);

	return Status;
}

 

 

My question is, where is it appropriate to insert the enable cyclic mode function: 

XAxiDma_BdRingEnableCyclicDMA(RxRingPtr);
XAxiDma_SelectCyclicMode(AxiDmaInstPtr, XAXIDMA_DEVICE_TO_DMA, 1);

 

Would that be in the RxSetup() after I create it?

I used it there but the application fails at XAxiDma_BdRingFree after one iteration.

How do I make it run for multiple iterations continously?

 

According to the DMA API, Allocate->RingtoHw->HwtoRing->FreeBD->Allocate again and so on are the steps.

Is it diiferent for the cyclic mode? since it always fails at Free BD? or could there be another reason for this?

 

Any insight would be of great help!

Thank you,

Surabhi

 

0 Kudos
5 Replies
Xilinx Employee
Xilinx Employee
293 Views
Registered: ‎10-04-2016

Re: DMA SG fails to free BDs and collect new data in cyclic mode

Hi @surabhiagp,

I'm not following your question #1. Why should ProcessedBdCount be 64? The way XAxiDma_BdRingFromHw works is that it will search a descriptor chain, looking for all of the packets that have the complete bit set. If hardware has only partially completed a packet that spans multiple BDs, that packet is not included in the results.

 

It is very easy for the function to discover that the hardware has completed processing more than 32 buffer descriptors but less than the 64 buffer descriptors you are expecting. If you want to wait until all 64 BDs are processed (assuming that is how many you have allocated), you need to change NUMBER_OF_PACKETS to 64.

 

Regards,

 

Deanna

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
0 Kudos
Xilinx Employee
Xilinx Employee
291 Views
Registered: ‎10-04-2016

Re: DMA SG fails to free BDs and collect new data in cyclic mode

Hi @surabhiagp,

Regarding question #2, please take a look at the xaxidma_example_sgcyclic_intr.c. This example recycles the buffer descriptors to perform a specified number of cyclic transfers. This example was first available in the 2017.3 AXI DMA bare metal drivers (look for driver v9.4 or more recent).

 

Regards,

 

Deanna

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
0 Kudos
Visitor vlenoir
Visitor
120 Views
Registered: ‎11-27-2018

Re: DMA SG fails to free BDs and collect new data in cyclic mode

Hi @demarco,

I have a similar problem. Let say I setup 10 BDs in my DMA S2MM ring, with the last BD pointing back to the first one and the cyclic mode enable. The IRQ threshold is set to 2 so I should have an IRQ every 2 transfers. However, after the first cycle of 10 BDs the XAxiDma_BdRingFromDma returns me 0 at each IRQ which seems to be in time with what I'm expecting. Thus, I'm wondering if there is anything to do between cycles to clear the completion bit ? What I'm understanding here is that the ring is running but the new completed BD are not taken into account. I tried with and without using XAxiDma_BDRingFree but it didn't change.

bd_count = 2
radio_if_dma_rx_s2mm_done = 2
invalidate CPU1 L1 data cache (3200000 bytes @ 0x18100000)
invalidate CPU1 L1 data cache (3200000 bytes @ 0x1840D400)
bd_count = 2
radio_if_dma_rx_s2mm_done = 4
invalidate CPU1 L1 data cache (3200000 bytes @ 0x1871A800)
invalidate CPU1 L1 data cache (3200000 bytes @ 0x18A27C00)
bd_count = 2
radio_if_dma_rx_s2mm_done = 6
invalidate CPU1 L1 data cache (3200000 bytes @ 0x18D35000)
invalidate CPU1 L1 data cache (3200000 bytes @ 0x19042400)
bd_count = 2
radio_if_dma_rx_s2mm_done = 8
invalidate CPU1 L1 data cache (3200000 bytes @ 0x1934F800)
invalidate CPU1 L1 data cache (3200000 bytes @ 0x1965CC00)
bd_count = 2
radio_if_dma_rx_s2mm_done = 10
invalidate CPU1 L1 data cache (3200000 bytes @ 0x1996A000)
invalidate CPU1 L1 data cache (3200000 bytes @ 0x19C77400)
bd_count = 0
radio_if_dma_rx_s2mm_done = 10
bd_count = 0
radio_if_dma_rx_s2mm_done = 10
bd_count = 0
radio_if_dma_rx_s2mm_done = 10
bd_count = 0
radio_if_dma_rx_s2mm_done = 10

Thanks,

Vincent

 

0 Kudos
Xilinx Employee
Xilinx Employee
107 Views
Registered: ‎10-04-2016

Re: DMA SG fails to free BDs and collect new data in cyclic mode

Hi @vlenoir,

Looks like you have stumbled into a recently discovered bug in the cyclic DMA example. The fix will be available in 2019.1.

Caleb described the workaround in this thread:

https://forums.xilinx.com/t5/Embedded-Processor-System-Design/AXI-DMA-SG-Cyclic-mode-BD-ring-size-vs-BD-allocated-number/m-p/938939/highlight/false#M44052

The moral is that in Cyclic mode the hardware can ignore the Complete bit in the BD but software still needs to manage it to keep the driver happy.

Regards,

Deanna

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
Visitor vlenoir
Visitor
96 Views
Registered: ‎11-27-2018

Re: DMA SG fails to free BDs and collect new data in cyclic mode

Hi @demarco,

Thanks for the quick reply. I've followed the recommendation of @calebd and it's indeed what I was observing. The fix I'm using in xaxidma_bdring.c at line 1305 is :

// Clear BD completed flag
XAxiDma_BdWrite(CurBdPtr, XAXIDMA_BD_STS_OFFSET, BdSts & ~XAXIDMA_BD_STS_COMPLETE_MASK);
Xil_DCacheFlushRange(CurBdPtr, 64);

Now at each IOC interrupt the return BD count is equal to the actual transfers count and no more the count of the first cycle.

Best regards,

Vincent

0 Kudos