]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A5_SAMA5D4x_EK_IAR/AtmelFiles/libboard_sama5d4x-ek/source/xdmad.c
Core kernel files:
[freertos] / FreeRTOS / Demo / CORTEX_A5_SAMA5D4x_EK_IAR / AtmelFiles / libboard_sama5d4x-ek / source / xdmad.c
1 /* ----------------------------------------------------------------------------\r
2  *         SAM Software Package License \r
3  * ----------------------------------------------------------------------------\r
4  * Copyright (c) 2014, Atmel Corporation\r
5  *\r
6  * All rights reserved.\r
7  *\r
8  * Redistribution and use in source and binary forms, with or without\r
9  * modification, are permitted provided that the following conditions are met:\r
10  *\r
11  * - Redistributions of source code must retain the above copyright notice,\r
12  * this list of conditions and the disclaimer below.\r
13  *\r
14  * Atmel's name may not be used to endorse or promote products derived from\r
15  * this software without specific prior written permission.\r
16  *\r
17  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR\r
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
20  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,\r
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
23  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
24  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
25  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
27  * ----------------------------------------------------------------------------\r
28  */\r
29 \r
30 /** \addtogroup xdmad_module \r
31  *\r
32  * \section Xdma xDma Configuration Usage\r
33  *\r
34  * To configure a XDMA channel, the user has to follow these few steps :\r
35  * <ul>\r
36  * <li> Initialize a XDMA driver instance by XDMAD_Initialize().</li>\r
37  * <li> choose an available (disabled) channel using XDMAD_AllocateChannel().</li>\r
38  * <li> After the XDMAC selected channel has been programmed, XDMAD_PrepareChannel() is to enable \r
39  * clock and dma peripheral of the DMA, and set Configuration register to set up the transfer type \r
40  * (memory or non-memory peripheral for source and destination) and flow control device.</li>\r
41  * <li> Invoke XDMAD_StartTransfer() to start DMA transfer  or XDMAD_StopTransfer() to force stop DMA transfer.</li>\r
42   * <li> Once the buffer of data is transferred, XDMAD_IsTransferDone() checks if DMA transfer is finished.</li>\r
43  * <li> XDMAD_Handler() handles XDMA interrupt, and invoking XDMAD_SetCallback() if provided.</li>\r
44  * </ul>\r
45  *\r
46  * Related files:\n\r
47  * \ref xdmad.h\n\r
48  * \ref xdmad.c.\n\r
49  */\r
50 \r
51 /** \file */\r
52 \r
53 /** \addtogroup dmad_functions\r
54   @{*/\r
55  \r
56 /*----------------------------------------------------------------------------\r
57  *        Includes\r
58  *----------------------------------------------------------------------------*/\r
59 \r
60 #include "board.h"\r
61 #include <assert.h>\r
62 \r
63 /*----------------------------------------------------------------------------\r
64  *        Local functions\r
65  *----------------------------------------------------------------------------*/\r
66 /**\r
67  * \brief Try to allocate a DMA channel for on given controller.\r
68  * \param pDmad  Pointer to DMA driver instance.\r
69  * \param bXdmac xDMA controller ID (0 ~ 1).\r
70  * \param bSrcID Source peripheral ID, 0xFF for memory.\r
71  * \param bDstID Destination peripheral ID, 0xFF for memory.\r
72  * \return Channel number if allocation sucessful, return\r
73  * DMAD_ALLOC_FAILED if allocation failed.\r
74  */\r
75 static uint32_t XDMAD_AllocateXdmacChannel( sXdmad *pXdmad,\r
76                                             uint8_t bXdmac,\r
77                                             uint8_t bSrcID,\r
78                                             uint8_t bDstID)\r
79 {\r
80     uint32_t i;\r
81     /* Can't support peripheral to peripheral */\r
82     if ((( bSrcID != XDMAD_TRANSFER_MEMORY ) && ( bDstID != XDMAD_TRANSFER_MEMORY )))\r
83     {\r
84         return XDMAD_ALLOC_FAILED;\r
85     }\r
86     /* dma transfer from peripheral to memory */\r
87     if ( bDstID == XDMAD_TRANSFER_MEMORY)\r
88     {\r
89         if( (!XDMAIF_IsValidatedPeripherOnDma(bXdmac, bSrcID)) )\r
90         {\r
91             return XDMAD_ALLOC_FAILED;\r
92         }\r
93     }\r
94     /* dma transfer from memory to peripheral */\r
95     if ( bSrcID == XDMAD_TRANSFER_MEMORY )\r
96     {\r
97         if( (!XDMAIF_IsValidatedPeripherOnDma(bXdmac, bDstID)) )\r
98         {\r
99             return XDMAD_ALLOC_FAILED;\r
100         }\r
101     }\r
102 \r
103     for (i = 0; i < pXdmad->numChannels; i ++)\r
104     {\r
105         if ( pXdmad->XdmaChannels[bXdmac][i].state == XDMAD_STATE_FREE )\r
106         {\r
107             /* Allocate the channel */\r
108             pXdmad->XdmaChannels[bXdmac][i].state = XDMAD_STATE_ALLOCATED;\r
109             /* Get general informations */\r
110             pXdmad->XdmaChannels[bXdmac][i].bSrcPeriphID = bSrcID;\r
111             pXdmad->XdmaChannels[bXdmac][i].bDstPeriphID = bDstID;\r
112             pXdmad->XdmaChannels[bXdmac][i].bSrcTxIfID =\r
113                 XDMAIF_Get_ChannelNumber(bXdmac, bSrcID, 0);\r
114             pXdmad->XdmaChannels[bXdmac][i].bSrcRxIfID =\r
115                 XDMAIF_Get_ChannelNumber(bXdmac, bSrcID, 1);\r
116             pXdmad->XdmaChannels[bXdmac][i].bDstTxIfID =\r
117                 XDMAIF_Get_ChannelNumber(bXdmac, bDstID, 0);\r
118             pXdmad->XdmaChannels[bXdmac][i].bDstTxIfID =\r
119                 XDMAIF_Get_ChannelNumber(bXdmac, bDstID, 1);\r
120             return ((bXdmac << 8)) | ((i) & 0xFF);\r
121         }\r
122     }\r
123     return XDMAD_ALLOC_FAILED;\r
124 }\r
125 \r
126 /*----------------------------------------------------------------------------\r
127  *        Exported functions\r
128  *----------------------------------------------------------------------------*/\r
129 \r
130 /**\r
131  * \brief Initialize xDMA driver instance.\r
132  * \param pXdmad Pointer to xDMA driver instance.\r
133  * \param bPollingMode Polling DMA transfer:\r
134  *                     1. Via XDMAD_IsTransferDone(); or\r
135  *                     2. Via XDMAD_Handler().\r
136  */\r
137 void XDMAD_Initialize( sXdmad *pXdmad, uint8_t bPollingMode )\r
138 {\r
139     uint32_t i, j;\r
140 \r
141     assert( pXdmad != NULL ) ;\r
142 \r
143     pXdmad->pXdmacs[0] = XDMAC0;\r
144     pXdmad->pXdmacs[1] = XDMAC1;\r
145     pXdmad->pollingMode = bPollingMode;\r
146     pXdmad->numControllers = XDMAC_CONTROLLER_NUM;\r
147     pXdmad->numChannels    = XDMAC_CHANNEL_NUM;\r
148 \r
149     for (i = 0; i < pXdmad->numControllers; i ++)\r
150     {\r
151         for (j = 0; j < pXdmad->numChannels; j ++)\r
152         {\r
153             pXdmad->XdmaChannels[i][j].fCallback = 0;\r
154             pXdmad->XdmaChannels[i][j].pArg      = 0;\r
155             pXdmad->XdmaChannels[i][j].bIrqOwner    = 0;\r
156             pXdmad->XdmaChannels[i][j].bSrcPeriphID = 0;\r
157             pXdmad->XdmaChannels[i][j].bDstPeriphID = 0;\r
158             pXdmad->XdmaChannels[i][j].bSrcTxIfID   = 0;\r
159             pXdmad->XdmaChannels[i][j].bSrcRxIfID   = 0;\r
160             pXdmad->XdmaChannels[i][j].bDstTxIfID   = 0;\r
161             pXdmad->XdmaChannels[i][j].bDstRxIfID   = 0;\r
162             pXdmad->XdmaChannels[i][j].state = XDMAD_STATE_FREE;\r
163         }\r
164     }\r
165 }\r
166 \r
167 \r
168 /**\r
169  * \brief Allocate a XDMA channel for upper layer.\r
170  * \param pXdmad  Pointer to xDMA driver instance.\r
171  * \param bSrcID Source peripheral ID, 0xFF for memory.\r
172  * \param bDstID Destination peripheral ID, 0xFF for memory.\r
173  * \return Channel number if allocation sucessful, return\r
174  * XDMAD_ALLOC_FAILED if allocation failed.\r
175  */\r
176 uint32_t XDMAD_AllocateChannel( sXdmad *pXdmad,\r
177                                 uint8_t bSrcID,\r
178                                 uint8_t bDstID)\r
179 {\r
180     uint32_t _iController;\r
181     uint32_t dwChannel = XDMAD_ALLOC_FAILED;\r
182     for ( _iController = 0; _iController < pXdmad->numControllers; _iController ++)\r
183     {\r
184         dwChannel = XDMAD_AllocateXdmacChannel( pXdmad, _iController, bSrcID, bDstID );\r
185         if (dwChannel != XDMAD_ALLOC_FAILED)\r
186             break;\r
187     }\r
188     return dwChannel;\r
189 }\r
190 \r
191 /**\r
192  * \brief Free the specified xDMA channel.\r
193  * \param pXdmad     Pointer to xDMA driver instance.\r
194  * \param dwChannel ControllerNumber << 8 | ChannelNumber.\r
195  */\r
196 eXdmadRC XDMAD_FreeChannel( sXdmad *pXdmad, \r
197                             uint32_t dwChannel )\r
198 {\r
199     uint8_t _iController = (dwChannel >> 8);\r
200     uint8_t iChannel    = (dwChannel) & 0xFF;\r
201 \r
202     assert( pXdmad != NULL ) ;\r
203     switch ( pXdmad->XdmaChannels[_iController][iChannel].state )\r
204     {\r
205         case XDMAD_STATE_START: \r
206             return XDMAD_BUSY;\r
207         case XDMAD_STATE_ALLOCATED: case XDMAD_STATE_DONE:\r
208             pXdmad->XdmaChannels[_iController][iChannel].state = XDMAD_STATE_FREE;\r
209             break;\r
210     }\r
211     return XDMAD_OK;\r
212 }\r
213 \r
214 \r
215 /**\r
216  * \brief Set the callback function for xDMA channel transfer.\r
217  * \param pXdmad     Pointer to xDMA driver instance.\r
218  * \param dwChannel ControllerNumber << 8 | ChannelNumber.\r
219  * \param fCallback Pointer to callback function.\r
220  * \param pArg Pointer to optional argument for callback.\r
221  */\r
222 eXdmadRC XDMAD_SetCallback( sXdmad *pXdmad, \r
223                             uint32_t dwChannel,\r
224                             XdmadTransferCallback fCallback, \r
225                             void* pArg )\r
226 {\r
227     uint8_t _iController = (dwChannel >> 8);\r
228     uint8_t iChannel    = (dwChannel) & 0xFF;\r
229     assert( pXdmad != NULL ) ;\r
230     if ( pXdmad->XdmaChannels[_iController][iChannel].state == XDMAD_STATE_FREE )\r
231         return XDMAD_ERROR;\r
232     else if ( pXdmad->XdmaChannels[_iController][iChannel].state == XDMAD_STATE_START )\r
233         return XDMAD_BUSY;\r
234 \r
235     pXdmad->XdmaChannels[_iController][iChannel].fCallback = fCallback;\r
236     pXdmad->XdmaChannels[_iController][iChannel].pArg = pArg;\r
237 \r
238     return XDMAD_OK;\r
239 }\r
240 \r
241 \r
242 /**\r
243  * \brief Enable clock of the xDMA peripheral, Enable the dma peripheral,\r
244  * configure configuration register for xDMA transfer.\r
245  * \param pXdmad     Pointer to xDMA driver instance.\r
246  * \param dwChannel ControllerNumber << 8 | ChannelNumber.\r
247  * \param dwCfg     Configuration value.\r
248  */\r
249 eXdmadRC XDMAD_PrepareChannel( sXdmad *pXdmad, uint32_t dwChannel)\r
250 {\r
251     uint8_t _iController = (dwChannel >> 8);\r
252     uint8_t iChannel    = (dwChannel) & 0xFF;\r
253     uint32_t _dwdmaId;\r
254 \r
255     assert( pXdmad != NULL ) ;\r
256     Xdmac *pXdmac = pXdmad->pXdmacs[_iController];\r
257 \r
258     if ( pXdmad->XdmaChannels[_iController][iChannel].state == XDMAD_STATE_FREE )\r
259         return XDMAD_ERROR;\r
260     else if ( pXdmad->XdmaChannels[_iController][iChannel].state == XDMAD_STATE_START )\r
261         return XDMAD_BUSY;\r
262     /* Clear dummy status */\r
263     XDMAC_GetGlobalChStatus( pXdmac );\r
264     XDMAC_GetGIsr (pXdmac);\r
265     _dwdmaId = (_iController == 0) ? ID_XDMAC0 : ID_XDMAC1;\r
266     /* Enable clock of the DMA peripheral */\r
267     if (!PMC_IsPeriphEnabled( _dwdmaId ))\r
268     {\r
269         PMC_EnablePeripheral( _dwdmaId );\r
270     }\r
271     /* Clear dummy status */\r
272     XDMAC_GetChannelIsr( pXdmac,iChannel );\r
273     /* Disables XDMAC interrupt for the given channel. */\r
274     XDMAC_DisableGIt (pXdmac, -1);\r
275     XDMAC_DisableChannelIt (pXdmac, iChannel, -1);\r
276     /* Disable the given dma channel. */\r
277     XDMAC_DisableChannel( pXdmac, iChannel );\r
278     XDMAC_SetSourceAddr(pXdmac, iChannel, 0);\r
279     XDMAC_SetDestinationAddr(pXdmac, iChannel, 0);\r
280     XDMAC_SetBlockControl(pXdmac, iChannel, 0);\r
281     XDMAC_SetChannelConfig( pXdmac, iChannel, 0x20);\r
282     XDMAC_SetDescriptorAddr(pXdmac, iChannel, 0, 0);\r
283     XDMAC_SetDescriptorControl(pXdmac, iChannel, 0);\r
284     return XDMAD_OK;\r
285 }\r
286 \r
287 /**\r
288  * \brief xDMA interrupt handler\r
289  * \param pxDmad Pointer to DMA driver instance.\r
290  */\r
291 void XDMAD_Handler( sXdmad *pDmad)\r
292 {\r
293     Xdmac *pXdmac;\r
294     sXdmadChannel *pCh;\r
295     uint32_t xdmaChannelIntStatus, xdmaGlobaIntStatus,xdmaGlobalChStatus;\r
296     uint8_t bExec = 0;\r
297     uint8_t _iController, _iChannel;\r
298     assert( pDmad != NULL ) ;\r
299 \r
300     for (_iController = 0; _iController < pDmad->numControllers; _iController ++)\r
301     {\r
302         pXdmac = pDmad->pXdmacs[_iController];\r
303         xdmaGlobaIntStatus = XDMAC_GetGIsr(pXdmac);\r
304         if ((xdmaGlobaIntStatus & 0xFFFF) == 0) continue;\r
305         xdmaGlobalChStatus = XDMAC_GetGlobalChStatus(pXdmac);\r
306         for (_iChannel = 0; _iChannel < pDmad->numChannels; _iChannel ++) \r
307         {\r
308             if (!(xdmaGlobaIntStatus & (1<<_iChannel))) continue;\r
309             pCh = &pDmad->XdmaChannels[_iController][_iChannel];\r
310             if ( pCh->state == XDMAD_STATE_FREE) return ;\r
311             if ((xdmaGlobalChStatus & ( XDMAC_GS_ST0 << _iChannel)) == 0) \r
312             {\r
313                 bExec = 0;\r
314                 xdmaChannelIntStatus = XDMAC_GetChannelIsr( pXdmac, _iChannel);\r
315                 if (xdmaChannelIntStatus & XDMAC_CIS_BIS) { \r
316                     if((XDMAC_GetChannelItMask(pXdmac, _iChannel) & XDMAC_CIM_LIM) == 0 ) {\r
317                         pCh->state = XDMAD_STATE_DONE ;\r
318                         bExec = 1;\r
319                     }\r
320                 //printf("XDMAC_CIS_BIS\n\r");\r
321                 }\r
322                 if (xdmaChannelIntStatus & XDMAC_CIS_FIS) {\r
323                    // printf("XDMAC_CIS_FIS\n\r");\r
324                 }\r
325                 if (xdmaChannelIntStatus & XDMAC_CIS_RBEIS) {\r
326                     //printf("XDMAC_CIS_RBEIS\n\r");\r
327                 }\r
328                 if (xdmaChannelIntStatus & XDMAC_CIS_WBEIS) {\r
329                    // printf("XDMAC_CIS_WBEIS\n\r");\r
330                 }\r
331                 if (xdmaChannelIntStatus & XDMAC_CIS_ROIS) {\r
332                    // printf("XDMAC_CIS_ROIS\n\r");\r
333                 }\r
334                 if (xdmaChannelIntStatus & XDMAC_CIS_LIS) {\r
335                    //printf("XDMAC_CIS_LIS\n\r");\r
336                   \r
337                     pCh->state = XDMAD_STATE_DONE ;\r
338                     bExec = 1;\r
339                 }\r
340                 if (xdmaChannelIntStatus & XDMAC_CIS_DIS ) \r
341                 {\r
342                     pCh->state = XDMAD_STATE_DONE ;\r
343                     bExec = 1;\r
344                 }\r
345             }\r
346             // printf("bExec =%d, _iChannel=%d \n\r",bExec,_iChannel);\r
347             /* Execute callback */\r
348             if (bExec && pCh->fCallback) {\r
349                //XDMAC_DisableGIt( pXdmac,1 << _iChannel);\r
350                pCh->fCallback(_iChannel, pCh->pArg);\r
351             }\r
352         }\r
353     }\r
354 }\r
355 \r
356 /**\r
357  * \brief Check if DMA transfer is finished.\r
358  *        In polling mode XDMAD_Handler() is polled.\r
359  * \param pDmad     Pointer to DMA driver instance.\r
360  * \param dwChannel ControllerNumber << 8 | ChannelNumber.\r
361  */\r
362 eXdmadRC XDMAD_IsTransferDone( sXdmad *pXdmad, uint32_t dwChannel )\r
363 {\r
364     uint8_t _iController = (dwChannel >> 8);\r
365     uint8_t iChannel    = (dwChannel) & 0xFF;\r
366     uint8_t state;\r
367     state = pXdmad->XdmaChannels[_iController][iChannel].state;\r
368     assert( pXdmad != NULL ) ;\r
369     if ( state == XDMAD_STATE_ALLOCATED ) return XDMAD_OK;\r
370     if ( state == XDMAD_STATE_FREE )\r
371         return XDMAD_ERROR;\r
372     else if ( state != XDMAD_STATE_DONE )\r
373     {\r
374         if(pXdmad->pollingMode)  XDMAD_Handler( pXdmad);\r
375         return XDMAD_BUSY;\r
376     }\r
377     return XDMAD_OK;\r
378 }\r
379 \r
380 \r
381 /**\r
382  * \brief Configure DMA for a single transfer.\r
383  * \param pXdmad     Pointer to xDMA driver instance.\r
384  * \param dwChannel ControllerNumber << 8 | ChannelNumber.\r
385  */\r
386 eXdmadRC XDMAD_ConfigureTransfer( sXdmad *pXdmad,\r
387                                   uint32_t dwChannel,\r
388                                   sXdmadCfg *pXdmaParam,\r
389                                   uint32_t dwXdmaDescCfg,\r
390                                   uint32_t dwXdmaDescAddr)\r
391 {\r
392     uint8_t _iController = (dwChannel >> 8);\r
393     uint8_t iChannel    = (dwChannel) & 0xFF;\r
394     Xdmac *pXdmac = pXdmad->pXdmacs[_iController];\r
395     XDMAC_GetGIsr(pXdmac);\r
396     XDMAC_GetChannelIsr( pXdmac, iChannel);\r
397     if ( pXdmad->XdmaChannels[_iController][iChannel].state == XDMAD_STATE_FREE )\r
398         return XDMAD_ERROR;\r
399     if ( pXdmad->XdmaChannels[_iController][iChannel].state == XDMAD_STATE_START )\r
400         return XDMAD_BUSY;\r
401     /* Linked List is enabled */\r
402     if ((dwXdmaDescCfg & XDMAC_CNDC_NDE) == XDMAC_CNDC_NDE_DSCR_FETCH_EN)\r
403     {\r
404         if ((dwXdmaDescCfg & XDMAC_CNDC_NDVIEW_Msk) == XDMAC_CNDC_NDVIEW_NDV0) {\r
405             XDMAC_SetChannelConfig( pXdmac, iChannel, pXdmaParam->mbr_cfg );\r
406             XDMAC_SetSourceAddr(pXdmac, iChannel, pXdmaParam->mbr_sa);\r
407             XDMAC_SetDestinationAddr(pXdmac, iChannel, pXdmaParam->mbr_da);\r
408         }\r
409         if ((dwXdmaDescCfg & XDMAC_CNDC_NDVIEW_Msk) == XDMAC_CNDC_NDVIEW_NDV1) {\r
410             XDMAC_SetChannelConfig( pXdmac, iChannel, pXdmaParam->mbr_cfg );\r
411         }\r
412         XDMAC_SetDescriptorAddr(pXdmac, iChannel, dwXdmaDescAddr, 0);\r
413         XDMAC_SetDescriptorControl(pXdmac, iChannel, dwXdmaDescCfg);\r
414         XDMAC_DisableChannelIt (pXdmac, iChannel, -1);\r
415         XDMAC_EnableChannelIt (pXdmac,iChannel, XDMAC_CIE_LIE );\r
416     }\r
417     /* LLI is disabled. */\r
418     else\r
419     {\r
420         XDMAC_SetSourceAddr(pXdmac, iChannel, pXdmaParam->mbr_sa);\r
421         XDMAC_SetDestinationAddr(pXdmac, iChannel, pXdmaParam->mbr_da);\r
422         XDMAC_SetMicroblockControl(pXdmac, iChannel, pXdmaParam->mbr_ubc);\r
423         XDMAC_SetBlockControl(pXdmac, iChannel, pXdmaParam->mbr_bc);\r
424         XDMAC_SetDataStride_MemPattern(pXdmac, iChannel, pXdmaParam->mbr_ds);\r
425         XDMAC_SetSourceMicroBlockStride(pXdmac, iChannel, pXdmaParam->mbr_sus);\r
426         XDMAC_SetDestinationMicroBlockStride(pXdmac, iChannel, pXdmaParam->mbr_dus);\r
427         XDMAC_SetChannelConfig( pXdmac, iChannel, pXdmaParam->mbr_cfg );\r
428         XDMAC_SetDescriptorAddr(pXdmac, iChannel, 0, 0);\r
429         XDMAC_SetDescriptorControl(pXdmac, iChannel, 0);\r
430         XDMAC_EnableChannelIt (pXdmac,\r
431                                iChannel,\r
432                                XDMAC_CIE_BIE   |\r
433                                XDMAC_CIE_DIE   |\r
434                                XDMAC_CIE_FIE   |\r
435                                XDMAC_CIE_RBIE  |\r
436                                XDMAC_CIE_WBIE  |\r
437                                XDMAC_CIE_ROIE);\r
438     }\r
439     return XDMAD_OK;\r
440 }\r
441 \r
442 /**\r
443  * \brief Start xDMA transfer.\r
444  * \param pXdmad     Pointer to XDMA driver instance.\r
445  * \param dwChannel ControllerNumber << 8 | ChannelNumber.\r
446  */\r
447 eXdmadRC XDMAD_StartTransfer( sXdmad *pXdmad, uint32_t dwChannel )\r
448 {\r
449     uint8_t _iController = (dwChannel >> 8);\r
450     uint8_t iChannel    = (dwChannel) & 0xFF;\r
451     Xdmac *pXdmac = pXdmad->pXdmacs[_iController];\r
452     if ( pXdmad->XdmaChannels[_iController][iChannel].state == XDMAD_STATE_FREE )\r
453     {\r
454         printf("-E- XDMAD_STATE_FREE \n\r");\r
455         return XDMAD_ERROR;\r
456     }\r
457     else if ( pXdmad->XdmaChannels[_iController][iChannel].state == XDMAD_STATE_START )\r
458     {\r
459         printf("-E- XDMAD_STATE_START \n\r");\r
460         return XDMAD_BUSY;\r
461     }\r
462     /* Change state to transferring */\r
463     pXdmad->XdmaChannels[_iController][iChannel].state = XDMAD_STATE_START;\r
464     XDMAC_EnableChannel(pXdmac, iChannel);\r
465     if ( pXdmad->pollingMode == 0 )\r
466     {\r
467         XDMAC_EnableGIt( pXdmac,1 << iChannel);\r
468     }\r
469     return XDMAD_OK;\r
470 }\r
471 \r
472 \r
473 /**\r
474  * \brief Stop DMA transfer.\r
475  * \param pDmad     Pointer to DMA driver instance.\r
476  * \param dwChannel ControllerNumber << 8 | ChannelNumber.\r
477  */\r
478 eXdmadRC XDMAD_StopTransfer( sXdmad *pXdmad, uint32_t dwChannel )\r
479 {\r
480     uint8_t _iController = (dwChannel >> 8);\r
481     uint8_t _iChannel    = (dwChannel) & 0xFF;\r
482     Xdmac *pXdmac = pXdmad->pXdmacs[_iController];\r
483 \r
484     pXdmad->XdmaChannels[_iController][_iChannel].state = XDMAD_STATE_ALLOCATED;\r
485     /* Disable channel */\r
486     XDMAC_DisableChannel(pXdmac, _iChannel);\r
487     /* Disable interrupts */\r
488     XDMAC_DisableChannelIt(pXdmac, _iChannel, -1);\r
489     /* Clear pending status */\r
490     XDMAC_GetChannelIsr( pXdmac, _iChannel);\r
491     XDMAC_GetGlobalChStatus(pXdmac);\r
492   \r
493     return XDMAD_OK;\r
494 }\r
495 \r
496 /**@}*/\r
497 \r