Statistics
| Branch: | Revision:

root / toolbox / serial.c @ a7a56246

History | View | Annotate | Download (1.29 KB)

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

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

    
8
ISR(USART1_RX_vect) {
9
  char data = UDR1;
10
  int new_end = rx_end+1;
11
  if (new_end == RX_BUFFER_SIZE) {
12
    new_end = 0;
13
  }
14
  if (new_end == rx_start) {
15
    // TODO warn of buffer overflow?
16
  } else {
17
    rx_buffer[rx_end] = data;
18
    rx_end = new_end;
19
  }
20
}
21

    
22
void serial_init() {
23
  // baud = F_CPU / (8 (UBRR + 1))
24
  uint16_t ubrr = F_CPU / 8 / BAUD_RATE - 1;
25
  UBRR1H = ubrr >> 8;
26
  UBRR1L = ubrr;
27
  // UMSEL = 0, asynchronous usart
28
  // UPM = 0, parity check disabled
29
  // USBS = 0, 1 stop bit
30
  // UCSZ = 3, 8-bit
31
  // U2X = 1, use 8 prescale instead of 16 for a more accurate baud rate
32
  UCSR1A = _BV(U2X1);
33
  UCSR1B = _BV(RXCIE1) | _BV(RXEN1) | _BV(TXEN1);
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
}