SAMV71 Xplained Ultra Software Package 1.4

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