Statistics
| Branch: | Revision:

root / scout_avr / src / Atmega128rfa1.cpp @ aadf0a75

History | View | Annotate | Download (2.25 KB)

1 88fb3a79 Tom Mullins
#include "Atmega128rfa1.h"
2 812788aa Tom Mullins
#include "bom.h"
3 88fb3a79 Tom Mullins
4
extern "C"
5
{
6
#include <avr/io.h>
7
#include <avr/interrupt.h>
8 49090532 Tom Mullins
  void __cxa_pure_virtual(void) {}
9 88fb3a79 Tom Mullins
}
10
11 812788aa Tom Mullins
#define T0_KHZ 76
12
#define T0_OCR (F_CPU / 1000 / T0_KHZ) // 210 ticks
13
#define T0_ERROR (F_CPU / 1000 - T0_OCR*T0_KHZ) // 40 ticks/ms
14
15
unsigned char t0_count, t0_error;
16 88fb3a79 Tom Mullins
unsigned long millis;
17
18 aadf0a75 Tom Mullins
int rx_start, rx_end;
19 20f94878 Tom Mullins
char rx_buffer[RX_BUFFER_SIZE];
20
21 88fb3a79 Tom Mullins
Atmega128rfa1::Atmega128rfa1()
22
{
23
}
24
25
ISR(TIMER0_COMPA_vect)
26
{
27 812788aa Tom Mullins
  bom_isr();
28
29
  // F_CPU = T0_OCR * T0_KHZ + T0_ERROR
30
  // every millisecond, accumulate T0_ERROR, and when it reaches T0_OCR skip
31
  // one iteration
32
  t0_count++;
33
  if (t0_count >= T0_KHZ) {
34
    t0_error += T0_ERROR;
35
    if (t0_error < T0_OCR) {
36
      t0_count = 0;
37
    } else {
38
      t0_count = -1;
39
      t0_error -= T0_OCR;
40
    }
41
    millis++;
42
  }
43 88fb3a79 Tom Mullins
}
44
45 807483bf Tom Mullins
ISR(USART0_RX_vect)
46 20f94878 Tom Mullins
{
47
  char data = UDR0;
48 aadf0a75 Tom Mullins
  int new_end = rx_end+1;
49
  if (new_end == RX_BUFFER_SIZE) {
50
    new_end = 0;
51
  }
52
  if (new_end == rx_start)
53 20f94878 Tom Mullins
  {
54
    // TODO warn of buffer overflow?
55
  }
56
  else
57
  {
58
    rx_buffer[rx_end] = data;
59 aadf0a75 Tom Mullins
    rx_end = new_end;
60 20f94878 Tom Mullins
  }
61
}
62
63 88fb3a79 Tom Mullins
void Atmega128rfa1::init()
64
{
65
  // === init serial ===
66 49090532 Tom Mullins
  // baud = F_CPU / (16 (UBRR + 1))
67 1c3c96ce Tom Mullins
  uint16_t ubrr = F_CPU / 16 / BAUD_RATE - 1;
68 49090532 Tom Mullins
  UBRR0H = ubrr >> 8;
69
  UBRR0L = ubrr;
70 88fb3a79 Tom Mullins
  // UMSEL0 = 0, asynchronous usart
71
  // UPM0 = 0, parity check disabled
72
  // USBS0 = 0, 1 stop bit
73
  // UCSZ0 = 3, 8-bit
74 20f94878 Tom Mullins
  UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0);
75 88fb3a79 Tom Mullins
  UCSR0C = _BV(UCSZ01) | _BV(UCSZ00);
76
77
  // === init time ===
78
  // COM0x = 0, pin OC0x not used
79
  // WGM0 = 2, clear timer on compare match, TOP = OCRA
80 812788aa Tom Mullins
  // CS0 = 1, no prescaler
81 88fb3a79 Tom Mullins
  TCCR0A = _BV(WGM01);
82 812788aa Tom Mullins
  TCCR0B = _BV(CS00);
83 88fb3a79 Tom Mullins
  // enable interrupt on compare match A
84
  TIMSK0 = _BV(OCIE0A);
85 812788aa Tom Mullins
  OCR0A = T0_OCR;
86 88fb3a79 Tom Mullins
  millis = 0;
87 20f94878 Tom Mullins
88
  sei();
89 88fb3a79 Tom Mullins
}
90
91
int Atmega128rfa1::read()
92
{
93 aadf0a75 Tom Mullins
  int ret;
94 cf115e3d Tom Mullins
  cli();
95 20f94878 Tom Mullins
  if (rx_start == rx_end)
96 aadf0a75 Tom Mullins
    ret = -1;
97 20f94878 Tom Mullins
  else
98
  {
99 aadf0a75 Tom Mullins
    ret = rx_buffer[rx_start];
100 20f94878 Tom Mullins
    rx_start++;
101
    if (rx_start == RX_BUFFER_SIZE)
102
      rx_start = 0;
103
  }
104 cf115e3d Tom Mullins
  sei();
105 aadf0a75 Tom Mullins
  return ret;
106 88fb3a79 Tom Mullins
}
107
108
void Atmega128rfa1::write(uint8_t* data, int length)
109
{
110
  // TODO make this non-blocking with a tx buffer
111
  int i;
112
  for (i = 0; i < length; i++)
113
  {
114
    while (!(UCSR0A & _BV(UDRE0)));
115
    UDR0 = data[i];
116
  }
117
}
118
119
unsigned long Atmega128rfa1::time()
120
{
121
  unsigned long ret;
122
  cli();
123
  ret = millis;
124
  sei();
125
  return ret;
126
}