Statistics
| Branch: | Revision:

root / scout_avr / src / range.cpp @ 399f7d1b

History | View | Annotate | Download (1.8 KB)

1 1c3c96ce Tom Mullins
extern "C"
2
{
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
}
6 cc9ca04e Tom Mullins
#include "range.h"
7 1c3c96ce Tom Mullins
8
/* Ultrasonic Sensor:
9
 * -if RX pin is left open, it will continuously take readings
10
 * -PW output is 147us/in.
11
 * -PW will be high for a maximum of 37.5ms if no target is detected
12
 * 
13
 * 37.5ms * 8 MHz / 8 prescaler = 37500 max wait
14 cc9ca04e Tom Mullins
 * 37.5ms * 16 MHz / 8 prescaler = problem
15 399f7d1b Tom Mullins
 * 37.5ms * 16 MHz / 64 prescaler = 9375 max wait
16 1c3c96ce Tom Mullins
 */
17
18 ec9e417d Tom Mullins
struct range_t {
19
  unsigned int start; // timer value on rising edge
20
  unsigned int value; // last measured range
21 fd73d758 Tom Mullins
  char done;
22
} volatile range[2];
23 ec9e417d Tom Mullins
24
static void on_edge(int which)
25 1c3c96ce Tom Mullins
{
26 807483bf Tom Mullins
  unsigned char int_high;
27 812788aa Tom Mullins
  unsigned int time = TCNT5;
28 807483bf Tom Mullins
  
29
  if (which)
30
  {
31 cc9ca04e Tom Mullins
    int_high = PIN_SONAR_PWM & _BV(P_SONAR_PWM1);
32 807483bf Tom Mullins
  }
33
  else
34
  {
35 cc9ca04e Tom Mullins
    int_high = PIN_SONAR_PWM & _BV(P_SONAR_PWM0);
36 807483bf Tom Mullins
  }
37
  
38
  if (int_high)
39 1c3c96ce Tom Mullins
  {
40 ec9e417d Tom Mullins
    range[which].start = time;
41 1c3c96ce Tom Mullins
  }
42
  else
43
  {
44 fd73d758 Tom Mullins
    PORT_SONAR_TX &= ~ _BV(P_SONAR_TX);
45 ec9e417d Tom Mullins
    // if timer overflowed since start, this arithmetic should still work out
46
    range[which].value = time - range[which].start;
47 fd73d758 Tom Mullins
    range[which].done = 1;
48 1c3c96ce Tom Mullins
  }
49
}
50
51 cc9ca04e Tom Mullins
ISR(INT3_vect)
52 ec9e417d Tom Mullins
{
53
  on_edge(0);
54
}
55
56 cc9ca04e Tom Mullins
ISR(INT2_vect)
57 ec9e417d Tom Mullins
{
58
  on_edge(1);
59
}
60
61 1c3c96ce Tom Mullins
void range_init()
62
{
63 ec9e417d Tom Mullins
  // ISCx = 1, edge triggered
64 cc9ca04e Tom Mullins
  EICRA |= _BV(ISC20) | _BV(ISC30);
65
  // enable INT2 and INT3
66
  EIMSK |= _BV(INT2) | _BV(INT3);
67 1c3c96ce Tom Mullins
  
68 399f7d1b Tom Mullins
  // CS1 = 3, 1/64 prescaler
69 f115416e Tom Mullins
  // if this is changed, remember to change recv_edge in bom.cpp!
70 399f7d1b Tom Mullins
  TCCR5B = _BV(CS50) | _BV(CS51);
71 fd73d758 Tom Mullins
72
  // set tx as output
73
  DDRG |= _BV(DDG1);
74
  PORT_SONAR_TX &= ~ _BV(P_SONAR_TX);
75 1c3c96ce Tom Mullins
}
76
77 fd73d758 Tom Mullins
void range_measure(unsigned int *values)
78 1c3c96ce Tom Mullins
{
79 fd73d758 Tom Mullins
  int i;
80
81
  for (i = 0; i < 2; i++)
82
  {
83
    range[i].value = RANGE_ERR;
84
    range[i].done = 0;
85
  }
86
87
  // TODO ensure that one interrupt won't be delayed because of the other
88
  PORT_SONAR_TX |= _BV(P_SONAR_TX);
89
90
  for (i = 0; i < 2; i++)
91 ec9e417d Tom Mullins
  {
92 fd73d758 Tom Mullins
    while (!range[i].done) {}
93
    values[i] = range[i].value;
94 ec9e417d Tom Mullins
  }
95 1c3c96ce Tom Mullins
}