Project

General

Profile

Statistics
| Branch: | Revision:

scoutos / scout_avr / src / range.cpp @ 86b48573

History | View | Annotate | Download (1.92 KB)

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