]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/edma3_lld.git/blob - examples/edma3_driver/src/dma_chain_test.c
Reverted PRSDK-927 implementation due to build
[keystone-rtos/edma3_lld.git] / examples / edma3_driver / src / dma_chain_test.c
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;