Subversion Repositories group.electronics

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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