/
xaxicdma_example_hybrid_poll.c
818 lines (686 loc) · 22 KB
/
xaxicdma_example_hybrid_poll.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
/******************************************************************************
* Copyright (C) 2010 - 2022 Xilinx, Inc. All rights reserved.
* Copyright (C) 2022 - 2023 Advanced Micro Devices, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xaxicdma_example_hybrid_poll.c
*
* This file demonstrates how to use xaxicdma driver on the Xilinx AXI
* CDMA core (AXICDMA) to transfer packets in hybrid transfer mode without
* interrupt. There are three transfers: a simple transfer, a sg transfer, and
* another simple transfer.
*
* The completion of the transfer is checked through polling. Using polling
* mode can give better performance on an idle system, where the DMA engine
* is lowly loaded, and the application has nothing else to do. The polling
* mode can yield better turn-around time for DMA transfers.
*
* Modify NUMBER_OF_BDS_TO_TRANSFER for a different number of BDs to be
* transferred in the SG transfer.
*
* To see the debug print, you need a uart16550 or uartlite in your system,
* and please set "-DDEBUG" in your compiler options for the example, also
* comment out the "#undef DEBUG" in xdebug.h. You need to rebuild your
* software executable.
*
* Make sure that MEMORY_BASE is defined properly as per the HW system
* and the transfer length should be cache-line size aligned.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a jz 07/30/10 First release
* 2.01a rkv 02/01/11 Modified function prototype of
* XAxiCdma_HybridPollExample to a function taking only one
* arguments i.e. device id.
* 2.01a srt 03/06/12 Added V7 DDR Base Address to fix CR 649405.
* Modified Flushing and Invalidation of Caches to fix CRs
* 648103, 648701.
* 2.02a srt 03/01/13 Updated DDR base address for IPI designs (CR 703656).
* 4.1 adk 01/07/16 Updated DDR base address for Ultrascale (CR 799532) and
* removed the defines for S6/V6.
* 4.3 ms 01/22/17 Modified xil_printf statement in main function to
* ensure that "Successfully ran" and "Failed" strings are
* available in all examples. This is a fix for CR-965028.
* ms 04/05/17 Modified Comment lines in functions to
* recognize it as documentation block for doxygen
* generation of examples.
* 4.4 rsp 02/22/18 Support data buffers above 4GB.Use UINTPTR for storing
* and typecasting buffer address(CR-995116).
* 4.8 sk 07/10/20 Fix CheckData failure by adding the Cache operations for
* receive and destination buffers.
* 4.8 sk 09/30/20 Modify the buffer length to make it cache-line aligned.
* 4.10 sa 08/12/22 Updated the example to use latest MIG cannoical define
* i.e XPAR_MIG_0_C0_DDR4_MEMORY_MAP_BASEADDR.
* 4.11 sa 09/29/22 Fix infinite loops in the examples.
* </pre>
*
****************************************************************************/
#include "xaxicdma.h"
#include "xdebug.h"
#include "xil_cache.h"
#include "xenv.h" /* memset */
#include "xparameters.h"
#include "xil_util.h"
#include "sleep.h"
#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.
*/
#ifndef SDT
#ifndef TESTAPP_GEN
#define DMA_CTRL_DEVICE_ID XPAR_AXICDMA_0_DEVICE_ID
#endif
#ifdef XPAR_AXI_7SDDR_0_S_AXI_BASEADDR
#define MEMORY_BASE XPAR_AXI_7SDDR_0_S_AXI_BASEADDR
#elif XPAR_MIG7SERIES_0_BASEADDR
#define MEMORY_BASE XPAR_MIG7SERIES_0_BASEADDR
#elif XPAR_MIG_0_C0_DDR4_MEMORY_MAP_BASEADDR
#define MEMORY_BASE XPAR_MIG_0_C0_DDR4_MEMORY_MAP_BASEADDR
#elif XPAR_PSU_DDR_0_S_AXI_BASEADDR
#define MEMORY_BASE XPAR_PSU_DDR_0_S_AXI_BASEADDR
#endif
#else
#ifdef XPAR_MEM0_BASEADDRESS
#define MEMORY_BASE XPAR_MEM0_BASEADDRESS
#endif
#define AXICDMA_BASE_ADDR XPAR_XAXICDMA_0_BASEADDR
#endif
#ifndef MEMORY_BASE
#warning CHECK FOR THE VALID DDR ADDRESS IN XPARAMETERS.H, \
DEFAULT SET TO 0x01000000
#define MEMORY_BASE 0x01000000
#endif
#define BD_SPACE_BASE (MEMORY_BASE + 0x03000000)
#define BD_SPACE_HIGH (MEMORY_BASE + 0x03001FFF)
#define TX_BUFFER_BASE (MEMORY_BASE + 0x00630000)
#define RX_BUFFER_BASE (MEMORY_BASE + 0x00660000)
#define RX_BUFFER_HIGH (MEMORY_BASE + 0x0068FFFF)
#define BUFFER_BYTESIZE 128 /* Length of the buffers for simple transfer */
#define MAX_PKT_LEN 1024 /* Length of BD for SG transfer */
#define MARK_UNCACHEABLE 0x701
/* Number of BDs in the transfer example
* We show how to submit multiple BDs for one transmit.
*/
#define NUMBER_OF_BDS_TO_TRANSFER 30
#define RESET_LOOP_COUNT 10 /* Number of times to check reset is done */
#define POLL_TIMEOUT_COUNTER 1000000U
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
#if defined(XPAR_UARTNS550_0_BASEADDR)
static void Uart550_Setup(void);
#endif
static int SetupSgTransfer(XAxiCdma *InstancePtr);
static int SubmitSgTransfer(XAxiCdma *InstancePtr);
static int CheckSgCompletion(XAxiCdma *InstancePtr);
static int CheckData(u8 *SrcPtr, u8 *DestPtr, int Length);
static int DoSimplePollTransfer(XAxiCdma *InstancePtr, int Length, int Retries);
static int DoSgPollTransfer(XAxiCdma *InstancePtr, int Length);
#ifndef SDT
int XAxiCdma_HybridPollExample(u16 DeviceId);
#else
int XAxiCdma_HybridPollExample(UINTPTR BaseAddress);
#endif
/************************** Variable Definitions *****************************/
static XAxiCdma Engine; /* Instance of the XAxiCdma */
/* Source and Destination buffer for simple transfer.
*/
volatile static u8 SrcBuffer[BUFFER_BYTESIZE] __attribute__ ((aligned (64)));
volatile static u8 DestBuffer[BUFFER_BYTESIZE] __attribute__ ((aligned (64)));
/* Transmit buffer for scatter gather transfer.
*/
static u32 *TransmitBufferPtr = (u32 *) TX_BUFFER_BASE;
static u32 *ReceiveBufferPtr = (u32 *) RX_BUFFER_BASE;
/* Shared variables used to test the callbacks.
*/
volatile static u32 Done = 0; /* Dma transfer is done */
volatile static u32 Error = 0; /* Dma Error occurs */
/*****************************************************************************/
/**
* The entry point for this example. It sets up uart16550 if one is available,
* invokes the example function, and reports the execution status.
*
* @param None.
*
* @return
* - XST_SUCCESS if example finishes successfully
* - XST_FAILURE if example fails.
*
* @note None.
*
******************************************************************************/
#ifndef TESTAPP_GEN
int main()
{
int Status;
#if defined(XPAR_UARTNS550_0_BASEADDR)
Uart550_Setup();
#endif
xil_printf("\r\n--- Entering main() --- \r\n");
/* Run the poll example for simple transfer
*/
#ifndef SDT
Status = XAxiCdma_HybridPollExample(DMA_CTRL_DEVICE_ID);
#else
Status = XAxiCdma_HybridPollExample(AXICDMA_BASE_ADDR);
#endif
if (Status != (XST_SUCCESS)) {
xil_printf("Axicdma Hybrid polled Example Failed\r\n");
return (XST_FAILURE);
}
xil_printf("Successfully ran Axicdma Hybrid polled Example\r\n");
xil_printf("--- Exiting main() --- \r\n");
return XST_SUCCESS;
}
#endif
#if defined(XPAR_UARTNS550_0_BASEADDR)
/*****************************************************************************/
/*
* This function setup the baudrate to 9600 and data bits to 8 in Uart16550
*
* @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 setup the driver for scatter gather transfer
*
* @param InstancePtr is a pointer to the XAxiCdma instance
*
* @return
* - XST_SUCCESS if setup successful
* - XST_FAILURE if setup failed with error
*
* @note None.
*
******************************************************************************/
static int SetupSgTransfer(XAxiCdma *InstancePtr)
{
int Status;
XAxiCdma_Bd BdTemplate;
int BdCount;
u8 *SrcBufferPtr;
int Index;
/* Setup BD ring */
BdCount = XAxiCdma_BdRingCntCalc(XAXICDMA_BD_MINIMUM_ALIGNMENT,
BD_SPACE_HIGH - BD_SPACE_BASE + 1,
(UINTPTR)BD_SPACE_BASE);
Status = XAxiCdma_BdRingCreate(InstancePtr, BD_SPACE_BASE,
BD_SPACE_BASE, XAXICDMA_BD_MINIMUM_ALIGNMENT, BdCount);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR, "Create BD ring failed %d\r\n",
Status);
return XST_FAILURE;
}
/*
* Setup a BD template to copy to every BD.
*/
XAxiCdma_BdClear(&BdTemplate);
Status = XAxiCdma_BdRingClone(InstancePtr, &BdTemplate);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR, "Clone BD ring failed %d\r\n",
Status);
return XST_FAILURE;
}
/* Initialize receive buffer to 0's and transmit buffer with pattern
*/
memset((void *)ReceiveBufferPtr, 0,
MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER);
SrcBufferPtr = (u8 *)TransmitBufferPtr;
for (Index = 0; Index < MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER; Index++) {
SrcBufferPtr[Index] = Index & 0xFF;
}
/* Flush the TransmitBuffer and ReceiveBuffer before the DMA transfer,
* in case the Data Cache is enabled
*/
Xil_DCacheFlushRange((UINTPTR)TransmitBufferPtr,
MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER);
Xil_DCacheFlushRange((UINTPTR)ReceiveBufferPtr,
MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER);
return XST_SUCCESS;
}
/*****************************************************************************/
/*
* This function submit the scatter gather transfer to the hardware
*
* @param InstancePtr is a pointer to the XAxiCdma instance
*
* @return
* - XST_SUCCESS if submission successful
* - XST_FAILURE if submission failed with error
*
* @note None.
*
******************************************************************************/
static int SubmitSgTransfer(XAxiCdma *InstancePtr)
{
XAxiCdma_Bd *BdPtr;
XAxiCdma_Bd *BdCurPtr;
int Status;
int Index;
UINTPTR SrcBufferAddr;
UINTPTR DstBufferAddr;
Status = XAxiCdma_BdRingAlloc(InstancePtr,
NUMBER_OF_BDS_TO_TRANSFER, &BdPtr);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR, "Failed bd alloc\r\n");
return XST_FAILURE;
}
SrcBufferAddr = (UINTPTR)TransmitBufferPtr;
DstBufferAddr = (UINTPTR)ReceiveBufferPtr;
BdCurPtr = BdPtr;
/* Set up the BDs
*/
for (Index = 0; Index < NUMBER_OF_BDS_TO_TRANSFER; Index++) {
Status = XAxiCdma_BdSetSrcBufAddr(BdCurPtr, SrcBufferAddr);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Set src addr failed %d, %x/%x\r\n",
Status, (unsigned int)BdCurPtr,
(unsigned int)SrcBufferAddr);
return XST_FAILURE;
}
Status = XAxiCdma_BdSetDstBufAddr(BdCurPtr, DstBufferAddr);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Set dst addr failed %d, %x/%x\r\n",
Status, (unsigned int)BdCurPtr,
(unsigned int)DstBufferAddr);
return XST_FAILURE;
}
Status = XAxiCdma_BdSetLength(BdCurPtr, MAX_PKT_LEN);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Set BD length failed %d\r\n", Status);
return XST_FAILURE;
}
SrcBufferAddr += MAX_PKT_LEN;
DstBufferAddr += MAX_PKT_LEN;
BdCurPtr = XAxiCdma_BdRingNext(InstancePtr, BdCurPtr);
}
/* Give the BDs to hardware */
Status = XAxiCdma_BdRingToHw(InstancePtr, NUMBER_OF_BDS_TO_TRANSFER,
BdPtr, NULL, NULL);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR, "Failed to hw %d\r\n", Status);
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/*
* This function checks the completion of the scatter gather transfer
*
* @param InstancePtr is a pointer to the XAxiCdma instance
*
* @return Number of BDs that hardware has finished transfer
*
* @note None.
*
******************************************************************************/
static int CheckSgCompletion(XAxiCdma *InstancePtr)
{
int BdCount;
XAxiCdma_Bd *BdPtr;
XAxiCdma_Bd *BdCurPtr;
int Status;
int Index;
/* Check whether the hardware has encountered any problems.
* In some error cases, the DMA engine may not able to update the
* BD that has caused the problem.
*/
if (XAxiCdma_GetError(InstancePtr) != 0x0) {
Error = 1;
return 0;
}
/* Get all processed BDs from hardware
*/
BdCount = XAxiCdma_BdRingFromHw(InstancePtr, XAXICDMA_ALL_BDS, &BdPtr);
/* Check finished BDs then release them
*/
if (BdCount > 0) {
BdCurPtr = BdPtr;
for (Index = 0; Index < BdCount; Index++) {
/* If the completed BD has error bit set,
* then the example fails
*/
if (XAxiCdma_BdGetSts(BdCurPtr) &
XAXICDMA_BD_STS_ALL_ERR_MASK) {
Error = 1;
return 0;
}
BdCurPtr = XAxiCdma_BdRingNext(InstancePtr, BdCurPtr);
}
/* Release the BDs so later submission can use them
*/
Status = XAxiCdma_BdRingFree(InstancePtr, BdCount, BdPtr);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Error free BD %d\r\n", Status);
Error = 1;
return 0;
}
Done += BdCount;
}
return Done;
}
/*****************************************************************************/
/*
* This function checks that two buffers have the same data
*
* @param SrcPtr is the source buffer
* @param DestPtr is the destination buffer
* @param Length is the length of the buffer to check
*
* @return
* - XST_SUCCESS if the two buffer matches
* - XST_FAILURE otherwise
*
* @note None.
*
******************************************************************************/
static int CheckData(u8 *SrcPtr, u8 *DestPtr, int Length)
{
int Index;
/* Invalidate the DestBuffer before receiving the data,
* in case the data cache is enabled
*/
Xil_DCacheInvalidateRange((UINTPTR)DestPtr, Length);
for (Index = 0; Index < Length; Index++) {
if ( DestPtr[Index] != SrcPtr[Index]) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Data check failure %d: %x/%x\r\n",
Index, (unsigned int)DestPtr[Index],
(unsigned int)SrcPtr[Index]);
return XST_FAILURE;
}
}
return XST_SUCCESS;
}
/*****************************************************************************/
/*
* This function does one simple transfer in polled mode
*
* @param InstancePtr is a pointer to the XAxiCdma instance
* @param Length is the transfer length
* @param Retries is how many times to retry on submission
*
* @return
* - XST_SUCCESS if transfer is successful
* - XST_FAILURE if either the transfer fails or the data has error
*
* @note None.
*
******************************************************************************/
static int DoSimplePollTransfer(XAxiCdma *InstancePtr, int Length, int Retries)
{
u32 Index;
u8 *SrcPtr;
u8 *DestPtr;
int Status = 0;
/* Initialize the source buffer bytes with a pattern and the
* the destination buffer bytes to zero
*/
SrcPtr = (u8 *)SrcBuffer;
DestPtr = (u8 *)DestBuffer;
for (Index = 0; Index < BUFFER_BYTESIZE; Index++) {
SrcPtr[Index] = Index & 0xFF;
DestPtr[Index] = 0;
}
/* Flush the SrcBuffer and DestBuffer before the DMA transfer,
* in case the Data Cache is enabled
*/
Xil_DCacheFlushRange((UINTPTR)&SrcBuffer, Length);
Xil_DCacheFlushRange((UINTPTR)&DestBuffer, Length);
/* Try to start the DMA transfer
*/
while (Retries) {
Retries -= 1;
Status = XAxiCdma_SimpleTransfer(InstancePtr, (UINTPTR)SrcBuffer,
(UINTPTR)DestBuffer, Length, NULL, NULL);
if (Status == XST_SUCCESS) {
break;
}
}
/* Return failure if failed to submit the transfer
*/
if (!Retries) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Failed to submit the transfer %d\r\n", Status);
return XST_FAILURE;
}
/* Wait until the DMA transfer is done or timeout
*/
Status = Xil_WaitForEvent(InstancePtr->BaseAddr + XAXICDMA_SR_OFFSET,
XAXICDMA_SR_IDLE_MASK, XAXICDMA_SR_IDLE_MASK, POLL_TIMEOUT_COUNTER);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Failed to complete the transfer with %d\r\n", Status);
return XST_FAILURE;
}
/* If the hardware has errors, this example fails
* This is a poll example, no interrupt handler is involved.
* Therefore, error conditions are not cleared by the driver.
*/
Error = XAxiCdma_GetError(InstancePtr);
if (Error != 0x0) {
int TimeOut = RESET_LOOP_COUNT;
xdbg_printf(XDBG_DEBUG_ERROR, "Transfer has error %x\r\n",
(unsigned int)Error);
/* Need to reset the hardware to restore to the correct state
*/
XAxiCdma_Reset(InstancePtr);
while (TimeOut) {
if (XAxiCdma_ResetIsDone(InstancePtr)) {
break;
}
TimeOut -= 1;
}
/* Reset has failed, print a message to notify the user
*/
if (!TimeOut) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Reset hardware failed with %d\r\n", Status);
}
return XST_FAILURE;
}
/* Transfer completes successfully, check data
*/
Status = CheckData(SrcPtr, DestPtr, Length);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR, "Check data failed for simple "
"transfer\r\n");
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/*
* This function does one scatter gather transfer with 2 BDs in polled mode
*
* @param InstancePtr is a pointer to the XAxiCdma instance
* @param Length is the transfer length
*
* @return
* - XST_SUCCESS if transfer is successful
* - XST_FAILURE if either the transfer fails or the data has
* error
*
* @note None.
*
******************************************************************************/
static int DoSgPollTransfer(XAxiCdma *InstancePtr, int Length)
{
int Status;
u8 *SrcPtr;
u8 *DstPtr;
int TimeOut = POLL_TIMEOUT_COUNTER;
SrcPtr = (u8 *)TransmitBufferPtr;
DstPtr = (u8 *)ReceiveBufferPtr;
#ifdef __aarch64__
Xil_SetTlbAttributes(BD_SPACE_BASE, MARK_UNCACHEABLE);
#endif
/* Submit the DMA transfer
*/
Status = SubmitSgTransfer(InstancePtr);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Do SG transfer failed with %d\r\n", Status);
return XST_FAILURE;
}
/*
* Wait until the DMA transfer is done or 1usec * 10^6 iterations
* of timeout occurs.
*/
while (TimeOut) {
if ((CheckSgCompletion(InstancePtr) >=
NUMBER_OF_BDS_TO_TRANSFER) && !Error) {
break;
}
TimeOut--;
usleep(1U);
}
if (Error) {
return XST_FAILURE;
}
/* Transfer completed successfully, check data
*/
Status = CheckData(SrcPtr, DstPtr,
MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR, "Check data failed for sg "
"transfer\r\n");
return XST_FAILURE;
}
/* Test finishes successfully, return successfully
*/
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* The example to do hybrid transfers through polling. The transfer sequence is:
* a simple polled transfer
* a scatter gather polled transfer with multiple BDs
* a simple polled transfer
*
* @param DeviceId is the Device Id of the XAxiCdma instance
*
* @return
* - XST_SUCCESS if example finishes successfully
* - XST_FAILURE if error occurs
*
* @note If the hardware build has problems with interrupt, then this
* function hangs
*
******************************************************************************/
#ifndef SDT
int XAxiCdma_HybridPollExample(u16 DeviceId)
#else
int XAxiCdma_HybridPollExample(UINTPTR BaseAddress)
#endif
{
XAxiCdma_Config *CfgPtr;
int Status;
int SubmitTries = 10; /* try 10 times on submission */
/* Initialize the XAxiCdma device.
*/
#ifndef SDT
CfgPtr = XAxiCdma_LookupConfig(DeviceId);
if (!CfgPtr) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Cannot find config structure for device %d\r\n",
DeviceId);
return XST_FAILURE;
}
#else
CfgPtr = XAxiCdma_LookupConfig(BaseAddress);
if (!CfgPtr) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Cannot find config structure for device %llx\r\n",
BaseAddress);
return XST_FAILURE;
}
#endif
Status = XAxiCdma_CfgInitialize(&Engine, CfgPtr,
CfgPtr->BaseAddress);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Initialization failed with %d\r\n", Status);
return XST_FAILURE;
}
/* Disable interrupts, we use polling mode
*/
XAxiCdma_IntrDisable(&Engine, XAXICDMA_XR_IRQ_ALL_MASK);
/* Setup scatter gather transfer
*/
Status = SetupSgTransfer(&Engine);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Setup SG transfer failed with error %d\r\n", Status);
return XST_FAILURE;
}
Done = 0;
Error = 0;
/* Do one simple transfer
*/
Status = DoSimplePollTransfer(&Engine,
BUFFER_BYTESIZE, SubmitTries);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR,
"First simple transfer failed with error %d\r\n", Status);
return XST_FAILURE;
}
xil_printf("First simple transfer successful\r\n");
Done = 0;
Error = 0;
/* Then do a scatter gather transfer
*/
Status = DoSgPollTransfer(&Engine, BUFFER_BYTESIZE);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Scatter gather transfer failed with error %d\r\n", Status);
return XST_FAILURE;
}
xil_printf("Scatter gather transfer successful\r\n");
Done = 0;
Error = 0;
/* Finally, do another simple transfer
*/
Status = DoSimplePollTransfer(&Engine,
BUFFER_BYTESIZE, SubmitTries);
if (Status != XST_SUCCESS) {
xdbg_printf(XDBG_DEBUG_ERROR,
"Second simple transfer failed with error %d\r\n", Status);
return XST_FAILURE;
}
xil_printf("Second simple transfer successful\r\n");
/* Test finishes successfully
*/
return XST_SUCCESS;
}