123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773 |
- //###########################################################################
- //
- // FILE: uartstdio.c
- //
- // TITLE: Utility driver to provide simple UART console functions.
- //
- //###########################################################################
- // $TI Release: F2837xD Support Library v3.05.00.00 $
- // $Release Date: Tue Jun 26 03:15:23 CDT 2018 $
- // $Copyright:
- // Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions
- // are met:
- //
- // Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- //
- // Redistributions in binary form must reproduce the above copyright
- // notice, this list of conditions and the following disclaimer in the
- // documentation and/or other materials provided with the
- // distribution.
- //
- // Neither the name of Texas Instruments Incorporated nor the names of
- // its contributors may be used to endorse or promote products derived
- // from this software without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- // $
- //###########################################################################
- //
- // Included Files
- //
- #include <stdbool.h>
- #include <stdint.h>
- #include <stdarg.h>
- #include "inc/hw_ints.h"
- #include "inc/hw_memmap.h"
- #include "inc/hw_types.h"
- #include "inc/hw_uart.h"
- #include "driverlib/debug.h"
- #include "driverlib/interrupt.h"
- #include "driverlib/rom.h"
- #include "driverlib/rom_map.h"
- #include "driverlib/sysctl.h"
- #include "driverlib/uart.h"
- #include "utils/uartstdio.h"
- //*****************************************************************************
- //
- //! \addtogroup uartstdio_api
- //! @{
- //
- //*****************************************************************************
- //
- // If buffered mode is defined, set aside RX and TX buffers and read/write
- // pointers to control them.
- //
- #ifdef UART_BUFFERED
- //
- // This global controls whether or not we are echoing characters back to the
- // transmitter. By default, echo is enabled but if using this module as a
- // convenient method of implementing a buffered serial interface over which
- // you will be running an application protocol, you are likely to want to
- // disable echo by calling UARTEchoSet(false).
- //
- static bool g_bDisableEcho;
- //
- // Output ring buffer. Buffer is full if g_ui32UARTTxReadIndex is one ahead of
- // g_ui32UARTTxWriteIndex. Buffer is empty if the two indices are the same.
- //
- static unsigned char g_pcUARTTxBuffer[UART_TX_BUFFER_SIZE];
- static volatile uint32_t g_ui32UARTTxWriteIndex = 0;
- static volatile uint32_t g_ui32UARTTxReadIndex = 0;
- //
- // Input ring buffer. Buffer is full if g_ui32UARTTxReadIndex is one ahead of
- // g_ui32UARTTxWriteIndex. Buffer is empty if the two indices are the same.
- //
- static unsigned char g_pcUARTRxBuffer[UART_RX_BUFFER_SIZE];
- static volatile uint32_t g_ui32UARTRxWriteIndex = 0;
- static volatile uint32_t g_ui32UARTRxReadIndex = 0;
- //
- // Macros to determine number of free and used bytes in the transmit buffer.
- //
- #define TX_BUFFER_USED (GetBufferCount(&g_ui32UARTTxReadIndex, \
- &g_ui32UARTTxWriteIndex, \
- UART_TX_BUFFER_SIZE))
- #define TX_BUFFER_FREE (UART_TX_BUFFER_SIZE - TX_BUFFER_USED)
- #define TX_BUFFER_EMPTY (IsBufferEmpty(&g_ui32UARTTxReadIndex, \
- &g_ui32UARTTxWriteIndex))
- #define TX_BUFFER_FULL (IsBufferFull(&g_ui32UARTTxReadIndex, \
- &g_ui32UARTTxWriteIndex, \
- UART_TX_BUFFER_SIZE))
- #define ADVANCE_TX_BUFFER_INDEX(Index) \
- (Index) = ((Index) + 1) % UART_TX_BUFFER_SIZE
- //
- // Macros to determine number of free and used bytes in the receive buffer.
- //
- #define RX_BUFFER_USED (GetBufferCount(&g_ui32UARTRxReadIndex, \
- &g_ui32UARTRxWriteIndex, \
- UART_RX_BUFFER_SIZE))
- #define RX_BUFFER_FREE (UART_RX_BUFFER_SIZE - RX_BUFFER_USED)
- #define RX_BUFFER_EMPTY (IsBufferEmpty(&g_ui32UARTRxReadIndex, \
- &g_ui32UARTRxWriteIndex))
- #define RX_BUFFER_FULL (IsBufferFull(&g_ui32UARTRxReadIndex, \
- &g_ui32UARTRxWriteIndex, \
- UART_RX_BUFFER_SIZE))
- #define ADVANCE_RX_BUFFER_INDEX(Index) \
- (Index) = ((Index) + 1) % UART_RX_BUFFER_SIZE
- #endif
- //
- // The base address of the chosen UART.
- //
- static uint32_t g_ui32Base = 0;
- //
- // A mapping from an integer between 0 and 15 to its ASCII character
- // equivalent.
- //
- static const char * const g_pcHex = "0123456789abcdef";
- //
- // The list of possible base addresses for the console UART.
- //
- static const uint32_t g_ui32UARTBase[4] =
- {
- UARTA_BASE, UARTB_BASE, UARTC_BASE, UARTD_BASE
- };
- #ifdef UART_BUFFERED
- //
- // The list of possible interrupts for the console UART.
- //
- static const uint32_t g_ui32UARTInt[3] =
- {
- INT_UART0, INT_UART1, INT_UART2
- };
- //
- // The port number in use.
- //
- static uint32_t g_ui32PortNum;
- #endif
- //
- // The list of UART peripherals.
- //
- static const uint32_t g_ui32UARTPeriph[3] =
- {
- SYSCTL_PERIPH_SCI1, SYSCTL_PERIPH_SCI2, SYSCTL_PERIPH_SCI3
- };
- //*****************************************************************************
- //
- //! Determines whether the ring buffer whose pointers and size are provided
- //! is full or not.
- //!
- //! \param pui32Read points to the read index for the buffer.
- //! \param pui32Write points to the write index for the buffer.
- //! \param ui32Size is the size of the buffer in bytes.
- //!
- //! This function is used to determine whether or not a given ring buffer is
- //! full. The structure of the code is specifically to ensure that we do not
- //! see warnings from the compiler related to the order of volatile accesses
- //! being undefined.
- //!
- //! \return Returns \b true if the buffer is full or \b false otherwise.
- //
- //*****************************************************************************
- #ifdef UART_BUFFERED
- static bool
- IsBufferFull(volatile uint32_t *pui32Read,
- volatile uint32_t *pui32Write, uint32_t ui32Size)
- {
- uint32_t ui32Write;
- uint32_t ui32Read;
- ui32Write = *pui32Write;
- ui32Read = *pui32Read;
- return((((ui32Write + 1) % ui32Size) == ui32Read) ? true : false);
- }
- #endif
- //*****************************************************************************
- //
- //! Determines whether the ring buffer whose pointers and size are provided
- //! is empty or not.
- //!
- //! \param pui32Read points to the read index for the buffer.
- //! \param pui32Write points to the write index for the buffer.
- //!
- //! This function is used to determine whether or not a given ring buffer is
- //! empty. The structure of the code is specifically to ensure that we do not
- //! see warnings from the compiler related to the order of volatile accesses
- //! being undefined.
- //!
- //! \return Returns \b true if the buffer is empty or \b false otherwise.
- //
- //*****************************************************************************
- #ifdef UART_BUFFERED
- static bool
- IsBufferEmpty(volatile uint32_t *pui32Read,
- volatile uint32_t *pui32Write)
- {
- uint32_t ui32Write;
- uint32_t ui32Read;
- ui32Write = *pui32Write;
- ui32Read = *pui32Read;
- return((ui32Write == ui32Read) ? true : false);
- }
- #endif
- //*****************************************************************************
- //
- //! Determines the number of bytes of data contained in a ring buffer.
- //!
- //! \param pui32Read points to the read index for the buffer.
- //! \param pui32Write points to the write index for the buffer.
- //! \param ui32Size is the size of the buffer in bytes.
- //!
- //! This function is used to determine how many bytes of data a given ring
- //! buffer currently contains. The structure of the code is specifically to
- //! ensure that we do not see warnings from the compiler related to the order
- //! of volatile accesses being undefined.
- //!
- //! \return Returns the number of bytes of data currently in the buffer.
- //
- //*****************************************************************************
- #ifdef UART_BUFFERED
- static uint32_t
- GetBufferCount(volatile uint32_t *pui32Read,
- volatile uint32_t *pui32Write, uint32_t ui32Size)
- {
- uint32_t ui32Write;
- uint32_t ui32Read;
- ui32Write = *pui32Write;
- ui32Read = *pui32Read;
- return((ui32Write >= ui32Read) ? (ui32Write - ui32Read) :
- (ui32Size - (ui32Read - ui32Write)));
- }
- #endif
- //*****************************************************************************
- //
- // Take as many bytes from the transmit buffer as we have space for and move
- // them into the UART transmit FIFO.
- //
- //*****************************************************************************
- #ifdef UART_BUFFERED
- static void
- UARTPrimeTransmit(uint32_t ui32Base)
- {
- //
- // Do we have any data to transmit?
- //
- if(!TX_BUFFER_EMPTY)
- {
- //
- // Disable the UART interrupt. If we don't do this there is a race
- // condition which can cause the read index to be corrupted.
- //
- MAP_IntDisable(g_ui32UARTInt[g_ui32PortNum]);
- //
- // Yes - take some characters out of the transmit buffer and feed
- // them to the UART transmit FIFO.
- //
- while(MAP_UARTSpaceAvail(ui32Base) && !TX_BUFFER_EMPTY)
- {
- MAP_UARTCharPutNonBlocking(ui32Base,
- g_pcUARTTxBuffer[g_ui32UARTTxReadIndex]);
- ADVANCE_TX_BUFFER_INDEX(g_ui32UARTTxReadIndex);
- }
- //
- // Reenable the UART interrupt.
- //
- MAP_IntEnable(g_ui32UARTInt[g_ui32PortNum]);
- }
- }
- #endif
- //*****************************************************************************
- //
- //! Configures the UART console.
- //!
- //! \param ui32PortNum is the number of UART port to use for the serial console
- //! (0-2)
- //! \param ui32Baud is the bit rate that the UART is to be configured to use.
- //! \param ui32SrcClock is the frequency of the source clock for the UART
- //! module.
- //!
- //! This function will configure the specified serial port to be used as a
- //! serial console. The serial parameters are set to the baud rate
- //! specified by the \e ui32Baud parameter and use 8 bit, no parity, and 1 stop
- //! bit.
- //!
- //! This function must be called prior to using any of the other UART console
- //! functions: UARTprintf() or UARTgets(). This function assumes that the
- //! caller has previously configured the relevant UART pins for operation as a
- //! UART rather than as GPIOs.
- //!
- //! \return None.
- //
- //*****************************************************************************
- void
- UARTStdioConfig(uint32_t ui32PortNum, uint32_t ui32Baud, uint32_t ui32SrcClock)
- {
- //
- // Check the arguments.
- //
- ASSERT((ui32PortNum == 0) || (ui32PortNum == 1) ||
- (ui32PortNum == 2));
- #ifdef UART_BUFFERED
- //
- // In buffered mode, we only allow a single instance to be opened.
- //
- ASSERT(g_ui32Base == 0);
- #endif
- //
- // Check to make sure the UART peripheral is present.
- //
- if(!MAP_SysCtlPeripheralPresent(g_ui32UARTPeriph[ui32PortNum]))
- {
- return;
- }
- //
- // Select the base address of the UART.
- //
- g_ui32Base = g_ui32UARTBase[ui32PortNum];
- //
- // Enable the UART peripheral for use.
- //
- MAP_SysCtlPeripheralEnable(g_ui32UARTPeriph[ui32PortNum]);
- //
- // Configure the UART for 115200, n, 8, 1
- //
- MAP_UARTConfigSetExpClk(g_ui32Base, ui32SrcClock, ui32Baud,
- (UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE |
- UART_CONFIG_WLEN_8));
- #ifdef UART_BUFFERED
- //
- // Set the UART to interrupt whenever the TX FIFO is almost empty or
- // when any character is received.
- //
- MAP_UARTFIFOLevelSet(g_ui32Base, UART_FIFO_TX1_8, UART_FIFO_RX1_8);
- //
- // Flush both the buffers.
- //
- UARTFlushRx();
- UARTFlushTx(true);
- //
- // Remember which interrupt we are dealing with.
- //
- g_ui32PortNum = ui32PortNum;
- //
- // We are configured for buffered output so enable the master interrupt
- // for this UART and the receive interrupts. We don't actually enable the
- // transmit interrupt in the UART itself until some data has been placed
- // in the transmit buffer.
- //
- MAP_UARTIntDisable(g_ui32Base, 0xFFFFFFFF);
- MAP_UARTIntEnable(g_ui32Base, UART_INT_RX | UART_INT_RT);
- MAP_IntEnable(g_ui32UARTInt[ui32PortNum]);
- #endif
- //
- // Enable the UART operation.
- //
- MAP_UARTEnable(g_ui32Base);
- }
- //*****************************************************************************
- //
- //! Writes a string of characters to the UART output.
- //!
- //! \param pcBuf points to a buffer containing the string to transmit.
- //! \param ui32Len is the length of the string to transmit.
- //!
- //! This function will transmit the string to the UART output. The number of
- //! characters transmitted is determined by the \e ui32Len parameter. This
- //! function does no interpretation or translation of any characters. Since
- //! the output is sent to a UART, any LF (/n) characters encountered will be
- //! replaced with a CRLF pair.
- //!
- //! Besides using the \e ui32Len parameter to stop transmitting the string, if
- //! a null character (0) is encountered, then no more characters will be
- //! transmitted and the function will return.
- //!
- //! In non-buffered mode, this function is blocking and will not return until
- //! all the characters have been written to the output FIFO. In buffered mode,
- //! the characters are written to the UART transmit buffer and the call returns
- //! immediately. If insufficient space remains in the transmit buffer,
- //! additional characters are discarded.
- //!
- //! \return Returns the count of characters written.
- //
- //*****************************************************************************
- int
- UARTwrite(const char *pcBuf, uint32_t ui32Len)
- {
- #ifdef UART_BUFFERED
- unsigned int uIdx;
- //
- // Check for valid arguments.
- //
- ASSERT(pcBuf != 0);
- ASSERT(g_ui32Base != 0);
- //
- // Send the characters
- //
- for(uIdx = 0; uIdx < ui32Len; uIdx++)
- {
- //
- // If the character to the UART is \n, then add a \r before it so that
- // \n is translated to \n\r in the output.
- //
- if(pcBuf[uIdx] == '\n')
- {
- if(!TX_BUFFER_FULL)
- {
- g_pcUARTTxBuffer[g_ui32UARTTxWriteIndex] = '\r';
- ADVANCE_TX_BUFFER_INDEX(g_ui32UARTTxWriteIndex);
- }
- else
- {
- //
- // Buffer is full - discard remaining characters and return.
- //
- break;
- }
- }
- //
- // Send the character to the UART output.
- //
- if(!TX_BUFFER_FULL)
- {
- g_pcUARTTxBuffer[g_ui32UARTTxWriteIndex] = pcBuf[uIdx];
- ADVANCE_TX_BUFFER_INDEX(g_ui32UARTTxWriteIndex);
- }
- else
- {
- //
- // Buffer is full - discard remaining characters and return.
- //
- break;
- }
- }
- //
- // If we have anything in the buffer, make sure that the UART is set
- // up to transmit it.
- //
- if(!TX_BUFFER_EMPTY)
- {
- UARTPrimeTransmit(g_ui32Base);
- MAP_UARTIntEnable(g_ui32Base, UART_INT_TX);
- }
- //
- // Return the number of characters written.
- //
- return(uIdx);
- #else
- unsigned int uIdx;
- //
- // Check for valid UART base address, and valid arguments.
- //
- ASSERT(g_ui32Base != 0);
- ASSERT(pcBuf != 0);
- //
- // Send the characters
- //
- for(uIdx = 0; uIdx < ui32Len; uIdx++)
- {
- //
- // If the character to the UART is \n, then add a \r before it so that
- // \n is translated to \n\r in the output.
- //
- if(pcBuf[uIdx] == '\n')
- {
- MAP_UARTCharPut(g_ui32Base, '\r');
- }
- //
- // Send the character to the UART output.
- //
- MAP_UARTCharPut(g_ui32Base, pcBuf[uIdx]);
- }
- //
- // Return the number of characters written.
- //
- return(uIdx);
- #endif
- }
- //*****************************************************************************
- //
- //! A simple UART based get string function, with some line processing.
- //!
- //! \param pcBuf points to a buffer for the incoming string from the UART.
- //! \param ui32Len is the length of the buffer for storage of the string,
- //! including the trailing 0.
- //!
- //! This function will receive a string from the UART input and store the
- //! characters in the buffer pointed to by \e pcBuf. The characters will
- //! continue to be stored until a termination character is received. The
- //! termination characters are CR, LF, or ESC. A CRLF pair is treated as a
- //! single termination character. The termination characters are not stored in
- //! the string. The string will be terminated with a 0 and the function will
- //! return.
- //!
- //! In both buffered and unbuffered modes, this function will block until
- //! a termination character is received. If non-blocking operation is required
- //! in buffered mode, a call to UARTPeek() may be made to determine whether
- //! a termination character already exists in the receive buffer prior to
- //! calling UARTgets().
- //!
- //! Since the string will be null terminated, the user must ensure that the
- //! buffer is sized to allow for the additional null character.
- //!
- //! \return Returns the count of characters that were stored, not including
- //! the trailing 0.
- //
- //*****************************************************************************
- int
- UARTgets(char *pcBuf, uint32_t ui32Len)
- {
- #ifdef UART_BUFFERED
- uint32_t ui32Count = 0;
- int8_t cChar;
- //
- // Check the arguments.
- //
- ASSERT(pcBuf != 0);
- ASSERT(ui32Len != 0);
- ASSERT(g_ui32Base != 0);
- //
- // Adjust the length back by 1 to leave space for the trailing
- // null terminator.
- //
- ui32Len--;
- //
- // Process characters until a newline is received.
- //
- while(1)
- {
- //
- // Read the next character from the receive buffer.
- //
- if(!RX_BUFFER_EMPTY)
- {
- cChar = g_pcUARTRxBuffer[g_ui32UARTRxReadIndex];
- ADVANCE_RX_BUFFER_INDEX(g_ui32UARTRxReadIndex);
- //
- // See if a newline or escape character was received.
- //
- if((cChar == '\r') || (cChar == '\n') || (cChar == 0x1b))
- {
- //
- // Stop processing the input and end the line.
- //
- break;
- }
- //
- // Process the received character as long as we are not at the end
- // of the buffer. If the end of the buffer has been reached then
- // all additional characters are ignored until a newline is
- // received.
- //
- if(ui32Count < ui32Len)
- {
- //
- // Store the character in the caller supplied buffer.
- //
- pcBuf[ui32Count] = cChar;
- //
- // Increment the count of characters received.
- //
- ui32Count++;
- }
- }
- }
- //
- // Add a null termination to the string.
- //
- pcBuf[ui32Count] = 0;
- //
- // Return the count of int8_ts in the buffer, not counting the trailing 0.
- //
- return(ui32Count);
- #else
- uint32_t ui32Count = 0;
- int8_t cChar;
- static int8_t bLastWasCR = 0;
- //
- // Check the arguments.
- //
- ASSERT(pcBuf != 0);
- ASSERT(ui32Len != 0);
- ASSERT(g_ui32Base != 0);
- //
- // Adjust the length back by 1 to leave space for the trailing
- // null terminator.
- //
- ui32Len--;
- //
- // Process characters until a newline is received.
- //
- while(1)
- {
- //
- // Read the next character from the console.
- //
- cChar = MAP_UARTCharGet(g_ui32Base);
- //
- // See if the backspace key was pressed.
- //
- if(cChar == '\b')
- {
- //
- // If there are any characters already in the buffer, then delete
- // the last.
- //
- if(ui32Count)
- {
- //
- // Rub out the previous character.
- //
- UARTwrite("\b \b", 3);
- //
- // Decrement the number of characters in the buffer.
- //
- ui32Count--;
- }
- //
- // Skip ahead to read the next character.
- //
- continue;
- }
- //
- // If this character is LF and last was CR, then just gobble up the
- // character because the EOL processing was taken care of with the CR.
- //
- if((cChar == '\n') && bLastWasCR)
- {
- bLastWasCR = 0;
- continue;
- }
- //
- // See if a newline or escape character was received.
- //
- if((cChar == '\r') || (cChar == '\n') || (cChar == 0x1b))
- {
- //
- // If the character is a CR, then it may be followed by a LF which
- // should be paired with the CR. So remember that a CR was
- // received.
- //
- if(cChar == '\r')
- {
- bLastWasCR = 1;
- }
- //
- // Stop processing the input and end the line.
- //
- break;
- }
- //
- // Process the received character as long as we are not at the end of
- // the buffer. If the end of the buffer has been reached then all
- // additional characters are ignored until a newline is received.
- //
- if(ui32Count < ui32Len)
- {
- //
- // Store the character in the caller supplied buffer.
- //
- pcBuf[ui32Count] = cChar;
- //
- // Increment the count of characters received.
- //
- ui32Count++;
- //
- // Reflect the character back to the user.
- //
- MAP_UARTCharPut(g_ui32Base, cChar);
- }
- }
- //
- // Add a null termination to the string.
- //
- pcBuf[ui32Count] = 0;
- //
- // Send a CRLF pair to the terminal to end the line.
- //
- UARTwrite("\r\n", 2);
- //
- // Return the count of int8_ts in the buffer, not counting the trailing 0.
- //
- return(ui32Count);
- #endif
- }
- //*****************************************************************************
- //
- //! Read a single character from the UART, blocking if necessary.
- //!
- //! This function will receive a single character from the UART and store it at
- //! the supplied address.
- //!
- //! In both buffered and unbuffered modes, this function will block until a
- //! character is received. If non-blocking operation is required in buffered
- //! mode, a call to UARTRxAvail() may be made to determine whether any
- //! characters are currently available for reading.
- //!
- //! \return Returns the character read.
- //
- //*****************************************************************************
- unsigned char
- UARTgetc(void)
- {
- #ifdef UART_BUFFERED
- unsigned char cChar;
- //
- // Wait for a character to be received.
- //
- while(RX_BUFFER_EMPTY)
- {
- //
- // Block waiting for a character to be received (if the buffer is
- // currently empty).
- //
- }
- //
- // Read a character from the buffer.
- //
- cChar = g_pcUARTRxBuffer[g_ui32UARTRxReadIndex];
- ADVANCE_RX_BUFFER_INDEX(g_ui32UARTRxReadIndex);
- //
- // Return the character to the caller.
- //
- return(cChar);
- #else
- //
- // Block until a character is received by the UART then return it to
- // the caller.
- //
- return(MAP_UARTCharGet(g_ui32Base));
- #endif
- }
- //*****************************************************************************
- //
- //! A simple UART based vprintf function supporting \%c, \%d, \%p, \%s, \%u,
- //! \%x, and \%X.
- //!
- //! \param pcString is the format string.
- //! \param vaArgP is a variable argument list pointer whose content will depend
- //! upon the format string passed in \e pcString.
- //!
- //! This function is very similar to the C library <tt>vprintf()</tt> function.
- //! All of its output will be sent to the UART. Only the following formatting
- //! characters are supported:
- //!
- //! - \%c to print a character
- //! - \%d or \%i to print a decimal value
- //! - \%l to print a long decimal value
- //! - \%s to print a string
- //! - \%u to print an unsigned decimal value
- //! - \%x to print a hexadecimal value using lower case letters
- //! - \%X to print a hexadecimal value using lower case letters (not upper case
- //! letters as would typically be used)
- //! - \%p to print a pointer as a hexadecimal value
- //! - \%\% to print out a \% character
- //!
- //! For \%s, \%d, \%i, \%u, \%p, \%x, and \%X, an optional number may reside
- //! between the \% and the format character, which specifies the minimum number
- //! of characters to use for that value; if preceded by a 0 then the extra
- //! characters will be filled with zeros instead of spaces. For example,
- //! ``\%8d'' will use eight characters to print the decimal value with spaces
- //! added to reach eight; ``\%08d'' will use eight characters as well but will
- //! add zeroes instead of spaces.
- //!
- //! The type of the arguments in the variable arguments list must match the
- //! requirements of the format string. For example, if an integer was passed
- //! where a string was expected, an error of some kind will most likely occur.
- //!
- //! \return None.
- //
- //*****************************************************************************
- void
- UARTvprintf(const char *pcString, va_list vaArgP)
- {
- uint32_t ui32Idx, ui32Value, ui32Pos, ui32Count, ui32Base, ui32Neg;
- char *pcStr, pcBuf[16], cFill;
- //
- // Check the arguments.
- //
- ASSERT(pcString != 0);
- //
- // Loop while there are more characters in the string.
- //
- while(*pcString)
- {
- //
- // Find the first non-% character, or the end of the string.
- //
- for(ui32Idx = 0;
- (pcString[ui32Idx] != '%') && (pcString[ui32Idx] != '\0');
- ui32Idx++)
- {
- }
- //
- // Write this portion of the string.
- //
- UARTwrite(pcString, ui32Idx);
- //
- // Skip the portion of the string that was written.
- //
- pcString += ui32Idx;
- //
- // See if the next character is a %.
- //
- if(*pcString == '%')
- {
- //
- // Skip the %.
- //
- pcString++;
- //
- // Set the digit count to zero, and the fill character to space
- // (in other words, to the defaults).
- //
- ui32Count = 0;
- cFill = ' ';
- //
- // It may be necessary to get back here to process more characters.
- // Goto's aren't pretty, but effective. I feel extremely dirty for
- // using not one but two of the beasts.
- //
- again:
- //
- // Determine how to handle the next character.
- //
- switch(*pcString++)
- {
- //
- // Handle the digit characters.
- //
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- {
- //
- // If this is a zero, and it is the first digit, then the
- // fill character is a zero instead of a space.
- //
- if((pcString[-1] == '0') && (ui32Count == 0))
- {
- cFill = '0';
- }
- //
- // Update the digit count.
- //
- ui32Count *= 10;
- ui32Count += pcString[-1] - '0';
- //
- // Get the next character.
- //
- goto again;
- }
- //
- // Handle the %c command.
- //
- case 'c':
- {
- //
- // Get the value from the varargs.
- //
- ui32Value = va_arg(vaArgP, uint32_t);
- //
- // Print out the character.
- //
- UARTwrite((char *)&ui32Value, 1);
- //
- // This command has been handled.
- //
- break;
- }
- //
- // Handle the %d and %i commands.
- //
- case 'd':
- case 'i':
- {
- //
- // Get the value from the varargs.
- //
- ui32Value = va_arg(vaArgP, uint16_t);
- //
- // Reset the buffer position.
- //
- ui32Pos = 0;
- //
- // If the value is negative, make it positive and indicate
- // that a minus sign is needed.
- //
- if((int32_t)ui32Value < 0)
- {
- //
- // Make the value positive.
- //
- ui32Value = -(int32_t)ui32Value;
- //
- // Indicate that the value is negative.
- //
- ui32Neg = 1;
- }
- else
- {
- //
- // Indicate that the value is positive so that a minus
- // sign isn't inserted.
- //
- ui32Neg = 0;
- }
- //
- // Set the base to 10.
- //
- ui32Base = 10;
- //
- // Convert the value to ASCII.
- //
- goto convert;
- }
- //
- // Handle the %l command.
- //
- case 'l':
- {
- //
- // Get the value from the varargs.
- //
- ui32Value = va_arg(vaArgP, uint32_t);
- //
- // Reset the buffer position.
- //
- ui32Pos = 0;
- //
- // If the value is negative, make it positive and indicate
- // that a minus sign is needed.
- //
- if((int32_t)ui32Value < 0)
- {
- //
- // Make the value positive.
- //
- ui32Value = -(int32_t)ui32Value;
- //
- // Indicate that the value is negative.
- //
- ui32Neg = 1;
- }
- else
- {
- //
- // Indicate that the value is positive so that a minus
- // sign isn't inserted.
- //
- ui32Neg = 0;
- }
- //
- // Set the base to 10.
- //
- ui32Base = 10;
- //
- // Convert the value to ASCII.
- //
- goto convert;
- }
- //
- // Handle the %s command.
- //
- case 's':
- {
- //
- // Get the string pointer from the varargs.
- //
- pcStr = va_arg(vaArgP, char *);
- //
- // Determine the length of the string.
- //
- for(ui32Idx = 0; pcStr[ui32Idx] != '\0'; ui32Idx++)
- {
- }
- //
- // Write the string.
- //
- UARTwrite(pcStr, ui32Idx);
- //
- // Write any required padding spaces
- //
- if(ui32Count > ui32Idx)
- {
- ui32Count -= ui32Idx;
- while(ui32Count--)
- {
- UARTwrite(" ", 1);
- }
- }
- //
- // This command has been handled.
- //
- break;
- }
- //
- // Handle the %u command.
- //
- case 'u':
- {
- //
- // Get the value from the varargs.
- //
- ui32Value = va_arg(vaArgP, uint32_t);
- //
- // Reset the buffer position.
- //
- ui32Pos = 0;
- //
- // Set the base to 10.
- //
- ui32Base = 10;
- //
- // Indicate that the value is positive so that a minus sign
- // isn't inserted.
- //
- ui32Neg = 0;
- //
- // Convert the value to ASCII.
- //
- goto convert;
- }
- //
- // Handle the %x and %X commands. Note that they are treated
- // identically; in other words, %X will use lower case letters
- // for a-f instead of the upper case letters it should use. We
- // also alias %p to %x.
- //
- case 'x':
- case 'X':
- case 'p':
- {
- //
- // Get the value from the varargs.
- //
- ui32Value = va_arg(vaArgP, uint32_t);
- //
- // Reset the buffer position.
- //
- ui32Pos = 0;
- //
- // Set the base to 16.
- //
- ui32Base = 16;
- //
- // Indicate that the value is positive so that a minus sign
- // isn't inserted.
- //
- ui32Neg = 0;
- //
- // Determine the number of digits in the string version of
- // the value.
- //
- convert:
- for(ui32Idx = 1;
- (((ui32Idx * ui32Base) <= ui32Value) &&
- (((ui32Idx * ui32Base) / ui32Base) == ui32Idx));
- ui32Idx *= ui32Base, ui32Count--)
- {
- }
- //
- // If the value is negative, reduce the count of padding
- // characters needed.
- //
- if(ui32Neg)
- {
- ui32Count--;
- }
- //
- // If the value is negative and the value is padded with
- // zeros, then place the minus sign before the padding.
- //
- if(ui32Neg && (cFill == '0'))
- {
- //
- // Place the minus sign in the output buffer.
- //
- pcBuf[ui32Pos++] = '-';
- //
- // The minus sign has been placed, so turn off the
- // negative flag.
- //
- ui32Neg = 0;
- }
- //
- // Provide additional padding at the beginning of the
- // string conversion if needed.
- //
- if((ui32Count > 1) && (ui32Count < 16))
- {
- for(ui32Count--; ui32Count; ui32Count--)
- {
- pcBuf[ui32Pos++] = cFill;
- }
- }
- //
- // If the value is negative, then place the minus sign
- // before the number.
- //
- if(ui32Neg)
- {
- //
- // Place the minus sign in the output buffer.
- //
- pcBuf[ui32Pos++] = '-';
- }
- //
- // Convert the value into a string.
- //
- for(; ui32Idx; ui32Idx /= ui32Base)
- {
- pcBuf[ui32Pos++] =
- g_pcHex[(ui32Value / ui32Idx) % ui32Base];
- }
- //
- // Write the string.
- //
- UARTwrite(pcBuf, ui32Pos);
- //
- // This command has been handled.
- //
- break;
- }
- //
- // Handle the %% command.
- //
- case '%':
- {
- //
- // Simply write a single %.
- //
- UARTwrite(pcString - 1, 1);
- //
- // This command has been handled.
- //
- break;
- }
- //
- // Handle all other commands.
- //
- default:
- {
- //
- // Indicate an error.
- //
- UARTwrite("ERROR", 5);
- //
- // This command has been handled.
- //
- break;
- }
- }
- }
- }
- }
- //*****************************************************************************
- //
- //! A simple UART based printf function supporting \%c, \%d, \%p, \%s, \%u,
- //! \%x, and \%X.
- //!
- //! \param pcString is the format string.
- //! \param ... are the optional arguments, which depend on the contents of the
- //! format string.
- //!
- //! This function is very similar to the C library <tt>fprintf()</tt> function.
- //! All of its output will be sent to the UART. Only the following formatting
- //! characters are supported:
- //!
- //! - \%c to print a character
- //! - \%d or \%i to print a decimal value
- //! - \%s to print a string
- //! - \%u to print an unsigned decimal value
- //! - \%x to print a hexadecimal value using lower case letters
- //! - \%X to print a hexadecimal value using lower case letters (not upper case
- //! letters as would typically be used)
- //! - \%p to print a pointer as a hexadecimal value
- //! - \%\% to print out a \% character
- //!
- //! For \%s, \%d, \%i, \%u, \%p, \%x, and \%X, an optional number may reside
- //! between the \% and the format character, which specifies the minimum number
- //! of characters to use for that value; if preceded by a 0 then the extra
- //! characters will be filled with zeros instead of spaces. For example,
- //! ``\%8d'' will use eight characters to print the decimal value with spaces
- //! added to reach eight; ``\%08d'' will use eight characters as well but will
- //! add zeroes instead of spaces.
- //!
- //! The type of the arguments after \e pcString must match the requirements of
- //! the format string. For example, if an integer was passed where a string
- //! was expected, an error of some kind will most likely occur.
- //!
- //! \return None.
- //
- //*****************************************************************************
- void
- UARTprintf(const char *pcString, ...)
- {
- va_list vaArgP;
- //
- // Start the varargs processing.
- //
- va_start(vaArgP, pcString);
- UARTvprintf(pcString, vaArgP);
- //
- // We're finished with the varargs now.
- //
- va_end(vaArgP);
- }
- //*****************************************************************************
- //
- //! Returns the number of bytes available in the receive buffer.
- //!
- //! This function, available only when the module is built to operate in
- //! buffered mode using \b UART_BUFFERED, may be used to determine the number
- //! of bytes of data currently available in the receive buffer.
- //!
- //! \return Returns the number of available bytes.
- //
- //*****************************************************************************
- #if defined(UART_BUFFERED) || defined(DOXYGEN)
- int
- UARTRxBytesAvail(void)
- {
- return(RX_BUFFER_USED);
- }
- #endif
- #if defined(UART_BUFFERED) || defined(DOXYGEN)
- //*****************************************************************************
- //
- //! Returns the number of bytes free in the transmit buffer.
- //!
- //! This function, available only when the module is built to operate in
- //! buffered mode using \b UART_BUFFERED, may be used to determine the amount
- //! of space currently available in the transmit buffer.
- //!
- //! \return Returns the number of free bytes.
- //
- //*****************************************************************************
- int
- UARTTxBytesFree(void)
- {
- return(TX_BUFFER_FREE);
- }
- #endif
- //*****************************************************************************
- //
- //! Looks ahead in the receive buffer for a particular character.
- //!
- //! \param ucChar is the character that is to be searched for.
- //!
- //! This function, available only when the module is built to operate in
- //! buffered mode using \b UART_BUFFERED, may be used to look ahead in the
- //! receive buffer for a particular character and report its position if found.
- //! It is typically used to determine whether a complete line of user input is
- //! available, in which case ucChar should be set to CR ('\\r') which is used
- //! as the line end marker in the receive buffer.
- //!
- //! \return Returns -1 to indicate that the requested character does not exist
- //! in the receive buffer. Returns a non-negative number if the character was
- //! found in which case the value represents the position of the first instance
- //! of \e ucChar relative to the receive buffer read pointer.
- //
- //*****************************************************************************
- #if defined(UART_BUFFERED) || defined(DOXYGEN)
- int
- UARTPeek(unsigned char ucChar)
- {
- int iCount;
- int iAvail;
- uint32_t ui32ReadIndex;
- //
- // How many characters are there in the receive buffer?
- //
- iAvail = (int)RX_BUFFER_USED;
- ui32ReadIndex = g_ui32UARTRxReadIndex;
- //
- // Check all the unread characters looking for the one passed.
- //
- for(iCount = 0; iCount < iAvail; iCount++)
- {
- if(g_pcUARTRxBuffer[ui32ReadIndex] == ucChar)
- {
- //
- // We found it so return the index
- //
- return(iCount);
- }
- else
- {
- //
- // This one didn't match so move on to the next character.
- //
- ADVANCE_RX_BUFFER_INDEX(ui32ReadIndex);
- }
- }
- //
- // If we drop out of the loop, we didn't find the character in the receive
- // buffer.
- //
- return(-1);
- }
- #endif
- //*****************************************************************************
- //
- //! Flushes the receive buffer.
- //!
- //! This function, available only when the module is built to operate in
- //! buffered mode using \b UART_BUFFERED, may be used to discard any data
- //! received from the UART but not yet read using UARTgets().
- //!
- //! \return None.
- //
- //*****************************************************************************
- #if defined(UART_BUFFERED) || defined(DOXYGEN)
- void
- UARTFlushRx(void)
- {
- uint32_t ui32Int;
- //
- // Temporarily turn off interrupts.
- //
- ui32Int = MAP_IntMasterDisable();
- //
- // Flush the receive buffer.
- //
- g_ui32UARTRxReadIndex = 0;
- g_ui32UARTRxWriteIndex = 0;
- //
- // If interrupts were enabled when we turned them off, turn them
- // back on again.
- //
- if(!ui32Int)
- {
- MAP_IntMasterEnable();
- }
- }
- #endif
- //*****************************************************************************
- //
- //! Flushes the transmit buffer.
- //!
- //! \param bDiscard indicates whether any remaining data in the buffer should
- //! be discarded (\b true) or transmitted (\b false).
- //!
- //! This function, available only when the module is built to operate in
- //! buffered mode using \b UART_BUFFERED, may be used to flush the transmit
- //! buffer, either discarding or transmitting any data received via calls to
- //! UARTprintf() that is waiting to be transmitted. On return, the transmit
- //! buffer will be empty.
- //!
- //! \return None.
- //
- //*****************************************************************************
- #if defined(UART_BUFFERED) || defined(DOXYGEN)
- void
- UARTFlushTx(bool bDiscard)
- {
- uint32_t ui32Int;
- //
- // Should the remaining data be discarded or transmitted?
- //
- if(bDiscard)
- {
- //
- // The remaining data should be discarded, so temporarily turn off
- // interrupts.
- //
- ui32Int = MAP_IntMasterDisable();
- //
- // Flush the transmit buffer.
- //
- g_ui32UARTTxReadIndex = 0;
- g_ui32UARTTxWriteIndex = 0;
- //
- // If interrupts were enabled when we turned them off, turn them
- // back on again.
- //
- if(!ui32Int)
- {
- MAP_IntMasterEnable();
- }
- }
- else
- {
- //
- // Wait for all remaining data to be transmitted before returning.
- //
- while(!TX_BUFFER_EMPTY)
- {
- }
- }
- }
- #endif
- //*****************************************************************************
- //
- //! Enables or disables echoing of received characters to the transmitter.
- //!
- //! \param bEnable must be set to \b true to enable echo or \b false to
- //! disable it.
- //!
- //! This function, available only when the module is built to operate in
- //! buffered mode using \b UART_BUFFERED, may be used to control whether or not
- //! received characters are automatically echoed back to the transmitter. By
- //! default, echo is enabled and this is typically the desired behavior if
- //! the module is being used to support a serial command line. In applications
- //! where this module is being used to provide a convenient, buffered serial
- //! interface over which application-specific binary protocols are being run,
- //! however, echo may be undesirable and this function can be used to disable
- //! it.
- //!
- //! \return None.
- //
- //*****************************************************************************
- #if defined(UART_BUFFERED) || defined(DOXYGEN)
- void
- UARTEchoSet(bool bEnable)
- {
- g_bDisableEcho = !bEnable;
- }
- #endif
- //*****************************************************************************
- //
- //! Handles UART interrupts.
- //!
- //! This function handles interrupts from the UART. It will copy data from the
- //! transmit buffer to the UART transmit FIFO if space is available, and it
- //! will copy data from the UART receive FIFO to the receive buffer if data is
- //! available.
- //!
- //! \return None.
- //
- //*****************************************************************************
- #if defined(UART_BUFFERED) || defined(DOXYGEN)
- void
- UARTStdioIntHandler(void)
- {
- uint32_t ui32Ints;
- int8_t cChar;
- int32_t i32Char;
- static bool bLastWasCR = false;
- //
- // Get and clear the current interrupt source(s)
- //
- ui32Ints = MAP_UARTIntStatus(g_ui32Base, true);
- MAP_UARTIntClear(g_ui32Base, ui32Ints);
- //
- // Are we being interrupted because the TX FIFO has space available?
- //
- if(ui32Ints & UART_INT_TX)
- {
- //
- // Move as many bytes as we can into the transmit FIFO.
- //
- UARTPrimeTransmit(g_ui32Base);
- //
- // If the output buffer is empty, turn off the transmit interrupt.
- //
- if(TX_BUFFER_EMPTY)
- {
- MAP_UARTIntDisable(g_ui32Base, UART_INT_TX);
- }
- }
- //
- // Are we being interrupted due to a received character?
- //
- if(ui32Ints & (UART_INT_RX | UART_INT_RT))
- {
- //
- // Get all the available characters from the UART.
- //
- while(MAP_UARTCharsAvail(g_ui32Base))
- {
- //
- // Read a character
- //
- i32Char = MAP_UARTCharGetNonBlocking(g_ui32Base);
- cChar = (unsigned char)(i32Char & 0xFF);
- //
- // If echo is disabled, we skip the various text filtering
- // operations that would typically be required when supporting a
- // command line.
- //
- if(!g_bDisableEcho)
- {
- //
- // Handle backspace by erasing the last character in the
- // buffer.
- //
- if(cChar == '\b')
- {
- //
- // If there are any characters already in the buffer, then
- // delete the last.
- //
- if(!RX_BUFFER_EMPTY)
- {
- //
- // Rub out the previous character on the users
- // terminal.
- //
- UARTwrite("\b \b", 3);
- //
- // Decrement the number of characters in the buffer.
- //
- if(g_ui32UARTRxWriteIndex == 0)
- {
- g_ui32UARTRxWriteIndex = UART_RX_BUFFER_SIZE - 1;
- }
- else
- {
- g_ui32UARTRxWriteIndex--;
- }
- }
- //
- // Skip ahead to read the next character.
- //
- continue;
- }
- //
- // If this character is LF and last was CR, then just gobble up
- // the character since we already echoed the previous CR and we
- // don't want to store 2 characters in the buffer if we don't
- // need to.
- //
- if((cChar == '\n') && bLastWasCR)
- {
- bLastWasCR = false;
- continue;
- }
- //
- // See if a newline or escape character was received.
- //
- if((cChar == '\r') || (cChar == '\n') || (cChar == 0x1b))
- {
- //
- // If the character is a CR, then it may be followed by an
- // LF which should be paired with the CR. So remember that
- // a CR was received.
- //
- if(cChar == '\r')
- {
- bLastWasCR = 1;
- }
- //
- // Regardless of the line termination character received,
- // put a CR in the receive buffer as a marker telling
- // UARTgets() where the line ends. We also send an
- // additional LF to ensure that the local terminal echo
- // receives both CR and LF.
- //
- cChar = '\r';
- UARTwrite("\n", 1);
- }
- }
- //
- // If there is space in the receive buffer, put the character
- // there, otherwise throw it away.
- //
- if(!RX_BUFFER_FULL)
- {
- //
- // Store the new character in the receive buffer
- //
- g_pcUARTRxBuffer[g_ui32UARTRxWriteIndex] =
- (unsigned char)(i32Char & 0xFF);
- ADVANCE_RX_BUFFER_INDEX(g_ui32UARTRxWriteIndex);
- //
- // If echo is enabled, write the character to the transmit
- // buffer so that the user gets some immediate feedback.
- //
- if(!g_bDisableEcho)
- {
- UARTwrite((const char *)&cChar, 1);
- }
- }
- }
- //
- // If we wrote anything to the transmit buffer, make sure it actually
- // gets transmitted.
- //
- UARTPrimeTransmit(g_ui32Base);
- MAP_UARTIntEnable(g_ui32Base, UART_INT_TX);
- }
- }
- #endif
- //*****************************************************************************
- //
- // Close the Doxygen group.
- //! @}
- //
- //*****************************************************************************
- //
- // End of file
- //
|