Subversion Repositories HomeAutomation

Rev

Rev 29 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 29 Rev 30
1
/*************************************************************************
1
/*************************************************************************
2
Title:     Interrupt UART library with receive/transmit circular buffers
2
Title:     Interrupt UART library with receive/transmit circular buffers
3
Author:    Peter Fleury <pfleury@gmx.ch>   http://jump.to/fleury
3
Author:    Peter Fleury <pfleury@gmx.ch>   http://jump.to/fleury
4
File:      $Id: uart.c,v 1.5.2.2 2004/02/27 22:00:28 peter Exp $
4
File:      $Id: uart.c,v 1.5.2.2 2004/02/27 22:00:28 peter Exp $
5
Software:  AVR-GCC 3.3
5
Software:  AVR-GCC 3.3
6
Hardware:  any AVR with built-in UART,
6
Hardware:  any AVR with built-in UART,
7
           tested on AT90S8515 at 4 Mhz and ATmega at 1Mhz
7
           tested on AT90S8515 at 4 Mhz and ATmega at 1Mhz
8
Extensions:- uart_puti by M. Thomas 9/2004
8
Extensions:- uart_puti by M. Thomas 9/2004
9
           - uart_puthex_nibble and _byte by M.T. 9/2004
9
           - uart_puthex_nibble and _byte by M.T. 9/2004
10
           - uart_putbin_byte by M.T. 1/2005
10
           - uart_putbin_byte by M.T. 1/2005
11
 
11
 
12
DESCRIPTION:
12
DESCRIPTION:
13
    An interrupt is generated when the UART has finished transmitting or
13
    An interrupt is generated when the UART has finished transmitting or
14
    receiving a byte. The interrupt handling routines use circular buffers
14
    receiving a byte. The interrupt handling routines use circular buffers
15
    for buffering received and transmitted data.
15
    for buffering received and transmitted data.
16
   
16
   
17
    The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE variables define
17
    The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE variables define
18
    the buffer size in bytes. Note that these variables must be a
18
    the buffer size in bytes. Note that these variables must be a
19
    power of 2.
19
    power of 2.
20
   
20
   
21
USAGE:
21
USAGE:
22
    Refere to the header file uart.h for a description of the routines.
22
    Refere to the header file uart.h for a description of the routines.
23
    See also example test_uart.c.
23
    See also example test_uart.c.
24
 
24
 
25
NOTES:
25
NOTES:
26
    Based on Atmel Application Note AVR306
26
    Based on Atmel Application Note AVR306
27
                   
27
                   
28
*************************************************************************/
28
*************************************************************************/
29
#include <stdlib.h>
29
#include <stdlib.h>
30
#include <avr/io.h>
30
#include <avr/io.h>
31
#include <avr/interrupt.h>
31
#include <avr/interrupt.h>
32
#include <avr/signal.h>
-
 
33
#include <avr/pgmspace.h>
32
#include <avr/pgmspace.h>
34
#include "uart.h"
33
#include "uart.h"
35
 
34
 
36
 
35
 
37
/*
36
/*
38
 *  constants and macros
37
 *  constants and macros
39
 */
38
 */
40
 
39
 
41
/* size of RX/TX buffers */
40
/* size of RX/TX buffers */
42
#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1)
41
#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1)
43
#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1)
42
#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1)
44
 
43
 
45
#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
44
#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
46
#error RX buffer size is not a power of 2
45
#error RX buffer size is not a power of 2
47
#endif
46
#endif
48
#if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
47
#if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
49
#error TX buffer size is not a power of 2
48
#error TX buffer size is not a power of 2
50
#endif
49
#endif
51
 
50
 
52
#if defined(__AVR_AT90S2313__) \
51
#if defined(__AVR_AT90S2313__) \
53
 || defined(__AVR_AT90S4414__) || defined(__AVR_AT90S4434__) \
52
 || defined(__AVR_AT90S4414__) || defined(__AVR_AT90S4434__) \
54
 || defined(__AVR_AT90S8515__) || defined(__AVR_AT90S8535__)
53
 || defined(__AVR_AT90S8515__) || defined(__AVR_AT90S8535__)
55
 /* old AVR classic with one UART */
54
 /* old AVR classic with one UART */
56
 #define AT90_UART
55
 #define AT90_UART
57
 #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
56
 #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
58
 #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
57
 #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
59
 #define UART0_STATUS   USR
58
 #define UART0_STATUS   USR
60
 #define UART0_CONTROL  UCR
59
 #define UART0_CONTROL  UCR
61
 #define UART0_DATA     UDR  
60
 #define UART0_DATA     UDR  
62
 #define UART0_UDRIE    UDRIE
61
 #define UART0_UDRIE    UDRIE
63
#elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__)
62
#elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__)
64
 /* old AVR classic with one UART */
63
 /* old AVR classic with one UART */
65
 #define AT90_UART
64
 #define AT90_UART
66
 #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
65
 #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
67
 #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
66
 #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
68
 #define UART0_STATUS   UCSRA
67
 #define UART0_STATUS   UCSRA
69
 #define UART0_CONTROL  UCSRB
68
 #define UART0_CONTROL  UCSRB
70
 #define UART0_DATA     UDR 
69
 #define UART0_DATA     UDR 
71
 #define UART0_UDRIE    UDRIE
70
 #define UART0_UDRIE    UDRIE
72
#elif  defined(__AVR_ATmega8__)  || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \
71
#elif  defined(__AVR_ATmega8__)  || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \
73
  || defined(__AVR_ATmega8515__) || defined(__AVR_ATmega8535__) \
72
  || defined(__AVR_ATmega8515__) || defined(__AVR_ATmega8535__) \
74
  || defined(__AVR_ATmega323__) 
73
  || defined(__AVR_ATmega323__) 
75
  /* ATMega with one USART */
74
  /* ATMega with one USART */
76
 #define ATMEGA_USART
75
 #define ATMEGA_USART
77
 #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
76
 #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
78
 #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
77
 #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
79
 #define UART0_STATUS   UCSRA
78
 #define UART0_STATUS   UCSRA
80
 #define UART0_CONTROL  UCSRB
79
 #define UART0_CONTROL  UCSRB
81
 #define UART0_DATA     UDR
80
 #define UART0_DATA     UDR
82
 #define UART0_UDRIE    UDRIE
81
 #define UART0_UDRIE    UDRIE
83
#elif defined(__AVR_ATmega163__) 
82
#elif defined(__AVR_ATmega163__) 
84
  /* ATMega163 with one UART */
83
  /* ATMega163 with one UART */
85
 #define ATMEGA_UART
84
 #define ATMEGA_UART
86
 #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
85
 #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
87
 #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
86
 #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
88
 #define UART0_STATUS   UCSRA
87
 #define UART0_STATUS   UCSRA
89
 #define UART0_CONTROL  UCSRB
88
 #define UART0_CONTROL  UCSRB
90
 #define UART0_DATA     UDR
89
 #define UART0_DATA     UDR
91
 #define UART0_UDRIE    UDRIE
90
 #define UART0_UDRIE    UDRIE
92
#elif defined(__AVR_ATmega162__)
91
#elif defined(__AVR_ATmega162__)
93
 /* ATMega with two USART */
92
 /* ATMega with two USART */
94
 #define ATMEGA_USART0
93
 #define ATMEGA_USART0
95
 #define ATMEGA_USART1
94
 #define ATMEGA_USART1
96
 #define UART0_RECEIVE_INTERRUPT   SIG_USART0_RECV
95
 #define UART0_RECEIVE_INTERRUPT   SIG_USART0_RECV
97
 #define UART1_RECEIVE_INTERRUPT   SIG_USART1_RECV
96
 #define UART1_RECEIVE_INTERRUPT   SIG_USART1_RECV
98
 #define UART0_TRANSMIT_INTERRUPT  SIG_USART0_DATA
97
 #define UART0_TRANSMIT_INTERRUPT  SIG_USART0_DATA
99
 #define UART1_TRANSMIT_INTERRUPT  SIG_USART1_DATA
98
 #define UART1_TRANSMIT_INTERRUPT  SIG_USART1_DATA
100
 #define UART0_STATUS   UCSR0A
99
 #define UART0_STATUS   UCSR0A
101
 #define UART0_CONTROL  UCSR0B
100
 #define UART0_CONTROL  UCSR0B
102
 #define UART0_DATA     UDR0
101
 #define UART0_DATA     UDR0
103
 #define UART0_UDRIE    UDRIE0
102
 #define UART0_UDRIE    UDRIE0
104
 #define UART1_STATUS   UCSR1A
103
 #define UART1_STATUS   UCSR1A
105
 #define UART1_CONTROL  UCSR1B
104
 #define UART1_CONTROL  UCSR1B
106
 #define UART1_DATA     UDR1
105
 #define UART1_DATA     UDR1
107
 #define UART1_UDRIE    UDRIE1
106
 #define UART1_UDRIE    UDRIE1
108
#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) 
107
#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) 
109
 /* ATMega with two USART */
108
 /* ATMega with two USART */
110
 #define ATMEGA_USART0
109
 #define ATMEGA_USART0
111
 #define ATMEGA_USART1
110
 #define ATMEGA_USART1
112
 #define UART0_RECEIVE_INTERRUPT   SIG_UART0_RECV
111
 #define UART0_RECEIVE_INTERRUPT   SIG_UART0_RECV
113
 #define UART1_RECEIVE_INTERRUPT   SIG_UART1_RECV
112
 #define UART1_RECEIVE_INTERRUPT   SIG_UART1_RECV
114
 #define UART0_TRANSMIT_INTERRUPT  SIG_UART0_DATA
113
 #define UART0_TRANSMIT_INTERRUPT  SIG_UART0_DATA
115
 #define UART1_TRANSMIT_INTERRUPT  SIG_UART1_DATA
114
 #define UART1_TRANSMIT_INTERRUPT  SIG_UART1_DATA
116
 #define UART0_STATUS   UCSR0A
115
 #define UART0_STATUS   UCSR0A
117
 #define UART0_CONTROL  UCSR0B
116
 #define UART0_CONTROL  UCSR0B
118
 #define UART0_DATA     UDR0
117
 #define UART0_DATA     UDR0
119
 #define UART0_UDRIE    UDRIE0
118
 #define UART0_UDRIE    UDRIE0
120
 #define UART1_STATUS   UCSR1A
119
 #define UART1_STATUS   UCSR1A
121
 #define UART1_CONTROL  UCSR1B
120
 #define UART1_CONTROL  UCSR1B
122
 #define UART1_DATA     UDR1
121
 #define UART1_DATA     UDR1
123
 #define UART1_UDRIE    UDRIE1
122
 #define UART1_UDRIE    UDRIE1
124
#elif defined(__AVR_ATmega103__)
123
#elif defined(__AVR_ATmega103__)
125
 /* ATMega with one UART */
124
 /* ATMega with one UART */
126
 #error "AVR ATmega103 currently not supported by this libaray !"
125
 #error "AVR ATmega103 currently not supported by this libaray !"
127
#elif defined(__AVR_ATmega161__)
126
#elif defined(__AVR_ATmega161__)
128
 /* ATmega with UART */
127
 /* ATmega with UART */
129
 #error "AVR ATmega161 currently not supported by this libaray !"
128
 #error "AVR ATmega161 currently not supported by this libaray !"
130
#elif defined(__AVR_ATmega169__)
129
#elif defined(__AVR_ATmega169__)
131
 #error "AVR ATmega169 currently not supported by this libaray !"
130
 #error "AVR ATmega169 currently not supported by this libaray !"
132
#endif
131
#endif
133
 
132
 
134
 
133
 
135
/*
134
/*
136
 *  module global variables
135
 *  module global variables
137
 */
136
 */
138
static volatile unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];
137
static volatile unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];
139
static volatile unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];
138
static volatile unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];
140
static volatile unsigned char UART_TxHead;
139
static volatile unsigned char UART_TxHead;
141
static volatile unsigned char UART_TxTail;
140
static volatile unsigned char UART_TxTail;
142
static volatile unsigned char UART_RxHead;
141
static volatile unsigned char UART_RxHead;
143
static volatile unsigned char UART_RxTail;
142
static volatile unsigned char UART_RxTail;
144
static volatile unsigned char UART_LastRxError;
143
static volatile unsigned char UART_LastRxError;
145
 
144
 
146
 
145
 
147
 
146
 
148
SIGNAL(UART0_RECEIVE_INTERRUPT)
147
ISR(UART0_RECEIVE_INTERRUPT)
149
/*************************************************************************
148
/*************************************************************************
150
Function: UART Receive Complete interrupt
149
Function: UART Receive Complete interrupt
151
Purpose:  called when the UART has received a character
150
Purpose:  called when the UART has received a character
152
**************************************************************************/
151
**************************************************************************/
153
{
152
{
154
    unsigned char tmphead;
153
    unsigned char tmphead;
155
    unsigned char data;
154
    unsigned char data;
156
    unsigned char usr;
155
    unsigned char usr;
157
    unsigned char lastRxError;
156
    unsigned char lastRxError;
158
 
157
 
159
 
158
 
160
    /* read UART status register and UART data register */
159
    /* read UART status register and UART data register */
161
    usr  = UART0_STATUS;
160
    usr  = UART0_STATUS;
162
    data = UART0_DATA;
161
    data = UART0_DATA;
163
   
162
   
164
    /* */
163
    /* */
165
#if defined( AT90_UART )
164
#if defined( AT90_UART )
166
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
165
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
167
#elif defined( ATMEGA_USART )
166
#elif defined( ATMEGA_USART )
168
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
167
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
169
#elif defined( ATMEGA_USART0 )
168
#elif defined( ATMEGA_USART0 )
170
    lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) );
169
    lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) );
171
#elif defined ( ATMEGA_UART )
170
#elif defined ( ATMEGA_UART )
172
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
171
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
173
#endif
172
#endif
174
       
173
       
175
    /* calculate buffer index */
174
    /* calculate buffer index */
176
    tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
175
    tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
177
   
176
   
178
    if ( tmphead == UART_RxTail ) {
177
    if ( tmphead == UART_RxTail ) {
179
        /* error: receive buffer overflow */
178
        /* error: receive buffer overflow */
180
        lastRxError = UART_BUFFER_OVERFLOW >> 8;
179
        lastRxError = UART_BUFFER_OVERFLOW >> 8;
181
    }else{
180
    }else{
182
        /* store new index */
181
        /* store new index */
183
        UART_RxHead = tmphead;
182
        UART_RxHead = tmphead;
184
        /* store received data in buffer */
183
        /* store received data in buffer */
185
        UART_RxBuf[tmphead] = data;
184
        UART_RxBuf[tmphead] = data;
186
    }
185
    }
187
    UART_LastRxError = lastRxError;  
186
    UART_LastRxError = lastRxError;  
188
}
187
}
189
 
188
 
190
 
189
 
191
SIGNAL(UART0_TRANSMIT_INTERRUPT)
190
ISR(UART0_TRANSMIT_INTERRUPT)
192
/*************************************************************************
191
/*************************************************************************
193
Function: UART Data Register Empty interrupt
192
Function: UART Data Register Empty interrupt
194
Purpose:  called when the UART is ready to transmit the next byte
193
Purpose:  called when the UART is ready to transmit the next byte
195
**************************************************************************/
194
**************************************************************************/
196
{
195
{
197
    unsigned char tmptail;
196
    unsigned char tmptail;
198
 
197
 
199
   
198
   
200
    if ( UART_TxHead != UART_TxTail) {
199
    if ( UART_TxHead != UART_TxTail) {
201
        /* calculate and store new buffer index */
200
        /* calculate and store new buffer index */
202
        tmptail = (UART_TxTail + 1) & UART_TX_BUFFER_MASK;
201
        tmptail = (UART_TxTail + 1) & UART_TX_BUFFER_MASK;
203
        UART_TxTail = tmptail;
202
        UART_TxTail = tmptail;
204
        /* get one byte from buffer and write it to UART */
203
        /* get one byte from buffer and write it to UART */
205
        UART0_DATA = UART_TxBuf[tmptail];  /* start transmission */
204
        UART0_DATA = UART_TxBuf[tmptail];  /* start transmission */
206
    }else{
205
    }else{
207
        /* tx buffer empty, disable UDRE interrupt */
206
        /* tx buffer empty, disable UDRE interrupt */
208
        UART0_CONTROL &= ~_BV(UART0_UDRIE);
207
        UART0_CONTROL &= ~_BV(UART0_UDRIE);
209
    }
208
    }
210
}
209
}
211
 
210
 
212
 
211
 
213
/*************************************************************************
212
/*************************************************************************
214
Function: uart_init()
213
Function: uart_init()
215
Purpose:  initialize UART and set baudrate
214
Purpose:  initialize UART and set baudrate
216
Input:    baudrate using macro UART_BAUD_SELECT()
215
Input:    baudrate using macro UART_BAUD_SELECT()
217
Returns:  none
216
Returns:  none
218
**************************************************************************/
217
**************************************************************************/
219
void uart_init(unsigned int baudrate)
218
void uart_init(unsigned int baudrate)
220
{
219
{
221
    UART_TxHead = 0;
220
    UART_TxHead = 0;
222
    UART_TxTail = 0;
221
    UART_TxTail = 0;
223
    UART_RxHead = 0;
222
    UART_RxHead = 0;
224
    UART_RxTail = 0;
223
    UART_RxTail = 0;
225
   
224
   
226
#if defined( AT90_UART )
225
#if defined( AT90_UART )
227
    /* set baud rate */
226
    /* set baud rate */
228
    UBRR = (unsigned char)baudrate;
227
    UBRR = (unsigned char)baudrate;
229
 
228
 
230
    /* enable UART receiver and transmmitter and receive complete interrupt */
229
    /* enable UART receiver and transmmitter and receive complete interrupt */
231
    UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|BV(TXEN);
230
    UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|BV(TXEN);
232
 
231
 
233
#elif defined (ATMEGA_USART)
232
#elif defined (ATMEGA_USART)
234
    /* Set baud rate */
233
    /* Set baud rate */
235
    UBRRH = (unsigned char)(baudrate>>8);
234
    UBRRH = (unsigned char)(baudrate>>8);
236
    UBRRL = (unsigned char) baudrate;
235
    UBRRL = (unsigned char) baudrate;
237
 
236
 
238
    /* Enable USART receiver and transmitter and receive complete interrupt */
237
    /* Enable USART receiver and transmitter and receive complete interrupt */
239
    UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
238
    UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
240
   
239
   
241
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
240
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
242
    #ifdef URSEL
241
    #ifdef URSEL
243
    UCSRC = (1<<URSEL)|(3<<UCSZ0);
242
    UCSRC = (1<<URSEL)|(3<<UCSZ0);
244
    #else
243
    #else
245
    UCSRC = (3<<UCSZ0);
244
    UCSRC = (3<<UCSZ0);
246
    #endif 
245
    #endif 
247
   
246
   
248
#elif defined (ATMEGA_USART0 )
247
#elif defined (ATMEGA_USART0 )
249
    /* Set baud rate */
248
    /* Set baud rate */
250
    UBRR0H = (unsigned char)(baudrate>>8);
249
    UBRR0H = (unsigned char)(baudrate>>8);
251
    UBRR0L = (unsigned char) baudrate;
250
    UBRR0L = (unsigned char) baudrate;
252
 
251
 
253
    /* Enable USART receiver and transmitter and receive complete interrupt */
252
    /* Enable USART receiver and transmitter and receive complete interrupt */
254
    UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
253
    UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
255
   
254
   
256
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
255
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
257
    #ifdef URSEL0
256
    #ifdef URSEL0
258
    UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
257
    UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
259
    #else
258
    #else
260
    UCSR0C = (3<<UCSZ00);
259
    UCSR0C = (3<<UCSZ00);
261
    #endif 
260
    #endif 
262
 
261
 
263
#elif defined ( ATMEGA_UART )
262
#elif defined ( ATMEGA_UART )
264
    /* set baud rate */
263
    /* set baud rate */
265
    UBRRHI = (unsigned char)(baudrate>>8);
264
    UBRRHI = (unsigned char)(baudrate>>8);
266
    UBRR   = (unsigned char) baudrate;
265
    UBRR   = (unsigned char) baudrate;
267
 
266
 
268
    /* Enable UART receiver and transmitter and receive complete interrupt */
267
    /* Enable UART receiver and transmitter and receive complete interrupt */
269
    UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
268
    UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
270
 
269
 
271
#endif
270
#endif
272
 
271
 
273
}/* uart_init */
272
}/* uart_init */
274
 
273
 
275
 
274
 
276
/*************************************************************************
275
/*************************************************************************
277
Function: uart_getc()
276
Function: uart_getc()
278
Purpose:  return byte from ringbuffer  
277
Purpose:  return byte from ringbuffer  
279
Returns:  lower byte:  received byte from ringbuffer
278
Returns:  lower byte:  received byte from ringbuffer
280
          higher byte: last receive error
279
          higher byte: last receive error
281
**************************************************************************/
280
**************************************************************************/
282
unsigned int uart_getc(void)
281
unsigned int uart_getc(void)
283
{    
282
{    
284
    unsigned char tmptail;
283
    unsigned char tmptail;
285
    unsigned char data;
284
    unsigned char data;
286
 
285
 
287
 
286
 
288
    if ( UART_RxHead == UART_RxTail ) {
287
    if ( UART_RxHead == UART_RxTail ) {
289
        return UART_NO_DATA;   /* no data available */
288
        return UART_NO_DATA;   /* no data available */
290
    }
289
    }
291
   
290
   
292
    /* calculate /store buffer index */
291
    /* calculate /store buffer index */
293
    tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
292
    tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
294
    UART_RxTail = tmptail;
293
    UART_RxTail = tmptail;
295
   
294
   
296
    /* get data from receive buffer */
295
    /* get data from receive buffer */
297
    data = UART_RxBuf[tmptail];
296
    data = UART_RxBuf[tmptail];
298
   
297
   
299
    return (UART_LastRxError << 8) + data;
298
    return (UART_LastRxError << 8) + data;
300
 
299
 
301
}/* uart_getc */
300
}/* uart_getc */
302
 
301
 
303
 
302
 
304
/*************************************************************************
303
/*************************************************************************
305
Function: uart_putc()
304
Function: uart_putc()
306
Purpose:  write byte to ringbuffer for transmitting via UART
305
Purpose:  write byte to ringbuffer for transmitting via UART
307
Input:    byte to be transmitted
306
Input:    byte to be transmitted
308
Returns:  none          
307
Returns:  none          
309
**************************************************************************/
308
**************************************************************************/
310
void uart_putc(unsigned char data)
309
void uart_putc(unsigned char data)
311
{
310
{
312
    unsigned char tmphead;
311
    unsigned char tmphead;
313
 
312
 
314
   
313
   
315
    tmphead  = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
314
    tmphead  = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
316
   
315
   
317
    while ( tmphead == UART_TxTail ){
316
    while ( tmphead == UART_TxTail ){
318
        ;/* wait for free space in buffer */
317
        ;/* wait for free space in buffer */
319
    }
318
    }
320
   
319
   
321
    UART_TxBuf[tmphead] = data;
320
    UART_TxBuf[tmphead] = data;
322
    UART_TxHead = tmphead;
321
    UART_TxHead = tmphead;
323
 
322
 
324
    /* enable UDRE interrupt */
323
    /* enable UDRE interrupt */
325
    UART0_CONTROL    |= _BV(UART0_UDRIE);
324
    UART0_CONTROL    |= _BV(UART0_UDRIE);
326
 
325
 
327
}/* uart_putc */
326
}/* uart_putc */
328
 
327
 
329
 
328
 
330
/*************************************************************************
329
/*************************************************************************
331
Function: uart_puts()
330
Function: uart_puts()
332
Purpose:  transmit string to UART
331
Purpose:  transmit string to UART
333
Input:    string to be transmitted
332
Input:    string to be transmitted
334
Returns:  none          
333
Returns:  none          
335
**************************************************************************/
334
**************************************************************************/
336
void uart_puts(const char *s )
335
void uart_puts(const char *s )
337
{
336
{
338
    while (*s)
337
    while (*s)
339
      uart_putc(*s++);
338
      uart_putc(*s++);
340
 
339
 
341
}/* uart_puts */
340
}/* uart_puts */
342
 
341
 
343
 
342
 
344
/*************************************************************************
343
/*************************************************************************
345
Function: uart_puts_p()
344
Function: uart_puts_p()
346
Purpose:  transmit string from program memory to UART
345
Purpose:  transmit string from program memory to UART
347
Input:    program memory string to be transmitted
346
Input:    program memory string to be transmitted
348
Returns:  none
347
Returns:  none
349
**************************************************************************/
348
**************************************************************************/
350
void uart_puts_p(const char *progmem_s )
349
void uart_puts_p(const char *progmem_s )
351
{
350
{
352
    register char c;
351
    register char c;
353
   
352
   
354
    while ( (c = pgm_read_byte(progmem_s++)) )
353
    while ( (c = pgm_read_byte(progmem_s++)) )
355
      uart_putc(c);
354
      uart_putc(c);
356
 
355
 
357
}/* uart_puts_p */
356
}/* uart_puts_p */
358
 
357
 
359
/*************************************************************************
358
/*************************************************************************
360
Function: uart_puti()
359
Function: uart_puti()
361
Purpose:  transmit integer as ASCII to UART
360
Purpose:  transmit integer as ASCII to UART
362
Input:    integer value
361
Input:    integer value
363
Returns:  none
362
Returns:  none
364
This functions has been added by Martin Thomas <eversmith@heizung-thomas.de>
363
This functions has been added by Martin Thomas <eversmith@heizung-thomas.de>
365
Don't blame P. Fleury if it doesn't work ;-)
364
Don't blame P. Fleury if it doesn't work ;-)
366
**************************************************************************/
365
**************************************************************************/
367
void uart_puti( const int val )
366
void uart_puti( const int val )
368
{
367
{
369
    char buffer[sizeof(int)*8+1];
368
    char buffer[sizeof(int)*8+1];
370
   
369
   
371
    uart_puts( itoa(val, buffer, 10) );
370
    uart_puts( itoa(val, buffer, 10) );
372
 
371
 
373
}/* uart_puti */
372
}/* uart_puti */
374
 
373
 
375
/*************************************************************************
374
/*************************************************************************
376
Function: uart_puthex_nibble()
375
Function: uart_puthex_nibble()
377
Purpose:  transmit lower nibble as ASCII-hex to UART
376
Purpose:  transmit lower nibble as ASCII-hex to UART
378
Input:    byte value
377
Input:    byte value
379
Returns:  none
378
Returns:  none
380
This functions has been added by Martin Thomas <eversmith@heizung-thomas.de>
379
This functions has been added by Martin Thomas <eversmith@heizung-thomas.de>
381
Don't blame P. Fleury if it doesn't work ;-)
380
Don't blame P. Fleury if it doesn't work ;-)
382
**************************************************************************/
381
**************************************************************************/
383
void uart_puthex_nibble(const unsigned char b)
382
void uart_puthex_nibble(const unsigned char b)
384
{
383
{
385
    unsigned char  c = b & 0x0f;
384
    unsigned char  c = b & 0x0f;
386
    if (c>9) c += 'A'-10;
385
    if (c>9) c += 'A'-10;
387
    else c += '0';
386
    else c += '0';
388
    uart_putc(c);
387
    uart_putc(c);
389
} /* uart_puthex_nibble */
388
} /* uart_puthex_nibble */
390
 
389
 
391
/*************************************************************************
390
/*************************************************************************
392
Function: uart_puthex_byte()
391
Function: uart_puthex_byte()
393
Purpose:  transmit upper and lower nibble as ASCII-hex to UART
392
Purpose:  transmit upper and lower nibble as ASCII-hex to UART
394
Input:    byte value
393
Input:    byte value
395
Returns:  none
394
Returns:  none
396
This functions has been added by Martin Thomas <eversmith@heizung-thomas.de>
395
This functions has been added by Martin Thomas <eversmith@heizung-thomas.de>
397
Don't blame P. Fleury if it doesn't work ;-)
396
Don't blame P. Fleury if it doesn't work ;-)
398
**************************************************************************/
397
**************************************************************************/
399
void uart_puthex_byte(const unsigned char  b)
398
void uart_puthex_byte(const unsigned char  b)
400
{
399
{
401
    uart_puthex_nibble(b>>4);
400
    uart_puthex_nibble(b>>4);
402
    uart_puthex_nibble(b);
401
    uart_puthex_nibble(b);
403
} /* uart_puthex_byte */
402
} /* uart_puthex_byte */
404
 
403
 
405
/*************************************************************************
404
/*************************************************************************
406
Function: uart_putbin_byte()
405
Function: uart_putbin_byte()
407
Purpose:  transmit byte as ASCII-bin to UART
406
Purpose:  transmit byte as ASCII-bin to UART
408
Input:    byte value
407
Input:    byte value
409
Returns:  none
408
Returns:  none
410
This functions has been added by Martin Thomas <eversmith@heizung-thomas.de>
409
This functions has been added by Martin Thomas <eversmith@heizung-thomas.de>
411
Don't blame P. Fleury if it doesn't work ;-)
410
Don't blame P. Fleury if it doesn't work ;-)
412
**************************************************************************/
411
**************************************************************************/
413
void uart_putbin_byte(const unsigned char b)
412
void uart_putbin_byte(const unsigned char b)
414
{
413
{
415
#if 0
414
#if 0
416
    char buffer[sizeof(int)*8+1];
415
    char buffer[sizeof(int)*8+1];
417
   
416
   
418
    uart_puts( itoa(b, buffer, 2) );
417
    uart_puts( itoa(b, buffer, 2) );
419
#else
418
#else
420
    signed char i;
419
    signed char i;
421
    for (i=7;i>=0;i--) {
420
    for (i=7;i>=0;i--) {
422
        if (b & (1<<i)) {
421
        if (b & (1<<i)) {
423
            uart_putc('1');
422
            uart_putc('1');
424
        }
423
        }
425
        else {
424
        else {
426
            uart_putc('0');
425
            uart_putc('0');
427
        }
426
        }
428
    }
427
    }
429
#endif
428
#endif
430
} /* uart_putbin_byte */
429
} /* uart_putbin_byte */
431
 
430