scoutos / scout_avr / src / range.cpp @ 812788aa
History | View | Annotate | Download (1.86 KB)
1 | 1c3c96ce | Tom Mullins | #include "range.h" |
---|---|---|---|
2 | |||
3 | extern "C" |
||
4 | { |
||
5 | #include <avr/io.h> |
||
6 | #include <avr/interrupt.h> |
||
7 | } |
||
8 | |||
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 | */
|
||
16 | |||
17 | 807483bf | Tom Mullins | // so that we can test on a 328 or the stk600
|
18 | #if defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega2560__)
|
||
19 | 1c3c96ce | Tom Mullins | # define read_INT0 (PIND & _BV(PD0))
|
20 | ec9e417d | Tom Mullins | # define read_INT1 (PIND & _BV(PD1))
|
21 | 1c3c96ce | Tom Mullins | #elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
|
22 | # define read_INT0 (PIND & _BV(PD2))
|
||
23 | ec9e417d | Tom Mullins | # define read_INT1 (PIND & _BV(PD3))
|
24 | 1c3c96ce | Tom Mullins | #else
|
25 | ec9e417d | Tom Mullins | # error "Please define read_INTx for this device" |
26 | 1c3c96ce | Tom Mullins | #endif
|
27 | |||
28 | ec9e417d | Tom Mullins | struct range_t {
|
29 | unsigned int start; // timer value on rising edge |
||
30 | unsigned int value; // last measured range |
||
31 | } range[2];
|
||
32 | |||
33 | static void on_edge(int which) |
||
34 | 1c3c96ce | Tom Mullins | { |
35 | 807483bf | Tom Mullins | unsigned char int_high; |
36 | 812788aa | Tom Mullins | // TODO centralize timer 5
|
37 | 31f4a032 | Tom Mullins | // TODO ensure this is in microseconds even for 16MHz
|
38 | 812788aa | Tom Mullins | unsigned int time = TCNT5; |
39 | 807483bf | Tom Mullins | |
40 | if (which)
|
||
41 | { |
||
42 | int_high = read_INT1; |
||
43 | } |
||
44 | else
|
||
45 | { |
||
46 | int_high = read_INT0; |
||
47 | } |
||
48 | |||
49 | if (int_high)
|
||
50 | 1c3c96ce | Tom Mullins | { |
51 | ec9e417d | Tom Mullins | range[which].start = time; |
52 | 1c3c96ce | Tom Mullins | } |
53 | else
|
||
54 | { |
||
55 | ec9e417d | Tom Mullins | // if timer overflowed since start, this arithmetic should still work out
|
56 | range[which].value = time - range[which].start; |
||
57 | 1c3c96ce | Tom Mullins | } |
58 | } |
||
59 | |||
60 | ec9e417d | Tom Mullins | ISR(INT0_vect) |
61 | { |
||
62 | on_edge(0);
|
||
63 | } |
||
64 | |||
65 | ISR(INT1_vect) |
||
66 | { |
||
67 | on_edge(1);
|
||
68 | } |
||
69 | |||
70 | 1c3c96ce | Tom Mullins | void range_init()
|
71 | { |
||
72 | ec9e417d | Tom Mullins | // ISCx = 1, edge triggered
|
73 | EICRA |= _BV(ISC10) | _BV(ISC00); |
||
74 | // enable INT0 and INT1
|
||
75 | EIMSK |= _BV(INT1) | _BV(INT0); |
||
76 | 1c3c96ce | Tom Mullins | |
77 | // CS1 = 2, 1/8 prescaler
|
||
78 | f115416e | Tom Mullins | // if this is changed, remember to change recv_edge in bom.cpp!
|
79 | 812788aa | Tom Mullins | TCCR5B = _BV(CS51); |
80 | 1c3c96ce | Tom Mullins | |
81 | 230b1b7f | Tom Mullins | range[0].value = RANGE_ERR;
|
82 | range[1].value = RANGE_ERR;
|
||
83 | 1c3c96ce | Tom Mullins | } |
84 | |||
85 | ec9e417d | Tom Mullins | unsigned int range_get(int which) |
86 | 1c3c96ce | Tom Mullins | { |
87 | ec9e417d | Tom Mullins | unsigned int ret; |
88 | if (0 <= which && which <= 1) |
||
89 | { |
||
90 | cli(); |
||
91 | ret = range[which].value; |
||
92 | sei(); |
||
93 | return ret;
|
||
94 | } |
||
95 | 230b1b7f | Tom Mullins | else return RANGE_ERR; |
96 | 1c3c96ce | Tom Mullins | } |