Subversion Repositories svnkaklik

Rev

Rev 510 | Details | Compare with Previous | Last modification | View Log

Rev Author Line No. Line
510 kaklik 1
/*! \file uart2.c \brief Dual UART driver with buffer support. */
2
//*****************************************************************************
3
//
4
// File Name	: 'uart2.c'
5
// Title		: Dual UART driver with buffer support
6
// Author		: Pascal Stang - Copyright (C) 2000-2004
7
// Created		: 11/20/2000
8
// Revised		: 07/04/2004
9
// Version		: 1.0
10
// Target MCU	: ATMEL AVR Series
11
// Editor Tabs	: 4
12
//
13
// Description	: This is a UART driver for AVR-series processors with two
14
//		hardware UARTs such as the mega161 and mega128 
15
//
16
// This code is distributed under the GNU Public License
17
//		which can be found at http://www.gnu.org/licenses/gpl.txt
18
//
19
//*****************************************************************************
20
 
21
#include <avr/io.h>
22
#include <avr/interrupt.h>
23
 
24
#include "buffer.h"
25
#include "uart2.h"
26
 
27
// UART global variables
28
// flag variables
29
volatile u08   uartReadyTx[2];
30
volatile u08   uartBufferedTx[2];
31
// receive and transmit buffers
32
cBuffer uartRxBuffer[2];
33
cBuffer uartTxBuffer[2];
34
unsigned short uartRxOverflow[2];
35
#ifndef UART_BUFFER_EXTERNAL_RAM
36
	// using internal ram,
37
	// automatically allocate space in ram for each buffer
38
	static char uart0RxData[UART0_RX_BUFFER_SIZE];
39
	static char uart0TxData[UART0_TX_BUFFER_SIZE];
40
	static char uart1RxData[UART1_RX_BUFFER_SIZE];
41
	static char uart1TxData[UART1_TX_BUFFER_SIZE];
42
#endif
43
 
44
typedef void (*voidFuncPtru08)(unsigned char);
45
volatile static voidFuncPtru08 UartRxFunc[2];
46
 
47
void uartInit(void)
48
{
49
	// initialize both uarts
50
	uart0Init();
51
	uart1Init();
52
}
53
 
54
void uart0Init(void)
55
{
56
	// initialize the buffers
57
	uart0InitBuffers();
58
	// initialize user receive handlers
59
	UartRxFunc[0] = 0;
60
	// enable RxD/TxD and interrupts
61
	outb(UCSR0B, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN));
62
	// set default baud rate
63
	uartSetBaudRate(0, UART0_DEFAULT_BAUD_RATE); 
64
	// initialize states
65
	uartReadyTx[0] = TRUE;
66
	uartBufferedTx[0] = FALSE;
67
	// clear overflow count
68
	uartRxOverflow[0] = 0;
69
	// enable interrupts
70
	sei();
71
}
72
 
73
void uart1Init(void)
74
{
75
	// initialize the buffers
76
	uart1InitBuffers();
77
	// initialize user receive handlers
78
	UartRxFunc[1] = 0;
79
	// enable RxD/TxD and interrupts
80
	outb(UCSR1B, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN));
81
	// set default baud rate
82
	uartSetBaudRate(1, UART1_DEFAULT_BAUD_RATE);
83
	// initialize states
84
	uartReadyTx[1] = TRUE;
85
	uartBufferedTx[1] = FALSE;
86
	// clear overflow count
87
	uartRxOverflow[1] = 0;
88
	// enable interrupts
89
	sei();
90
}
91
 
92
void uart0InitBuffers(void)
93
{
94
	#ifndef UART_BUFFER_EXTERNAL_RAM
95
		// initialize the UART0 buffers
96
		bufferInit(&uartRxBuffer[0], uart0RxData, UART0_RX_BUFFER_SIZE);
97
		bufferInit(&uartTxBuffer[0], uart0TxData, UART0_TX_BUFFER_SIZE);
98
	#else
99
		// initialize the UART0 buffers
100
		bufferInit(&uartRxBuffer[0], (u08*) UART0_RX_BUFFER_ADDR, UART0_RX_BUFFER_SIZE);
101
		bufferInit(&uartTxBuffer[0], (u08*) UART0_TX_BUFFER_ADDR, UART0_TX_BUFFER_SIZE);
102
	#endif
103
}
104
 
105
void uart1InitBuffers(void)
106
{
107
	#ifndef UART_BUFFER_EXTERNAL_RAM
108
		// initialize the UART1 buffers
109
		bufferInit(&uartRxBuffer[1], uart1RxData, UART1_RX_BUFFER_SIZE);
110
		bufferInit(&uartTxBuffer[1], uart1TxData, UART1_TX_BUFFER_SIZE);
111
	#else
112
		// initialize the UART1 buffers
113
		bufferInit(&uartRxBuffer[1], (u08*) UART1_RX_BUFFER_ADDR, UART1_RX_BUFFER_SIZE);
114
		bufferInit(&uartTxBuffer[1], (u08*) UART1_TX_BUFFER_ADDR, UART1_TX_BUFFER_SIZE);
115
	#endif
116
}
117
 
118
void uartSetRxHandler(u08 nUart, void (*rx_func)(unsigned char c))
119
{
120
	// make sure the uart number is within bounds
121
	if(nUart < 2)
122
	{
123
		// set the receive interrupt to run the supplied user function
124
		UartRxFunc[nUart] = rx_func;
125
	}
126
}
127
 
128
void uartSetBaudRate(u08 nUart, u32 baudrate)
129
{
130
	// calculate division factor for requested baud rate, and set it
131
	u16 bauddiv = ((F_CPU+(baudrate*8L))/(baudrate*16L)-1);
132
	if(nUart)
133
	{
134
		outb(UBRR1L, bauddiv);
135
		#ifdef UBRR1H
136
		outb(UBRR1H, bauddiv>>8);
137
		#endif
138
	}
139
	else
140
	{
141
		outb(UBRR0L, bauddiv);
142
		#ifdef UBRR0H
143
		outb(UBRR0H, bauddiv>>8);
144
		#endif
145
	}
146
}
147
 
148
cBuffer* uartGetRxBuffer(u08 nUart)
149
{
150
	// return rx buffer pointer
151
	return &uartRxBuffer[nUart];
152
}
153
 
154
cBuffer* uartGetTxBuffer(u08 nUart)
155
{
156
	// return tx buffer pointer
157
	return &uartTxBuffer[nUart];
158
}
159
 
160
void uartSendByte(u08 nUart, u08 txData)
161
{
162
	// wait for the transmitter to be ready
163
//	while(!uartReadyTx[nUart]);
164
	// send byte
165
	if(nUart)
166
	{
167
		while(!(UCSR1A & (1<<UDRE)));
168
		outb(UDR1, txData);
169
	}
170
	else
171
	{
172
		while(!(UCSR0A & (1<<UDRE)));
173
		outb(UDR0, txData);
174
	}
175
	// set ready state to FALSE
176
	uartReadyTx[nUart] = FALSE;
177
}
178
 
179
void uart0SendByte(u08 data)
180
{
181
	// send byte on UART0
182
	uartSendByte(0, data);
183
}
184
 
185
void uart1SendByte(u08 data)
186
{
187
	// send byte on UART1
188
	uartSendByte(1, data);
189
}
190
 
191
int uart0GetByte(void)
192
{
193
	// get single byte from receive buffer (if available)
194
	u08 c;
195
	if(uartReceiveByte(0,&c))
196
		return c;
197
	else
198
		return -1;
199
}
200
 
201
int uart1GetByte(void)
202
{
203
	// get single byte from receive buffer (if available)
204
	u08 c;
205
	if(uartReceiveByte(1,&c))
206
		return c;
207
	else
208
		return -1;
209
}
210
 
211
 
212
u08 uartReceiveByte(u08 nUart, u08* rxData)
213
{
214
	// make sure we have a receive buffer
215
	if(uartRxBuffer[nUart].size)
216
	{
217
		// make sure we have data
218
		if(uartRxBuffer[nUart].datalength)
219
		{
220
			// get byte from beginning of buffer
221
			*rxData = bufferGetFromFront(&uartRxBuffer[nUart]);
222
			return TRUE;
223
		}
224
		else
225
			return FALSE;			// no data
226
	}
227
	else
228
		return FALSE;				// no buffer
229
}
230
 
231
void uartFlushReceiveBuffer(u08 nUart)
232
{
233
	// flush all data from receive buffer
234
	bufferFlush(&uartRxBuffer[nUart]);
235
}
236
 
237
u08 uartReceiveBufferIsEmpty(u08 nUart)
238
{
239
	return (uartRxBuffer[nUart].datalength == 0);
240
}
241
 
242
void uartAddToTxBuffer(u08 nUart, u08 data)
243
{
244
	// add data byte to the end of the tx buffer
245
	bufferAddToEnd(&uartTxBuffer[nUart], data);
246
}
247
 
248
void uart0AddToTxBuffer(u08 data)
249
{
250
	uartAddToTxBuffer(0,data);
251
}
252
 
253
void uart1AddToTxBuffer(u08 data)
254
{
255
	uartAddToTxBuffer(1,data);
256
}
257
 
258
void uartSendTxBuffer(u08 nUart)
259
{
260
	// turn on buffered transmit
261
	uartBufferedTx[nUart] = TRUE;
262
	// send the first byte to get things going by interrupts
263
	uartSendByte(nUart, bufferGetFromFront(&uartTxBuffer[nUart]));
264
}
265
 
266
u08 uartSendBuffer(u08 nUart, char *buffer, u16 nBytes)
267
{
268
	register u08 first;
269
	register u16 i;
270
 
271
	// check if there's space (and that we have any bytes to send at all)
272
	if((uartTxBuffer[nUart].datalength + nBytes < uartTxBuffer[nUart].size) && nBytes)
273
	{
274
		// grab first character
275
		first = *buffer++;
276
		// copy user buffer to uart transmit buffer
277
		for(i = 0; i < nBytes-1; i++)
278
		{
279
			// put data bytes at end of buffer
280
			bufferAddToEnd(&uartTxBuffer[nUart], *buffer++);
281
		}
282
 
283
		// send the first byte to get things going by interrupts
284
		uartBufferedTx[nUart] = TRUE;
285
		uartSendByte(nUart, first);
286
		// return success
287
		return TRUE;
288
	}
289
	else
290
	{
291
		// return failure
292
		return FALSE;
293
	}
294
}
295
 
296
// UART Transmit Complete Interrupt Function
297
void uartTransmitService(u08 nUart)
298
{
299
	// check if buffered tx is enabled
300
	if(uartBufferedTx[nUart])
301
	{
302
		// check if there's data left in the buffer
303
		if(uartTxBuffer[nUart].datalength)
304
		{
305
			// send byte from top of buffer
306
			if(nUart)
307
				outb(UDR1,  bufferGetFromFront(&uartTxBuffer[1]) );
308
			else
309
				outb(UDR0,  bufferGetFromFront(&uartTxBuffer[0]) );
310
		}
311
		else
312
		{
313
			// no data left
314
			uartBufferedTx[nUart] = FALSE;
315
			// return to ready state
316
			uartReadyTx[nUart] = TRUE;
317
		}
318
	}
319
	else
320
	{
321
		// we're using single-byte tx mode
322
		// indicate transmit complete, back to ready
323
		uartReadyTx[nUart] = TRUE;
324
	}
325
}
326
 
327
// UART Receive Complete Interrupt Function
328
void uartReceiveService(u08 nUart)
329
{
330
	u08 c;
331
	// get received char
332
	if(nUart)
333
		c = inb(UDR1);
334
	else
335
		c = inb(UDR0);
336
 
337
	// if there's a user function to handle this receive event
338
	if(UartRxFunc[nUart])
339
	{
340
		// call it and pass the received data
341
		UartRxFunc[nUart](c);
342
	}
343
	else
344
	{
345
		// otherwise do default processing
346
		// put received char in buffer
347
		// check if there's space
348
		if( !bufferAddToEnd(&uartRxBuffer[nUart], c) )
349
		{
350
			// no space in buffer
351
			// count overflow
352
			uartRxOverflow[nUart]++;
353
		}
354
	}
355
}
356
 
357
UART_INTERRUPT_HANDLER(SIG_UART0_TRANS)      
358
{
359
	// service UART0 transmit interrupt
360
	uartTransmitService(0);
361
}
362
 
363
UART_INTERRUPT_HANDLER(SIG_UART1_TRANS)      
364
{
365
	// service UART1 transmit interrupt
366
	uartTransmitService(1);
367
}
368
 
369
UART_INTERRUPT_HANDLER(SIG_UART0_RECV)      
370
{
371
	// service UART0 receive interrupt
372
	uartReceiveService(0);
373
}
374
 
375
UART_INTERRUPT_HANDLER(SIG_UART1_RECV)      
376
{
377
	// service UART1 receive interrupt
378
	uartReceiveService(1);
379
}