SAMV71 Xplained Ultra Software Package 1.3

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