1// Literatur: AVR uController Manuals
2
3
4/******************************************************
5 * hal.h *
6 ******************************************************/
7 #ifndef HAL_H
8 #define HAL_H
9
10 // UART baudrates
11 typedef enum UART_BR_e
12 {
13 BR_4800,
14 BR_9600,
15 BR_19200,
16 BR_38400,
17 BR_57600,
18 BR_115200,
19 } UART_BR_t;
20
21 // UART receiver callback
22 typedef void (*UARTCALLBACK) (unsigned char data);
23
24 // UART signals
25 #define UART_PORT PORTE
26 #define UART_DDR DDRE
27 #define UART_RXD_PIN 0
28 #define UART_TXD_PIN 1
29
30 #define TX_BUFFER_SIZE 512
31 #define UART_TX_BUFFER_MASK (TX_BUFFER_SIZE - 1)
32
33 #endif
34
35
36/******************************************************
37 * uart.h *
38 ******************************************************/
39 #ifndef UART_H
40 #define UART_H
41
42 #include <avr/pgmspace.h>
43 #include "hal.h"
44
45 void uart_init(tUART_BR Baudrate);
46 void uart_putHex(unsigned char);
47 void uart_putByte(unsigned char);
48 void uart_putInt(unsigned int);
49 void uart_putLong(unsigned long);
50 void uart_putStr(unsigned char *);
51 void uart_putData(unsigned char *, unsigned char);
52 void uart_putStrf(PGM_P);
53 void uart_putChar(unsigned char);
54 BOOL uart_dataAvailable(void);
55
56 void uart_registerCallback(UARTCALLBACK CallBack);
57
58 #endif
59
60
61/******************************************************
62 * uart.c *
63 ******************************************************/
64 #include <avr/io.h>
65 #include <avr/interrupt.h>
66 #include <stdio.h>
67 #include <string.h>
68 #include "uart.h"
69
70 // global variables
71 static volatile unsigned char uart_TxBuf[TX_BUFFER_SIZE];
72 static volatile unsigned char uart_TxHead = 0;
73 static volatile unsigned char uart_TxTail = 0;
74
75 static volatile UARTCALLBACK UartRecCallback = NULL;
76
77 void UART0_RegisterCallback(UARTCALLBACK CallBack)
78 {
79 UartRecCallback = CallBack;
80 }
81
82 void uart_init(UART_BR_t Baudrate)
83 {
84 unsigned int UBRRVAL = 0;
85
86 switch (Baudrate)
87 {
88 case BR_4800:
89 UBRRVAL = (F_CPU/(4800L*16L)-1);
90 break;
91 case BR_9600:
92 UBRRVAL = (F_CPU/(9600L*16L)-1);
93 break;
94 case BR_19200:
95 UBRRVAL = (F_CPU/(19200L*16L)-1);
96 break;
97 case BR_38400:
98 UBRRVAL = (F_CPU/(38400L*16L)-1);
99 break;
100 case BR_57600:
101 UBRRVAL = (F_CPU/(57600L*16L)-1);
102 break;
103 case BR_115200:
104 UBRRVAL = (F_CPU/(115200L*16L)-1);
105 break;
106 default:
107 UBRRVAL = (F_CPU/(9600L*16L)-1);
108 break;
109 }
110
111 UBRR0H = (unsigned char)(UBRRVAL>>8);
112 UBRR0L = (unsigned char)UBRRVAL;
113
114 // enable receiver and transmitter
115 UCSR0B = (1<<TXEN0)|(1<<RXEN0)|(1<<RXCIE0);
116 // set frame format: 8data, 1stop bit
117 UCSR0C = (3<<UCSZ00);
118
119 UART0_TxHead = 0;
120 UART0_TxTail = 0;
121 }
122
123 // send hex character via serial
124 void uart_putHex(unsigned char data)
125 {
126 unsigned char buf[5];
127 sprintf((char *)buf, "%02x", data);
128 uart_putStr(buf);
129 }
130
131 // send a byte
132 void uart_putByte(unsigned char data)
133 {
134 unsigned char buf[5];
135 sprintf((char *)buf, "%02u", data);
136 uart_putStr(buf);
137 }
138
139 // send an integer
140 void uart_putInt(unsigned int data)
141 {
142 unsigned char buf[6];
143 sprintf((char *)buf, "%5u", data);
144 uart_putStr(buf);
145 }
146
147 // send a long value
148 void uart_putLong(unsigned long Value)
149 {
150 unsigned char Cnt;
151 unsigned char Buf[20];
152
153 // convert
154 Cnt = 10;
155 do
156 {
157 Cnt--;
158 Buf[Cnt] = Value % 10;
159 Value /= 10;
160 } while (Value > 0);
161
162 // output
163 while (Cnt < 10)
164 {
165 uart_putChar(Buf[Cnt] + '0');
166 Cnt++;
167 }
168 }
169
170 // send a string
171 void uart_putStr(unsigned char * pdata)
172 {
173 while (*pdata)
174 {
175 uart_putChar(*pdata++);
176 }
177 }
178
179 // send a string
180 void uart_putData(unsigned char * pdata, unsigned char Len)
181 {
182 while (Len--)
183 {
184 uart_putChar(*pdata++);
185 }
186 }
187
188 // send a string from flash-memory
189 void uart_putStrf(PGM_P pdata)
190 {
191 // while not 0 continue
192 while (pgm_read_byte(pdata))
193 {
194 uart_putChar(pgm_read_byte(pdata++));
195 }
196 }
197
198 // send a character via serial using a ringbuffer
199 void uart_putChar(unsigned char data)
200 {
201 unsigned char tmphead;
202
203 tmphead = (uart_TxHead + 1) & UART_TX_BUFFER_MASK;
204
205 uart_TxBuf[tmphead] = data;
206 uart_TxHead = tmphead;
207
208 // enable UDRE signal
209 UCSR0B |= (1<<UDRIE0);
210 }
211
212
213 // serial UART data register empty signal vector
214 SIGNAL (SIG_USART0_DATA)
215 {
216 unsigned char tmptail;
217
218 if (uart_TxHead != UART0_TxTail)
219 {
220 // calculate and store new buffer index
221 tmptail = (uart_TxTail + 1) & UART_TX_BUFFER_MASK;
222 uart_TxTail = tmptail;
223
224 // get one byte from buffer and write it to UART
225 UDR0 = uart_TxBuf[tmptail];
226 }
227 else
228 {
229 // tx buffer empty, disable UDRE signal
230 UCSR0B &= ~(1<<UDRIE0);
231 }
232 }
233
234 // serial UART receive complete signal vector
235 SIGNAL (SIG_USART0_RECV)
236 {
237 if (UartRecCallback != NULL)
238 {
239 UartRecCallback(UDR0);
240 }
241 }