1 /*
2 * dma_chain_test.c
3 *
4 * Test case demonstrating the usgae of DMA channels for transferring data
5 * between two memory locations. The two DMA channels are chained to each other.
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 extern signed char _srcBuff1[MAX_BUFFER_SIZE];
43 extern signed char _srcBuff2[MAX_BUFFER_SIZE];
44 extern signed char _dstBuff1[MAX_BUFFER_SIZE];
45 extern signed char _dstBuff2[MAX_BUFFER_SIZE];
47 extern signed char *srcBuff1;
48 extern signed char *srcBuff2;
49 extern signed char *dstBuff1;
50 extern signed char *dstBuff2;
52 extern void *AppSemHandle2;
53 /**
54 * \brief EDMA3 mem-to-mem data copy test case, using two DMA channels,
55 * chained to each other.
56 *
57 * \param acnt [IN] Number of bytes in an array
58 * \param bcnt [IN] Number of arrays in a frame
59 * \param ccnt [IN] Number of frames in a block
60 * \param syncType [IN] Synchronization type (A/AB Sync)
61 *
62 * \return EDMA3_DRV_SOK or EDMA3_DRV Error Code
63 */
64 EDMA3_DRV_Result edma3_test_with_chaining(
65 EDMA3_DRV_Handle hEdma,
66 uint32_t acnt,
67 uint32_t bcnt,
68 uint32_t ccnt,
69 EDMA3_DRV_SyncType syncType)
70 {
71 EDMA3_DRV_ChainOptions chain = {EDMA3_DRV_TCCHEN_DIS,
72 EDMA3_DRV_ITCCHEN_DIS,
73 EDMA3_DRV_TCINTEN_DIS,
74 EDMA3_DRV_ITCINTEN_DIS};
75 EDMA3_DRV_Result result = EDMA3_DRV_SOK;
76 uint32_t BRCnt = 0;
77 int srcbidx = 0, desbidx = 0;
78 int srccidx = 0, descidx = 0;
79 uint32_t ch1Id = 0;
80 uint32_t ch2Id = 0;
81 uint32_t tcc1 = 0;
82 uint32_t tcc2 = 0;
83 int i;
84 uint32_t numenabled = 0;
85 uint32_t count;
86 uint32_t Istestpassed1 = 0u;
87 uint32_t Istestpassed2 = 0u;
90 srcBuff1 = (signed char*) GLOBAL_ADDR(_srcBuff1);
91 dstBuff1 = (signed char*) GLOBAL_ADDR(_dstBuff1);
92 srcBuff2 = (signed char*) GLOBAL_ADDR(_srcBuff2);
93 dstBuff2 = (signed char*) GLOBAL_ADDR(_dstBuff2);
96 /* Initalize source and destination buffers */
97 for (count = 0u; count < (acnt*bcnt*ccnt); count++)
98 {
99 srcBuff1[count] = (int)count+4;
100 srcBuff2[count] = (int)count+4;
101 /**
102 * No need to initialize the destination buffer as it is being invalidated.
103 dstBuff1[count] = initval;
104 dstBuff2[count] = initval;
105 */
106 }
109 #ifdef EDMA3_ENABLE_DCACHE
110 /*
111 * Note: These functions are required if the buffer is in DDR.
112 * For other cases, where buffer is NOT in DDR, user
113 * may or may not require the below functions.
114 */
115 /* Flush the Source Buffers */
116 if (result == EDMA3_DRV_SOK)
117 {
118 result = Edma3_CacheFlush((uint32_t)srcBuff1, (acnt*bcnt*ccnt));
119 }
120 if (result == EDMA3_DRV_SOK)
121 {
122 result = Edma3_CacheFlush((uint32_t)srcBuff2, (acnt*bcnt*ccnt));
123 }
125 /* Invalidate the Destination Buffers */
126 if (result == EDMA3_DRV_SOK)
127 {
128 result = Edma3_CacheInvalidate((uint32_t)dstBuff1, (acnt*bcnt*ccnt));
129 }
130 if (result == EDMA3_DRV_SOK)
131 {
132 result = Edma3_CacheInvalidate((uint32_t)dstBuff2, (acnt*bcnt*ccnt));
133 }
134 #endif /* EDMA3_ENABLE_DCACHE */
137 /* Set B count reload as B count. */
138 BRCnt = bcnt;
140 /* Setting up the SRC/DES Index */
141 srcbidx = (int)acnt;
142 desbidx = (int)acnt;
144 if (syncType == EDMA3_DRV_SYNC_A)
145 {
146 /* A Sync Transfer Mode */
147 srccidx = (int)acnt;
148 descidx = (int)acnt;
149 }
150 else
151 {
152 /* AB Sync Transfer Mode */
153 srccidx = ((int)acnt * (int)bcnt);
154 descidx = ((int)acnt * (int)bcnt);
155 }
158 /* Transfer complete chaining enable. */
159 chain.tcchEn = EDMA3_DRV_TCCHEN_EN;
160 /* Intermediate transfer complete chaining enable. */
161 chain.itcchEn = EDMA3_DRV_ITCCHEN_EN;
162 /* Transfer complete interrupt is enabled. */
163 chain.tcintEn = EDMA3_DRV_TCINTEN_EN;
164 /* Intermediate transfer complete interrupt is disabled. */
165 chain.itcintEn = EDMA3_DRV_ITCINTEN_DIS;
168 /* Setup for Channel 1*/
169 tcc1 = EDMA3_DRV_TCC_ANY;
170 ch1Id = EDMA3_DRV_DMA_CHANNEL_ANY;
172 if (result == EDMA3_DRV_SOK)
173 {
174 result = EDMA3_DRV_requestChannel (hEdma, &ch1Id, &tcc1,
175 (EDMA3_RM_EventQueue)0,
176 &callback1, NULL);
177 }
179 if (result == EDMA3_DRV_SOK)
180 {
181 result = EDMA3_DRV_setSrcParams (hEdma, ch1Id,
182 (uint32_t)(srcBuff1),
183 EDMA3_DRV_ADDR_MODE_INCR,
184 EDMA3_DRV_W8BIT);
185 }
187 if (result == EDMA3_DRV_SOK)
188 {
189 result = EDMA3_DRV_setDestParams (hEdma, ch1Id,
190 (uint32_t)(dstBuff1),
191 EDMA3_DRV_ADDR_MODE_INCR,
192 EDMA3_DRV_W8BIT);
193 }
195 if (result == EDMA3_DRV_SOK)
196 {
197 result = EDMA3_DRV_setSrcIndex (hEdma, ch1Id, srcbidx, srccidx);
198 }
200 if (result == EDMA3_DRV_SOK)
201 {
202 result = EDMA3_DRV_setDestIndex (hEdma, ch1Id, desbidx, descidx);
203 }
205 if (result == EDMA3_DRV_SOK)
206 {
207 if (syncType == EDMA3_DRV_SYNC_A)
208 {
209 result = EDMA3_DRV_setTransferParams (hEdma, ch1Id, acnt, bcnt,
210 ccnt,BRCnt,
211 EDMA3_DRV_SYNC_A);
212 }
213 else
214 {
215 /* AB Sync Transfer Mode */
216 result = EDMA3_DRV_setTransferParams (hEdma, ch1Id, acnt, bcnt,
217 ccnt, BRCnt,
218 EDMA3_DRV_SYNC_AB);
219 }
220 }
223 if (result == EDMA3_DRV_SOK)
224 {
225 /* Setup for Channel 2 */
226 tcc2 = EDMA3_DRV_TCC_ANY;
227 ch2Id = EDMA3_DRV_DMA_CHANNEL_ANY;
229 result = EDMA3_DRV_requestChannel (hEdma, &ch2Id, &tcc2,
230 (EDMA3_RM_EventQueue)0,
231 &callback2, NULL);
232 }
234 if (result == EDMA3_DRV_SOK)
235 {
236 result = EDMA3_DRV_setSrcParams (hEdma, ch2Id, (uint32_t)(srcBuff2),
237 EDMA3_DRV_ADDR_MODE_INCR,
238 EDMA3_DRV_W8BIT);
239 }
241 if (result == EDMA3_DRV_SOK)
242 {
243 result = EDMA3_DRV_setDestParams (hEdma, ch2Id,
244 (uint32_t)(dstBuff2),
245 EDMA3_DRV_ADDR_MODE_INCR,
246 EDMA3_DRV_W8BIT);
247 }
249 if (result == EDMA3_DRV_SOK)
250 {
251 result = EDMA3_DRV_setSrcIndex (hEdma, ch2Id, srcbidx, srccidx);
252 }
254 if (result == EDMA3_DRV_SOK)
255 {
256 result = EDMA3_DRV_setDestIndex (hEdma, ch2Id, desbidx, descidx);
257 }
259 if (result == EDMA3_DRV_SOK)
260 {
261 if (syncType == EDMA3_DRV_SYNC_A)
262 {
263 result = EDMA3_DRV_setTransferParams (hEdma, ch2Id, acnt, bcnt,
264 ccnt, BRCnt,
265 EDMA3_DRV_SYNC_A);
266 }
267 else
268 {
269 /* AB Sync Transfer Mode */
270 result = EDMA3_DRV_setTransferParams (hEdma, ch2Id, acnt, bcnt,
271 ccnt, BRCnt,
272 EDMA3_DRV_SYNC_AB);
273 }
274 }
277 if (result == EDMA3_DRV_SOK)
278 {
279 /**
280 * Enable the Transfer Completion Interrupt on the Chained Channel
281 * (Ch 2).
282 */
283 result = EDMA3_DRV_setOptField (hEdma, ch2Id,
284 EDMA3_DRV_OPT_FIELD_TCINTEN, 1u);
285 }
287 if (result == EDMA3_DRV_SOK)
288 {
289 /**
290 * Enable the Intermediate Transfer Completion Interrupt on the
291 * Chained Channel (Ch 2).
292 */
293 result = EDMA3_DRV_setOptField (hEdma, ch2Id,
294 EDMA3_DRV_OPT_FIELD_ITCINTEN, 1u);
295 }
298 if (result == EDMA3_DRV_SOK)
299 {
300 /* Now chain the two channels together. */
301 result = EDMA3_DRV_chainChannel(hEdma, ch1Id, ch2Id,
302 (EDMA3_DRV_ChainOptions *)&chain);
303 }
306 /*Need to activate next param*/
307 if (syncType == EDMA3_DRV_SYNC_A)
308 {
309 numenabled = bcnt * ccnt;
310 }
311 else
312 {
313 /* AB Sync Transfer Mode */
314 numenabled = ccnt;
315 }
318 if (result == EDMA3_DRV_SOK)
319 {
320 for (i = 0; i < numenabled; i++)
321 {
322 irqRaised2 = 0;
324 /*
325 * Now enable the transfer for Master channel as many times
326 * as calculated above.
327 */
328 result = EDMA3_DRV_enableTransfer (hEdma, ch1Id,
329 EDMA3_DRV_TRIG_MODE_MANUAL);
330 if (result != EDMA3_DRV_SOK)
331 {
332 #ifdef EDMA3_DRV_DEBUG
333 EDMA3_DRV_PRINTF ("error from edma3_test_with_chaining\n\r\n");
334 #endif /* EDMA3_DRV_DEBUG */
335 break;
336 }
339 /**
340 * Transfer on the master channel (ch1Id) will finish after some
341 * time.
342 * Now, because of the enabling of intermediate chaining on channel
343 * 1, after the transfer gets over, a sync event will be sent
344 * to channel 2, which will trigger the transfer on it.
345 * Also, Final and Intermediate Transfer Complete
346 * Interrupts are enabled on channel 2, so we should wait for the
347 * completion ISR on channel 2 first, before proceeding
348 * ahead.
349 */
350 edma3OsSemTake(AppSemHandle2, EDMA3_OSSEM_NO_TIMEOUT);
351 while (irqRaised2 == 0)
352 {
353 /* Wait for the Completion ISR on channel 2. */
354 printf ("waiting for interrupt...\n");
355 }
357 /* Check the status of the completed transfer */
358 if (irqRaised2 < 0)
359 {
360 /* Some error occured, break from the FOR loop. */
361 #ifdef EDMA3_DRV_DEBUG
362 EDMA3_DRV_PRINTF ("\r\nedma3_test_with_chaining: Event Miss Occured!!!\r\n");
363 #endif /* EDMA3_DRV_DEBUG */
365 /* Clear the error bits first */
366 result = EDMA3_DRV_clearErrorBits (hEdma, ch1Id);
368 break;
369 }
370 }
371 }
374 if (result == EDMA3_DRV_SOK)
375 {
376 /* Match the Source and Destination Buffers. */
377 if (result == EDMA3_DRV_SOK)
378 {
379 for (i = 0; i < (acnt*bcnt*ccnt); i++)
380 {
381 if (srcBuff1[i] != dstBuff1[i])
382 {
383 Istestpassed1 = 0;
385 #ifdef EDMA3_DRV_DEBUG
386 EDMA3_DRV_PRINTF("edma3_test_with_chaining: Data write-read " \
387 "matching FAILED at i = %d " \
388 "(srcBuff1 -> dstBuff1)\r\n", i);
389 #endif /* EDMA3_DRV_DEBUG */
390 break;
391 }
392 }
393 if (i == (acnt*bcnt*ccnt))
394 {
395 Istestpassed1 = 1u;
396 }
399 for (i = 0; i < (acnt*bcnt*ccnt); i++)
400 {
401 if (srcBuff2[i] != dstBuff2[i])
402 {
403 Istestpassed2 = 0;
405 #ifdef EDMA3_DRV_DEBUG
406 EDMA3_DRV_PRINTF("edma3_test_with_chaining: Data write-read " \
407 "matching FAILED at i = %d " \
408 "(srcBuff2 -> dstBuff2)\r\n", i);
409 #endif /* EDMA3_DRV_DEBUG */
410 break;
411 }
412 }
413 if (i == (acnt*bcnt*ccnt))
414 {
415 Istestpassed2 = 1u;
416 }
417 }
420 if (result == EDMA3_DRV_SOK)
421 {
422 /* Free the previously allocated channels. */
423 result = EDMA3_DRV_freeChannel (hEdma, ch1Id);
424 if (result != EDMA3_DRV_SOK)
425 {
426 #ifdef EDMA3_DRV_DEBUG
427 EDMA3_DRV_PRINTF("edma3_test_with_chaining: EDMA3_DRV_freeChannel() for ch 1 FAILED, error code: %d\r\n", result);
428 #endif /* EDMA3_DRV_DEBUG */
429 }
430 else
431 {
432 result = EDMA3_DRV_freeChannel (hEdma, ch2Id);
433 if (result != EDMA3_DRV_SOK)
434 {
435 #ifdef EDMA3_DRV_DEBUG
436 EDMA3_DRV_PRINTF("edma3_test_with_chaining: EDMA3_DRV_freeChannel() for ch 2 FAILED, error code: %d\r\n", result);
437 #endif /* EDMA3_DRV_DEBUG */
438 }
439 }
440 }
441 }
444 if((Istestpassed1 == 1u) && (Istestpassed2 == 1u))
445 {
446 #ifdef EDMA3_DRV_DEBUG
447 EDMA3_DRV_PRINTF("edma3_test_with_chaining PASSED\r\n");
448 #endif /* EDMA3_DRV_DEBUG */
449 }
450 else
451 {
452 #ifdef EDMA3_DRV_DEBUG
453 EDMA3_DRV_PRINTF("edma3_test_with_chaining FAILED\r\n");
454 #endif /* EDMA3_DRV_DEBUG */
455 result = ((EDMA3_DRV_SOK == result) ?
456 EDMA3_DATA_MISMATCH_ERROR : result);
457 }
458 return result;
459 }