Project

General

Profile

Statistics
| Branch: | Revision:

scoutos / scout_avr / src / range.cpp @ fd73d758

History | View | Annotate | Download (1.74 KB)

1
extern "C"
2
{
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
}
6
#include "range.h"
7

    
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
 * 37.5ms * 16 MHz / 8 prescaler = problem
15
 */
16

    
17
struct range_t {
18
  unsigned int start; // timer value on rising edge
19
  unsigned int value; // last measured range
20
  char done;
21
} volatile range[2];
22

    
23
static void on_edge(int which)
24
{
25
  unsigned char int_high;
26
  unsigned int time = TCNT5;
27
  
28
  if (which)
29
  {
30
    int_high = PIN_SONAR_PWM & _BV(P_SONAR_PWM1);
31
  }
32
  else
33
  {
34
    int_high = PIN_SONAR_PWM & _BV(P_SONAR_PWM0);
35
  }
36
  
37
  if (int_high)
38
  {
39
    range[which].start = time;
40
  }
41
  else
42
  {
43
    PORT_SONAR_TX &= ~ _BV(P_SONAR_TX);
44
    // if timer overflowed since start, this arithmetic should still work out
45
    range[which].value = time - range[which].start;
46
    range[which].done = 1;
47
  }
48
}
49

    
50
ISR(INT3_vect)
51
{
52
  on_edge(0);
53
}
54

    
55
ISR(INT2_vect)
56
{
57
  on_edge(1);
58
}
59

    
60
void range_init()
61
{
62
  // ISCx = 1, edge triggered
63
  EICRA |= _BV(ISC20) | _BV(ISC30);
64
  // enable INT2 and INT3
65
  EIMSK |= _BV(INT2) | _BV(INT3);
66
  
67
  // CS1 = 2, 1/8 prescaler
68
  // if this is changed, remember to change recv_edge in bom.cpp!
69
  TCCR5B = _BV(CS51);
70

    
71
  // set tx as output
72
  DDRG |= _BV(DDG1);
73
  PORT_SONAR_TX &= ~ _BV(P_SONAR_TX);
74
}
75

    
76
void range_measure(unsigned int *values)
77
{
78
  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
  {
91
    while (!range[i].done) {}
92
    values[i] = range[i].value;
93
  }
94
}