Statistics
| Branch: | Revision:

root / scout_avr / src / Atmega128rfa1.cpp @ f115416e

History | View | Annotate | Download (1.81 KB)

1
#include "Atmega128rfa1.h"
2

    
3
extern "C"
4
{
5
#include <avr/io.h>
6
#include <avr/interrupt.h>
7
  void __cxa_pure_virtual(void) {}
8
}
9

    
10
unsigned long millis;
11

    
12
int rx_start = 0, rx_end = 0;
13
char rx_buffer[RX_BUFFER_SIZE];
14

    
15
Atmega128rfa1::Atmega128rfa1()
16
{
17
}
18

    
19
ISR(TIMER0_COMPA_vect)
20
{
21
  millis++;
22
}
23

    
24
ISR(USART0_RX_vect)
25
{
26
  char data = UDR0;
27
  if (rx_end == rx_start-1 || (rx_start == 0 && rx_end == RX_BUFFER_SIZE-1))
28
  {
29
    // TODO warn of buffer overflow?
30
  }
31
  else
32
  {
33
    rx_buffer[rx_end] = data;
34
    rx_end++;
35
    if (rx_end == RX_BUFFER_SIZE)
36
      rx_end = 0;
37
  }
38
}
39

    
40
void Atmega128rfa1::init()
41
{
42
  // === init serial ===
43
  // baud = F_CPU / (16 (UBRR + 1))
44
  uint16_t ubrr = F_CPU / 16 / BAUD_RATE - 1;
45
  UBRR0H = ubrr >> 8;
46
  UBRR0L = ubrr;
47
  // UMSEL0 = 0, asynchronous usart
48
  // UPM0 = 0, parity check disabled
49
  // USBS0 = 0, 1 stop bit
50
  // UCSZ0 = 3, 8-bit
51
  UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0);
52
  UCSR0C = _BV(UCSZ01) | _BV(UCSZ00);
53

    
54
  // === init time ===
55
  // COM0x = 0, pin OC0x not used
56
  // WGM0 = 2, clear timer on compare match, TOP = OCRA
57
  // CS0 = 3, 64 prescaler
58
  TCCR0A = _BV(WGM01);
59
  TCCR0B = _BV(CS01) | _BV(CS00);
60
  // enable interrupt on compare match A
61
  TIMSK0 = _BV(OCIE0A);
62
  // 1 ms with 1/64 prescaler
63
  OCR0A = F_CPU / 1000 / 64;
64
  millis = 0;
65

    
66
  sei();
67
}
68

    
69
int Atmega128rfa1::read()
70
{
71
  cli();
72
  if (rx_start == rx_end)
73
    return -1;
74
  else
75
  {
76
    int ret = rx_buffer[rx_start];
77
    rx_start++;
78
    if (rx_start == RX_BUFFER_SIZE)
79
      rx_start = 0;
80
    return ret;
81
  }
82
  sei();
83
}
84

    
85
void Atmega128rfa1::write(uint8_t* data, int length)
86
{
87
  // TODO make this non-blocking with a tx buffer
88
  int i;
89
  for (i = 0; i < length; i++)
90
  {
91
    while (!(UCSR0A & _BV(UDRE0)));
92
    UDR0 = data[i];
93
  }
94
}
95

    
96
unsigned long Atmega128rfa1::time()
97
{
98
  unsigned long ret;
99
  cli();
100
  ret = millis;
101
  sei();
102
  return ret;
103
}