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