SAMV71 Xplained Ultra Software Package 1.5

usart_dma.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 /**
00031 * \addtogroup usart_dma_module USART xDMA driver
00032 * \section Usage
00033 *
00034 * <ul>
00035 * <li> USARTD_Configure() initializes and configures the USART peripheral
00036 * and xDMA for data transfer.</li>
00037 * <li> Configures the parameters for the device corresponding to the cs
00038 * value by USARTD_ConfigureCS(). </li>
00039 * </ul>
00040 *
00041 */
00042 
00043 /**
00044  * \file
00045  *
00046  * Implementation for the USART with xDMA driver.
00047  *
00048  */
00049 
00050 /*----------------------------------------------------------------------------
00051  *        Headers
00052  *----------------------------------------------------------------------------*/
00053 
00054 #include "chip.h"
00055 #include "string.h"
00056 #include "stdlib.h"
00057 
00058 /*----------------------------------------------------------------------------
00059  *        Local functions
00060  *----------------------------------------------------------------------------*/
00061 
00062 /**
00063  * \brief USART xDMA Rx callback
00064  * Invoked on USART DMA reception done.
00065  * \param channel DMA channel.
00066  * \param pArg Pointer to callback argument - Pointer to USARTDma instance.
00067  */
00068 static void USARTD_Rx_Cb(uint32_t channel, UsartDma *pArg)
00069 {
00070 
00071     UsartChannel *pUsartdCh = pArg->pRxChannel;
00072 
00073     if (channel != pUsartdCh->ChNum)
00074         return;
00075 
00076     /* Release the DMA channels */
00077     XDMAD_FreeChannel(pArg->pXdmad, pUsartdCh->ChNum);
00078     pUsartdCh->dmaProgress = 1;
00079     SCB_InvalidateDCache_by_Addr((uint32_t *)pUsartdCh->pBuff, pUsartdCh->BuffSize);
00080 
00081 }
00082 
00083 /**
00084  * \brief USART xDMA Rx callback
00085  * Invoked on USART DMA reception done.
00086  * \param channel DMA channel.
00087  * \param pArg Pointer to callback argument - Pointer to USARTDma instance.
00088  */
00089 static void USARTD_Tx_Cb(uint32_t channel, UsartDma *pArg)
00090 {
00091     UsartChannel *pUsartdCh = pArg->pTxChannel;
00092 
00093     if (channel != pUsartdCh->ChNum)
00094         return;
00095 
00096     /* Release the DMA channels */
00097     XDMAD_FreeChannel(pArg->pXdmad, pUsartdCh->ChNum);
00098 
00099     pUsartdCh->dmaProgress = 1;
00100 }
00101 
00102 /**
00103  * \brief Configure the USART Rx DMA Destination with Linker List mode.
00104  *
00105  * \param UsartChannel Pointer to USART dma channel
00106  * \returns 0 if the dma multibuffer configuration successfully; otherwise
00107  * returnsUSARTD_ERROR_XXX.
00108  */
00109 static uint8_t _configureRxDma(UsartDma *pUsart, UsartChannel *pUsartRx)
00110 {
00111     sXdmadCfg xdmadRxCfg;
00112     uint32_t xdmaCndc, xdmaInt;
00113     uint32_t i, LLI_Size;
00114     Usart *pUsartHwRx = pUsart->pUsartHw;
00115     sXdmad *pXdmadRx = pUsart->pXdmad;
00116     uint8_t *pBuff = 0;
00117 
00118 
00119     /* Setup RX Single block */
00120     if (pUsartRx->dmaProgrammingMode < XDMAD_LLI) {
00121         xdmadRxCfg.mbr_ubc = pUsartRx->BuffSize;
00122         xdmadRxCfg.mbr_da = (uint32_t)pUsartRx->pBuff;
00123 
00124         xdmadRxCfg.mbr_sa = (uint32_t)&pUsartHwRx->US_RHR;
00125         xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
00126                              XDMAC_CC_MBSIZE_SIXTEEN |
00127                              XDMAC_CC_DSYNC_PER2MEM |
00128                              XDMAC_CC_CSIZE_CHK_1 |
00129                              XDMAC_CC_DWIDTH_BYTE |
00130                              XDMAC_CC_SIF_AHB_IF1 |
00131                              XDMAC_CC_DIF_AHB_IF1 |
00132                              XDMAC_CC_SAM_FIXED_AM |
00133                              XDMAC_CC_DAM_INCREMENTED_AM |
00134                              XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
00135                                             (pUsart->usartId, XDMAD_TRANSFER_RX));
00136 
00137         xdmadRxCfg.mbr_bc = 0;
00138 
00139         if (pUsartRx->dmaProgrammingMode == XDMAD_MULTI)
00140             xdmadRxCfg.mbr_bc = pUsartRx->dmaBlockSize;
00141 
00142         xdmadRxCfg.mbr_sus = 0;
00143         xdmadRxCfg.mbr_dus = 0;
00144         xdmaCndc = 0;
00145         xdmaInt =  (XDMAC_CIE_BIE   |
00146                     XDMAC_CIE_DIE   |
00147                     XDMAC_CIE_FIE   |
00148                     XDMAC_CIE_RBIE  |
00149                     XDMAC_CIE_WBIE  |
00150                     XDMAC_CIE_ROIE);
00151     } else if (pUsartRx->dmaProgrammingMode == XDMAD_LLI) {
00152 
00153         /* Setup RX Link List */
00154         LLI_Size = pUsartRx->dmaBlockSize;
00155         pBuff = pUsartRx->pBuff;
00156 
00157         if (pUsartRx->pLLIview != NULL) {
00158             free(pUsartRx->pLLIview);
00159             pUsartRx->pLLIview = NULL;
00160         }
00161 
00162         pUsartRx->pLLIview = malloc(sizeof(LinkedListDescriporView1) * LLI_Size);
00163 
00164         if (pUsartRx->pLLIview == NULL) {
00165             TRACE_ERROR(" Can not allocate memory to Rx LLI");
00166             return USARTD_ERROR;
00167         }
00168 
00169         xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
00170                              XDMAC_CC_MBSIZE_SIXTEEN |
00171                              XDMAC_CC_DSYNC_PER2MEM |
00172                              XDMAC_CC_MEMSET_NORMAL_MODE |
00173                              XDMAC_CC_CSIZE_CHK_1 |
00174                              XDMAC_CC_DWIDTH_BYTE |
00175                              XDMAC_CC_SIF_AHB_IF1 |
00176                              XDMAC_CC_DIF_AHB_IF1 |
00177                              XDMAC_CC_SAM_FIXED_AM |
00178                              XDMAC_CC_DAM_INCREMENTED_AM |
00179                              XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
00180                                             (pUsart->usartId, XDMAD_TRANSFER_RX));
00181         xdmadRxCfg.mbr_bc = 0;
00182 
00183         for (i = 0; i < LLI_Size; i++) {
00184             pUsartRx->pLLIview[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 |
00185                                             XDMA_UBC_NSEN_UNCHANGED |
00186                                             XDMA_UBC_NDEN_UPDATED |
00187                                             ((i == LLI_Size - 1) ? (
00188                                                  (pUsartRx->dmaRingBuffer) ?
00189                                                  XDMA_UBC_NDE_FETCH_EN : 0) :
00190                                              XDMA_UBC_NDE_FETCH_EN) |
00191                                             pUsartRx->BuffSize;
00192             pUsartRx->pLLIview[i].mbr_sa = (uint32_t)&pUsartHwRx->US_RHR;
00193             pUsartRx->pLLIview[i].mbr_da = (uint32_t)pBuff;
00194             pUsartRx->pLLIview[i].mbr_nda = (i == (LLI_Size - 1)) ?
00195                                             ((pUsartRx->dmaRingBuffer) ? (uint32_t)pUsartRx->pLLIview : 0)
00196                                             : (uint32_t)&pUsartRx->pLLIview[ i + 1 ];
00197             pBuff += pUsartRx->BuffSize;
00198         }
00199 
00200         SCB_CleanDCache_by_Addr((uint32_t *)(pUsartRx->pLLIview),
00201                                 sizeof(LinkedListDescriporView1)*LLI_Size);
00202         xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 |
00203                    XDMAC_CNDC_NDE_DSCR_FETCH_EN |
00204                    XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED |
00205                    XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED;
00206         xdmaInt = ((pUsartRx->dmaRingBuffer) ? XDMAC_CIE_BIE : XDMAC_CIE_LIE);
00207     } else
00208         return 1;
00209 
00210     if (XDMAD_ConfigureTransfer(
00211             pXdmadRx, pUsartRx->ChNum, &xdmadRxCfg, xdmaCndc,
00212             (uint32_t)pUsartRx->pLLIview, xdmaInt))
00213         return USARTD_ERROR;
00214 
00215     return 0;
00216 }
00217 
00218 /**
00219  * \brief Configure the USART tx DMA source with Linker List mode.
00220  *
00221  * \param UsartChannel Pointer to USART dma channel
00222   * \returns 0 if the dma multibuffer configuration successfully; otherwise returns
00223  * USARTD_ERROR_XXX.
00224  */
00225 static uint8_t _configureTxDma(UsartDma *pUsart, UsartChannel *pUsartTx)
00226 {
00227     sXdmadCfg xdmadTxCfg;
00228     uint32_t xdmaCndc, xdmaInt, LLI_Size, i;
00229     uint8_t *pBuff = 0;
00230     Usart *pUsartHwTx = pUsart->pUsartHw;
00231     sXdmad *pXdmadTx = pUsart->pXdmad;
00232 
00233     /* Setup TX Link List */
00234 
00235     if (pUsartTx->dmaProgrammingMode < XDMAD_LLI) {
00236         /* Number of Data */
00237         xdmadTxCfg.mbr_ubc =   pUsartTx->BuffSize;
00238         /* Source and Destination address of DMA */
00239         xdmadTxCfg.mbr_sa = (uint32_t)pUsartTx->pBuff;
00240         xdmadTxCfg.mbr_da = (uint32_t)&pUsartHwTx->US_THR;
00241         /* DMA Channel configuration */
00242         xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
00243                              XDMAC_CC_MBSIZE_SIXTEEN |
00244                              XDMAC_CC_DSYNC_MEM2PER |
00245                              XDMAC_CC_CSIZE_CHK_1 |
00246                              XDMAC_CC_DWIDTH_BYTE |
00247                              XDMAC_CC_SIF_AHB_IF1 |
00248                              XDMAC_CC_DIF_AHB_IF1 |
00249                              XDMAC_CC_SAM_INCREMENTED_AM |
00250                              XDMAC_CC_DAM_FIXED_AM |
00251                              XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
00252                                             (pUsart->usartId, XDMAD_TRANSFER_TX));
00253 
00254         xdmadTxCfg.mbr_bc = 0;
00255 
00256         if (pUsartTx->dmaProgrammingMode == XDMAD_MULTI)
00257             xdmadTxCfg.mbr_bc = pUsartTx->dmaBlockSize;
00258 
00259         xdmadTxCfg.mbr_sus = 0;
00260         xdmadTxCfg.mbr_dus = 0;
00261         xdmadTxCfg.mbr_ds = 0;
00262         xdmaCndc = 0;
00263         /* Enable End of Block; Read Bus error;  Write Bus Error;
00264         Overflow Error interrupt */
00265         xdmaInt =  (XDMAC_CIE_BIE    |
00266                     XDMAC_CIE_RBIE  |
00267                     XDMAC_CIE_WBIE  |
00268                     XDMAC_CIE_ROIE);
00269     } else if (pUsartTx->dmaProgrammingMode == XDMAD_LLI) {
00270         LLI_Size = pUsartTx->dmaBlockSize;
00271         pBuff = pUsartTx->pBuff;
00272 
00273         /* If channel's LLI is already configured and application
00274         want to reconfigured it, free before re-allocating memory */
00275         if (pUsartTx->pLLIview != NULL) {
00276             free(pUsartTx->pLLIview);
00277             pUsartTx->pLLIview = NULL;
00278         }
00279 
00280         pUsartTx->pLLIview = malloc(sizeof(LinkedListDescriporView1) * LLI_Size);
00281 
00282         if (pUsartTx->pLLIview == NULL) {
00283             TRACE_ERROR(" Can not allocate memory to Tx LLI");
00284             return USARTD_ERROR;
00285         }
00286 
00287         xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
00288                              XDMAC_CC_MBSIZE_SIXTEEN |
00289                              XDMAC_CC_DSYNC_MEM2PER |
00290                              XDMAC_CC_MEMSET_NORMAL_MODE |
00291                              XDMAC_CC_CSIZE_CHK_1 |
00292                              XDMAC_CC_DWIDTH_BYTE |
00293                              XDMAC_CC_SIF_AHB_IF1 |
00294                              XDMAC_CC_DIF_AHB_IF1 |
00295                              XDMAC_CC_SAM_INCREMENTED_AM |
00296                              XDMAC_CC_DAM_FIXED_AM |
00297                              XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
00298                                             (pUsart->usartId, XDMAD_TRANSFER_TX));
00299         xdmadTxCfg.mbr_bc = 0;
00300 
00301         for (i = 0; i < LLI_Size; i++) {
00302             pUsartTx->pLLIview[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 |
00303                                             XDMA_UBC_NSEN_UPDATED |
00304                                             XDMA_UBC_NDEN_UNCHANGED |
00305                                             ((i == LLI_Size - 1) ? ((pUsartTx->dmaRingBuffer)
00306                                                     ? XDMA_UBC_NDE_FETCH_EN : 0) :
00307                                              XDMA_UBC_NDE_FETCH_EN) | pUsartTx->BuffSize;
00308             pUsartTx->pLLIview[i].mbr_sa = (uint32_t)pBuff;
00309             pUsartTx->pLLIview[i].mbr_da = (uint32_t)&pUsartHwTx->US_THR;
00310             pUsartTx->pLLIview[i].mbr_nda = (i == (LLI_Size - 1)) ?
00311                                             ((pUsartTx->dmaRingBuffer) ? (uint32_t)pUsartTx->pLLIview : 0)
00312                                             : (uint32_t)&pUsartTx->pLLIview[ i + 1 ];
00313             pBuff += pUsartTx->BuffSize;
00314         }
00315 
00316         SCB_CleanDCache_by_Addr((uint32_t *)(pUsartTx->pLLIview),
00317                                 sizeof(LinkedListDescriporView1)*LLI_Size);
00318         xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 |
00319                    XDMAC_CNDC_NDE_DSCR_FETCH_EN |
00320                    XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED |
00321                    XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED;
00322         xdmaInt = ((pUsartTx->dmaRingBuffer) ? XDMAC_CIE_BIE : XDMAC_CIE_LIE);
00323     } else {
00324         TRACE_ERROR("DmaProgState is incorrect \n\r");
00325         return 1;
00326     }
00327 
00328     if (XDMAD_ConfigureTransfer(pXdmadTx, pUsartTx->ChNum,
00329                                  &xdmadTxCfg, xdmaCndc, (uint32_t)pUsartTx->pLLIview, xdmaInt))
00330         return USARTD_ERROR;
00331 
00332     return 0;
00333 }
00334 
00335 /*----------------------------------------------------------------------------
00336  *        Exported functions
00337  *----------------------------------------------------------------------------*/
00338 /**
00339  * \brief Initializes the USARTDma structure and the corresponding USART & DMA .
00340  * hardware select value.
00341  * The driver will uses DMA channel 0 for RX and DMA channel 1 for TX.
00342  * The DMA channels are freed automatically when no USART command processing.
00343  *
00344  * \param pUSARTD  Pointer to a UsartDma instance.
00345  * \param pUsartHw Associated USART peripheral.
00346  * \param usartId  USART peripheral identifier.
00347  * \param UsartClk USART clock.
00348  * \param pXdmad  Pointer to a Dmad instance.
00349  */
00350 uint32_t USARTD_Configure(UsartDma *pUsartd ,
00351                            uint8_t usartId,
00352                            uint32_t UsartMode,
00353                            uint32_t BaudRate,
00354                            uint32_t UsartClk)
00355 {
00356     /* Enable the peripheral clock in the PMC*/
00357     PMC_EnablePeripheral(usartId);
00358 
00359     /* Initialize the USART structure */
00360     pUsartd->usartId  = usartId;
00361 
00362     if (usartId == ID_USART0)
00363         pUsartd->pUsartHw = USART0;
00364 
00365     if (usartId == ID_USART1)
00366         pUsartd->pUsartHw = USART1;
00367 
00368     if (usartId == ID_USART2)
00369         pUsartd->pUsartHw = USART2;
00370 
00371 
00372     pUsartd->pXdmad->pXdmacs = XDMAC;
00373     /* Enable the USART Peripheral ,Execute a software reset of the USART,
00374         Configure USART in Master Mode*/
00375     USART_Configure (pUsartd->pUsartHw, UsartMode, BaudRate, UsartClk);
00376 
00377     /* Driver initialize */
00378     XDMAD_Initialize(pUsartd->pXdmad, 0);
00379 
00380     /* Check if DMA IRQ is enable; if not clear pending IRQs in init it */
00381     if (!(NVIC_GetActive(XDMAC_IRQn)))
00382         NVIC_ClearPendingIRQ(XDMAC_IRQn);
00383 
00384     return 0;
00385 }
00386 
00387 /**
00388  * \brief This function initialize the appropriate DMA channel for Rx channel
00389  * of USART
00390  * \param pUsartd       Pointer to a UsartDma instance.
00391  * \param pRxCh         Pointer to TxChannel configuration
00392  * \returns             0 if the transfer has been started successfully;
00393  * otherwise returns USARTD_ERROR_LOCK is the driver is in use, or
00394  * USARTD_ERROR if the command is not valid.
00395  */
00396 uint32_t USARTD_EnableRxChannels(UsartDma *pUsartd, UsartChannel *pRxCh)
00397 {
00398     uint32_t Channel;
00399 
00400     assert(pRxCh);
00401     /* Init USART Rx Channel. */
00402     pUsartd->pRxChannel = pRxCh;
00403 
00404     /* Enables the USART to receive data. */
00405     USART_SetReceiverEnabled (pUsartd->pUsartHw , ENABLE);
00406 
00407 
00408     /* Allocate a DMA channel for USART0/1 RX. */
00409     Channel =  XDMAD_AllocateChannel(pUsartd->pXdmad, pUsartd->usartId,
00410                                       XDMAD_TRANSFER_MEMORY);
00411 
00412     if (Channel == XDMAD_ALLOC_FAILED)
00413         return USARTD_ERROR;
00414 
00415     pRxCh->ChNum = Channel;
00416 
00417     /* Setup callbacks for USART RX */
00418     if (pUsartd->pRxChannel->callback) {
00419         XDMAD_SetCallback(pUsartd->pXdmad, pRxCh->ChNum,
00420                           (XdmadTransferCallback)pRxCh->callback, pRxCh->pArgument);
00421     } else {
00422         XDMAD_SetCallback(pUsartd->pXdmad, pRxCh->ChNum,
00423                           (XdmadTransferCallback)USARTD_Rx_Cb, pUsartd);
00424     }
00425 
00426 
00427     if (XDMAD_PrepareChannel(pUsartd->pXdmad, pRxCh->ChNum))
00428         return USARTD_ERROR;
00429 
00430     if (_configureRxDma(pUsartd , pUsartd->pRxChannel))
00431         return USARTD_ERROR_LOCK;
00432 
00433     /* Check if DMA IRQ is enable; if not Enable it */
00434     if (!(NVIC_GetActive(XDMAC_IRQn))) {
00435         /* Enable interrupt  */
00436         NVIC_EnableIRQ(XDMAC_IRQn);
00437     }
00438 
00439     return 0;
00440 }
00441 
00442 /**
00443  * \brief This function initialize the appropriate DMA channel for Tx channel
00444  * of USART
00445  * \param pUsartd       Pointer to a USARTDma instance.
00446  * \param pTxCh         Pointer to TxChannel configuration
00447  * \returns             0 if the transfer has been started successfully;
00448  * otherwise returns USARTD_ERROR_LOCK is the driver is in use, or
00449  * USARTD_ERROR if the command is not valid.
00450  */
00451 uint32_t USARTD_EnableTxChannels(UsartDma *pUsartd, UsartChannel *pTxCh)
00452 {
00453 
00454     uint32_t Channel;
00455 
00456     assert(pTxCh);
00457 
00458     /* Init USART Tx Channel. */
00459     pUsartd->pTxChannel = pTxCh;
00460 
00461     /* Enables the USART to transfer data. */
00462     USART_SetTransmitterEnabled (pUsartd->pUsartHw , ENABLE);
00463 
00464     /* Allocate a DMA channel for USART0/1 TX. */
00465     Channel =  XDMAD_AllocateChannel(pUsartd->pXdmad, XDMAD_TRANSFER_MEMORY,
00466                                       pUsartd->usartId);
00467 
00468     if (Channel == XDMAD_ALLOC_FAILED)
00469         return USARTD_ERROR;
00470 
00471     pTxCh->ChNum = Channel;
00472 
00473     /* Setup callbacks for USART0/1 TX */
00474     if (pUsartd->pTxChannel->callback) {
00475         XDMAD_SetCallback(pUsartd->pXdmad, pTxCh->ChNum,
00476                           (XdmadTransferCallback)pTxCh->callback, pTxCh->pArgument);
00477     } else
00478         XDMAD_SetCallback(pUsartd->pXdmad, pTxCh->ChNum,
00479                           (XdmadTransferCallback)USARTD_Tx_Cb, pUsartd);
00480 
00481     if (XDMAD_PrepareChannel(pUsartd->pXdmad, pTxCh->ChNum))
00482         return USARTD_ERROR;
00483 
00484     if (_configureTxDma(pUsartd , pUsartd->pTxChannel))
00485         return USARTD_ERROR_LOCK;
00486 
00487     /* Check if DMA IRQ is enable; if not Enable it */
00488     if (!(NVIC_GetActive(XDMAC_IRQn))) {
00489         /* Enable interrupt  */
00490         NVIC_EnableIRQ(XDMAC_IRQn);
00491     }
00492 
00493     return 0;
00494 }
00495 
00496 /**
00497  * \brief This function disables the appropriate DMA channel for Rx channel of
00498  * USART
00499  * \param pUsartd       Pointer to a UsartDma instance.
00500  * \param pRxCh         Pointer to TxChannel configuration
00501  * \returns             0 if the transfer has been started successfully;
00502  * otherwise returns USARTD_ERROR_LOCK is the driver is in use, or
00503  * USARTD_ERROR if the command is not valid.
00504  */
00505 uint32_t USARTD_DisableRxChannels(UsartDma *pUsartd, UsartChannel *pRxCh)
00506 {
00507     assert(pRxCh);
00508 
00509     /* Enables the USART to transfer data. */
00510     USART_SetReceiverEnabled (pUsartd->pUsartHw , DISABLE);
00511 
00512     XDMAD_StopTransfer(pUsartd->pXdmad, pRxCh->ChNum);
00513 
00514     XDMAD_SetCallback(pUsartd->pXdmad, pRxCh->ChNum, NULL, NULL);
00515 
00516     /* Free allocated DMA channel for USART TX. */
00517     if (XDMAD_FreeChannel(pUsartd->pXdmad, pRxCh->ChNum) != XDMAD_OK)
00518         return USARTD_ERROR;
00519 
00520     if (pRxCh->dmaProgrammingMode == XDMAD_LLI) {
00521         free(pRxCh->pLLIview);
00522         pRxCh->pLLIview = NULL;
00523     }
00524 
00525     pRxCh->dmaProgress = 1;
00526     return 0;
00527 }
00528 
00529 /**
00530  * \brief This function disables the appropriate DMA channel for Tx channel of
00531  * USART
00532  * \param pUsartd       Pointer to a USARTDma instance.
00533  * \param pTxCh         Pointer to TxChannel configuration
00534  * \returns             0 if the transfer has been started successfully;
00535  * otherwise returns USARTD_ERROR_LOCK is the driver is in use, or
00536  * USARTD_ERROR if the command is not valid.
00537  */
00538 
00539 uint32_t USARTD_DisableTxChannels(UsartDma *pUsartd, UsartChannel *pTxCh)
00540 {
00541     assert(pTxCh);
00542 
00543     /* Enables the USART to transfer data. */
00544     USART_SetTransmitterEnabled (pUsartd->pUsartHw , DISABLE);
00545 
00546     XDMAD_StopTransfer(pUsartd->pXdmad, pTxCh->ChNum);
00547 
00548     XDMAD_SetCallback(pUsartd->pXdmad, pTxCh->ChNum, NULL, NULL);
00549 
00550     /* Free allocated DMA channel for USART TX. */
00551     if (XDMAD_FreeChannel(pUsartd->pXdmad, pTxCh->ChNum) != XDMAD_OK)
00552         return USARTD_ERROR;
00553 
00554     if (pTxCh->dmaProgrammingMode == XDMAD_LLI) {
00555         free(pTxCh->pLLIview);
00556         pTxCh->pLLIview = NULL;
00557     }
00558 
00559     pTxCh->dmaProgress = 1;
00560     return 0;
00561 }
00562 
00563 /**
00564  * \brief Starts a USART master transfer. This is a non blocking function. It
00565  * will return as soon as the transfer is started.
00566  *
00567  * \param pUSARTD  Pointer to a USARTDma instance.
00568  * \returns 0 if the transfer has been started successfully; otherwise returns
00569  * USARTD_ERROR_LOCK is the driver is in use, or USARTD_ERROR if the command is
00570  * not valid.
00571  */
00572 uint32_t USARTD_SendData(UsartDma *pUsartd)
00573 {
00574     /* Start DMA 0(RX) && 1(TX) */
00575     pUsartd->pTxChannel->dmaProgress = 0;
00576     SCB_CleanDCache_by_Addr((uint32_t *)pUsartd->pTxChannel->pBuff,
00577                             pUsartd->pTxChannel->BuffSize);
00578 
00579     if (XDMAD_StartTransfer(pUsartd->pXdmad, pUsartd->pTxChannel->ChNum))
00580         return USARTD_ERROR_LOCK;
00581 
00582     return 0;
00583 }
00584 
00585 /**
00586  * \brief Starts a USART master transfer. This is a non blocking function. It will
00587  *  return as soon as the transfer is started.
00588  *
00589  * \param pUSARTD  Pointer to a USARTDma instance.
00590  * \returns 0 if the transfer has been started successfully; otherwise returns
00591  * USARTD_ERROR_LOCK is the driver is in use, or USARTD_ERROR if the command is not
00592  * valid.
00593  */
00594 uint32_t USARTD_RcvData(UsartDma *pUsartd)
00595 {
00596     /* Start DMA 0(RX) && 1(TX) */
00597     pUsartd->pRxChannel->dmaProgress = 0;
00598 
00599     if (XDMAD_StartTransfer(pUsartd->pXdmad, pUsartd->pRxChannel->ChNum))
00600         return USARTD_ERROR_LOCK;
00601 
00602     return 0;
00603 }
00604 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines