Subversion Repositories svnkaklik

Rev

Details | Last modification | View Log

Rev Author Line No. Line
507 kaklik 1
/*------------------------------------------------*/
2
/* UART functions                                 */
3
 
4
 
5
#include <avr/io.h>
6
#include <avr/interrupt.h>
7
#include "uart.h"
8
 
9
#define	SYSCLK		9216000
10
#define	BAUD		115200
11
 
12
 
13
typedef struct _fifo {
14
	uint8_t	idx_w;
15
	uint8_t	idx_r;
16
	uint8_t	count;
17
	uint8_t buff[64];
18
} FIFO;
19
 
20
 
21
static volatile
22
FIFO txfifo, rxfifo;
23
 
24
 
25
 
26
/* Initialize UART */
27
 
28
void uart_init()
29
{
30
	rxfifo.idx_r = 0;
31
	rxfifo.idx_w = 0;
32
	rxfifo.count = 0;
33
	txfifo.idx_r = 0;
34
	txfifo.idx_w = 0;
35
	txfifo.count = 0;
36
 
37
	UBRR0L = SYSCLK/BAUD/16-1;
38
	UCSR0B = _BV(RXEN0)|_BV(RXCIE0)|_BV(TXEN0);
39
}
40
 
41
 
42
/* Get a received character */
43
 
44
uint8_t uart_test ()
45
{
46
	return rxfifo.count;
47
}
48
 
49
 
50
uint8_t uart_get ()
51
{
52
	uint8_t d, i;
53
 
54
 
55
	i = rxfifo.idx_r;
56
	while(rxfifo.count == 0);
57
	d = rxfifo.buff[i++];
58
	cli();
59
	rxfifo.count--;
60
	sei();
61
	if(i >= sizeof(rxfifo.buff))
62
		i = 0;
63
	rxfifo.idx_r = i;
64
 
65
	return d;
66
}
67
 
68
 
69
/* Put a character to transmit */
70
 
71
void uart_put (uint8_t d)
72
{
73
	uint8_t i;
74
 
75
 
76
	i = txfifo.idx_w;
77
	while(txfifo.count >= sizeof(txfifo.buff));
78
	txfifo.buff[i++] = d;
79
	cli();
80
	txfifo.count++;
81
	UCSR0B = _BV(RXEN0)|_BV(RXCIE0)|_BV(TXEN0)|_BV(UDRIE0);
82
	sei();
83
	if(i >= sizeof(txfifo.buff))
84
		i = 0;
85
	txfifo.idx_w = i;
86
}
87
 
88
 
89
/* UART RXC interrupt */
90
 
91
SIGNAL(SIG_UART0_RECV)
92
{
93
	uint8_t d, n, i;
94
 
95
 
96
	d = UDR0;
97
	n = rxfifo.count;
98
	if(n < sizeof(rxfifo.buff)) {
99
		rxfifo.count = ++n;
100
		i = rxfifo.idx_w;
101
		rxfifo.buff[i++] = d;
102
		if(i >= sizeof(rxfifo.buff))
103
			i = 0;
104
		rxfifo.idx_w = i;
105
	}
106
}
107
 
108
 
109
/* UART UDRE interrupt */
110
 
111
SIGNAL(SIG_UART0_DATA)
112
{
113
	uint8_t n, i;
114
 
115
 
116
	n = txfifo.count;
117
	if(n) {
118
		txfifo.count = --n;
119
		i = txfifo.idx_r;
120
		UDR0 = txfifo.buff[i++];
121
		if(i >= sizeof(txfifo.buff))
122
			i = 0;
123
		txfifo.idx_r = i;
124
	}
125
	if(n == 0)
126
		UCSR0B = _BV(RXEN0)|_BV(RXCIE0)|_BV(TXEN0);
127
}
128