Statistics
| Branch: | Revision:

root / serial.c @ 20e5429c

History | View | Annotate | Download (1.31 KB)

1
#include "serial.h"
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <util/atomic.h>
5

    
6
static int rx_start = 0, rx_end = 0;
7
static char rx_buffer[RX_BUFFER_SIZE];
8

    
9
ISR(USART1_RX_vect) {
10
  char data = UDR1;
11
  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
  // baud = F_CPU / (8 (UBRR + 1))
25
  uint16_t ubrr = F_CPU / 8 / BAUD_RATE - 1;
26
  UBRR1H = ubrr >> 8;
27
  UBRR1L = ubrr;
28
  // UMSEL = 0, asynchronous usart
29
  // UPM = 0, parity check disabled
30
  // USBS = 0, 1 stop bit
31
  // UCSZ = 3, 8-bit
32
  // U2X = 1, use 8 prescale instead of 16 for a more accurate baud rate
33
  UCSR1B = _BV(RXCIE1) | _BV(RXEN1) | _BV(TXEN1) | _BV(U2X1);
34
  UCSR1C = _BV(UCSZ11) | _BV(UCSZ10);
35
}
36

    
37
int serial_read() {
38
  int ret;
39
  cli();
40
  if (rx_start == rx_end) {
41
    ret = -1;
42
  } else {
43
    ret = rx_buffer[rx_start];
44
    rx_start++;
45
    if (rx_start == RX_BUFFER_SIZE)
46
      rx_start = 0;
47
  }
48
  sei();
49
  return ret;
50
}
51

    
52
char serial_read_blocking() {
53
  int c;
54
  do {
55
    c = serial_read();
56
  } while (c < 0);
57
  return c;
58
}
59

    
60
void serial_write(char* data, int length) {
61
  int i;
62
  for (i = 0; i < length; i++) {
63
    while (!(UCSR1A & _BV(UDRE1)));
64
    UDR1 = data[i];
65
  }
66
}