uartstdio.c 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773
  1. //###########################################################################
  2. //
  3. // FILE: uartstdio.c
  4. //
  5. // TITLE: Utility driver to provide simple UART console functions.
  6. //
  7. //###########################################################################
  8. // $TI Release: F2837xD Support Library v3.05.00.00 $
  9. // $Release Date: Tue Jun 26 03:15:23 CDT 2018 $
  10. // $Copyright:
  11. // Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
  12. //
  13. // Redistribution and use in source and binary forms, with or without
  14. // modification, are permitted provided that the following conditions
  15. // are met:
  16. //
  17. // Redistributions of source code must retain the above copyright
  18. // notice, this list of conditions and the following disclaimer.
  19. //
  20. // Redistributions in binary form must reproduce the above copyright
  21. // notice, this list of conditions and the following disclaimer in the
  22. // documentation and/or other materials provided with the
  23. // distribution.
  24. //
  25. // Neither the name of Texas Instruments Incorporated nor the names of
  26. // its contributors may be used to endorse or promote products derived
  27. // from this software without specific prior written permission.
  28. //
  29. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  30. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  31. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  32. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  33. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  34. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  35. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  36. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  37. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  39. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  40. // $
  41. //###########################################################################
  42. //
  43. // Included Files
  44. //
  45. #include <stdbool.h>
  46. #include <stdint.h>
  47. #include <stdarg.h>
  48. #include "inc/hw_ints.h"
  49. #include "inc/hw_memmap.h"
  50. #include "inc/hw_types.h"
  51. #include "inc/hw_uart.h"
  52. #include "driverlib/debug.h"
  53. #include "driverlib/interrupt.h"
  54. #include "driverlib/rom.h"
  55. #include "driverlib/rom_map.h"
  56. #include "driverlib/sysctl.h"
  57. #include "driverlib/uart.h"
  58. #include "utils/uartstdio.h"
  59. //*****************************************************************************
  60. //
  61. //! \addtogroup uartstdio_api
  62. //! @{
  63. //
  64. //*****************************************************************************
  65. //
  66. // If buffered mode is defined, set aside RX and TX buffers and read/write
  67. // pointers to control them.
  68. //
  69. #ifdef UART_BUFFERED
  70. //
  71. // This global controls whether or not we are echoing characters back to the
  72. // transmitter. By default, echo is enabled but if using this module as a
  73. // convenient method of implementing a buffered serial interface over which
  74. // you will be running an application protocol, you are likely to want to
  75. // disable echo by calling UARTEchoSet(false).
  76. //
  77. static bool g_bDisableEcho;
  78. //
  79. // Output ring buffer. Buffer is full if g_ui32UARTTxReadIndex is one ahead of
  80. // g_ui32UARTTxWriteIndex. Buffer is empty if the two indices are the same.
  81. //
  82. static unsigned char g_pcUARTTxBuffer[UART_TX_BUFFER_SIZE];
  83. static volatile uint32_t g_ui32UARTTxWriteIndex = 0;
  84. static volatile uint32_t g_ui32UARTTxReadIndex = 0;
  85. //
  86. // Input ring buffer. Buffer is full if g_ui32UARTTxReadIndex is one ahead of
  87. // g_ui32UARTTxWriteIndex. Buffer is empty if the two indices are the same.
  88. //
  89. static unsigned char g_pcUARTRxBuffer[UART_RX_BUFFER_SIZE];
  90. static volatile uint32_t g_ui32UARTRxWriteIndex = 0;
  91. static volatile uint32_t g_ui32UARTRxReadIndex = 0;
  92. //
  93. // Macros to determine number of free and used bytes in the transmit buffer.
  94. //
  95. #define TX_BUFFER_USED (GetBufferCount(&g_ui32UARTTxReadIndex, \
  96. &g_ui32UARTTxWriteIndex, \
  97. UART_TX_BUFFER_SIZE))
  98. #define TX_BUFFER_FREE (UART_TX_BUFFER_SIZE - TX_BUFFER_USED)
  99. #define TX_BUFFER_EMPTY (IsBufferEmpty(&g_ui32UARTTxReadIndex, \
  100. &g_ui32UARTTxWriteIndex))
  101. #define TX_BUFFER_FULL (IsBufferFull(&g_ui32UARTTxReadIndex, \
  102. &g_ui32UARTTxWriteIndex, \
  103. UART_TX_BUFFER_SIZE))
  104. #define ADVANCE_TX_BUFFER_INDEX(Index) \
  105. (Index) = ((Index) + 1) % UART_TX_BUFFER_SIZE
  106. //
  107. // Macros to determine number of free and used bytes in the receive buffer.
  108. //
  109. #define RX_BUFFER_USED (GetBufferCount(&g_ui32UARTRxReadIndex, \
  110. &g_ui32UARTRxWriteIndex, \
  111. UART_RX_BUFFER_SIZE))
  112. #define RX_BUFFER_FREE (UART_RX_BUFFER_SIZE - RX_BUFFER_USED)
  113. #define RX_BUFFER_EMPTY (IsBufferEmpty(&g_ui32UARTRxReadIndex, \
  114. &g_ui32UARTRxWriteIndex))
  115. #define RX_BUFFER_FULL (IsBufferFull(&g_ui32UARTRxReadIndex, \
  116. &g_ui32UARTRxWriteIndex, \
  117. UART_RX_BUFFER_SIZE))
  118. #define ADVANCE_RX_BUFFER_INDEX(Index) \
  119. (Index) = ((Index) + 1) % UART_RX_BUFFER_SIZE
  120. #endif
  121. //
  122. // The base address of the chosen UART.
  123. //
  124. static uint32_t g_ui32Base = 0;
  125. //
  126. // A mapping from an integer between 0 and 15 to its ASCII character
  127. // equivalent.
  128. //
  129. static const char * const g_pcHex = "0123456789abcdef";
  130. //
  131. // The list of possible base addresses for the console UART.
  132. //
  133. static const uint32_t g_ui32UARTBase[4] =
  134. {
  135. UARTA_BASE, UARTB_BASE, UARTC_BASE, UARTD_BASE
  136. };
  137. #ifdef UART_BUFFERED
  138. //
  139. // The list of possible interrupts for the console UART.
  140. //
  141. static const uint32_t g_ui32UARTInt[3] =
  142. {
  143. INT_UART0, INT_UART1, INT_UART2
  144. };
  145. //
  146. // The port number in use.
  147. //
  148. static uint32_t g_ui32PortNum;
  149. #endif
  150. //
  151. // The list of UART peripherals.
  152. //
  153. static const uint32_t g_ui32UARTPeriph[3] =
  154. {
  155. SYSCTL_PERIPH_SCI1, SYSCTL_PERIPH_SCI2, SYSCTL_PERIPH_SCI3
  156. };
  157. //*****************************************************************************
  158. //
  159. //! Determines whether the ring buffer whose pointers and size are provided
  160. //! is full or not.
  161. //!
  162. //! \param pui32Read points to the read index for the buffer.
  163. //! \param pui32Write points to the write index for the buffer.
  164. //! \param ui32Size is the size of the buffer in bytes.
  165. //!
  166. //! This function is used to determine whether or not a given ring buffer is
  167. //! full. The structure of the code is specifically to ensure that we do not
  168. //! see warnings from the compiler related to the order of volatile accesses
  169. //! being undefined.
  170. //!
  171. //! \return Returns \b true if the buffer is full or \b false otherwise.
  172. //
  173. //*****************************************************************************
  174. #ifdef UART_BUFFERED
  175. static bool
  176. IsBufferFull(volatile uint32_t *pui32Read,
  177. volatile uint32_t *pui32Write, uint32_t ui32Size)
  178. {
  179. uint32_t ui32Write;
  180. uint32_t ui32Read;
  181. ui32Write = *pui32Write;
  182. ui32Read = *pui32Read;
  183. return((((ui32Write + 1) % ui32Size) == ui32Read) ? true : false);
  184. }
  185. #endif
  186. //*****************************************************************************
  187. //
  188. //! Determines whether the ring buffer whose pointers and size are provided
  189. //! is empty or not.
  190. //!
  191. //! \param pui32Read points to the read index for the buffer.
  192. //! \param pui32Write points to the write index for the buffer.
  193. //!
  194. //! This function is used to determine whether or not a given ring buffer is
  195. //! empty. The structure of the code is specifically to ensure that we do not
  196. //! see warnings from the compiler related to the order of volatile accesses
  197. //! being undefined.
  198. //!
  199. //! \return Returns \b true if the buffer is empty or \b false otherwise.
  200. //
  201. //*****************************************************************************
  202. #ifdef UART_BUFFERED
  203. static bool
  204. IsBufferEmpty(volatile uint32_t *pui32Read,
  205. volatile uint32_t *pui32Write)
  206. {
  207. uint32_t ui32Write;
  208. uint32_t ui32Read;
  209. ui32Write = *pui32Write;
  210. ui32Read = *pui32Read;
  211. return((ui32Write == ui32Read) ? true : false);
  212. }
  213. #endif
  214. //*****************************************************************************
  215. //
  216. //! Determines the number of bytes of data contained in a ring buffer.
  217. //!
  218. //! \param pui32Read points to the read index for the buffer.
  219. //! \param pui32Write points to the write index for the buffer.
  220. //! \param ui32Size is the size of the buffer in bytes.
  221. //!
  222. //! This function is used to determine how many bytes of data a given ring
  223. //! buffer currently contains. The structure of the code is specifically to
  224. //! ensure that we do not see warnings from the compiler related to the order
  225. //! of volatile accesses being undefined.
  226. //!
  227. //! \return Returns the number of bytes of data currently in the buffer.
  228. //
  229. //*****************************************************************************
  230. #ifdef UART_BUFFERED
  231. static uint32_t
  232. GetBufferCount(volatile uint32_t *pui32Read,
  233. volatile uint32_t *pui32Write, uint32_t ui32Size)
  234. {
  235. uint32_t ui32Write;
  236. uint32_t ui32Read;
  237. ui32Write = *pui32Write;
  238. ui32Read = *pui32Read;
  239. return((ui32Write >= ui32Read) ? (ui32Write - ui32Read) :
  240. (ui32Size - (ui32Read - ui32Write)));
  241. }
  242. #endif
  243. //*****************************************************************************
  244. //
  245. // Take as many bytes from the transmit buffer as we have space for and move
  246. // them into the UART transmit FIFO.
  247. //
  248. //*****************************************************************************
  249. #ifdef UART_BUFFERED
  250. static void
  251. UARTPrimeTransmit(uint32_t ui32Base)
  252. {
  253. //
  254. // Do we have any data to transmit?
  255. //
  256. if(!TX_BUFFER_EMPTY)
  257. {
  258. //
  259. // Disable the UART interrupt. If we don't do this there is a race
  260. // condition which can cause the read index to be corrupted.
  261. //
  262. MAP_IntDisable(g_ui32UARTInt[g_ui32PortNum]);
  263. //
  264. // Yes - take some characters out of the transmit buffer and feed
  265. // them to the UART transmit FIFO.
  266. //
  267. while(MAP_UARTSpaceAvail(ui32Base) && !TX_BUFFER_EMPTY)
  268. {
  269. MAP_UARTCharPutNonBlocking(ui32Base,
  270. g_pcUARTTxBuffer[g_ui32UARTTxReadIndex]);
  271. ADVANCE_TX_BUFFER_INDEX(g_ui32UARTTxReadIndex);
  272. }
  273. //
  274. // Reenable the UART interrupt.
  275. //
  276. MAP_IntEnable(g_ui32UARTInt[g_ui32PortNum]);
  277. }
  278. }
  279. #endif
  280. //*****************************************************************************
  281. //
  282. //! Configures the UART console.
  283. //!
  284. //! \param ui32PortNum is the number of UART port to use for the serial console
  285. //! (0-2)
  286. //! \param ui32Baud is the bit rate that the UART is to be configured to use.
  287. //! \param ui32SrcClock is the frequency of the source clock for the UART
  288. //! module.
  289. //!
  290. //! This function will configure the specified serial port to be used as a
  291. //! serial console. The serial parameters are set to the baud rate
  292. //! specified by the \e ui32Baud parameter and use 8 bit, no parity, and 1 stop
  293. //! bit.
  294. //!
  295. //! This function must be called prior to using any of the other UART console
  296. //! functions: UARTprintf() or UARTgets(). This function assumes that the
  297. //! caller has previously configured the relevant UART pins for operation as a
  298. //! UART rather than as GPIOs.
  299. //!
  300. //! \return None.
  301. //
  302. //*****************************************************************************
  303. void
  304. UARTStdioConfig(uint32_t ui32PortNum, uint32_t ui32Baud, uint32_t ui32SrcClock)
  305. {
  306. //
  307. // Check the arguments.
  308. //
  309. ASSERT((ui32PortNum == 0) || (ui32PortNum == 1) ||
  310. (ui32PortNum == 2));
  311. #ifdef UART_BUFFERED
  312. //
  313. // In buffered mode, we only allow a single instance to be opened.
  314. //
  315. ASSERT(g_ui32Base == 0);
  316. #endif
  317. //
  318. // Check to make sure the UART peripheral is present.
  319. //
  320. if(!MAP_SysCtlPeripheralPresent(g_ui32UARTPeriph[ui32PortNum]))
  321. {
  322. return;
  323. }
  324. //
  325. // Select the base address of the UART.
  326. //
  327. g_ui32Base = g_ui32UARTBase[ui32PortNum];
  328. //
  329. // Enable the UART peripheral for use.
  330. //
  331. MAP_SysCtlPeripheralEnable(g_ui32UARTPeriph[ui32PortNum]);
  332. //
  333. // Configure the UART for 115200, n, 8, 1
  334. //
  335. MAP_UARTConfigSetExpClk(g_ui32Base, ui32SrcClock, ui32Baud,
  336. (UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE |
  337. UART_CONFIG_WLEN_8));
  338. #ifdef UART_BUFFERED
  339. //
  340. // Set the UART to interrupt whenever the TX FIFO is almost empty or
  341. // when any character is received.
  342. //
  343. MAP_UARTFIFOLevelSet(g_ui32Base, UART_FIFO_TX1_8, UART_FIFO_RX1_8);
  344. //
  345. // Flush both the buffers.
  346. //
  347. UARTFlushRx();
  348. UARTFlushTx(true);
  349. //
  350. // Remember which interrupt we are dealing with.
  351. //
  352. g_ui32PortNum = ui32PortNum;
  353. //
  354. // We are configured for buffered output so enable the master interrupt
  355. // for this UART and the receive interrupts. We don't actually enable the
  356. // transmit interrupt in the UART itself until some data has been placed
  357. // in the transmit buffer.
  358. //
  359. MAP_UARTIntDisable(g_ui32Base, 0xFFFFFFFF);
  360. MAP_UARTIntEnable(g_ui32Base, UART_INT_RX | UART_INT_RT);
  361. MAP_IntEnable(g_ui32UARTInt[ui32PortNum]);
  362. #endif
  363. //
  364. // Enable the UART operation.
  365. //
  366. MAP_UARTEnable(g_ui32Base);
  367. }
  368. //*****************************************************************************
  369. //
  370. //! Writes a string of characters to the UART output.
  371. //!
  372. //! \param pcBuf points to a buffer containing the string to transmit.
  373. //! \param ui32Len is the length of the string to transmit.
  374. //!
  375. //! This function will transmit the string to the UART output. The number of
  376. //! characters transmitted is determined by the \e ui32Len parameter. This
  377. //! function does no interpretation or translation of any characters. Since
  378. //! the output is sent to a UART, any LF (/n) characters encountered will be
  379. //! replaced with a CRLF pair.
  380. //!
  381. //! Besides using the \e ui32Len parameter to stop transmitting the string, if
  382. //! a null character (0) is encountered, then no more characters will be
  383. //! transmitted and the function will return.
  384. //!
  385. //! In non-buffered mode, this function is blocking and will not return until
  386. //! all the characters have been written to the output FIFO. In buffered mode,
  387. //! the characters are written to the UART transmit buffer and the call returns
  388. //! immediately. If insufficient space remains in the transmit buffer,
  389. //! additional characters are discarded.
  390. //!
  391. //! \return Returns the count of characters written.
  392. //
  393. //*****************************************************************************
  394. int
  395. UARTwrite(const char *pcBuf, uint32_t ui32Len)
  396. {
  397. #ifdef UART_BUFFERED
  398. unsigned int uIdx;
  399. //
  400. // Check for valid arguments.
  401. //
  402. ASSERT(pcBuf != 0);
  403. ASSERT(g_ui32Base != 0);
  404. //
  405. // Send the characters
  406. //
  407. for(uIdx = 0; uIdx < ui32Len; uIdx++)
  408. {
  409. //
  410. // If the character to the UART is \n, then add a \r before it so that
  411. // \n is translated to \n\r in the output.
  412. //
  413. if(pcBuf[uIdx] == '\n')
  414. {
  415. if(!TX_BUFFER_FULL)
  416. {
  417. g_pcUARTTxBuffer[g_ui32UARTTxWriteIndex] = '\r';
  418. ADVANCE_TX_BUFFER_INDEX(g_ui32UARTTxWriteIndex);
  419. }
  420. else
  421. {
  422. //
  423. // Buffer is full - discard remaining characters and return.
  424. //
  425. break;
  426. }
  427. }
  428. //
  429. // Send the character to the UART output.
  430. //
  431. if(!TX_BUFFER_FULL)
  432. {
  433. g_pcUARTTxBuffer[g_ui32UARTTxWriteIndex] = pcBuf[uIdx];
  434. ADVANCE_TX_BUFFER_INDEX(g_ui32UARTTxWriteIndex);
  435. }
  436. else
  437. {
  438. //
  439. // Buffer is full - discard remaining characters and return.
  440. //
  441. break;
  442. }
  443. }
  444. //
  445. // If we have anything in the buffer, make sure that the UART is set
  446. // up to transmit it.
  447. //
  448. if(!TX_BUFFER_EMPTY)
  449. {
  450. UARTPrimeTransmit(g_ui32Base);
  451. MAP_UARTIntEnable(g_ui32Base, UART_INT_TX);
  452. }
  453. //
  454. // Return the number of characters written.
  455. //
  456. return(uIdx);
  457. #else
  458. unsigned int uIdx;
  459. //
  460. // Check for valid UART base address, and valid arguments.
  461. //
  462. ASSERT(g_ui32Base != 0);
  463. ASSERT(pcBuf != 0);
  464. //
  465. // Send the characters
  466. //
  467. for(uIdx = 0; uIdx < ui32Len; uIdx++)
  468. {
  469. //
  470. // If the character to the UART is \n, then add a \r before it so that
  471. // \n is translated to \n\r in the output.
  472. //
  473. if(pcBuf[uIdx] == '\n')
  474. {
  475. MAP_UARTCharPut(g_ui32Base, '\r');
  476. }
  477. //
  478. // Send the character to the UART output.
  479. //
  480. MAP_UARTCharPut(g_ui32Base, pcBuf[uIdx]);
  481. }
  482. //
  483. // Return the number of characters written.
  484. //
  485. return(uIdx);
  486. #endif
  487. }
  488. //*****************************************************************************
  489. //
  490. //! A simple UART based get string function, with some line processing.
  491. //!
  492. //! \param pcBuf points to a buffer for the incoming string from the UART.
  493. //! \param ui32Len is the length of the buffer for storage of the string,
  494. //! including the trailing 0.
  495. //!
  496. //! This function will receive a string from the UART input and store the
  497. //! characters in the buffer pointed to by \e pcBuf. The characters will
  498. //! continue to be stored until a termination character is received. The
  499. //! termination characters are CR, LF, or ESC. A CRLF pair is treated as a
  500. //! single termination character. The termination characters are not stored in
  501. //! the string. The string will be terminated with a 0 and the function will
  502. //! return.
  503. //!
  504. //! In both buffered and unbuffered modes, this function will block until
  505. //! a termination character is received. If non-blocking operation is required
  506. //! in buffered mode, a call to UARTPeek() may be made to determine whether
  507. //! a termination character already exists in the receive buffer prior to
  508. //! calling UARTgets().
  509. //!
  510. //! Since the string will be null terminated, the user must ensure that the
  511. //! buffer is sized to allow for the additional null character.
  512. //!
  513. //! \return Returns the count of characters that were stored, not including
  514. //! the trailing 0.
  515. //
  516. //*****************************************************************************
  517. int
  518. UARTgets(char *pcBuf, uint32_t ui32Len)
  519. {
  520. #ifdef UART_BUFFERED
  521. uint32_t ui32Count = 0;
  522. int8_t cChar;
  523. //
  524. // Check the arguments.
  525. //
  526. ASSERT(pcBuf != 0);
  527. ASSERT(ui32Len != 0);
  528. ASSERT(g_ui32Base != 0);
  529. //
  530. // Adjust the length back by 1 to leave space for the trailing
  531. // null terminator.
  532. //
  533. ui32Len--;
  534. //
  535. // Process characters until a newline is received.
  536. //
  537. while(1)
  538. {
  539. //
  540. // Read the next character from the receive buffer.
  541. //
  542. if(!RX_BUFFER_EMPTY)
  543. {
  544. cChar = g_pcUARTRxBuffer[g_ui32UARTRxReadIndex];
  545. ADVANCE_RX_BUFFER_INDEX(g_ui32UARTRxReadIndex);
  546. //
  547. // See if a newline or escape character was received.
  548. //
  549. if((cChar == '\r') || (cChar == '\n') || (cChar == 0x1b))
  550. {
  551. //
  552. // Stop processing the input and end the line.
  553. //
  554. break;
  555. }
  556. //
  557. // Process the received character as long as we are not at the end
  558. // of the buffer. If the end of the buffer has been reached then
  559. // all additional characters are ignored until a newline is
  560. // received.
  561. //
  562. if(ui32Count < ui32Len)
  563. {
  564. //
  565. // Store the character in the caller supplied buffer.
  566. //
  567. pcBuf[ui32Count] = cChar;
  568. //
  569. // Increment the count of characters received.
  570. //
  571. ui32Count++;
  572. }
  573. }
  574. }
  575. //
  576. // Add a null termination to the string.
  577. //
  578. pcBuf[ui32Count] = 0;
  579. //
  580. // Return the count of int8_ts in the buffer, not counting the trailing 0.
  581. //
  582. return(ui32Count);
  583. #else
  584. uint32_t ui32Count = 0;
  585. int8_t cChar;
  586. static int8_t bLastWasCR = 0;
  587. //
  588. // Check the arguments.
  589. //
  590. ASSERT(pcBuf != 0);
  591. ASSERT(ui32Len != 0);
  592. ASSERT(g_ui32Base != 0);
  593. //
  594. // Adjust the length back by 1 to leave space for the trailing
  595. // null terminator.
  596. //
  597. ui32Len--;
  598. //
  599. // Process characters until a newline is received.
  600. //
  601. while(1)
  602. {
  603. //
  604. // Read the next character from the console.
  605. //
  606. cChar = MAP_UARTCharGet(g_ui32Base);
  607. //
  608. // See if the backspace key was pressed.
  609. //
  610. if(cChar == '\b')
  611. {
  612. //
  613. // If there are any characters already in the buffer, then delete
  614. // the last.
  615. //
  616. if(ui32Count)
  617. {
  618. //
  619. // Rub out the previous character.
  620. //
  621. UARTwrite("\b \b", 3);
  622. //
  623. // Decrement the number of characters in the buffer.
  624. //
  625. ui32Count--;
  626. }
  627. //
  628. // Skip ahead to read the next character.
  629. //
  630. continue;
  631. }
  632. //
  633. // If this character is LF and last was CR, then just gobble up the
  634. // character because the EOL processing was taken care of with the CR.
  635. //
  636. if((cChar == '\n') && bLastWasCR)
  637. {
  638. bLastWasCR = 0;
  639. continue;
  640. }
  641. //
  642. // See if a newline or escape character was received.
  643. //
  644. if((cChar == '\r') || (cChar == '\n') || (cChar == 0x1b))
  645. {
  646. //
  647. // If the character is a CR, then it may be followed by a LF which
  648. // should be paired with the CR. So remember that a CR was
  649. // received.
  650. //
  651. if(cChar == '\r')
  652. {
  653. bLastWasCR = 1;
  654. }
  655. //
  656. // Stop processing the input and end the line.
  657. //
  658. break;
  659. }
  660. //
  661. // Process the received character as long as we are not at the end of
  662. // the buffer. If the end of the buffer has been reached then all
  663. // additional characters are ignored until a newline is received.
  664. //
  665. if(ui32Count < ui32Len)
  666. {
  667. //
  668. // Store the character in the caller supplied buffer.
  669. //
  670. pcBuf[ui32Count] = cChar;
  671. //
  672. // Increment the count of characters received.
  673. //
  674. ui32Count++;
  675. //
  676. // Reflect the character back to the user.
  677. //
  678. MAP_UARTCharPut(g_ui32Base, cChar);
  679. }
  680. }
  681. //
  682. // Add a null termination to the string.
  683. //
  684. pcBuf[ui32Count] = 0;
  685. //
  686. // Send a CRLF pair to the terminal to end the line.
  687. //
  688. UARTwrite("\r\n", 2);
  689. //
  690. // Return the count of int8_ts in the buffer, not counting the trailing 0.
  691. //
  692. return(ui32Count);
  693. #endif
  694. }
  695. //*****************************************************************************
  696. //
  697. //! Read a single character from the UART, blocking if necessary.
  698. //!
  699. //! This function will receive a single character from the UART and store it at
  700. //! the supplied address.
  701. //!
  702. //! In both buffered and unbuffered modes, this function will block until a
  703. //! character is received. If non-blocking operation is required in buffered
  704. //! mode, a call to UARTRxAvail() may be made to determine whether any
  705. //! characters are currently available for reading.
  706. //!
  707. //! \return Returns the character read.
  708. //
  709. //*****************************************************************************
  710. unsigned char
  711. UARTgetc(void)
  712. {
  713. #ifdef UART_BUFFERED
  714. unsigned char cChar;
  715. //
  716. // Wait for a character to be received.
  717. //
  718. while(RX_BUFFER_EMPTY)
  719. {
  720. //
  721. // Block waiting for a character to be received (if the buffer is
  722. // currently empty).
  723. //
  724. }
  725. //
  726. // Read a character from the buffer.
  727. //
  728. cChar = g_pcUARTRxBuffer[g_ui32UARTRxReadIndex];
  729. ADVANCE_RX_BUFFER_INDEX(g_ui32UARTRxReadIndex);
  730. //
  731. // Return the character to the caller.
  732. //
  733. return(cChar);
  734. #else
  735. //
  736. // Block until a character is received by the UART then return it to
  737. // the caller.
  738. //
  739. return(MAP_UARTCharGet(g_ui32Base));
  740. #endif
  741. }
  742. //*****************************************************************************
  743. //
  744. //! A simple UART based vprintf function supporting \%c, \%d, \%p, \%s, \%u,
  745. //! \%x, and \%X.
  746. //!
  747. //! \param pcString is the format string.
  748. //! \param vaArgP is a variable argument list pointer whose content will depend
  749. //! upon the format string passed in \e pcString.
  750. //!
  751. //! This function is very similar to the C library <tt>vprintf()</tt> function.
  752. //! All of its output will be sent to the UART. Only the following formatting
  753. //! characters are supported:
  754. //!
  755. //! - \%c to print a character
  756. //! - \%d or \%i to print a decimal value
  757. //! - \%l to print a long decimal value
  758. //! - \%s to print a string
  759. //! - \%u to print an unsigned decimal value
  760. //! - \%x to print a hexadecimal value using lower case letters
  761. //! - \%X to print a hexadecimal value using lower case letters (not upper case
  762. //! letters as would typically be used)
  763. //! - \%p to print a pointer as a hexadecimal value
  764. //! - \%\% to print out a \% character
  765. //!
  766. //! For \%s, \%d, \%i, \%u, \%p, \%x, and \%X, an optional number may reside
  767. //! between the \% and the format character, which specifies the minimum number
  768. //! of characters to use for that value; if preceded by a 0 then the extra
  769. //! characters will be filled with zeros instead of spaces. For example,
  770. //! ``\%8d'' will use eight characters to print the decimal value with spaces
  771. //! added to reach eight; ``\%08d'' will use eight characters as well but will
  772. //! add zeroes instead of spaces.
  773. //!
  774. //! The type of the arguments in the variable arguments list must match the
  775. //! requirements of the format string. For example, if an integer was passed
  776. //! where a string was expected, an error of some kind will most likely occur.
  777. //!
  778. //! \return None.
  779. //
  780. //*****************************************************************************
  781. void
  782. UARTvprintf(const char *pcString, va_list vaArgP)
  783. {
  784. uint32_t ui32Idx, ui32Value, ui32Pos, ui32Count, ui32Base, ui32Neg;
  785. char *pcStr, pcBuf[16], cFill;
  786. //
  787. // Check the arguments.
  788. //
  789. ASSERT(pcString != 0);
  790. //
  791. // Loop while there are more characters in the string.
  792. //
  793. while(*pcString)
  794. {
  795. //
  796. // Find the first non-% character, or the end of the string.
  797. //
  798. for(ui32Idx = 0;
  799. (pcString[ui32Idx] != '%') && (pcString[ui32Idx] != '\0');
  800. ui32Idx++)
  801. {
  802. }
  803. //
  804. // Write this portion of the string.
  805. //
  806. UARTwrite(pcString, ui32Idx);
  807. //
  808. // Skip the portion of the string that was written.
  809. //
  810. pcString += ui32Idx;
  811. //
  812. // See if the next character is a %.
  813. //
  814. if(*pcString == '%')
  815. {
  816. //
  817. // Skip the %.
  818. //
  819. pcString++;
  820. //
  821. // Set the digit count to zero, and the fill character to space
  822. // (in other words, to the defaults).
  823. //
  824. ui32Count = 0;
  825. cFill = ' ';
  826. //
  827. // It may be necessary to get back here to process more characters.
  828. // Goto's aren't pretty, but effective. I feel extremely dirty for
  829. // using not one but two of the beasts.
  830. //
  831. again:
  832. //
  833. // Determine how to handle the next character.
  834. //
  835. switch(*pcString++)
  836. {
  837. //
  838. // Handle the digit characters.
  839. //
  840. case '0':
  841. case '1':
  842. case '2':
  843. case '3':
  844. case '4':
  845. case '5':
  846. case '6':
  847. case '7':
  848. case '8':
  849. case '9':
  850. {
  851. //
  852. // If this is a zero, and it is the first digit, then the
  853. // fill character is a zero instead of a space.
  854. //
  855. if((pcString[-1] == '0') && (ui32Count == 0))
  856. {
  857. cFill = '0';
  858. }
  859. //
  860. // Update the digit count.
  861. //
  862. ui32Count *= 10;
  863. ui32Count += pcString[-1] - '0';
  864. //
  865. // Get the next character.
  866. //
  867. goto again;
  868. }
  869. //
  870. // Handle the %c command.
  871. //
  872. case 'c':
  873. {
  874. //
  875. // Get the value from the varargs.
  876. //
  877. ui32Value = va_arg(vaArgP, uint32_t);
  878. //
  879. // Print out the character.
  880. //
  881. UARTwrite((char *)&ui32Value, 1);
  882. //
  883. // This command has been handled.
  884. //
  885. break;
  886. }
  887. //
  888. // Handle the %d and %i commands.
  889. //
  890. case 'd':
  891. case 'i':
  892. {
  893. //
  894. // Get the value from the varargs.
  895. //
  896. ui32Value = va_arg(vaArgP, uint16_t);
  897. //
  898. // Reset the buffer position.
  899. //
  900. ui32Pos = 0;
  901. //
  902. // If the value is negative, make it positive and indicate
  903. // that a minus sign is needed.
  904. //
  905. if((int32_t)ui32Value < 0)
  906. {
  907. //
  908. // Make the value positive.
  909. //
  910. ui32Value = -(int32_t)ui32Value;
  911. //
  912. // Indicate that the value is negative.
  913. //
  914. ui32Neg = 1;
  915. }
  916. else
  917. {
  918. //
  919. // Indicate that the value is positive so that a minus
  920. // sign isn't inserted.
  921. //
  922. ui32Neg = 0;
  923. }
  924. //
  925. // Set the base to 10.
  926. //
  927. ui32Base = 10;
  928. //
  929. // Convert the value to ASCII.
  930. //
  931. goto convert;
  932. }
  933. //
  934. // Handle the %l command.
  935. //
  936. case 'l':
  937. {
  938. //
  939. // Get the value from the varargs.
  940. //
  941. ui32Value = va_arg(vaArgP, uint32_t);
  942. //
  943. // Reset the buffer position.
  944. //
  945. ui32Pos = 0;
  946. //
  947. // If the value is negative, make it positive and indicate
  948. // that a minus sign is needed.
  949. //
  950. if((int32_t)ui32Value < 0)
  951. {
  952. //
  953. // Make the value positive.
  954. //
  955. ui32Value = -(int32_t)ui32Value;
  956. //
  957. // Indicate that the value is negative.
  958. //
  959. ui32Neg = 1;
  960. }
  961. else
  962. {
  963. //
  964. // Indicate that the value is positive so that a minus
  965. // sign isn't inserted.
  966. //
  967. ui32Neg = 0;
  968. }
  969. //
  970. // Set the base to 10.
  971. //
  972. ui32Base = 10;
  973. //
  974. // Convert the value to ASCII.
  975. //
  976. goto convert;
  977. }
  978. //
  979. // Handle the %s command.
  980. //
  981. case 's':
  982. {
  983. //
  984. // Get the string pointer from the varargs.
  985. //
  986. pcStr = va_arg(vaArgP, char *);
  987. //
  988. // Determine the length of the string.
  989. //
  990. for(ui32Idx = 0; pcStr[ui32Idx] != '\0'; ui32Idx++)
  991. {
  992. }
  993. //
  994. // Write the string.
  995. //
  996. UARTwrite(pcStr, ui32Idx);
  997. //
  998. // Write any required padding spaces
  999. //
  1000. if(ui32Count > ui32Idx)
  1001. {
  1002. ui32Count -= ui32Idx;
  1003. while(ui32Count--)
  1004. {
  1005. UARTwrite(" ", 1);
  1006. }
  1007. }
  1008. //
  1009. // This command has been handled.
  1010. //
  1011. break;
  1012. }
  1013. //
  1014. // Handle the %u command.
  1015. //
  1016. case 'u':
  1017. {
  1018. //
  1019. // Get the value from the varargs.
  1020. //
  1021. ui32Value = va_arg(vaArgP, uint32_t);
  1022. //
  1023. // Reset the buffer position.
  1024. //
  1025. ui32Pos = 0;
  1026. //
  1027. // Set the base to 10.
  1028. //
  1029. ui32Base = 10;
  1030. //
  1031. // Indicate that the value is positive so that a minus sign
  1032. // isn't inserted.
  1033. //
  1034. ui32Neg = 0;
  1035. //
  1036. // Convert the value to ASCII.
  1037. //
  1038. goto convert;
  1039. }
  1040. //
  1041. // Handle the %x and %X commands. Note that they are treated
  1042. // identically; in other words, %X will use lower case letters
  1043. // for a-f instead of the upper case letters it should use. We
  1044. // also alias %p to %x.
  1045. //
  1046. case 'x':
  1047. case 'X':
  1048. case 'p':
  1049. {
  1050. //
  1051. // Get the value from the varargs.
  1052. //
  1053. ui32Value = va_arg(vaArgP, uint32_t);
  1054. //
  1055. // Reset the buffer position.
  1056. //
  1057. ui32Pos = 0;
  1058. //
  1059. // Set the base to 16.
  1060. //
  1061. ui32Base = 16;
  1062. //
  1063. // Indicate that the value is positive so that a minus sign
  1064. // isn't inserted.
  1065. //
  1066. ui32Neg = 0;
  1067. //
  1068. // Determine the number of digits in the string version of
  1069. // the value.
  1070. //
  1071. convert:
  1072. for(ui32Idx = 1;
  1073. (((ui32Idx * ui32Base) <= ui32Value) &&
  1074. (((ui32Idx * ui32Base) / ui32Base) == ui32Idx));
  1075. ui32Idx *= ui32Base, ui32Count--)
  1076. {
  1077. }
  1078. //
  1079. // If the value is negative, reduce the count of padding
  1080. // characters needed.
  1081. //
  1082. if(ui32Neg)
  1083. {
  1084. ui32Count--;
  1085. }
  1086. //
  1087. // If the value is negative and the value is padded with
  1088. // zeros, then place the minus sign before the padding.
  1089. //
  1090. if(ui32Neg && (cFill == '0'))
  1091. {
  1092. //
  1093. // Place the minus sign in the output buffer.
  1094. //
  1095. pcBuf[ui32Pos++] = '-';
  1096. //
  1097. // The minus sign has been placed, so turn off the
  1098. // negative flag.
  1099. //
  1100. ui32Neg = 0;
  1101. }
  1102. //
  1103. // Provide additional padding at the beginning of the
  1104. // string conversion if needed.
  1105. //
  1106. if((ui32Count > 1) && (ui32Count < 16))
  1107. {
  1108. for(ui32Count--; ui32Count; ui32Count--)
  1109. {
  1110. pcBuf[ui32Pos++] = cFill;
  1111. }
  1112. }
  1113. //
  1114. // If the value is negative, then place the minus sign
  1115. // before the number.
  1116. //
  1117. if(ui32Neg)
  1118. {
  1119. //
  1120. // Place the minus sign in the output buffer.
  1121. //
  1122. pcBuf[ui32Pos++] = '-';
  1123. }
  1124. //
  1125. // Convert the value into a string.
  1126. //
  1127. for(; ui32Idx; ui32Idx /= ui32Base)
  1128. {
  1129. pcBuf[ui32Pos++] =
  1130. g_pcHex[(ui32Value / ui32Idx) % ui32Base];
  1131. }
  1132. //
  1133. // Write the string.
  1134. //
  1135. UARTwrite(pcBuf, ui32Pos);
  1136. //
  1137. // This command has been handled.
  1138. //
  1139. break;
  1140. }
  1141. //
  1142. // Handle the %% command.
  1143. //
  1144. case '%':
  1145. {
  1146. //
  1147. // Simply write a single %.
  1148. //
  1149. UARTwrite(pcString - 1, 1);
  1150. //
  1151. // This command has been handled.
  1152. //
  1153. break;
  1154. }
  1155. //
  1156. // Handle all other commands.
  1157. //
  1158. default:
  1159. {
  1160. //
  1161. // Indicate an error.
  1162. //
  1163. UARTwrite("ERROR", 5);
  1164. //
  1165. // This command has been handled.
  1166. //
  1167. break;
  1168. }
  1169. }
  1170. }
  1171. }
  1172. }
  1173. //*****************************************************************************
  1174. //
  1175. //! A simple UART based printf function supporting \%c, \%d, \%p, \%s, \%u,
  1176. //! \%x, and \%X.
  1177. //!
  1178. //! \param pcString is the format string.
  1179. //! \param ... are the optional arguments, which depend on the contents of the
  1180. //! format string.
  1181. //!
  1182. //! This function is very similar to the C library <tt>fprintf()</tt> function.
  1183. //! All of its output will be sent to the UART. Only the following formatting
  1184. //! characters are supported:
  1185. //!
  1186. //! - \%c to print a character
  1187. //! - \%d or \%i to print a decimal value
  1188. //! - \%s to print a string
  1189. //! - \%u to print an unsigned decimal value
  1190. //! - \%x to print a hexadecimal value using lower case letters
  1191. //! - \%X to print a hexadecimal value using lower case letters (not upper case
  1192. //! letters as would typically be used)
  1193. //! - \%p to print a pointer as a hexadecimal value
  1194. //! - \%\% to print out a \% character
  1195. //!
  1196. //! For \%s, \%d, \%i, \%u, \%p, \%x, and \%X, an optional number may reside
  1197. //! between the \% and the format character, which specifies the minimum number
  1198. //! of characters to use for that value; if preceded by a 0 then the extra
  1199. //! characters will be filled with zeros instead of spaces. For example,
  1200. //! ``\%8d'' will use eight characters to print the decimal value with spaces
  1201. //! added to reach eight; ``\%08d'' will use eight characters as well but will
  1202. //! add zeroes instead of spaces.
  1203. //!
  1204. //! The type of the arguments after \e pcString must match the requirements of
  1205. //! the format string. For example, if an integer was passed where a string
  1206. //! was expected, an error of some kind will most likely occur.
  1207. //!
  1208. //! \return None.
  1209. //
  1210. //*****************************************************************************
  1211. void
  1212. UARTprintf(const char *pcString, ...)
  1213. {
  1214. va_list vaArgP;
  1215. //
  1216. // Start the varargs processing.
  1217. //
  1218. va_start(vaArgP, pcString);
  1219. UARTvprintf(pcString, vaArgP);
  1220. //
  1221. // We're finished with the varargs now.
  1222. //
  1223. va_end(vaArgP);
  1224. }
  1225. //*****************************************************************************
  1226. //
  1227. //! Returns the number of bytes available in the receive buffer.
  1228. //!
  1229. //! This function, available only when the module is built to operate in
  1230. //! buffered mode using \b UART_BUFFERED, may be used to determine the number
  1231. //! of bytes of data currently available in the receive buffer.
  1232. //!
  1233. //! \return Returns the number of available bytes.
  1234. //
  1235. //*****************************************************************************
  1236. #if defined(UART_BUFFERED) || defined(DOXYGEN)
  1237. int
  1238. UARTRxBytesAvail(void)
  1239. {
  1240. return(RX_BUFFER_USED);
  1241. }
  1242. #endif
  1243. #if defined(UART_BUFFERED) || defined(DOXYGEN)
  1244. //*****************************************************************************
  1245. //
  1246. //! Returns the number of bytes free in the transmit buffer.
  1247. //!
  1248. //! This function, available only when the module is built to operate in
  1249. //! buffered mode using \b UART_BUFFERED, may be used to determine the amount
  1250. //! of space currently available in the transmit buffer.
  1251. //!
  1252. //! \return Returns the number of free bytes.
  1253. //
  1254. //*****************************************************************************
  1255. int
  1256. UARTTxBytesFree(void)
  1257. {
  1258. return(TX_BUFFER_FREE);
  1259. }
  1260. #endif
  1261. //*****************************************************************************
  1262. //
  1263. //! Looks ahead in the receive buffer for a particular character.
  1264. //!
  1265. //! \param ucChar is the character that is to be searched for.
  1266. //!
  1267. //! This function, available only when the module is built to operate in
  1268. //! buffered mode using \b UART_BUFFERED, may be used to look ahead in the
  1269. //! receive buffer for a particular character and report its position if found.
  1270. //! It is typically used to determine whether a complete line of user input is
  1271. //! available, in which case ucChar should be set to CR ('\\r') which is used
  1272. //! as the line end marker in the receive buffer.
  1273. //!
  1274. //! \return Returns -1 to indicate that the requested character does not exist
  1275. //! in the receive buffer. Returns a non-negative number if the character was
  1276. //! found in which case the value represents the position of the first instance
  1277. //! of \e ucChar relative to the receive buffer read pointer.
  1278. //
  1279. //*****************************************************************************
  1280. #if defined(UART_BUFFERED) || defined(DOXYGEN)
  1281. int
  1282. UARTPeek(unsigned char ucChar)
  1283. {
  1284. int iCount;
  1285. int iAvail;
  1286. uint32_t ui32ReadIndex;
  1287. //
  1288. // How many characters are there in the receive buffer?
  1289. //
  1290. iAvail = (int)RX_BUFFER_USED;
  1291. ui32ReadIndex = g_ui32UARTRxReadIndex;
  1292. //
  1293. // Check all the unread characters looking for the one passed.
  1294. //
  1295. for(iCount = 0; iCount < iAvail; iCount++)
  1296. {
  1297. if(g_pcUARTRxBuffer[ui32ReadIndex] == ucChar)
  1298. {
  1299. //
  1300. // We found it so return the index
  1301. //
  1302. return(iCount);
  1303. }
  1304. else
  1305. {
  1306. //
  1307. // This one didn't match so move on to the next character.
  1308. //
  1309. ADVANCE_RX_BUFFER_INDEX(ui32ReadIndex);
  1310. }
  1311. }
  1312. //
  1313. // If we drop out of the loop, we didn't find the character in the receive
  1314. // buffer.
  1315. //
  1316. return(-1);
  1317. }
  1318. #endif
  1319. //*****************************************************************************
  1320. //
  1321. //! Flushes the receive buffer.
  1322. //!
  1323. //! This function, available only when the module is built to operate in
  1324. //! buffered mode using \b UART_BUFFERED, may be used to discard any data
  1325. //! received from the UART but not yet read using UARTgets().
  1326. //!
  1327. //! \return None.
  1328. //
  1329. //*****************************************************************************
  1330. #if defined(UART_BUFFERED) || defined(DOXYGEN)
  1331. void
  1332. UARTFlushRx(void)
  1333. {
  1334. uint32_t ui32Int;
  1335. //
  1336. // Temporarily turn off interrupts.
  1337. //
  1338. ui32Int = MAP_IntMasterDisable();
  1339. //
  1340. // Flush the receive buffer.
  1341. //
  1342. g_ui32UARTRxReadIndex = 0;
  1343. g_ui32UARTRxWriteIndex = 0;
  1344. //
  1345. // If interrupts were enabled when we turned them off, turn them
  1346. // back on again.
  1347. //
  1348. if(!ui32Int)
  1349. {
  1350. MAP_IntMasterEnable();
  1351. }
  1352. }
  1353. #endif
  1354. //*****************************************************************************
  1355. //
  1356. //! Flushes the transmit buffer.
  1357. //!
  1358. //! \param bDiscard indicates whether any remaining data in the buffer should
  1359. //! be discarded (\b true) or transmitted (\b false).
  1360. //!
  1361. //! This function, available only when the module is built to operate in
  1362. //! buffered mode using \b UART_BUFFERED, may be used to flush the transmit
  1363. //! buffer, either discarding or transmitting any data received via calls to
  1364. //! UARTprintf() that is waiting to be transmitted. On return, the transmit
  1365. //! buffer will be empty.
  1366. //!
  1367. //! \return None.
  1368. //
  1369. //*****************************************************************************
  1370. #if defined(UART_BUFFERED) || defined(DOXYGEN)
  1371. void
  1372. UARTFlushTx(bool bDiscard)
  1373. {
  1374. uint32_t ui32Int;
  1375. //
  1376. // Should the remaining data be discarded or transmitted?
  1377. //
  1378. if(bDiscard)
  1379. {
  1380. //
  1381. // The remaining data should be discarded, so temporarily turn off
  1382. // interrupts.
  1383. //
  1384. ui32Int = MAP_IntMasterDisable();
  1385. //
  1386. // Flush the transmit buffer.
  1387. //
  1388. g_ui32UARTTxReadIndex = 0;
  1389. g_ui32UARTTxWriteIndex = 0;
  1390. //
  1391. // If interrupts were enabled when we turned them off, turn them
  1392. // back on again.
  1393. //
  1394. if(!ui32Int)
  1395. {
  1396. MAP_IntMasterEnable();
  1397. }
  1398. }
  1399. else
  1400. {
  1401. //
  1402. // Wait for all remaining data to be transmitted before returning.
  1403. //
  1404. while(!TX_BUFFER_EMPTY)
  1405. {
  1406. }
  1407. }
  1408. }
  1409. #endif
  1410. //*****************************************************************************
  1411. //
  1412. //! Enables or disables echoing of received characters to the transmitter.
  1413. //!
  1414. //! \param bEnable must be set to \b true to enable echo or \b false to
  1415. //! disable it.
  1416. //!
  1417. //! This function, available only when the module is built to operate in
  1418. //! buffered mode using \b UART_BUFFERED, may be used to control whether or not
  1419. //! received characters are automatically echoed back to the transmitter. By
  1420. //! default, echo is enabled and this is typically the desired behavior if
  1421. //! the module is being used to support a serial command line. In applications
  1422. //! where this module is being used to provide a convenient, buffered serial
  1423. //! interface over which application-specific binary protocols are being run,
  1424. //! however, echo may be undesirable and this function can be used to disable
  1425. //! it.
  1426. //!
  1427. //! \return None.
  1428. //
  1429. //*****************************************************************************
  1430. #if defined(UART_BUFFERED) || defined(DOXYGEN)
  1431. void
  1432. UARTEchoSet(bool bEnable)
  1433. {
  1434. g_bDisableEcho = !bEnable;
  1435. }
  1436. #endif
  1437. //*****************************************************************************
  1438. //
  1439. //! Handles UART interrupts.
  1440. //!
  1441. //! This function handles interrupts from the UART. It will copy data from the
  1442. //! transmit buffer to the UART transmit FIFO if space is available, and it
  1443. //! will copy data from the UART receive FIFO to the receive buffer if data is
  1444. //! available.
  1445. //!
  1446. //! \return None.
  1447. //
  1448. //*****************************************************************************
  1449. #if defined(UART_BUFFERED) || defined(DOXYGEN)
  1450. void
  1451. UARTStdioIntHandler(void)
  1452. {
  1453. uint32_t ui32Ints;
  1454. int8_t cChar;
  1455. int32_t i32Char;
  1456. static bool bLastWasCR = false;
  1457. //
  1458. // Get and clear the current interrupt source(s)
  1459. //
  1460. ui32Ints = MAP_UARTIntStatus(g_ui32Base, true);
  1461. MAP_UARTIntClear(g_ui32Base, ui32Ints);
  1462. //
  1463. // Are we being interrupted because the TX FIFO has space available?
  1464. //
  1465. if(ui32Ints & UART_INT_TX)
  1466. {
  1467. //
  1468. // Move as many bytes as we can into the transmit FIFO.
  1469. //
  1470. UARTPrimeTransmit(g_ui32Base);
  1471. //
  1472. // If the output buffer is empty, turn off the transmit interrupt.
  1473. //
  1474. if(TX_BUFFER_EMPTY)
  1475. {
  1476. MAP_UARTIntDisable(g_ui32Base, UART_INT_TX);
  1477. }
  1478. }
  1479. //
  1480. // Are we being interrupted due to a received character?
  1481. //
  1482. if(ui32Ints & (UART_INT_RX | UART_INT_RT))
  1483. {
  1484. //
  1485. // Get all the available characters from the UART.
  1486. //
  1487. while(MAP_UARTCharsAvail(g_ui32Base))
  1488. {
  1489. //
  1490. // Read a character
  1491. //
  1492. i32Char = MAP_UARTCharGetNonBlocking(g_ui32Base);
  1493. cChar = (unsigned char)(i32Char & 0xFF);
  1494. //
  1495. // If echo is disabled, we skip the various text filtering
  1496. // operations that would typically be required when supporting a
  1497. // command line.
  1498. //
  1499. if(!g_bDisableEcho)
  1500. {
  1501. //
  1502. // Handle backspace by erasing the last character in the
  1503. // buffer.
  1504. //
  1505. if(cChar == '\b')
  1506. {
  1507. //
  1508. // If there are any characters already in the buffer, then
  1509. // delete the last.
  1510. //
  1511. if(!RX_BUFFER_EMPTY)
  1512. {
  1513. //
  1514. // Rub out the previous character on the users
  1515. // terminal.
  1516. //
  1517. UARTwrite("\b \b", 3);
  1518. //
  1519. // Decrement the number of characters in the buffer.
  1520. //
  1521. if(g_ui32UARTRxWriteIndex == 0)
  1522. {
  1523. g_ui32UARTRxWriteIndex = UART_RX_BUFFER_SIZE - 1;
  1524. }
  1525. else
  1526. {
  1527. g_ui32UARTRxWriteIndex--;
  1528. }
  1529. }
  1530. //
  1531. // Skip ahead to read the next character.
  1532. //
  1533. continue;
  1534. }
  1535. //
  1536. // If this character is LF and last was CR, then just gobble up
  1537. // the character since we already echoed the previous CR and we
  1538. // don't want to store 2 characters in the buffer if we don't
  1539. // need to.
  1540. //
  1541. if((cChar == '\n') && bLastWasCR)
  1542. {
  1543. bLastWasCR = false;
  1544. continue;
  1545. }
  1546. //
  1547. // See if a newline or escape character was received.
  1548. //
  1549. if((cChar == '\r') || (cChar == '\n') || (cChar == 0x1b))
  1550. {
  1551. //
  1552. // If the character is a CR, then it may be followed by an
  1553. // LF which should be paired with the CR. So remember that
  1554. // a CR was received.
  1555. //
  1556. if(cChar == '\r')
  1557. {
  1558. bLastWasCR = 1;
  1559. }
  1560. //
  1561. // Regardless of the line termination character received,
  1562. // put a CR in the receive buffer as a marker telling
  1563. // UARTgets() where the line ends. We also send an
  1564. // additional LF to ensure that the local terminal echo
  1565. // receives both CR and LF.
  1566. //
  1567. cChar = '\r';
  1568. UARTwrite("\n", 1);
  1569. }
  1570. }
  1571. //
  1572. // If there is space in the receive buffer, put the character
  1573. // there, otherwise throw it away.
  1574. //
  1575. if(!RX_BUFFER_FULL)
  1576. {
  1577. //
  1578. // Store the new character in the receive buffer
  1579. //
  1580. g_pcUARTRxBuffer[g_ui32UARTRxWriteIndex] =
  1581. (unsigned char)(i32Char & 0xFF);
  1582. ADVANCE_RX_BUFFER_INDEX(g_ui32UARTRxWriteIndex);
  1583. //
  1584. // If echo is enabled, write the character to the transmit
  1585. // buffer so that the user gets some immediate feedback.
  1586. //
  1587. if(!g_bDisableEcho)
  1588. {
  1589. UARTwrite((const char *)&cChar, 1);
  1590. }
  1591. }
  1592. }
  1593. //
  1594. // If we wrote anything to the transmit buffer, make sure it actually
  1595. // gets transmitted.
  1596. //
  1597. UARTPrimeTransmit(g_ui32Base);
  1598. MAP_UARTIntEnable(g_ui32Base, UART_INT_TX);
  1599. }
  1600. }
  1601. #endif
  1602. //*****************************************************************************
  1603. //
  1604. // Close the Doxygen group.
  1605. //! @}
  1606. //
  1607. //*****************************************************************************
  1608. //
  1609. // End of file
  1610. //