Statistics
| Branch: | Revision:

root / scout_avr / src / range.cpp @ cc9ca04e

History | View | Annotate | Download (1.48 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
} range[2];
21

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

    
47
ISR(INT3_vect)
48
{
49
  on_edge(0);
50
}
51

    
52
ISR(INT2_vect)
53
{
54
  on_edge(1);
55
}
56

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

    
72
unsigned int range_get(int which)
73
{
74
  unsigned int ret;
75
  if (0 <= which && which <= 1)
76
  {
77
    cli();
78
    ret = range[which].value;
79
    sei();
80
    return ret;
81
  }
82
  else return RANGE_ERR;
83
}