1 /*
2 * dma_ping_pong_test.c
3 *
4 * EDMA3 ping-pong buffers based data copy test case, using a DMA and a link
5 * channel.
6 *
7 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
8 *
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 *
17 * Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the
20 * distribution.
21 *
22 * Neither the name of Texas Instruments Incorporated nor the names of
23 * its contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 *
38 */
40 #include "sample.h"
42 /** Test Case Description **/
43 /**
44 * There are two big buffers of size (PING_PONG_NUM_COLUMNS * PING_PONG_NUM_ROWS).
45 * Both are present in DDR and are known as pingpongSrcBuf and pingpongDestBuf.
46 * There are two small buffers of size (PING_PONG_L1D_BUFFER_SIZE). They are known as
47 * ping buffer and pong buffer.
48 * The pingpongSrcBuf is divided into chunks, each having size of
49 * PING_PONG_L1D_BUFFER_SIZE. Data is being transferred from pingpongSrcBuf
50 * to either ping or pong buffers, using EDMA3. Logic behind using two ping pong
51 * buffers is that one can be processed by DSP while the other is used by EDMA3
52 * for data movement. So ping and pong are alternately used by EDMA3 and DSP.
53 * Also, to simulate the real world scenario, as a part of DSP processing,
54 * I am copying data from ping/pong buffers to pingpongDestBuf.
55 * In the end, I compare pingpongSrcBuf and pingpongDestBuf to check whether
56 * the algorithm has worked fine.
57 */
58 /**
59 * Number of columns in the bigger source buffer.
60 */
61 #define PING_PONG_NUM_COLUMNS (72u)
63 /**
64 * Number of columns in the bigger source buffer.
65 */
66 #define PING_PONG_NUM_ROWS (48u)
68 /* ACNT is equal to number of columns. */
69 #define PING_PONG_ACNT PING_PONG_NUM_COLUMNS
70 /* BCNT is equal to number of rows which will be transferred in one shot. */
71 #define PING_PONG_BCNT (8u)
72 /* CCNT is equal to 1. */
73 #define PING_PONG_CCNT (1u)
75 /* Number of times DMA will be triggered. */
76 #define PING_PONG_NUM_TRIGGERS (PING_PONG_NUM_ROWS/PING_PONG_BCNT)
78 /* Size of bigger buffers in DDR. */
79 #define PING_PONG_DDR_BUFFER_SIZE (PING_PONG_NUM_COLUMNS*PING_PONG_NUM_ROWS)
80 /* Size of smaller buffers in IRAM. */
81 #define PING_PONG_L1D_BUFFER_SIZE (PING_PONG_ACNT*PING_PONG_BCNT)
84 /* Ping pong source buffer */
85 #ifdef EDMA3_ENABLE_DCACHE
86 /* Cache line aligned big source buffer. */
87 /**
88 * The DATA_ALIGN pragma aligns the symbol to an alignment boundary. The
89 * alignment boundary is the maximum of the symbol\92s default alignment value
90 * or the value of the constant in bytes. The constant must be a power of 2.
91 * The syntax of the pragma in C is:
92 * #pragma DATA_ALIGN (symbol, constant);
93 */
94 #pragma DATA_ALIGN(_pingpongSrcBuf, EDMA3_CACHE_LINE_SIZE_IN_BYTES);
95 #endif /* #ifdef EDMA3_ENABLE_DCACHE */
96 #pragma DATA_SECTION(_pingpongSrcBuf, ".my_sect_ddr");
97 static signed char _pingpongSrcBuf[PING_PONG_DDR_BUFFER_SIZE];
100 /**
101 * Ping pong destination buffer.
102 * It will be used to copy data from L1D ping/pong buffers to check the
103 * validity.
104 */
105 #ifdef EDMA3_ENABLE_DCACHE
106 /* Cache line aligned big destination buffer. */
107 /**
108 * The DATA_ALIGN pragma aligns the symbol to an alignment boundary. The
109 * alignment boundary is the maximum of the symbol\92s default alignment value
110 * or the value of the constant in bytes. The constant must be a power of 2.
111 * The syntax of the pragma in C is:
112 * #pragma DATA_ALIGN (symbol, constant);
113 */
114 #pragma DATA_ALIGN(_pingpongDestBuf, EDMA3_CACHE_LINE_SIZE_IN_BYTES);
115 #endif /* #ifdef EDMA3_ENABLE_DCACHE */
116 #pragma DATA_SECTION(_pingpongDestBuf, ".my_sect_ddr");
117 static signed char _pingpongDestBuf[PING_PONG_DDR_BUFFER_SIZE];
120 /* These destination buffers are in IRAM. */
121 #ifdef EDMA3_ENABLE_DCACHE
122 /* Cache line aligned destination buffer 1 i.e. Ping buffer. */
123 /**
124 * The DATA_ALIGN pragma aligns the symbol to an alignment boundary. The
125 * alignment boundary is the maximum of the symbol\92s default alignment value
126 * or the value of the constant in bytes. The constant must be a power of 2.
127 * The syntax of the pragma in C is:
128 * #pragma DATA_ALIGN (symbol, constant);
129 */
130 #pragma DATA_ALIGN(_dstL1DBuff1, EDMA3_CACHE_LINE_SIZE_IN_BYTES);
131 #endif /* #ifdef EDMA3_ENABLE_DCACHE */
132 #pragma DATA_SECTION(_dstL1DBuff1, ".my_sect_iram");
133 static signed char _dstL1DBuff1[PING_PONG_L1D_BUFFER_SIZE];
135 #ifdef EDMA3_ENABLE_DCACHE
136 /* Cache line aligned destination buffer 2 i.e. Pong buffer. */
137 /**
138 * The DATA_ALIGN pragma aligns the symbol to an alignment boundary. The
139 * alignment boundary is the maximum of the symbol\92s default alignment value
140 * or the value of the constant in bytes. The constant must be a power of 2.
141 * The syntax of the pragma in C is:
142 * #pragma DATA_ALIGN (symbol, constant);
143 */
144 #pragma DATA_ALIGN(_dstL1DBuff2, EDMA3_CACHE_LINE_SIZE_IN_BYTES);
145 #endif /* #ifdef EDMA3_ENABLE_DCACHE */
146 #pragma DATA_SECTION(_dstL1DBuff2, ".my_sect_iram");
147 static signed char _dstL1DBuff2[PING_PONG_L1D_BUFFER_SIZE];
149 /* Pointers for all those buffers */
150 static signed char *pingpongSrcBuf;
151 static signed char *pingpongDestBuf;
152 static signed char *pingpongSrcBufCopy;
153 static signed char *pingpongDestBufCopy;
155 static signed char *dstL1DBuff1;
156 static signed char *dstL1DBuff2;
158 /** Local MemCpy function */
159 extern void edma3MemCpy(void *dst, const void *src, unsigned int len);
161 static EDMA3_DRV_Result process_ping_pong_buffer(unsigned short buff_id)
162 {
163 EDMA3_DRV_Result result = EDMA3_DRV_SOK;
165 /**
166 * Copy the L1D ping-pong buffers from L1D to DDR using CPU.
167 * This is kind of dummy processing routine.
168 */
169 if (buff_id == 1u)
170 {
171 /* Copy pong buffer */
173 /* Invalidate first if cache is enabled, otherwise CPU will take from cache. */
174 /**
175 * Since the ping/pong buffers are in IRAM, there is no need of invalidating
176 * them. If they are in DDR, invalidate them.
177 */
178 #ifdef EDMA3_ENABLE_DCACHE
179 /*
180 if (result == EDMA3_DRV_SOK)
181 {
182 result = Edma3_CacheInvalidate((unsigned int)dstL1DBuff2,
183 PING_PONG_L1D_BUFFER_SIZE);
184 }
185 */
186 #endif /* EDMA3_ENABLE_DCACHE */
188 if (result == EDMA3_DRV_SOK)
189 {
190 edma3MemCpy((void *)(pingpongDestBufCopy),
191 (const void *)(dstL1DBuff2),
192 PING_PONG_L1D_BUFFER_SIZE);
193 }
194 }
195 else
196 {
197 /* Copy ping buffer */
199 /* Invalidate first if cache is enabled, otherwise CPU will take from cache. */
200 #ifdef EDMA3_ENABLE_DCACHE
201 /*
202 if (result == EDMA3_DRV_SOK)
203 {
204 result = Edma3_CacheInvalidate((unsigned int)dstL1DBuff1,
205 PING_PONG_L1D_BUFFER_SIZE);
206 }
207 */
208 #endif /* EDMA3_ENABLE_DCACHE */
210 if (result == EDMA3_DRV_SOK)
211 {
212 edma3MemCpy((void *)(pingpongDestBufCopy),
213 (const void *)(dstL1DBuff1),
214 PING_PONG_L1D_BUFFER_SIZE);
215 }
216 }
218 /* Adjust the pointer. */
219 pingpongDestBufCopy += PING_PONG_L1D_BUFFER_SIZE;
221 return result;
222 }
225 /**
226 * \brief EDMA3 ping-pong based data copy test case, using a DMA and
227 * a link channel.
228 *
229 * \return EDMA3_DRV_SOK or EDMA3_DRV Error Code
230 */
231 EDMA3_DRV_Result edma3_test_ping_pong_mode(EDMA3_DRV_Handle hEdma)
232 {
233 EDMA3_DRV_Result result = EDMA3_DRV_SOK;
234 EDMA3_DRV_PaRAMRegs paramSet = {0,0,0,0,0,0,0,0,0,0,0,0};
235 /* One master channel */
236 unsigned int chId = 0;
237 /* Two link channels */
238 unsigned int lChId1 = 0;
239 unsigned int lChId2 = 0;
240 unsigned int tcc = 0;
241 int i;
242 unsigned int count;
243 unsigned int Istestpassed = 0u;
244 unsigned int BRCnt = 0;
245 int srcbidx = 0, desbidx = 0;
246 int srccidx = 0, descidx = 0;
247 /* PaRAM Set handle */
248 unsigned int phyaddress = 0;
249 EDMA3_DRV_ParamentryRegs *param_handle = NULL;
250 /* Number of triggers for EDMA3. */
251 unsigned int numenabled = PING_PONG_NUM_TRIGGERS;
253 pingpongSrcBuf = (signed char*)_pingpongSrcBuf;
254 pingpongDestBuf = (signed char*)_pingpongDestBuf;
255 pingpongSrcBufCopy = pingpongSrcBuf;
256 pingpongDestBufCopy = pingpongDestBuf;
257 dstL1DBuff1 = (signed char*)_dstL1DBuff1;
258 dstL1DBuff2 = (signed char*)_dstL1DBuff2;
261 /* Initalize source buffer for PING_PONG_DDR_BUFFER_SIZE bytes of data */
262 for (count = 0u; count < PING_PONG_DDR_BUFFER_SIZE; count++)
263 {
264 pingpongSrcBuf[count] = (count % 0xFF);
265 }
268 #ifdef EDMA3_ENABLE_DCACHE
269 /*
270 * Note: These functions are required if the buffer is in DDR.
271 * For other cases, where buffer is NOT in DDR, user
272 * may or may not require the below functions.
273 */
274 /* Flush the Source Buffer */
275 if (result == EDMA3_DRV_SOK)
276 {
277 result = Edma3_CacheFlush((unsigned int)pingpongSrcBuf, PING_PONG_DDR_BUFFER_SIZE);
278 }
280 /* Invalidate the Destination Buffers */
281 if (result == EDMA3_DRV_SOK)
282 {
283 result = Edma3_CacheInvalidate((unsigned int)pingpongDestBuf, PING_PONG_DDR_BUFFER_SIZE);
284 }
286 /**
287 * Since the ping/pong buffers are in IRAM, there is no need of invalidating
288 * them. If they are in DDR, invalidate them.
289 */
291 /*
292 if (result == EDMA3_DRV_SOK)
293 {
294 result = Edma3_CacheInvalidate((unsigned int)dstL1DBuff1, PING_PONG_L1D_BUFFER_SIZE);
295 }
296 if (result == EDMA3_DRV_SOK)
297 {
298 result = Edma3_CacheInvalidate((unsigned int)dstL1DBuff2, PING_PONG_L1D_BUFFER_SIZE);
299 }
300 */
301 #endif /* EDMA3_ENABLE_DCACHE */
304 /* Set B count reload as B count. */
305 BRCnt = PING_PONG_BCNT;
307 /* Setting up the SRC/DES Index */
308 srcbidx = (int)PING_PONG_ACNT;
309 desbidx = (int)PING_PONG_ACNT;
311 /* AB Sync Transfer Mode */
312 srccidx = ((int)PING_PONG_ACNT * (int)PING_PONG_BCNT);
313 descidx = ((int)PING_PONG_ACNT * (int)PING_PONG_BCNT);
315 /* Setup for DMA Channel 1*/
316 tcc = EDMA3_DRV_TCC_ANY;
317 chId = EDMA3_DRV_DMA_CHANNEL_ANY;
319 /* Request any DMA channel and any TCC */
320 if (result == EDMA3_DRV_SOK)
321 {
322 result = EDMA3_DRV_requestChannel (hEdma, &chId, &tcc,
323 (EDMA3_RM_EventQueue)0,
324 &callback1, NULL);
325 }
327 /* If successful, allocate the two link channels. */
328 if (result == EDMA3_DRV_SOK)
329 {
330 lChId1 = EDMA3_DRV_LINK_CHANNEL;
331 lChId2 = EDMA3_DRV_LINK_CHANNEL;
333 result = (
334 (EDMA3_DRV_requestChannel (hEdma, &lChId1, NULL,
335 (EDMA3_RM_EventQueue)0,
336 &callback1, NULL))
337 ||
338 (EDMA3_DRV_requestChannel (hEdma, &lChId2, NULL,
339 (EDMA3_RM_EventQueue)0,
340 &callback1, NULL))
341 );
342 }
345 /**
346 * Fill the PaRAM Sets associated with all these channels with transfer
347 * specific information.
348 */
349 if (result == EDMA3_DRV_SOK)
350 {
351 paramSet.srcBIdx = srcbidx;
352 paramSet.destBIdx = desbidx;
353 paramSet.srcCIdx = srccidx;
354 paramSet.destCIdx = descidx;
356 paramSet.aCnt = PING_PONG_ACNT;
357 paramSet.bCnt = PING_PONG_BCNT;
358 paramSet.cCnt = PING_PONG_CCNT;
360 /* For AB-synchronized transfers, BCNTRLD is not used. */
361 paramSet.bCntReload = BRCnt;
363 /* Src & Dest are in INCR modes */
364 paramSet.opt &= 0xFFFFFFFCu;
365 /* Program the TCC */
366 paramSet.opt |= ((tcc << OPT_TCC_SHIFT) & OPT_TCC_MASK);
368 /* Enable Intermediate & Final transfer completion interrupt */
369 paramSet.opt |= (1 << OPT_ITCINTEN_SHIFT);
370 paramSet.opt |= (1 << OPT_TCINTEN_SHIFT);
372 /* AB Sync Transfer Mode */
373 paramSet.opt |= (1 << OPT_SYNCDIM_SHIFT);
376 /* Program the source and dest addresses for master DMA channel */
377 paramSet.srcAddr = (unsigned int)(pingpongSrcBuf);
378 paramSet.destAddr = (unsigned int)(dstL1DBuff1);
381 /* Write to the master DMA channel first. */
382 result = EDMA3_DRV_setPaRAM(hEdma, chId, ¶mSet);
383 }
386 /* If write is successful, write the same thing to first link channel. */
387 if (result == EDMA3_DRV_SOK)
388 {
389 result = EDMA3_DRV_setPaRAM(hEdma, lChId1, ¶mSet);
390 }
393 /**
394 * Now modify the dest addresses and write the param set to the
395 * second link channel.
396 */
397 if (result == EDMA3_DRV_SOK)
398 {
399 paramSet.destAddr = (unsigned int)(dstL1DBuff2);
401 result = EDMA3_DRV_setPaRAM(hEdma, lChId2, ¶mSet);
402 }
406 /**
407 * Do the linking now.
408 * Master DMA channel is linked to IInd Link channel.
409 * IInd Link channel is linked to Ist Link channel.
410 * Ist Link channel is again linked to IInd Link channel.
411 */
412 if (result == EDMA3_DRV_SOK)
413 {
414 result = (
415 (EDMA3_DRV_linkChannel (hEdma, chId, lChId2))
416 ||
417 (EDMA3_DRV_linkChannel (hEdma, lChId2, lChId1))
418 ||
419 (EDMA3_DRV_linkChannel (hEdma, lChId1, lChId2))
420 );
421 }
423 /**
424 * Save the handle to the master dma channel param set.
425 * It will be used later to modify the source address quickly.
426 */
427 if (result == EDMA3_DRV_SOK)
428 {
429 result = EDMA3_DRV_getPaRAMPhyAddr(hEdma, chId, &phyaddress);
430 }
432 /*
433 - Algorithm used in the ping pong copy:
434 1. Application starts EDMA of first image stripe into ping buffer in L1D.
435 2. Application waits for ping EDMA to finish.
436 3. Application starts EDMA of next image stripe into pong buffer in L1D.
437 4. Application starts processing ping buffer.
438 5. Application waits for pong EDMA to finish.
439 6. Application starts EDMA of next image stripe into ping buffer in L1D.
440 7. Application starts processing pong buffer.
441 8. Repeat from step 3, until image exhausted.
442 - EDMA re-programming should be minimized to reduce overhead (PaRAM
443 accesses via slow config bus), i.e. use 2 reload PaRAM entries, and
444 only change src address fields.
445 */
447 if (result == EDMA3_DRV_SOK)
448 {
449 /* Param address successfully fetched. */
450 param_handle = (EDMA3_DRV_ParamentryRegs *)phyaddress;
452 /* Step 1 */
453 result = EDMA3_DRV_enableTransfer (hEdma, chId,
454 EDMA3_DRV_TRIG_MODE_MANUAL);
455 /**
456 * Every time a transfer is triggered, numenabled is decremented.
457 */
458 numenabled--;
460 /**
461 * Every time a transfer is triggered, pingpongSrcBufCopy is
462 * incremented to point it to correct source address.
463 */
464 pingpongSrcBufCopy += PING_PONG_L1D_BUFFER_SIZE;
465 }
468 if (result == EDMA3_DRV_SOK)
469 {
470 /* Need to activate next param till numenabled is exhausted. */
471 for (i = 0; numenabled; i++)
472 {
473 /* Step 2 */
474 /* Wait for the Completion ISR. */
475 while (irqRaised1 == 0u)
476 {
477 Task_sleep (1u);
478 }
480 irqRaised1 = 0;
482 /*
483 * Now modify the source buffer in the param set
484 * loaded to the master dma channel and trigger
485 * the transfer again..
486 */
487 param_handle->SRC = (unsigned int)pingpongSrcBufCopy;
489 /* Step 3 */
490 result = EDMA3_DRV_enableTransfer (hEdma, chId,
491 EDMA3_DRV_TRIG_MODE_MANUAL);
493 /**
494 * Every time a transfer is triggered, numenabled is decremented.
495 */
496 numenabled--;
498 /**
499 * Every time a transfer is triggered, pingpongSrcBufCopy is
500 * incremented to point it to correct source address.
501 */
502 pingpongSrcBufCopy += PING_PONG_L1D_BUFFER_SIZE;
504 if (result != EDMA3_DRV_SOK)
505 {
506 #ifdef EDMA3_DRV_DEBUG
507 EDMA3_DRV_PRINTF ("edma3_test_ping_pong_mode: EDMA3_DRV_enableTransfer " \
508 "Failed, error code: %d\r\n", result);
509 #endif /* EDMA3_DRV_DEBUG */
510 break;
511 }
513 /**
514 * Step 4, copy the ping buffer to the dest buffer in
515 * DDR (using CPU), as a part of processing.
516 */
517 result = process_ping_pong_buffer(0u);
518 if (result != EDMA3_DRV_SOK)
519 {
520 #ifdef EDMA3_DRV_DEBUG
521 EDMA3_DRV_PRINTF ("edma3_test_ping_pong_mode: process_ping_pong_buffer " \
522 "Failed, error code: %d\r\n", result);
523 #endif /* EDMA3_DRV_DEBUG */
524 break;
525 }
528 /* Step 5 */
529 /* Wait for the Completion ISR. */
530 while (irqRaised1 == 0u)
531 {
532 Task_sleep (1u);
533 }
535 /* Check the status of the completed transfer */
536 if (irqRaised1 < 0)
537 {
538 /* Some error occured, break from the FOR loop. */
539 #ifdef EDMA3_DRV_DEBUG
540 EDMA3_DRV_PRINTF ("\r\nedma3_test: Event Miss Occured!!!\r\n");
541 #endif /* EDMA3_DRV_DEBUG */
543 /* Clear the error bits first */
544 result = EDMA3_DRV_clearErrorBits (hEdma, chId);
545 break;
546 }
549 /**
550 * Last row will be transferred by the Pong buffer.
551 * So this step should be jumped over.
552 * Check for that...
553 */
554 if (numenabled)
555 {
556 irqRaised1 = 0;
558 /* Step 6 */
559 /*
560 * Now modify the source buffer in the param set
561 * again and trigger the transfer...
562 */
563 param_handle->SRC = (unsigned int)pingpongSrcBufCopy;
565 result = EDMA3_DRV_enableTransfer (hEdma, chId,
566 EDMA3_DRV_TRIG_MODE_MANUAL);
567 /**
568 * Every time a transfer is triggered, numenabled is decremented.
569 */
570 numenabled--;
572 /**
573 * Every time a transfer is triggered, pingpongSrcBufCopy is
574 * incremented to point it to correct source address.
575 */
576 pingpongSrcBufCopy += PING_PONG_L1D_BUFFER_SIZE;
578 if (result != EDMA3_DRV_SOK)
579 {
580 #ifdef EDMA3_DRV_DEBUG
581 EDMA3_DRV_PRINTF ("edma3_test_ping_pong_mode: EDMA3_DRV_enableTransfer " \
582 "Failed, error code: %d\r\n", result);
583 #endif /* EDMA3_DRV_DEBUG */
584 break;
585 }
586 }
588 /**
589 * Step 7, copy the pong buffer to the dest buffer in
590 * DDR (using CPU), as a part of processing.
591 */
592 result = process_ping_pong_buffer(1u);
593 if (result != EDMA3_DRV_SOK)
594 {
595 #ifdef EDMA3_DRV_DEBUG
596 EDMA3_DRV_PRINTF ("edma3_test_ping_pong_mode: process_ping_pong_buffer " \
597 "Failed, error code: %d\r\n", result);
598 #endif /* EDMA3_DRV_DEBUG */
599 break;
600 }
601 }
602 }
606 if (EDMA3_DRV_SOK == result)
607 {
608 /* Match the Source and Destination Buffers. */
609 for (i = 0; i < PING_PONG_DDR_BUFFER_SIZE; i++)
610 {
611 if (pingpongSrcBuf[i] != pingpongDestBuf[i])
612 {
613 Istestpassed = 0u;
614 #ifdef EDMA3_DRV_DEBUG
615 EDMA3_DRV_PRINTF("edma3_test_ping_pong_mode: Data write-read matching" \
616 "FAILED at i = %d\r\n", i);
617 #endif /* EDMA3_DRV_DEBUG */
618 break;
619 }
620 }
621 if (i == PING_PONG_DDR_BUFFER_SIZE)
622 {
623 Istestpassed = 1u;
624 }
628 /* Free the previously allocated channels. */
629 result = (
630 (EDMA3_DRV_freeChannel (hEdma, chId))
631 ||
632 (EDMA3_DRV_freeChannel (hEdma, lChId1))
633 ||
634 (EDMA3_DRV_freeChannel (hEdma, lChId2))
635 );
637 if (result != EDMA3_DRV_SOK)
638 {
639 #ifdef EDMA3_DRV_DEBUG
640 EDMA3_DRV_PRINTF("edma3_test_ping_pong_mode: EDMA3_DRV_freeChannel() FAILED, " \
641 "error code: %d\r\n", result);
642 #endif /* EDMA3_DRV_DEBUG */
643 }
644 }
647 if(Istestpassed == 1u)
648 {
649 #ifdef EDMA3_DRV_DEBUG
650 EDMA3_DRV_PRINTF("edma3_test_ping_pong_mode PASSED\r\n");
651 #endif /* EDMA3_DRV_DEBUG */
652 }
653 else
654 {
655 #ifdef EDMA3_DRV_DEBUG
656 EDMA3_DRV_PRINTF("edma3_test_ping_pong_mode FAILED\r\n");
657 #endif /* EDMA3_DRV_DEBUG */
658 result = ((EDMA3_DRV_SOK == result) ?
659 EDMA3_DATA_MISMATCH_ERROR : result);
660 }
663 return result;
664 }