1 | #ifndef UART_H
|
2 | #define UART_H
|
3 | /************************************************************************
|
4 | Title: Interrupt UART library with receive/transmit circular buffers
|
5 | Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
|
6 | File: $Id: uart.h,v 1.12 2012/11/19 19:52:27 peter Exp $
|
7 | Software: AVR-GCC 4.1, AVR Libc 1.4
|
8 | Hardware: any AVR with built-in UART, tested on AT90S8515 & ATmega8 at 4 Mhz
|
9 | License: GNU General Public License
|
10 | Usage: see Doxygen manual
|
11 |
|
12 | LICENSE:
|
13 | Copyright (C) 2006 Peter Fleury
|
14 |
|
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 |
|
20 | This program is distributed in the hope that it will be useful,
|
21 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
22 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
23 | GNU General Public License for more details.
|
24 |
|
25 | ************************************************************************/
|
26 |
|
27 | /**
|
28 | * @defgroup pfleury_uart UART Library
|
29 | * @code #include <uart.h> @endcode
|
30 | *
|
31 | * @brief Interrupt UART library using the built-in UART with transmit and receive circular buffers.
|
32 | *
|
33 | * This library can be used to transmit and receive data through the built in UART.
|
34 | *
|
35 | * An interrupt is generated when the UART has finished transmitting or
|
36 | * receiving a byte. The interrupt handling routines use circular buffers
|
37 | * for buffering received and transmitted data.
|
38 | *
|
39 | * The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE constants define
|
40 | * the size of the circular buffers in bytes. Note that these constants must be a power of 2.
|
41 | * You may need to adapt this constants to your target and your application by adding
|
42 | * CDEFS += -DUART_RX_BUFFER_SIZE=nn -DUART_RX_BUFFER_SIZE=nn to your Makefile.
|
43 | *
|
44 | * @note Based on Atmel Application Note AVR306
|
45 | * @author Peter Fleury pfleury@gmx.ch http://jump.to/fleury
|
46 | */
|
47 |
|
48 | /**@{*/
|
49 |
|
50 |
|
51 | #if (__GNUC__ * 100 + __GNUC_MINOR__) < 304
|
52 | #error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !"
|
53 | #endif
|
54 |
|
55 |
|
56 | /*
|
57 | ** constants and macros
|
58 | */
|
59 |
|
60 | /** @brief UART Baudrate Expression
|
61 | * @param xtalcpu system clock in Mhz, e.g. 4000000UL for 4Mhz
|
62 | * @param baudrate baudrate in bps, e.g. 1200, 2400, 9600
|
63 | */
|
64 | #define UART_BAUD_SELECT(baudRate,xtalCpu) (((xtalCpu) + 8UL * (baudRate)) / (16UL * (baudRate)) -1UL)
|
65 |
|
66 | /** @brief UART Baudrate Expression for ATmega double speed mode
|
67 | * @param xtalcpu system clock in Mhz, e.g. 4000000UL for 4Mhz
|
68 | * @param baudrate baudrate in bps, e.g. 1200, 2400, 9600
|
69 | */
|
70 | #define UART_BAUD_SELECT_DOUBLE_SPEED(baudRate,xtalCpu) ( ((((xtalCpu) + 4UL * (baudRate)) / (8UL * (baudRate)) -1UL)) | 0x8000)
|
71 |
|
72 |
|
73 | /** Size of the circular receive buffer, must be power of 2 */
|
74 | #ifndef UART_RX_BUFFER_SIZE
|
75 | #define UART_RX_BUFFER_SIZE 32
|
76 | #endif
|
77 | /** Size of the circular transmit buffer, must be power of 2 */
|
78 | #ifndef UART_TX_BUFFER_SIZE
|
79 | #define UART_TX_BUFFER_SIZE 32
|
80 | #endif
|
81 |
|
82 | /* test if the size of the circular buffers fits into SRAM */
|
83 | #if ( (UART_RX_BUFFER_SIZE+UART_TX_BUFFER_SIZE) >= (RAMEND-0x60 ) )
|
84 | #error "size of UART_RX_BUFFER_SIZE + UART_TX_BUFFER_SIZE larger than size of SRAM"
|
85 | #endif
|
86 |
|
87 | /*
|
88 | ** high byte error return code of uart_getc()
|
89 | */
|
90 | #define UART_FRAME_ERROR 0x1000 /* Framing Error by UART */
|
91 | #define UART_OVERRUN_ERROR 0x0800 /* Overrun condition by UART */
|
92 | #define UART_PARITY_ERROR 0x0400 /* Parity Error by UART */
|
93 | #define UART_BUFFER_OVERFLOW 0x0200 /* receive ringbuffer overflow */
|
94 | #define UART_NO_DATA 0x0100 /* no receive data available */
|
95 |
|
96 |
|
97 | /*
|
98 | ** function prototypes
|
99 | */
|
100 |
|
101 | /**
|
102 | @brief Initialize UART and set baudrate
|
103 | @param baudrate Specify baudrate using macro UART_BAUD_SELECT()
|
104 | @return none
|
105 | */
|
106 | extern void uart_init(unsigned int baudrate);
|
107 |
|
108 |
|
109 | /**
|
110 | * @brief Get received byte from ringbuffer
|
111 | *
|
112 | * Returns in the lower byte the received character and in the
|
113 | * higher byte the last receive error.
|
114 | * UART_NO_DATA is returned when no data is available.
|
115 | *
|
116 | * @param void
|
117 | * @return lower byte: received byte from ringbuffer
|
118 | * @return higher byte: last receive status
|
119 | * - \b 0 successfully received data from UART
|
120 | * - \b UART_NO_DATA
|
121 | * <br>no receive data available
|
122 | * - \b UART_BUFFER_OVERFLOW
|
123 | * <br>Receive ringbuffer overflow.
|
124 | * We are not reading the receive buffer fast enough,
|
125 | * one or more received character have been dropped
|
126 | * - \b UART_OVERRUN_ERROR
|
127 | * <br>Overrun condition by UART.
|
128 | * A character already present in the UART UDR register was
|
129 | * not read by the interrupt handler before the next character arrived,
|
130 | * one or more received characters have been dropped.
|
131 | * - \b UART_FRAME_ERROR
|
132 | * <br>Framing Error by UART
|
133 | */
|
134 | extern unsigned int uart_getc(void);
|
135 |
|
136 |
|
137 | /**
|
138 | * @brief Put byte to ringbuffer for transmitting via UART
|
139 | * @param data byte to be transmitted
|
140 | * @return none
|
141 | */
|
142 | extern void uart_putc(unsigned char data);
|
143 |
|
144 |
|
145 | /**
|
146 | * @brief Put string to ringbuffer for transmitting via UART
|
147 | *
|
148 | * The string is buffered by the uart library in a circular buffer
|
149 | * and one character at a time is transmitted to the UART using interrupts.
|
150 | * Blocks if it can not write the whole string into the circular buffer.
|
151 | *
|
152 | * @param s string to be transmitted
|
153 | * @return none
|
154 | */
|
155 | extern void uart_puts(const char *s );
|
156 |
|
157 |
|
158 | /**
|
159 | * @brief Put string from program memory to ringbuffer for transmitting via UART.
|
160 | *
|
161 | * The string is buffered by the uart library in a circular buffer
|
162 | * and one character at a time is transmitted to the UART using interrupts.
|
163 | * Blocks if it can not write the whole string into the circular buffer.
|
164 | *
|
165 | * @param s program memory string to be transmitted
|
166 | * @return none
|
167 | * @see uart_puts_P
|
168 | */
|
169 | extern void uart_puts_p(const char *s );
|
170 |
|
171 | /**
|
172 | * @brief Macro to automatically put a string constant into program memory
|
173 | */
|
174 | #define uart_puts_P(__s) uart_puts_p(PSTR(__s))
|
175 |
|
176 |
|
177 |
|
178 | /** @brief Initialize USART1 (only available on selected ATmegas) @see uart_init */
|
179 | extern void uart1_init(unsigned int baudrate);
|
180 | /** @brief Get received byte of USART1 from ringbuffer. (only available on selected ATmega) @see uart_getc */
|
181 | extern unsigned int uart1_getc(void);
|
182 | /** @brief Put byte to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_putc */
|
183 | extern void uart1_putc(unsigned char data);
|
184 | /** @brief Put string to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_puts */
|
185 | extern void uart1_puts(const char *s );
|
186 | /** @brief Put string from program memory to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_puts_p */
|
187 | extern void uart1_puts_p(const char *s );
|
188 | /** @brief Macro to automatically put a string constant into program memory */
|
189 | #define uart1_puts_P(__s) uart1_puts_p(PSTR(__s))
|
190 |
|
191 | /**@}*/
|
192 |
|
193 |
|
194 | #endif // UART_H
|