SAMV71 Xplained Ultra Software Package 1.3

xdmad.c

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