Statistics
| Branch: | Revision:

root / scout_avr / src / range.cpp @ fd73d758

History | View | Annotate | Download (1.74 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 1c3c96ce Tom Mullins
 */
16
17 ec9e417d Tom Mullins
struct range_t {
18
  unsigned int start; // timer value on rising edge
19
  unsigned int value; // last measured range
20 fd73d758 Tom Mullins
  char done;
21
} volatile range[2];
22 ec9e417d Tom Mullins
23
static void on_edge(int which)
24 1c3c96ce Tom Mullins
{
25 807483bf Tom Mullins
  unsigned char int_high;
26 812788aa Tom Mullins
  unsigned int time = TCNT5;
27 807483bf Tom Mullins
  
28
  if (which)
29
  {
30 cc9ca04e Tom Mullins
    int_high = PIN_SONAR_PWM & _BV(P_SONAR_PWM1);
31 807483bf Tom Mullins
  }
32
  else
33
  {
34 cc9ca04e Tom Mullins
    int_high = PIN_SONAR_PWM & _BV(P_SONAR_PWM0);
35 807483bf Tom Mullins
  }
36
  
37
  if (int_high)
38 1c3c96ce Tom Mullins
  {
39 ec9e417d Tom Mullins
    range[which].start = time;
40 1c3c96ce Tom Mullins
  }
41
  else
42
  {
43 fd73d758 Tom Mullins
    PORT_SONAR_TX &= ~ _BV(P_SONAR_TX);
44 ec9e417d Tom Mullins
    // if timer overflowed since start, this arithmetic should still work out
45
    range[which].value = time - range[which].start;
46 fd73d758 Tom Mullins
    range[which].done = 1;
47 1c3c96ce Tom Mullins
  }
48
}
49
50 cc9ca04e Tom Mullins
ISR(INT3_vect)
51 ec9e417d Tom Mullins
{
52
  on_edge(0);
53
}
54
55 cc9ca04e Tom Mullins
ISR(INT2_vect)
56 ec9e417d Tom Mullins
{
57
  on_edge(1);
58
}
59
60 1c3c96ce Tom Mullins
void range_init()
61
{
62 ec9e417d Tom Mullins
  // ISCx = 1, edge triggered
63 cc9ca04e Tom Mullins
  EICRA |= _BV(ISC20) | _BV(ISC30);
64
  // enable INT2 and INT3
65
  EIMSK |= _BV(INT2) | _BV(INT3);
66 1c3c96ce Tom Mullins
  
67
  // CS1 = 2, 1/8 prescaler
68 f115416e Tom Mullins
  // if this is changed, remember to change recv_edge in bom.cpp!
69 812788aa Tom Mullins
  TCCR5B = _BV(CS51);
70 fd73d758 Tom Mullins
71
  // set tx as output
72
  DDRG |= _BV(DDG1);
73
  PORT_SONAR_TX &= ~ _BV(P_SONAR_TX);
74 1c3c96ce Tom Mullins
}
75
76 fd73d758 Tom Mullins
void range_measure(unsigned int *values)
77 1c3c96ce Tom Mullins
{
78 fd73d758 Tom Mullins
  int i;
79
80
  for (i = 0; i < 2; i++)
81
  {
82
    range[i].value = RANGE_ERR;
83
    range[i].done = 0;
84
  }
85
86
  // TODO ensure that one interrupt won't be delayed because of the other
87
  PORT_SONAR_TX |= _BV(P_SONAR_TX);
88
89
  for (i = 0; i < 2; i++)
90 ec9e417d Tom Mullins
  {
91 fd73d758 Tom Mullins
    while (!range[i].done) {}
92
    values[i] = range[i].value;
93 ec9e417d Tom Mullins
  }
94 1c3c96ce Tom Mullins
}