root / toolbox / serial.c @ 975af07c
History | View | Annotate | Download (1.45 KB)
1 | 6ca98a3f | Tom Mullins | #include <stdint.h> |
---|---|---|---|
2 | 20e5429c | Tom Mullins | #include <avr/io.h> |
3 | #include <avr/interrupt.h> |
||
4 | 6ca98a3f | Tom Mullins | #include "serial.h" |
5 | 20e5429c | Tom Mullins | |
6 | static int rx_start = 0, rx_end = 0; |
||
7 | 6ca98a3f | Tom Mullins | static uint8_t rx_buffer[RX_BUFFER_SIZE];
|
8 | 20e5429c | Tom Mullins | |
9 | ISR(USART1_RX_vect) { |
||
10 | 6ca98a3f | Tom Mullins | uint8_t data = UDR1; |
11 | 20e5429c | Tom Mullins | int new_end = rx_end+1; |
12 | if (new_end == RX_BUFFER_SIZE) {
|
||
13 | new_end = 0;
|
||
14 | } |
||
15 | if (new_end == rx_start) {
|
||
16 | // TODO warn of buffer overflow?
|
||
17 | } else {
|
||
18 | rx_buffer[rx_end] = data; |
||
19 | rx_end = new_end; |
||
20 | } |
||
21 | } |
||
22 | |||
23 | void serial_init() {
|
||
24 | 89915eeb | Tom Mullins | // baud = F_CPU / (div (UBRR + 1))
|
25 | // where div = 16 if U2X = 0, or 8 otherwise
|
||
26 | 20e5429c | Tom Mullins | uint16_t ubrr = F_CPU / 8 / BAUD_RATE - 1; |
27 | UBRR1H = ubrr >> 8;
|
||
28 | UBRR1L = ubrr; |
||
29 | // UMSEL = 0, asynchronous usart
|
||
30 | // UPM = 0, parity check disabled
|
||
31 | // USBS = 0, 1 stop bit
|
||
32 | // UCSZ = 3, 8-bit
|
||
33 | // U2X = 1, use 8 prescale instead of 16 for a more accurate baud rate
|
||
34 | a7a56246 | Tom Mullins | UCSR1A = _BV(U2X1); |
35 | UCSR1B = _BV(RXCIE1) | _BV(RXEN1) | _BV(TXEN1); |
||
36 | 20e5429c | Tom Mullins | UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); |
37 | } |
||
38 | |||
39 | int serial_read() {
|
||
40 | int ret;
|
||
41 | cli(); |
||
42 | if (rx_start == rx_end) {
|
||
43 | ret = -1;
|
||
44 | } else {
|
||
45 | ret = rx_buffer[rx_start]; |
||
46 | rx_start++; |
||
47 | 6ca98a3f | Tom Mullins | if (rx_start == RX_BUFFER_SIZE) {
|
48 | 20e5429c | Tom Mullins | rx_start = 0;
|
49 | 6ca98a3f | Tom Mullins | } |
50 | 20e5429c | Tom Mullins | } |
51 | sei(); |
||
52 | return ret;
|
||
53 | } |
||
54 | |||
55 | 89915eeb | Tom Mullins | void serial_flush() {
|
56 | cli(); |
||
57 | rx_start = 0;
|
||
58 | rx_end = 0;
|
||
59 | sei(); |
||
60 | } |
||
61 | |||
62 | 6ca98a3f | Tom Mullins | uint8_t serial_read_blocking() { |
63 | 20e5429c | Tom Mullins | int c;
|
64 | do {
|
||
65 | c = serial_read(); |
||
66 | } while (c < 0); |
||
67 | return c;
|
||
68 | } |
||
69 | |||
70 | 6ca98a3f | Tom Mullins | void serial_write(uint8_t* data, int length) { |
71 | 20e5429c | Tom Mullins | int i;
|
72 | for (i = 0; i < length; i++) { |
||
73 | while (!(UCSR1A & _BV(UDRE1)));
|
||
74 | UDR1 = data[i]; |
||
75 | } |
||
76 | } |