You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

436 lines
17 KiB

  1. #ifndef USART_H
  2. #define USART_H
  3. /************************************************************************
  4. Title: Interrupt UART library with receive/transmit circular buffers
  5. Author: Andy Gock
  6. Software: AVR-GCC 4.1, AVR Libc 1.4
  7. Hardware: any AVR with built-in UART, tested on AT90S8515 & ATmega8 at 4 Mhz
  8. License: GNU General Public License
  9. Usage: see README.md and Doxygen manual
  10. Based on original library by Peter Fluery, Tim Sharpe, Nicholas Zambetti.
  11. https://github.com/andygock/avr-uart
  12. LICENSE:
  13. Copyright (C) 2012 Andy Gock
  14. Copyright (C) 2006 Peter Fleury
  15. This program is free software; you can redistribute it and/or modify
  16. it under the terms of the GNU General Public License as published by
  17. the Free Software Foundation; either version 2 of the License, or
  18. any later version.
  19. This program is distributed in the hope that it will be useful,
  20. but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. GNU General Public License for more details.
  23. ************************************************************************/
  24. /************************************************************************
  25. uart_available, uart_flush, uart1_available, and uart1_flush functions
  26. were adapted from the Arduino HardwareSerial.h library by Tim Sharpe on
  27. 11 Jan 2009. The license info for HardwareSerial.h is as follows:
  28. HardwareSerial.h - Hardware serial library for Wiring
  29. Copyright (c) 2006 Nicholas Zambetti. All right reserved.
  30. This library is free software; you can redistribute it and/or
  31. modify it under the terms of the GNU Lesser General Public
  32. License as published by the Free Software Foundation; either
  33. version 2.1 of the License, or (at your option) any later version.
  34. This library is distributed in the hope that it will be useful,
  35. but WITHOUT ANY WARRANTY; without even the implied warranty of
  36. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  37. Lesser General Public License for more details.
  38. You should have received a copy of the GNU Lesser General Public
  39. License along with this library; if not, write to the Free Software
  40. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  41. ************************************************************************/
  42. /**
  43. * @defgroup avr-uart UART Library
  44. * @code #include <uart.h> @endcode
  45. *
  46. * @brief Interrupt UART library using the built-in UART with transmit and receive circular buffers.
  47. * @see README.md
  48. *
  49. * This library can be used to transmit and receive data through the built in UART.
  50. *
  51. * An interrupt is generated when the UART has finished transmitting or
  52. * receiving a byte. The interrupt handling routines use circular buffers
  53. * for buffering received and transmitted data.
  54. *
  55. * The UART_RXn_BUFFER_SIZE and UART_TXn_BUFFER_SIZE constants define
  56. * the size of the circular buffers in bytes. Note that these constants must be a power of 2.
  57. *
  58. * You need to define these buffer sizes as a symbol in your compiler settings or in uart.h
  59. *
  60. * See README.md for more detailed information. Especially that relating to symbols: USARTn_ENABLED and USARTn_LARGE_BUFFER
  61. *
  62. * @author Andy Gock <andy@gock.net>
  63. * @note Based on Atmel Application Note AVR306 and original library by Peter Fleury and Tim Sharpe.
  64. */
  65. /**@{*/
  66. #include <stdint.h>
  67. #include <avr/io.h>
  68. #if (__GNUC__ * 100 + __GNUC_MINOR__) < 304
  69. #error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !"
  70. #endif
  71. /*
  72. * constants and macros
  73. */
  74. /* Enable USART 1, 2, 3 as required */
  75. /* Can be defined in compiler symbol setup with -D option (preferred) */
  76. #ifndef USART0_ENABLED
  77. #define USART0_ENABLED /**< Enable USART0 */
  78. #endif
  79. //#define USART1_ENABLED
  80. //#define USART2_ENABLED
  81. //#define USART3_ENABLED
  82. /* Set size of receive and transmit buffers */
  83. #ifndef UART_RX0_BUFFER_SIZE
  84. #define UART_RX0_BUFFER_SIZE 128 /**< Size of the circular receive buffer, must be power of 2 */
  85. #endif
  86. #ifndef UART_RX1_BUFFER_SIZE
  87. #define UART_RX1_BUFFER_SIZE 128 /**< Size of the circular receive buffer, must be power of 2 */
  88. #endif
  89. #ifndef UART_RX2_BUFFER_SIZE
  90. #define UART_RX2_BUFFER_SIZE 128 /**< Size of the circular receive buffer, must be power of 2 */
  91. #endif
  92. #ifndef UART_RX3_BUFFER_SIZE
  93. #define UART_RX3_BUFFER_SIZE 128 /**< Size of the circular receive buffer, must be power of 2 */
  94. #endif
  95. #ifndef UART_TX0_BUFFER_SIZE
  96. #define UART_TX0_BUFFER_SIZE 128 /**< Size of the circular transmit buffer, must be power of 2 */
  97. #endif
  98. #ifndef UART_TX1_BUFFER_SIZE
  99. #define UART_TX1_BUFFER_SIZE 128 /**< Size of the circular transmit buffer, must be power of 2 */
  100. #endif
  101. #ifndef UART_TX2_BUFFER_SIZE
  102. #define UART_TX2_BUFFER_SIZE 128 /**< Size of the circular transmit buffer, must be power of 2 */
  103. #endif
  104. #ifndef UART_TX3_BUFFER_SIZE
  105. #define UART_TX3_BUFFER_SIZE 128 /**< Size of the circular transmit buffer, must be power of 2 */
  106. #endif
  107. /* Check buffer sizes are not too large for 8-bit positioning */
  108. #if (UART_RX0_BUFFER_SIZE > 256 & !defined(USART0_LARGE_BUFFER))
  109. #error "Buffer too large, please use -DUSART0_LARGE_BUFFER switch in compiler options"
  110. #endif
  111. #if (UART_RX1_BUFFER_SIZE > 256 & !defined(USART1_LARGE_BUFFER))
  112. #error "Buffer too large, please use -DUSART1_LARGE_BUFFER switch in compiler options"
  113. #endif
  114. #if (UART_RX2_BUFFER_SIZE > 256 & !defined(USART2_LARGE_BUFFER))
  115. #error "Buffer too large, please use -DUSART2_LARGE_BUFFER switch in compiler options"
  116. #endif
  117. #if (UART_RX3_BUFFER_SIZE > 256 & !defined(USART3_LARGE_BUFFER))
  118. #error "Buffer too large, please use -DUSART3_LARGE_BUFFER switch in compiler options"
  119. #endif
  120. /* Check buffer sizes are not too large for *_LARGE_BUFFER operation (16-bit positioning) */
  121. #if (UART_RX0_BUFFER_SIZE > 32768)
  122. #error "Buffer too large, maximum allowed is 32768 bytes"
  123. #endif
  124. #if (UART_RX1_BUFFER_SIZE > 32768)
  125. #error "Buffer too large, maximum allowed is 32768 bytes"
  126. #endif
  127. #if (UART_RX2_BUFFER_SIZE > 32768)
  128. #error "Buffer too large, maximum allowed is 32768 bytes"
  129. #endif
  130. #if (UART_RX3_BUFFER_SIZE > 32768)
  131. #error "Buffer too large, maximum allowed is 32768 bytes"
  132. #endif
  133. /** @brief UART Baudrate Expression
  134. * @param xtalCpu system clock in Mhz, e.g. 4000000L for 4Mhz
  135. * @param baudRate baudrate in bps, e.g. 1200, 2400, 9600
  136. */
  137. #define UART_BAUD_SELECT(baudRate,xtalCpu) (((xtalCpu)+8UL*(baudRate))/(16UL*(baudRate))-1UL)
  138. /** @brief UART Baudrate Expression for ATmega double speed mode
  139. * @param xtalCpu system clock in Mhz, e.g. 4000000L for 4Mhz
  140. * @param baudRate baudrate in bps, e.g. 1200, 2400, 9600
  141. */
  142. #define UART_BAUD_SELECT_DOUBLE_SPEED(baudRate,xtalCpu) ((((xtalCpu)+4UL*(baudRate))/(8UL*(baudRate))-1)|0x8000)
  143. /* test if the size of the circular buffers fits into SRAM */
  144. #if defined(USART0_ENABLED) && ( (UART_RX0_BUFFER_SIZE+UART_TX0_BUFFER_SIZE) >= (RAMEND-0x60))
  145. #error "size of UART_RX0_BUFFER_SIZE + UART_TX0_BUFFER_SIZE larger than size of SRAM"
  146. #endif
  147. #if defined(USART1_ENABLED) && ( (UART_RX1_BUFFER_SIZE+UART_TX1_BUFFER_SIZE) >= (RAMEND-0x60))
  148. #error "size of UART_RX1_BUFFER_SIZE + UART_TX1_BUFFER_SIZE larger than size of SRAM"
  149. #endif
  150. #if defined(USART2_ENABLED) && ( (UART_RX2_BUFFER_SIZE+UART_RX2_BUFFER_SIZE) >= (RAMEND-0x60))
  151. #error "size of UART_RX2_BUFFER_SIZE + UART_TX2_BUFFER_SIZE larger than size of SRAM"
  152. #endif
  153. #if defined(USART3_ENABLED) && ( (UART_RX3_BUFFER_SIZE+UART_RX3_BUFFER_SIZE) >= (RAMEND-0x60))
  154. #error "size of UART_RX3_BUFFER_SIZE + UART_TX3_BUFFER_SIZE larger than size of SRAM"
  155. #endif
  156. /*
  157. ** high byte error return code of uart_getc()
  158. */
  159. #define UART_FRAME_ERROR 0x0800 /**< Framing Error by UART */
  160. #define UART_OVERRUN_ERROR 0x0400 /**< Overrun condition by UART */
  161. #define UART_BUFFER_OVERFLOW 0x0200 /**< receive ringbuffer overflow */
  162. #define UART_NO_DATA 0x0100 /**< no receive data available */
  163. /* Macros, to allow use of legacy names */
  164. /** @brief Macro to initialize USART0 (only available on selected ATmegas) @see uart0_init */
  165. #define uart_init(b) uart0_init(b)
  166. /** @brief Macro to get received byte of USART0 from ringbuffer. (only available on selected ATmega) @see uart0_getc */
  167. #define uart_getc() uart0_getc()
  168. /** @brief Macro to peek at next byte in USART0 ringbuffer */
  169. #define uart_peek() uart0_peek()
  170. /** @brief Macro to put byte to ringbuffer for transmitting via USART0 (only available on selected ATmega) @see uart0_putc */
  171. #define uart_putc(d) uart0_putc(d)
  172. /** @brief Macro to put string to ringbuffer for transmitting via USART0 (only available on selected ATmega) @see uart0_puts */
  173. #define uart_puts(s) uart0_puts(s)
  174. /** @brief Macro to put string from program memory to ringbuffer for transmitting via USART0 (only available on selected ATmega) @see uart0_puts_p */
  175. #define uart_puts_p(s) uart0_puts_p(s)
  176. /** @brief Macro to return number of bytes waiting in the receive buffer of USART0 @see uart0_available */
  177. #define uart_available() uart0_available()
  178. /** @brief Macro to flush bytes waiting in receive buffer of USART0 @see uart0_flush */
  179. #define uart_flush() uart0_flush()
  180. /*
  181. ** function prototypes
  182. */
  183. /**
  184. @brief Initialize UART and set baudrate
  185. @param baudrate Specify baudrate using macro UART_BAUD_SELECT()
  186. @return none
  187. */
  188. /*extern*/void uart0_init(uint16_t baudrate);
  189. /**
  190. * @brief Get received byte from ringbuffer
  191. *
  192. * Returns in the lower byte the received character and in the
  193. * higher byte the last receive error.
  194. * UART_NO_DATA is returned when no data is available.
  195. *
  196. * @return lower byte: received byte from ringbuffer
  197. * @return higher byte: last receive status
  198. * - \b 0 successfully received data from UART
  199. * - \b UART_NO_DATA
  200. * <br>no receive data available
  201. * - \b UART_BUFFER_OVERFLOW
  202. * <br>Receive ringbuffer overflow.
  203. * We are not reading the receive buffer fast enough,
  204. * one or more received character have been dropped
  205. * - \b UART_OVERRUN_ERROR
  206. * <br>Overrun condition by UART.
  207. * A character already present in the UART UDR register was
  208. * not read by the interrupt handler before the next character arrived,
  209. * one or more received characters have been dropped.
  210. * - \b UART_FRAME_ERROR
  211. * <br>Framing Error by UART
  212. */
  213. /*extern*/uint16_t uart0_getc(void);
  214. /**
  215. * @brief Peek at next byte in ringbuffer
  216. *
  217. * Returns the next byte (character) of incoming UART data without removing it from the
  218. * internal ring buffer. That is, successive calls to uartN_peek() will return the same
  219. * character, as will the next call to uartN_getc().
  220. *
  221. * UART_NO_DATA is returned when no data is available.
  222. *
  223. * @return lower byte: next byte in ringbuffer
  224. * @return higher byte: last receive status
  225. * - \b 0 successfully received data from UART
  226. * - \b UART_NO_DATA
  227. * <br>no receive data available
  228. * - \b UART_BUFFER_OVERFLOW
  229. * <br>Receive ringbuffer overflow.
  230. * We are not reading the receive buffer fast enough,
  231. * one or more received character have been dropped
  232. * - \b UART_OVERRUN_ERROR
  233. * <br>Overrun condition by UART.
  234. * A character already present in the UART UDR register was
  235. * not read by the interrupt handler before the next character arrived,
  236. * one or more received characters have been dropped.
  237. * - \b UART_FRAME_ERROR
  238. * <br>Framing Error by UART
  239. */
  240. /*extern*/uint16_t uart0_peek(void);
  241. /**
  242. * @brief Put byte to ringbuffer for transmitting via UART
  243. * @param data byte to be transmitted
  244. * @return none
  245. */
  246. /*extern*/void uart0_putc(uint8_t data);
  247. /**
  248. * @brief Put string to ringbuffer for transmitting via UART
  249. *
  250. * The string is buffered by the uart library in a circular buffer
  251. * and one character at a time is transmitted to the UART using interrupts.
  252. * Blocks if it can not write the whole string into the circular buffer.
  253. *
  254. * @param s string to be transmitted
  255. * @return none
  256. */
  257. /*extern*/void uart0_puts(const char *s);
  258. /**
  259. * @brief Put string from program memory to ringbuffer for transmitting via UART.
  260. *
  261. * The string is buffered by the uart library in a circular buffer
  262. * and one character at a time is transmitted to the UART using interrupts.
  263. * Blocks if it can not write the whole string into the circular buffer.
  264. *
  265. * @param s program memory string to be transmitted
  266. * @return none
  267. * @see uart0_puts_P
  268. */
  269. /*extern*/void uart0_puts_p(const char *s);
  270. /**
  271. * @brief Macro to automatically put a string constant into program memory
  272. * \param __s string in program memory
  273. */
  274. #define uart_puts_P(__s) uart0_puts_p(PSTR(__s))
  275. /** @brief Macro to automatically put a string constant into program memory */
  276. #define uart0_puts_P(__s) uart0_puts_p(PSTR(__s))
  277. /**
  278. * @brief Return number of bytes waiting in the receive buffer
  279. * @return bytes waiting in the receive buffer
  280. */
  281. /*extern*/uint16_t uart0_available(void);
  282. /**
  283. * @brief Flush bytes waiting in receive buffer
  284. */
  285. /*extern*/void uart0_flush(void);
  286. /** @brief Initialize USART1 (only available on selected ATmegas) @see uart_init */
  287. /*extern*/void uart1_init(uint16_t baudrate);
  288. /** @brief Get received byte of USART1 from ringbuffer. (only available on selected ATmega) @see uart_getc */
  289. /*extern*/uint16_t uart1_getc(void);
  290. /** @brief Peek at next byte in USART1 ringbuffer */
  291. /*extern*/uint16_t uart1_peek(void);
  292. /** @brief Put byte to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_putc */
  293. /*extern*/void uart1_putc(uint8_t data);
  294. /** @brief Put string to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_puts */
  295. /*extern*/void uart1_puts(const char *s);
  296. /** @brief Put string from program memory to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_puts_p */
  297. /*extern*/void uart1_puts_p(const char *s);
  298. /** @brief Macro to automatically put a string constant into program memory of USART1 @see uart1_puts_p */
  299. #define uart1_puts_P(__s) uart1_puts_p(PSTR(__s))
  300. /** @brief Return number of bytes waiting in the receive buffer of USART1 */
  301. /*extern*/uint16_t uart1_available(void);
  302. /** @brief Flush bytes waiting in receive buffer of USART1 */
  303. /*extern*/void uart1_flush(void);
  304. /** @brief Initialize USART2 (only available on selected ATmegas) @see uart_init */
  305. /*extern*/void uart2_init(uint16_t baudrate);
  306. /** @brief Get received byte of USART2 from ringbuffer. (only available on selected ATmega) @see uart_getc */
  307. /*extern*/uint16_t uart2_getc(void);
  308. /** @brief Peek at next byte in USART2 ringbuffer */
  309. /*extern*/uint16_t uart2_peek(void);
  310. /** @brief Put byte to ringbuffer for transmitting via USART2 (only available on selected ATmega) @see uart_putc */
  311. /*extern*/void uart2_putc(uint8_t data);
  312. /** @brief Put string to ringbuffer for transmitting via USART2 (only available on selected ATmega) @see uart_puts */
  313. /*extern*/void uart2_puts(const char *s);
  314. /** @brief Put string from program memory to ringbuffer for transmitting via USART2 (only available on selected ATmega) @see uart_puts_p */
  315. /*extern*/void uart2_puts_p(const char *s);
  316. /** @brief Macro to automatically put a string constant into program memory of USART2 @see uart2_puts_p */
  317. #define uart2_puts_P(__s) uart2_puts_p(PSTR(__s))
  318. /** @brief Return number of bytes waiting in the receive buffer of USART2 */
  319. /*extern*/uint16_t uart2_available(void);
  320. /** @brief Flush bytes waiting in receive buffer of USART2 */
  321. /*extern*/void uart2_flush(void);
  322. /** @brief Initialize USART3 (only available on selected ATmegas) @see uart_init */
  323. /*extern*/void uart3_init(uint16_t baudrate);
  324. /** @brief Get received byte of USART3 from ringbuffer. (only available on selected ATmega) @see uart_getc */
  325. /*extern*/uint16_t uart3_getc(void);
  326. /** @brief Peek at next byte in USART3 ringbuffer */
  327. /*extern*/uint16_t uart3_peek(void);
  328. /** @brief Put byte to ringbuffer for transmitting via USART3 (only available on selected ATmega) @see uart_putc */
  329. /*extern*/void uart3_putc(uint8_t data);
  330. /** @brief Put string to ringbuffer for transmitting via USART3 (only available on selected ATmega) @see uart_puts */
  331. /*extern*/void uart3_puts(const char *s);
  332. /** @brief Put string from program memory to ringbuffer for transmitting via USART3 (only available on selected ATmega) @see uart_puts_p */
  333. /*extern*/void uart3_puts_p(const char *s);
  334. /** @brief Macro to automatically put a string constant into program memory of USART3 @see uart3_puts_p */
  335. #define uart3_puts_P(__s) uart3_puts_p(PSTR(__s))
  336. /** @brief Return number of bytes waiting in the receive buffer of USART3 */
  337. /*extern*/uint16_t uart3_available(void);
  338. /** @brief Flush bytes waiting in receive buffer of USART3 */
  339. /*extern*/void uart3_flush(void);
  340. /**@}*/
  341. #endif // UART_H