root / scout_avr / src / range.cpp @ 6c9146d5
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 | } |