Statistics
| Branch: | Revision:

root / scout_avr / src / range.cpp @ 812788aa

History | View | Annotate | Download (1.86 KB)

1 1c3c96ce Tom Mullins
#include "range.h"
2
3
extern "C"
4
{
5
#include <avr/io.h>
6
#include <avr/interrupt.h>
7
}
8
9
/* Ultrasonic Sensor:
10
 * -if RX pin is left open, it will continuously take readings
11
 * -PW output is 147us/in.
12
 * -PW will be high for a maximum of 37.5ms if no target is detected
13
 * 
14
 * 37.5ms * 8 MHz / 8 prescaler = 37500 max wait
15
 */
16
17 807483bf Tom Mullins
// so that we can test on a 328 or the stk600
18
#if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega2560__)
19 1c3c96ce Tom Mullins
#  define read_INT0 (PIND & _BV(PD0))
20 ec9e417d Tom Mullins
#  define read_INT1 (PIND & _BV(PD1))
21 1c3c96ce Tom Mullins
#elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
22
#  define read_INT0 (PIND & _BV(PD2))
23 ec9e417d Tom Mullins
#  define read_INT1 (PIND & _BV(PD3))
24 1c3c96ce Tom Mullins
#else
25 ec9e417d Tom Mullins
#  error "Please define read_INTx for this device"
26 1c3c96ce Tom Mullins
#endif
27
28 ec9e417d Tom Mullins
struct range_t {
29
  unsigned int start; // timer value on rising edge
30
  unsigned int value; // last measured range
31
} range[2];
32
33
static void on_edge(int which)
34 1c3c96ce Tom Mullins
{
35 807483bf Tom Mullins
  unsigned char int_high;
36 812788aa Tom Mullins
  // TODO centralize timer 5
37 31f4a032 Tom Mullins
  // TODO ensure this is in microseconds even for 16MHz
38 812788aa Tom Mullins
  unsigned int time = TCNT5;
39 807483bf Tom Mullins
  
40
  if (which)
41
  {
42
    int_high = read_INT1;
43
  }
44
  else
45
  {
46
    int_high = read_INT0;
47
  }
48
  
49
  if (int_high)
50 1c3c96ce Tom Mullins
  {
51 ec9e417d Tom Mullins
    range[which].start = time;
52 1c3c96ce Tom Mullins
  }
53
  else
54
  {
55 ec9e417d Tom Mullins
    // if timer overflowed since start, this arithmetic should still work out
56
    range[which].value = time - range[which].start;
57 1c3c96ce Tom Mullins
  }
58
}
59
60 ec9e417d Tom Mullins
ISR(INT0_vect)
61
{
62
  on_edge(0);
63
}
64
65
ISR(INT1_vect)
66
{
67
  on_edge(1);
68
}
69
70 1c3c96ce Tom Mullins
void range_init()
71
{
72 ec9e417d Tom Mullins
  // ISCx = 1, edge triggered
73
  EICRA |= _BV(ISC10) | _BV(ISC00);
74
  // enable INT0 and INT1
75
  EIMSK |= _BV(INT1) | _BV(INT0);
76 1c3c96ce Tom Mullins
  
77
  // CS1 = 2, 1/8 prescaler
78 f115416e Tom Mullins
  // if this is changed, remember to change recv_edge in bom.cpp!
79 812788aa Tom Mullins
  TCCR5B = _BV(CS51);
80 1c3c96ce Tom Mullins
  
81 230b1b7f Tom Mullins
  range[0].value = RANGE_ERR;
82
  range[1].value = RANGE_ERR;
83 1c3c96ce Tom Mullins
}
84
85 ec9e417d Tom Mullins
unsigned int range_get(int which)
86 1c3c96ce Tom Mullins
{
87 ec9e417d Tom Mullins
  unsigned int ret;
88
  if (0 <= which && which <= 1)
89
  {
90
    cli();
91
    ret = range[which].value;
92
    sei();
93
    return ret;
94
  }
95 230b1b7f Tom Mullins
  else return RANGE_ERR;
96 1c3c96ce Tom Mullins
}