Project

General

Profile

Statistics
| Branch: | Revision:

root / scout_avr / src / Atmega128rfa1.cpp @ cf115e3d

History | View | Annotate | Download (1.86 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(USART_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 / 38400 - 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) * 16 MHz / 64 prescaler = 250
63
  //OCR0A = 250;
64
  // (1 ms) * 8 MHz / 64 prescaler = 125
65
  OCR0A = 125;
66
  millis = 0;
67

    
68
  sei();
69
}
70

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

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

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