SAMV71 Xplained Ultra Software Package 1.5

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