SAMV71 Xplained Ultra Software Package 1.5

main.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  *  \page usart_hw_handshaking USART Hardware Handshaking Example
00032  *
00033  *  \section Purpose
00034  *
00035  *  This example demonstrates the hardware handshaking mode (i.e. RTS/CTS)
00036  *  provided by the USART peripherals on SAMV7/E7 microcontrollers. The practical
00037  *  use of hardware handshaking is that it allows to stop transfer on the USART
00038  *  without losing any data in the process. This is very useful for applications
00039  *  that need to program slow memories for example.
00040  *
00041  *  \section Requirements
00042  *
00043  *  This package can be used with SAMV71 Xplained Ultra board or SAME70 Xplained board.
00044  *  It requires a fly some serial lines with hardware control support( TXD and
00045  *  RXD cross over,
00046  *  RTS and CTS cross over) to connect the PINs and PC.
00047  *  Connection:
00048  *     USART0 CTS0 (D39)
00049  *     USART0 RTS0 (D40)
00050  *     USART0 RXD0 (D14)
00051  *     USART0 TXD0 (D15)
00052  *
00053  *  \section Description
00054  *
00055  *  The provided program uses hardware handshaking mode to regulate the data
00056  *  rate of an incoming file transfer. A terminal application, such as
00057  *  hyper-terminal, is used to send a text file to the device (without any
00058  *  protocol such as X-modem). The device will enforce the configured
00059  *  bytes per second (bps) rate with its Request To Send (RTS) line.
00060  *
00061  *  Whenever the data rate meet or exceed the configurable threshold, the device
00062  *  stops receiving data on the USART. Since no buffer is provided to the XDMA,
00063  *  this will set the RTS line, telling the computer to stop sending data. Each
00064  *  second, the current data rate and total number of bytes received are
00065  *  displayed; the transfer is also restarted.
00066  *
00067  *  Note that the device may receive slightly less bytes than the actual file
00068  *  size, depending on the nature of the file. This does NOT mean that bytes
00069  *  have been lost: this is simply an issue with how line breaks are transmitted
00070  *  by the terminal. It is therefore better to use binary files, as they most
00071  *  often do not contain line breaks. For example, send one of the object files
00072  *  generated by the compiler.
00073  *
00074  *  \section Usage
00075  *
00076  *  -# Build the program and download it inside the board.
00077  *  Please refer to the Getting Started with SAM V71/E70 Microcontrollers.pdf
00078  *  -# Connect a serial cable to a USART port on the evaluation kit.
00079  *  -# On the computer, open and configure a terminal application (e.g.
00080  *     HyperTerminal on Microsoft Windows) with these settings:
00081  *        - 115200 baud rates
00082  *        - 8 data bits
00083  *        - No parity
00084  *        - 1 stop bit
00085  *        - Hardware flow control (RTS/CTS)
00086  *  -# Start the application. The following traces shall appear on the debug
00087  * terminal:
00088  *     \code
00089  *     -- USART Hardware Handshaking Example xxx --
00090  *     -- SAMxxxxx-xx
00091  *     -- Compiled: xxx xx xxxx xx:xx:xx --
00092  *     -I- Configure system tick to get 1ms tick period.
00093 *      -I- Please send a file to serial port (USART0)
00094  *     Total bytes received 0x0
00095  *     \endcode
00096  *  -# Send a file in text format to the device. On HyperTerminal, this is done
00097  *     by selecting "Transfer -> Send Text File" (this does not prevent you from
00098  *     sending binary files). The transfer will start and the device will update
00099  *     the bytes received counter on the terminal.
00100  *  -# Whenever the transfer is complete, the total number of bytes received
00101  *     should match the size of the sent file (unless it is a text file, see
00102  *     explanation in description section).
00103  *
00104  *  \section References
00105  *  - usart_hw_handshaking/main.c
00106  *  - pio.h
00107  *  - usart_dma.h
00108  *  - usart.h
00109  */
00110 
00111 /** \file
00112  *
00113  *  This file contains all the specific code for the usart_hw_handshaking.
00114  */
00115 
00116 /*------------------------------------------------------------------------------
00117  *         Headers
00118  *-----------------------------------------------------------------------------*/
00119 
00120 #include "board.h"
00121 #include "..\..\..\..\utils\utility.h"
00122 #include <string.h>
00123 #include <stdio.h>
00124 #include <stdlib.h>
00125 #include "..\..\..\..\utils\md5\md5.h"
00126 /*------------------------------------------------------------------------------
00127  *         Local definition
00128  *-----------------------------------------------------------------------------*/
00129 
00130 //#define USE_MD5_CHECK
00131 #define FULL_DUPLEX
00132 /** Size of the receive buffer used by the DMA, in bytes.*/
00133 #define BUFFER_SIZE         128
00134 
00135 /** Pins for USART */
00136 #define PINS_USART          PIN_USART0_TXD, PIN_USART0_RXD, PIN_USART0_RTS, PIN_USART0_CTS
00137 
00138 /** Register base for USART */
00139 #define BASE_USART          USART0
00140 
00141 /** Register base for USART */
00142 #define BASE_USART_IRQ      USART0_IRQn
00143 
00144 /** ID for USART */
00145 #define ID_USART           ID_USART0
00146 
00147 #define USART_Interrupt    USART0_Handler
00148 
00149 #define USART_TX_TIMEOUT   5000    // 5 seconds
00150 
00151 
00152 /* USART DMA LLI size ---- should not be less than 2*/
00153 #define USART_DMA_LLI      10
00154 
00155 #define APP_BUFFER         ( 100*1024)                          // 100 KB
00156 #define RX_BUFFER          ( BUFFER_SIZE * USART_DMA_LLI )      // RingBuffer's Size
00157 #define MIN_FREE_BYTES     ( BUFFER_SIZE * (USART_DMA_LLI-1) )  // min free bytes in ring buffer
00158 #define MAX_FREE_BYTES     ( BUFFER_SIZE * (USART_DMA_LLI-2) )  // min free bytes in ring buffer
00159 
00160 #define XDMA_NVIC_PRIO     1
00161 #define USART_NVIC_PRIO    3
00162 #define TC_NVIC_PRIO       4
00163 
00164 #ifdef USE_MD5_CHECK
00165 static md5_state_t pms;
00166 static uint8_t md5[16];
00167 #endif
00168 
00169 /*------------------------------------------------------------------------------
00170  *          Type
00171  * ----------------------------------------------------------------------------*/
00172  /* RingBuffer structure */
00173 COMPILER_PACK_SET(4)
00174 typedef struct
00175 {
00176     uint8_t               *pBuffer;       /* RingBuffer's data buffer */
00177     const uint8_t         reserved[3];    /* reserved */
00178     uint32_t              BuffSize;       /* RinBuffer's Size */
00179     volatile uint32_t     Count;          /* Unread bytes in buffer */
00180     volatile uint32_t     *pHead;         /* Head pointer of buffer */
00181     uint32_t              pTail;          /* Tail pointer of buffer */
00182 }RignBuffer_t;
00183 COMPILER_PACK_RESET()
00184 
00185 /*------------------------------------------------------------------------------
00186  *          Local variables
00187  * ----------------------------------------------------------------------------*/
00188 /** Global DMA driver for all transfer */
00189 static sXdmad ChDma;
00190 
00191 static UsartDma Usartd;
00192 static UsartChannel UsartTx, UsartRx;
00193 
00194 
00195 /**  Pins to configure for the application.*/
00196 const Pin pins[] = {PINS_USART};
00197 
00198 /**  Number of bytes received between two timer ticks.*/
00199 volatile uint32_t mutexTimeout;
00200 volatile uint8_t semaphore = 0;
00201 volatile uint32_t dmaflush = 0;
00202 static uint32_t TotalbytesReceived = 0;
00203 static uint8_t PingPongBufferFlag = 0;
00204 volatile uint32_t TimeOutTimer = 0;
00205 
00206 //uint8_t __attribute__((at(0x20448c94))) pRxBuffer[RX_BUFFER];
00207 //volatile uint32_t __attribute__((at(0x20448c94+RX_BUFFER))) dmaflush = 0;
00208 
00209 /**  Ring buffer */
00210 COMPILER_ALIGNED(32) uint8_t pRxBuffer[RX_BUFFER];
00211 
00212 /**  Application Rx buffer.*/
00213 COMPILER_ALIGNED(32) uint8_t FirstAppBuff[APP_BUFFER];
00214 COMPILER_ALIGNED(32) uint8_t SecondAppBuff[APP_BUFFER];
00215 
00216 COMPILER_WORD_ALIGNED RignBuffer_t *pUsartBuffer;
00217 
00218 static void _DmaRxCallback(uint8_t status, void* pArg);
00219 
00220 /*----------------------------------------------------------------------------
00221  *         Local functions
00222  *----------------------------------------------------------------------------*/
00223 #ifdef FULL_DUPLEX
00224 __STATIC_INLINE void _UpdateTxConfig(uint32_t Source, uint32_t size)
00225 {
00226     XDMAC_SetSourceAddr(ChDma.pXdmacs, UsartTx.ChNum, Source);
00227     XDMAC_SetMicroblockControl(ChDma.pXdmacs, UsartTx.ChNum, size);
00228 }
00229 
00230 /**
00231  *  \brief Callback function for DMA receiving.
00232  */
00233 static void _DmaTxCallback(uint8_t status, void* pArg)
00234 {
00235     /*dummy*/
00236     status = status;
00237     pArg = pArg;
00238 
00239     UsartTx.dmaProgress = 1;
00240     if (PingPongBufferFlag)
00241         _UpdateTxConfig((uint32_t)&SecondAppBuff[0], APP_BUFFER);
00242     else
00243     _UpdateTxConfig((uint32_t)&FirstAppBuff[0], APP_BUFFER);
00244 }
00245 
00246 /**
00247  * \brief Send the rest of the data in buffer if it is less than 100KB
00248 */
00249 __STATIC_INLINE void FlushTxBuffer(uint32_t TxBytesLeft)
00250 {
00251     if (PingPongBufferFlag)
00252         _UpdateTxConfig((uint32_t)&SecondAppBuff[0], TxBytesLeft);
00253     else
00254         _UpdateTxConfig((uint32_t)&FirstAppBuff[0], TxBytesLeft);
00255     USARTD_SendData(&Usartd);
00256     while (!UsartTx.dmaProgress);
00257 }
00258 
00259 #endif
00260 /**
00261 * \brief This function updates the Count variable of ring buffer
00262 **/
00263 __STATIC_INLINE void _UpdateCount(void)
00264 {
00265     /* check if there is detain ring buffer  */
00266     if (pUsartBuffer->pTail != *pUsartBuffer->pHead) {
00267         if (pUsartBuffer->pTail > *pUsartBuffer->pHead)
00268             pUsartBuffer->Count = (pUsartBuffer->BuffSize -
00269                 (pUsartBuffer->pTail % *pUsartBuffer->pHead));
00270         else
00271             pUsartBuffer->Count = (*pUsartBuffer->pHead % pUsartBuffer->pTail);
00272     }
00273     memory_barrier();
00274     TRACE_DEBUG("COUNT is %d \n\r",pUsartBuffer->Count);
00275 }
00276 
00277 /**
00278  * ISR for XDMA interrupt
00279  */
00280 void XDMAC_Handler(void)
00281 {
00282     XDMAD_Handler(&ChDma);
00283 }
00284 
00285 /**
00286  *  \brief USART interrupt routine to serve Timeout interrupts from USART
00287  */
00288 void USART_Interrupt(void)
00289 {
00290     if (BASE_USART->US_CSR & US_CSR_TIMEOUT) {
00291         /* calculate the number of bytes in circular buffer */
00292         USART_AcknowledgeRxTimeOut(BASE_USART, 0);
00293         /* Flush the DMA FIFO */
00294         BASE_USART->US_CR = US_CR_RTSEN;
00295         XDMAC_SoftwareFlushReq(ChDma.pXdmacs, UsartRx.ChNum);
00296         dmaflush++;
00297         TRACE_DEBUG(" Time out \n\r");
00298     }
00299 }
00300 
00301 /**
00302  *  \brief Callback function for DMA receiving.
00303  */
00304 static void _DmaRxCallback( uint8_t status, void* pArg )
00305 {
00306     /*dummy*/
00307     status = status;
00308     pArg = pArg;
00309 
00310     mutexTimeout = 0x7FF;
00311     while (LockMutex(semaphore, mutexTimeout)); // lock semaphore
00312     _UpdateCount();
00313     SCB_InvalidateDCache_by_Addr((uint32_t *)pRxBuffer,sizeof(pRxBuffer));
00314     if (__LDREXW(&pUsartBuffer->Count) >= MAX_FREE_BYTES) {
00315         /* Send signal to Tx side to stop sending data after filling all
00316          * except one block of buffer
00317          */
00318         BASE_USART->US_CR = US_CR_RTSEN;
00319     }
00320     ReleaseMutex(semaphore);
00321 }
00322 
00323 /**
00324  * \brief Initialize circular buffer
00325 */
00326 __STATIC_INLINE void _initCircularBuffer(RignBuffer_t *pBuff)
00327 {
00328     pBuff->pBuffer = &pRxBuffer[0];
00329     pBuff->BuffSize = RX_BUFFER;
00330     pBuff->pTail = (uint32_t )pRxBuffer;
00331     // point Head pointer of buffer to Destination address of DMA
00332     pBuff->pHead = &ChDma.pXdmacs->XDMAC_CHID[UsartRx.ChNum].XDMAC_CDA;
00333     pBuff->Count = 0;
00334 }
00335 
00336 /**
00337  *  \brief USART hardware handshaking configuration
00338  *
00339  * Configures USART in hardware handshaking mode, asynchronous, 8 bits, 1 stop
00340  * bit, no parity, 115200 baud rates and enables its transmitter and receiver.
00341  */
00342 __STATIC_INLINE void _ConfigureUsart(uint32_t baudrate, uint32_t rxTimeout)
00343 {
00344     uint32_t mode = 0
00345                 | US_MR_USART_MODE_HW_HANDSHAKING
00346                 | US_MR_USCLKS_MCK
00347                 | US_MR_CHRL_8_BIT
00348                 | US_MR_PAR_NO
00349                 | US_MR_NBSTOP_1_BIT
00350                 | US_MR_CHMODE_NORMAL;
00351 
00352     /* Reset the Tx and Rx Channel */
00353     memset(&UsartTx, 0, sizeof(UsartChannel));
00354     memset(&UsartRx, 0, sizeof(UsartChannel));
00355 
00356     /* Initialize the Rx DMA channel of USART*/
00357     UsartRx.BuffSize= BUFFER_SIZE;
00358     UsartRx.pBuff = pRxBuffer;
00359     UsartRx.callback = _DmaRxCallback;
00360     UsartRx.dmaProgrammingMode = XDMAD_LLI;
00361     UsartRx.dmaBlockSize = USART_DMA_LLI;
00362     UsartRx.dmaRingBuffer = 1;
00363     UsartRx.dmaProgress = 1;
00364 
00365     /* Initialize the Rx DMA channel of USART*/
00366 #ifdef FULL_DUPLEX
00367     UsartTx.BuffSize= APP_BUFFER;
00368     UsartTx.pBuff = FirstAppBuff;
00369     UsartTx.callback = _DmaTxCallback;
00370     UsartTx.dmaProgrammingMode = XDMAD_SINGLE;
00371     UsartTx.dmaBlockSize =  0;
00372     UsartTx.dmaRingBuffer = 0;
00373 #endif
00374     UsartTx.dmaProgress = 1;
00375 
00376     Usartd.pXdmad = &ChDma;
00377     Usartd.pRxChannel = &UsartRx;
00378     Usartd.pTxChannel = &UsartTx;
00379     USARTD_Configure(&Usartd, ID_USART, mode, baudrate, BOARD_MCK);
00380 
00381     NVIC_ClearPendingIRQ(BASE_USART_IRQ);
00382     NVIC_SetPriority( BASE_USART_IRQ , USART_NVIC_PRIO);
00383 
00384     USART_EnableIt(BASE_USART, US_IER_TIMEOUT);
00385 
00386     NVIC_EnableIRQ(BASE_USART_IRQ);
00387     USART_EnableRecvTimeOut( BASE_USART, rxTimeout);
00388     TRACE_INFO("Baudrate is set to %u and TimeOut is %f Sec",
00389             (unsigned)baudrate, (float)((float)rxTimeout / baudrate));
00390 }
00391 
00392 /**
00393 * \brief Ring buffer management
00394 * This function copies data from ring buffer to application buffer with a given length.
00395 * \param pBuff          Usart Rx DMA ring buffer
00396 * \param pDestination   Usart application buffer
00397 * \param Len            Num of dat to copy from ring buffer
00398 * \return function returns number of bytes read from ringbuffer
00399 *
00400 */
00401 static uint32_t RingBufferRead(RignBuffer_t *pBuff, uint8_t *pDestination, uint32_t Len)
00402 {
00403     uint32_t EndAddrs = ((uint32_t)pBuff->pBuffer + pBuff->BuffSize);
00404     uint32_t UnreadCount = 0;
00405     uint32_t EnableRTS = 0;
00406     uint32_t TotalLen = 0;
00407     uint32_t TailAddrs, BytesLeft;
00408 
00409     /* If timeout has occurred then re calculate the unread number of bytes */
00410     if (dmaflush) {
00411         mutexTimeout = 0x7FF;
00412         BASE_USART->US_CR = US_CR_RTSEN;            // disable transmission
00413         __disable_irq();
00414         while (LockMutex(semaphore, mutexTimeout));           // lock mutex
00415         _UpdateCount();
00416         /* If Circular buffer has still free space to fill */
00417         if (pBuff->Count < MAX_FREE_BYTES)
00418             EnableRTS = US_CR_RTSDIS;
00419         dmaflush = 0;
00420         memory_sync();
00421         ReleaseMutex(semaphore);
00422         BASE_USART->US_CR = EnableRTS;
00423         __enable_irq();
00424     }
00425 
00426     /* If there are unread bytes in ringbuffer then copy them to application
00427         buffer */
00428     if (pBuff->Count) {
00429         UnreadCount = __LDREXW(&pBuff->Count);          // unread bytes count
00430         memory_barrier();
00431         TotalLen = (Len > UnreadCount) ? UnreadCount : Len;
00432 
00433         // if read length surpasses the ring buffer boundary, then loop over
00434         if ((pBuff->pTail + TotalLen) >= EndAddrs) {
00435             BytesLeft = (EndAddrs - pBuff->pTail);
00436             memcpy( pDestination , (uint32_t *)pBuff->pTail, BytesLeft );
00437 
00438             memcpy( (pDestination +(EndAddrs - pBuff->pTail)),
00439                 (uint32_t *)(pBuff->pBuffer), TotalLen - BytesLeft);
00440             TailAddrs = ( (uint32_t)pBuff->pBuffer + (TotalLen - BytesLeft));
00441         } else {
00442             memcpy( pDestination , (uint32_t *)pBuff->pTail, TotalLen);
00443             TailAddrs = pBuff->pTail + TotalLen;
00444         }
00445         /* In this part function enable the RTS signal to stop all reception
00446         disable irq to enter in critical part gets a lock on semaphore
00447         updates Tail pointer and count of ring buffer
00448         check if RTS need to be disable to accept the data from host
00449         frees the semaphore and enable irq*/
00450         BASE_USART->US_CR = US_CR_RTSEN;            // disable transmission
00451         __disable_irq();
00452         mutexTimeout = 0x7FF;
00453         while (LockMutex(semaphore, mutexTimeout));  // lock mutex
00454         pBuff->pTail = TailAddrs;
00455         pBuff->Count -=TotalLen;                   // update count of ring buffer
00456         TotalbytesReceived +=TotalLen;
00457         memory_sync();
00458 #ifdef FULL_DUPLEX
00459         TimeOutTimer = GetTicks();
00460 #endif
00461         /* If Circular buffer is read completely */
00462         if (pUsartBuffer->Count < MAX_FREE_BYTES)
00463             EnableRTS = US_CR_RTSDIS;
00464         ReleaseMutex(semaphore);
00465         BASE_USART->US_CR = EnableRTS;
00466         __enable_irq();
00467 
00468         printf("\r Total bytes received 0x%x (%u)", \
00469             (unsigned)TotalbytesReceived, (unsigned)TotalbytesReceived);
00470 
00471         return TotalLen;      // return the number of bytes
00472     } else
00473         return 0;
00474 }
00475 
00476 
00477 /*------------------------------------------------------------------------------*/
00478 /*         Global functions                                                     */
00479 /*------------------------------------------------------------------------------*/
00480 
00481 /**
00482  *  \brief usart-hw-handshaking Application entry point..
00483  *
00484  *  Configures USART in hardware handshaking mode and
00485  *  Timer Counter 0 to generate an interrupt every second. Then, start the first
00486  *  transfer on the USART and wait in an endless loop.
00487  *
00488  *  \return Unused (ANSI-C compatibility).
00489  */
00490 int main( void )
00491 {
00492     char pbaud_time[8];
00493     uint32_t BytesRead, BytesToRead, baudrate, timeout, TxBytesLeft;
00494     uint8_t AppBufferRollOver = 0;
00495     uint8_t *pTxBuff;
00496 
00497     /* Disable watchdog*/
00498     WDT_Disable(WDT);
00499 
00500     printf("-- USART Hardware Handshaking Example %s --\n\r", SOFTPACK_VERSION);
00501     printf("-- %s\n\r", BOARD_NAME);
00502     printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__, COMPILER_NAME);
00503 
00504     /* Enable I and D cache */
00505     SCB_EnableICache();
00506     SCB_EnableDCache();
00507 
00508     /* Configure USART pins*/
00509     PIO_Configure(pins, PIO_LISTSIZE(pins));
00510 
00511     /* Configure systick for 1 ms. */
00512     TimeTick_Configure();
00513 
00514     NVIC_SetPriority(XDMAC_IRQn , XDMA_NVIC_PRIO);
00515 
00516 
00517     printf("\n\rEnter required baudrate:");
00518     gets(pbaud_time);
00519     baudrate = (atoi(pbaud_time)) ? (atoi(pbaud_time)): 921600;
00520     printf("\n\rEnter required timeout (in microsec):");
00521     gets(pbaud_time);
00522 
00523     timeout = atoi(pbaud_time);
00524     if (timeout > 1000) {
00525         timeout /= 1000;
00526         timeout = ((timeout * baudrate) / 1000);
00527     } else {
00528         timeout = (timeout * baudrate) / 1000000;
00529     }
00530     timeout = (timeout) ? ((timeout > MAX_RX_TIMEOUT) ? MAX_RX_TIMEOUT : timeout) \
00531         : MAX_RX_TIMEOUT;
00532     printf("\n\r");
00533     /* Configure USART */
00534     _ConfigureUsart(baudrate, timeout);
00535     printf("\n\r");
00536 
00537     /*Enable Rx channel of USART */
00538     USARTD_EnableRxChannels(&Usartd, &UsartRx);
00539 
00540 #ifdef FULL_DUPLEX
00541     /*Enable Tx channel of USART */
00542     USARTD_EnableTxChannels(&Usartd, &UsartTx);
00543 #endif
00544 
00545     /* Start receiving data and start timer*/
00546     USARTD_RcvData(&Usartd);
00547 
00548     /*Initialize Ring buffer */
00549     pUsartBuffer = (RignBuffer_t *)malloc(sizeof(RignBuffer_t));
00550     _initCircularBuffer(pUsartBuffer);
00551 
00552     pTxBuff = &FirstAppBuff[0];
00553 
00554     TxBytesLeft = 0;
00555 
00556 #ifdef USE_MD5_CHECK
00557     md5_init(&pms);
00558 #endif //USE_MD5_CHECK
00559 
00560 #ifdef FULL_DUPLEX
00561     printf( "\n\r-I- USART is in Full Duplex mode \n\r");
00562 #else
00563     printf( "\n\r-I- USART is in Half Duplex mode \n\r");
00564 #endif
00565     printf( "\n\r-I- Please send a file to serial port (USART0) \n\r");
00566     BytesToRead = MIN_FREE_BYTES; // Bytes to read from ring-buffer
00567 
00568     while (1) {
00569 #ifdef USE_MD5_CHECK
00570         if (DBG_IsRxReady()) {
00571             ch = DBG_GetChar();
00572             if (ch == 'm') {
00573                 uint8_t i;
00574                 md5_finish(&pms, md5);
00575                 printf("\r\nmd5:");
00576                 for (i = 0; i < sizeof(md5);i++)
00577                     printf("%.2x",md5[i]);
00578                 printf("\r\n");
00579                 md5_init(&pms);
00580                 TotalbytesReceived = 0;
00581             }
00582         }
00583 #endif
00584         /* Check Application buffer (100 KB)overflow */
00585         if (((PingPongBufferFlag == 0) &&
00586             (pTxBuff+BytesToRead) >= &FirstAppBuff[APP_BUFFER]) ||
00587             (( PingPongBufferFlag == 1) && (pTxBuff+BytesToRead) >=
00588             &SecondAppBuff[APP_BUFFER])) {
00589             AppBufferRollOver = 1;
00590             // Roll over and start copying to the beginning of Application buffer to avoid errors
00591             if (PingPongBufferFlag)
00592                 BytesToRead = (&SecondAppBuff[APP_BUFFER] - pTxBuff);
00593             else
00594                 BytesToRead = (&FirstAppBuff[APP_BUFFER] - pTxBuff);
00595             memory_barrier();
00596         }
00597         /* Read ring buffer */
00598         BytesRead = RingBufferRead(pUsartBuffer, pTxBuff, BytesToRead);
00599         memory_sync();
00600         TxBytesLeft += BytesRead;       // number of bytes to send via USART Tx
00601 
00602 #ifdef USE_MD5_CHECK
00603         if (BytesRead > 0)
00604             md5_append(&pms,pTxBuff,BytesRead);
00605 #endif
00606 
00607         /* check if one of the application buffer is full and ready to send */
00608         if (AppBufferRollOver && (TxBytesLeft == APP_BUFFER)) {
00609             AppBufferRollOver = 0;
00610             TxBytesLeft = 0;
00611             BytesRead = 0;
00612             BytesToRead = MIN_FREE_BYTES; // Bytes to read from ring-buffer
00613             while (!UsartTx.dmaProgress);
00614             if (PingPongBufferFlag) {
00615                 PingPongBufferFlag = 0;
00616                 pTxBuff = &FirstAppBuff[0];
00617             } else {
00618                 PingPongBufferFlag = 1;
00619                 pTxBuff = &SecondAppBuff[0];
00620             }
00621             memory_sync();
00622 #ifdef FULL_DUPLEX
00623             USARTD_SendData(&Usartd);
00624 #endif
00625         }
00626         /* otherwise keep storing in same application buffer from Rx DMA's ring
00627             buffer */
00628         else {
00629             BytesToRead = MIN_FREE_BYTES; // Bytes to read from ring-buffer
00630             pTxBuff += BytesRead;
00631 
00632 #ifdef FULL_DUPLEX
00633             /* Check for Tx timeout, if there is timeout then send the bytes left
00634                 (less than 100 KB) in application buffer */
00635             if ((GetDelayInTicks(TimeOutTimer, GetTicks()) == USART_TX_TIMEOUT)
00636                 && TxBytesLeft) {
00637                 // wait for any eventual USART Tx in progress
00638                 while (!UsartTx.dmaProgress);
00639                 FlushTxBuffer(TxBytesLeft);
00640                 TimeOutTimer = GetTicks();
00641                 PingPongBufferFlag = 0;
00642                 TxBytesLeft = 0;
00643                 BytesRead = 0;
00644                 BytesToRead = MIN_FREE_BYTES; // Bytes to read from ring-buffer
00645                 pTxBuff = &FirstAppBuff[0];
00646                 _UpdateTxConfig((uint32_t)&FirstAppBuff[0], APP_BUFFER);
00647                 TRACE_INFO_WP(" TX Tiemout \n\r");
00648             }
00649 #endif
00650         }
00651     }
00652 }
00653 /** \endcond */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines