SAMV71 Xplained Ultra Software Package 1.5

xdmad.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- */
00002 /*                  Atmel Microcontroller Software Support                      */
00003 /*                       SAM Software Package License                           */
00004 /* ---------------------------------------------------------------------------- */
00005 /* Copyright (c) 2015, Atmel Corporation                                        */
00006 /*                                                                              */
00007 /* All rights reserved.                                                         */
00008 /*                                                                              */
00009 /* Redistribution and use in source and binary forms, with or without           */
00010 /* modification, are permitted provided that the following condition is met:    */
00011 /*                                                                              */
00012 /* - Redistributions of source code must retain the above copyright notice,     */
00013 /* this list of conditions and the disclaimer below.                            */
00014 /*                                                                              */
00015 /* Atmel's name may not be used to endorse or promote products derived from     */
00016 /* this software without specific prior written permission.                     */
00017 /*                                                                              */
00018 /* DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR   */
00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE   */
00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,      */
00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  */
00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING         */
00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */
00028 /* ---------------------------------------------------------------------------- */
00029 
00030 /** \addtogroup xdmad_module
00031  *
00032  * \section Xdma xDma Configuration Usage
00033  *
00034  * To configure a XDMA channel, the user has to follow these few steps :
00035  * <ul>
00036  * <li> Initialize a XDMA driver instance by XDMAD_Initialize().</li>
00037  * <li> choose an available (disabled) channel using XDMAD_AllocateChannel().</li>
00038  * <li> After the XDMAC selected channel has been programmed,
00039  * XDMAD_PrepareChannel() is to enable clock and dma peripheral of the DMA, and
00040  * set Configuration register to set up the transfer type (memory or non-memory
00041  * peripheral for source and destination) and flow control device.</li>
00042  * <li> Invoke XDMAD_StartTransfer() to start DMA transfer  or
00043  * XDMAD_StopTransfer() to force stop DMA transfer.</li>
00044  * <li> Once the buffer of data is transferred, XDMAD_IsTransferDone()
00045  * checks if DMA transfer is finished.</li>
00046  * <li> XDMAD_Handler() handles XDMA interrupt, and invoking XDMAD_SetCallback()
00047  * if provided.</li>
00048  * </ul>
00049  *
00050  * Related files:\n
00051  * \ref xdmad.h\n
00052  * \ref xdmad.c.\n
00053  */
00054 
00055 /** \file */
00056 
00057 /** \addtogroup dmad_functions
00058   @{*/
00059 
00060 /*----------------------------------------------------------------------------
00061  *        Includes
00062  *----------------------------------------------------------------------------*/
00063 
00064 #include "chip.h"
00065 #include <assert.h>
00066 static uint8_t xDmad_Initialized = 0;
00067 
00068 /*----------------------------------------------------------------------------
00069  *        Local functions
00070  *----------------------------------------------------------------------------*/
00071 /**
00072  * \brief Try to allocate a DMA channel for on given controller.
00073  * \param pDmad  Pointer to DMA driver instance.
00074  * \param bSrcID Source peripheral ID, 0xFF for memory.
00075  * \param bDstID Destination peripheral ID, 0xFF for memory.
00076  * \return Channel number if allocation successful, return
00077  * DMAD_ALLOC_FAILED if allocation failed.
00078  */
00079 static uint32_t XDMAD_AllocateXdmacChannel(sXdmad *pXdmad,
00080         uint8_t bSrcID,
00081         uint8_t bDstID)
00082 {
00083     uint32_t i;
00084 
00085     /* Can't support peripheral to peripheral */
00086     if (((bSrcID != XDMAD_TRANSFER_MEMORY)
00087          && (bDstID != XDMAD_TRANSFER_MEMORY)))
00088         return XDMAD_ALLOC_FAILED;
00089 
00090     /* dma transfer from peripheral to memory */
00091     if (bDstID == XDMAD_TRANSFER_MEMORY) {
00092         if ((!XDMAIF_IsValidatedPeripherOnDma(bSrcID))) {
00093             TRACE_ERROR("%s:: Allocation failed", __FUNCTION__);
00094             return XDMAD_ALLOC_FAILED;
00095         }
00096     }
00097 
00098     /* dma transfer from memory to peripheral */
00099     if (bSrcID == XDMAD_TRANSFER_MEMORY) {
00100         if ((!XDMAIF_IsValidatedPeripherOnDma(bDstID))) {
00101             TRACE_ERROR("%s:: Allocation failed", __FUNCTION__);
00102             return XDMAD_ALLOC_FAILED;
00103         }
00104     }
00105 
00106     for (i = 0; i < pXdmad->numChannels; i ++) {
00107         if (pXdmad->XdmaChannels[i].state == XDMAD_STATE_FREE) {
00108             /* Allocate the channel */
00109             pXdmad->XdmaChannels[i].state = XDMAD_STATE_ALLOCATED;
00110             /* Get general informations */
00111             pXdmad->XdmaChannels[i].bSrcPeriphID = bSrcID;
00112             pXdmad->XdmaChannels[i].bDstPeriphID = bDstID;
00113             pXdmad->XdmaChannels[i].bSrcTxIfID =
00114                 XDMAIF_Get_ChannelNumber(bSrcID, 0);
00115             pXdmad->XdmaChannels[i].bSrcRxIfID =
00116                 XDMAIF_Get_ChannelNumber(bSrcID, 1);
00117             pXdmad->XdmaChannels[i].bDstTxIfID =
00118                 XDMAIF_Get_ChannelNumber(bDstID, 0);
00119             pXdmad->XdmaChannels[i].bDstRxIfID =
00120                 XDMAIF_Get_ChannelNumber(bDstID, 1);
00121             return  ((i) & 0xFF);
00122         }
00123     }
00124 
00125     TRACE_ERROR("%s:: Allocation failed, all channels are occupied", __FUNCTION__);
00126     return XDMAD_ALLOC_FAILED;
00127 }
00128 
00129 /*----------------------------------------------------------------------------
00130  *        Exported functions
00131  *----------------------------------------------------------------------------*/
00132 
00133 /**
00134  * \brief Initialize xDMA driver instance.
00135  * \param pXdmad Pointer to xDMA driver instance.
00136  * \param bPollingMode Polling DMA transfer:
00137  *                     1. Via XDMAD_IsTransferDone(); or
00138  *                     2. Via XDMAD_Handler().
00139  */
00140 void XDMAD_Initialize(sXdmad *pXdmad, uint8_t bPollingMode)
00141 {
00142     uint32_t j;
00143     uint32_t volatile timer = 0x7FF;
00144 
00145     assert(pXdmad);
00146     LockMutex(pXdmad->xdmaMutex, timer);
00147 
00148     if (xDmad_Initialized) {
00149         ReleaseMutex(pXdmad->xdmaMutex);
00150         return;
00151     }
00152 
00153     pXdmad->pXdmacs = XDMAC;
00154     pXdmad->pollingMode = bPollingMode;
00155     pXdmad->numControllers = XDMAC_CONTROLLER_NUM;
00156     pXdmad->numChannels    = (XDMAC_GTYPE_NB_CH(XDMAC_GetType(XDMAC)) + 1);
00157 
00158     for (j = 0; j < pXdmad->numChannels; j ++) {
00159         pXdmad->XdmaChannels[j].fCallback = 0;
00160         pXdmad->XdmaChannels[j].pArg      = 0;
00161         pXdmad->XdmaChannels[j].bIrqOwner    = 0;
00162         pXdmad->XdmaChannels[j].bSrcPeriphID = 0;
00163         pXdmad->XdmaChannels[j].bDstPeriphID = 0;
00164         pXdmad->XdmaChannels[j].bSrcTxIfID   = 0;
00165         pXdmad->XdmaChannels[j].bSrcRxIfID   = 0;
00166         pXdmad->XdmaChannels[j].bDstTxIfID   = 0;
00167         pXdmad->XdmaChannels[j].bDstRxIfID   = 0;
00168         pXdmad->XdmaChannels[j].state = XDMAD_STATE_FREE;
00169     }
00170 
00171     xDmad_Initialized = 1;
00172     ReleaseMutex(pXdmad->xdmaMutex);
00173 }
00174 
00175 
00176 /**
00177  * \brief Allocate a XDMA channel for upper layer.
00178  * \param pXdmad  Pointer to xDMA driver instance.
00179  * \param bSrcID Source peripheral ID, 0xFF for memory.
00180  * \param bDstID Destination peripheral ID, 0xFF for memory.
00181  * \return Channel number if allocation successful, return
00182  * XDMAD_ALLOC_FAILED if allocation failed.
00183  */
00184 uint32_t XDMAD_AllocateChannel(sXdmad *pXdmad,
00185                                 uint8_t bSrcID,
00186                                 uint8_t bDstID)
00187 {
00188     uint32_t dwChannel = XDMAD_ALLOC_FAILED;
00189     uint32_t volatile timer = 0x7FF;
00190 
00191     LockMutex(pXdmad->xdmaMutex, timer);
00192     dwChannel = XDMAD_AllocateXdmacChannel(pXdmad,  bSrcID, bDstID);
00193     ReleaseMutex(pXdmad->xdmaMutex);
00194 
00195     return dwChannel;
00196 }
00197 
00198 /**
00199  * \brief Free the specified xDMA channel.
00200  * \param pXdmad     Pointer to xDMA driver instance.
00201  * \param dwChannel ControllerNumber << 8 | ChannelNumber.
00202  */
00203 eXdmadRC XDMAD_FreeChannel(sXdmad *pXdmad,
00204                             uint32_t dwChannel)
00205 {
00206     uint8_t iChannel    = (dwChannel) & 0xFF;
00207     assert(pXdmad != NULL);
00208 
00209     if (iChannel >= pXdmad->numChannels) return XDMAD_ERROR;
00210 
00211     switch (pXdmad->XdmaChannels[iChannel].state) {
00212     case XDMAD_STATE_ALLOCATED:
00213     case XDMAD_STATE_START:
00214     case XDMAD_STATE_IN_XFR:
00215         return XDMAD_BUSY;
00216 
00217     case XDMAD_STATE_DONE:
00218     case XDMAD_STATE_HALTED:
00219         pXdmad->XdmaChannels[iChannel].state = XDMAD_STATE_FREE;
00220         break;
00221     }
00222 
00223     return XDMAD_OK;
00224 }
00225 
00226 /**
00227  * \brief Set the callback function for xDMA channel transfer.
00228  * \param pXdmad     Pointer to xDMA driver instance.
00229  * \param dwChannel ControllerNumber << 8 | ChannelNumber.
00230  * \param fCallback Pointer to callback function.
00231  * \param pArg Pointer to optional argument for callback.
00232  */
00233 eXdmadRC XDMAD_SetCallback(sXdmad *pXdmad,
00234                             uint32_t dwChannel,
00235                             XdmadTransferCallback fCallback,
00236                             void *pArg)
00237 {
00238 
00239     uint8_t iChannel    = (dwChannel) & 0xFF;
00240     assert(pXdmad != NULL);
00241 
00242     if (iChannel >= pXdmad->numChannels) return XDMAD_ERROR;
00243 
00244     if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_FREE)
00245         return XDMAD_ERROR;
00246     else if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_START)
00247         return XDMAD_BUSY;
00248 
00249     pXdmad->XdmaChannels[iChannel].fCallback = fCallback;
00250     pXdmad->XdmaChannels[iChannel].pArg = pArg;
00251 
00252     return XDMAD_OK;
00253 }
00254 
00255 
00256 /**
00257  * \brief Enable clock of the xDMA peripheral, Enable the dma peripheral,
00258  * configure configuration register for xDMA transfer.
00259  * \param pXdmad     Pointer to xDMA driver instance.
00260  * \param dwChannel ControllerNumber << 8 | ChannelNumber.
00261  * \param dwCfg     Configuration value.
00262  */
00263 eXdmadRC XDMAD_PrepareChannel(sXdmad *pXdmad, uint32_t dwChannel)
00264 {
00265 
00266     uint8_t iChannel    = (dwChannel) & 0xFF;
00267     Xdmac *pXdmac = pXdmad->pXdmacs;
00268 
00269     assert(pXdmad != NULL);
00270 
00271     if (iChannel >= pXdmad->numChannels) return XDMAD_ERROR;
00272 
00273     if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_FREE)
00274         return XDMAD_ERROR;
00275     else if ((pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_START)
00276               || (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_IN_XFR))
00277         return XDMAD_BUSY;
00278 
00279 
00280     /* Enable clock of the DMA peripheral */
00281     if (!PMC_IsPeriphEnabled(ID_XDMAC))
00282         PMC_EnablePeripheral(ID_XDMAC);
00283 
00284     /* Clear dummy status */
00285     XDMAC_GetChannelIsr(pXdmac, iChannel);
00286     /* Disables XDMAC interrupt for the given channel. */
00287     XDMAC_DisableGIt (pXdmac, iChannel);
00288     XDMAC_DisableChannelIt (pXdmac, iChannel, 0xFF);
00289     /* Disable the given dma channel. */
00290     XDMAC_DisableChannel(pXdmac, iChannel);
00291     XDMAC_SetSourceAddr(pXdmac, iChannel, 0);
00292     XDMAC_SetDestinationAddr(pXdmac, iChannel, 0);
00293     XDMAC_SetBlockControl(pXdmac, iChannel, 0);
00294     XDMAC_SetChannelConfig(pXdmac, iChannel, 0x20);
00295     XDMAC_SetDescriptorAddr(pXdmac, iChannel, 0, 0);
00296     XDMAC_SetDescriptorControl(pXdmac, iChannel, 0);
00297     return XDMAD_OK;
00298 }
00299 
00300 /**
00301  * \brief xDMA interrupt handler
00302  * \param pxDmad Pointer to DMA driver instance.
00303  */
00304 void XDMAD_Handler(sXdmad *pDmad)
00305 {
00306     Xdmac *pXdmac;
00307     sXdmadChannel *pCh;
00308     uint32_t xdmaChannelIntStatus, xdmaGlobaIntStatus, xdmaGlobalChStatus;
00309     uint8_t bExec = 0;
00310     uint8_t _iChannel;
00311     assert(pDmad != NULL);
00312 
00313     pXdmac = pDmad->pXdmacs;
00314     xdmaGlobaIntStatus = XDMAC_GetGIsr(pXdmac);
00315 
00316     if ((xdmaGlobaIntStatus & 0xFFFFFF) != 0) {
00317         xdmaGlobalChStatus = XDMAC_GetGlobalChStatus(pXdmac);
00318 
00319         for (_iChannel = 0; _iChannel < pDmad->numChannels; _iChannel ++) {
00320             if (!(xdmaGlobaIntStatus & (1 << _iChannel))) continue;
00321 
00322             pCh = &pDmad->XdmaChannels[_iChannel];
00323 
00324             if (pCh->state == XDMAD_STATE_FREE) return;
00325 
00326             if ((xdmaGlobalChStatus & (XDMAC_GS_ST0 << _iChannel)) == 0) {
00327                 bExec = 0;
00328                 xdmaChannelIntStatus = XDMAC_GetMaskChannelIsr(pXdmac, _iChannel);
00329 
00330                 if (xdmaChannelIntStatus & XDMAC_CIS_BIS) {
00331                     if ((XDMAC_GetChannelItMask(pXdmac, _iChannel) & XDMAC_CIM_LIM)
00332                         == 0) {
00333                         pCh->state = XDMAD_STATE_DONE;
00334                         bExec = 1;
00335                     }
00336 
00337                     TRACE_DEBUG("XDMAC_CIS_BIS\n\r");
00338                 }
00339 
00340                 if (xdmaChannelIntStatus & XDMAC_CIS_FIS)
00341                     TRACE_DEBUG("XDMAC_CIS_FIS\n\r");
00342 
00343                 if (xdmaChannelIntStatus & XDMAC_CIS_RBEIS)
00344                     TRACE_DEBUG("XDMAC_CIS_RBEIS\n\r");
00345 
00346                 if (xdmaChannelIntStatus & XDMAC_CIS_WBEIS)
00347                     TRACE_DEBUG("XDMAC_CIS_WBEIS\n\r");
00348 
00349                 if (xdmaChannelIntStatus & XDMAC_CIS_ROIS)
00350                     TRACE_DEBUG("XDMAC_CIS_ROIS\n\r");
00351 
00352                 if (xdmaChannelIntStatus & XDMAC_CIS_LIS) {
00353                     TRACE_DEBUG("XDMAC_CIS_LIS\n\r");
00354                     pCh->state = XDMAD_STATE_DONE;
00355                     bExec = 1;
00356                 }
00357 
00358                 if (xdmaChannelIntStatus & XDMAC_CIS_DIS) {
00359                     pCh->state = XDMAD_STATE_DONE;
00360                     bExec = 1;
00361                 }
00362 
00363             } else {
00364                 /* Block end interrupt for LLI dma mode */
00365                 if (XDMAC_GetChannelIsr(pXdmac, _iChannel) & XDMAC_CIS_BIS) {
00366                     /* Execute callback */
00367                     pCh->fCallback(_iChannel, pCh->pArg);
00368                 }
00369             }
00370 
00371             /* Execute callback */
00372             if (bExec && pCh->fCallback)
00373                 pCh->fCallback(_iChannel, pCh->pArg);
00374         }
00375     }
00376 }
00377 
00378 /**
00379  * \brief Check if DMA transfer is finished.
00380  *        In polling mode XDMAD_Handler() is polled.
00381  * \param pDmad     Pointer to DMA driver instance.
00382  * \param dwChannel ControllerNumber << 8 | ChannelNumber.
00383  */
00384 eXdmadRC XDMAD_IsTransferDone(sXdmad *pXdmad, uint32_t dwChannel)
00385 {
00386     uint8_t iChannel = (dwChannel) & 0xFF;
00387     uint8_t state;
00388     assert(pXdmad != NULL);
00389 
00390     if (iChannel >= pXdmad->numChannels)
00391         return XDMAD_ERROR;
00392 
00393     state = pXdmad->XdmaChannels[iChannel].state;
00394 
00395     if (state == XDMAD_STATE_ALLOCATED) return XDMAD_OK;
00396 
00397     if (state == XDMAD_STATE_FREE) return XDMAD_ERROR;
00398     else if (state != XDMAD_STATE_DONE) {
00399         if (pXdmad->pollingMode)  XDMAD_Handler(pXdmad);
00400 
00401         return XDMAD_BUSY;
00402     }
00403 
00404     return XDMAD_OK;
00405 }
00406 
00407 
00408 /**
00409  * \brief Configure DMA for a single transfer.
00410  * \param pXdmad     Pointer to xDMA driver instance.
00411  * \param dwChannel ControllerNumber << 8 | ChannelNumber.
00412  */
00413 eXdmadRC XDMAD_ConfigureTransfer(sXdmad *pXdmad,
00414                                   uint32_t dwChannel,
00415                                   sXdmadCfg *pXdmaParam,
00416                                   uint32_t dwXdmaDescCfg,
00417                                   uint32_t dwXdmaDescAddr,
00418                                   uint32_t dwXdmaIntEn)
00419 {
00420     uint8_t iChannel    = (dwChannel) & 0xFF;
00421 
00422     assert(pXdmad != NULL);
00423 
00424     if (iChannel >= pXdmad->numChannels)
00425         return XDMAD_ERROR;
00426 
00427     Xdmac *pXdmac = pXdmad->pXdmacs;
00428     XDMAC_GetChannelIsr(pXdmac, iChannel);
00429 
00430     if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_FREE)
00431         return XDMAD_ERROR;
00432 
00433     if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_START)
00434         return XDMAD_BUSY;
00435 
00436     /* Linked List is enabled */
00437     if ((dwXdmaDescCfg & XDMAC_CNDC_NDE) == XDMAC_CNDC_NDE_DSCR_FETCH_EN) {
00438         if ((dwXdmaDescCfg & XDMAC_CNDC_NDVIEW_Msk) == XDMAC_CNDC_NDVIEW_NDV0) {
00439             XDMAC_SetChannelConfig(pXdmac, iChannel, pXdmaParam->mbr_cfg);
00440             XDMAC_SetSourceAddr(pXdmac, iChannel, pXdmaParam->mbr_sa);
00441             XDMAC_SetDestinationAddr(pXdmac, iChannel, pXdmaParam->mbr_da);
00442         }
00443 
00444         if ((dwXdmaDescCfg & XDMAC_CNDC_NDVIEW_Msk) == XDMAC_CNDC_NDVIEW_NDV1)
00445             XDMAC_SetChannelConfig(pXdmac, iChannel, pXdmaParam->mbr_cfg);
00446 
00447         XDMAC_SetDescriptorAddr(pXdmac, iChannel, dwXdmaDescAddr, 0);
00448         XDMAC_SetDescriptorControl(pXdmac, iChannel, dwXdmaDescCfg);
00449         XDMAC_DisableChannelIt (pXdmac, iChannel, 0xFF);
00450         XDMAC_EnableChannelIt (pXdmac, iChannel, dwXdmaIntEn);
00451     } else {
00452         /* LLI is disabled. */
00453         XDMAC_SetSourceAddr(pXdmac, iChannel, pXdmaParam->mbr_sa);
00454         XDMAC_SetDestinationAddr(pXdmac, iChannel, pXdmaParam->mbr_da);
00455         XDMAC_SetMicroblockControl(pXdmac, iChannel, pXdmaParam->mbr_ubc);
00456         XDMAC_SetBlockControl(pXdmac, iChannel, pXdmaParam->mbr_bc);
00457         XDMAC_SetDataStride_MemPattern(pXdmac, iChannel, pXdmaParam->mbr_ds);
00458         XDMAC_SetSourceMicroBlockStride(pXdmac, iChannel, pXdmaParam->mbr_sus);
00459         XDMAC_SetDestinationMicroBlockStride(pXdmac, iChannel, pXdmaParam->mbr_dus);
00460         XDMAC_SetChannelConfig(pXdmac, iChannel, pXdmaParam->mbr_cfg);
00461         XDMAC_SetDescriptorAddr(pXdmac, iChannel, 0, 0);
00462         XDMAC_SetDescriptorControl(pXdmac, iChannel, 0);
00463         XDMAC_EnableChannelIt (pXdmac, iChannel, dwXdmaIntEn);
00464     }
00465 
00466     return XDMAD_OK;
00467 }
00468 
00469 /**
00470  * \brief Start xDMA transfer.
00471  * \param pXdmad     Pointer to XDMA driver instance.
00472  * \param dwChannel ControllerNumber << 8 | ChannelNumber.
00473  */
00474 eXdmadRC XDMAD_StartTransfer(sXdmad *pXdmad, uint32_t dwChannel)
00475 {
00476     uint8_t iChannel    = (dwChannel) & 0xFF;
00477 
00478     assert(pXdmad != NULL);
00479 
00480     if (iChannel >= pXdmad->numChannels) return XDMAD_ERROR;
00481 
00482     Xdmac *pXdmac = pXdmad->pXdmacs;
00483 
00484     if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_FREE) {
00485         TRACE_ERROR("%s:: XDMAD_STATE_FREE \n\r", __FUNCTION__);
00486         return XDMAD_ERROR;
00487     } else if (pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_START) {
00488         TRACE_ERROR("%s:: XDMAD_STATE_START \n\r", __FUNCTION__)
00489         return XDMAD_BUSY;
00490     }
00491 
00492     /* Change state to transferring */
00493     pXdmad->XdmaChannels[iChannel].state = XDMAD_STATE_START;
00494     XDMAC_EnableChannel(pXdmac, iChannel);
00495 
00496     if (pXdmad->pollingMode == 0)
00497         XDMAC_EnableGIt(pXdmac, iChannel);
00498 
00499     return XDMAD_OK;
00500 }
00501 
00502 
00503 /**
00504  * \brief Stop DMA transfer.
00505  * \param pDmad     Pointer to DMA driver instance.
00506  * \param dwChannel ControllerNumber << 8 | ChannelNumber.
00507  */
00508 eXdmadRC XDMAD_StopTransfer(sXdmad *pXdmad, uint32_t dwChannel)
00509 {
00510     uint8_t _iChannel    = (dwChannel) & 0xFF;
00511     assert(pXdmad != NULL);
00512 
00513     if (_iChannel >= pXdmad->numChannels) return XDMAD_ERROR;
00514 
00515     Xdmac *pXdmac = pXdmad->pXdmacs;
00516 
00517     pXdmad->XdmaChannels[_iChannel].state = XDMAD_STATE_HALTED;
00518     /* Disable channel */
00519     XDMAC_DisableChannel(pXdmac, _iChannel);
00520     /* Disable interrupts */
00521     XDMAC_DisableChannelIt(pXdmac, _iChannel, 0xFF);
00522     /* Clear pending status */
00523     XDMAC_GetChannelIsr(pXdmac, _iChannel);
00524     XDMAC_GetGlobalChStatus(pXdmac);
00525     return XDMAD_OK;
00526 }
00527 
00528 /**@}*/
00529 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines