Revision 63e19141
Committing Anson's BOM changes
scout_avr/src/bom.cpp | ||
---|---|---|
15 | 15 |
* BOM uses timer 4 for period timing, and timer 0 for 38kHz signal |
16 | 16 |
*/ |
17 | 17 |
|
18 |
/* |
|
19 |
* Recently modified so that when BOM is sending, it stops listening. When |
|
20 |
* not sending, it keeps listening. |
|
21 |
*/ |
|
22 |
|
|
18 | 23 |
#define TIME_MICROS(us, prescale) (F_CPU / 1000000 * (us) / (prescale)) |
19 | 24 |
|
20 | 25 |
typedef uint16_t sharp_msg_t; |
... | ... | |
60 | 65 |
static void init_38kHz_signal() { |
61 | 66 |
out_high = 0; |
62 | 67 |
out_pin_mask = 0; |
63 |
|
|
68 |
|
|
64 | 69 |
// timer configuration now done in Atmega128rfa1.cpp |
65 | 70 |
} |
66 | 71 |
|
... | ... | |
71 | 76 |
} |
72 | 77 |
|
73 | 78 |
static void stop_38kHz_signal() { |
74 |
PORT_BOM_EMIT &= ~ out_pin_mask; |
|
79 |
PORT_BOM_EMIT &= ~ out_pin_mask; // why not just do PORT_BOM_EMIT &= 0; ?
|
|
75 | 80 |
out_high = 0; |
76 | 81 |
} |
77 | 82 |
|
... | ... | |
79 | 84 |
// timer 4 mode CTC (clear timer on compare), TOP = OCRA |
80 | 85 |
TCCR4A = 0; |
81 | 86 |
TCCR4B = _BV(WGM42); |
82 |
|
|
87 |
|
|
83 | 88 |
// run interrupt immediately when timer started |
84 | 89 |
OCR4A = 0; |
85 |
|
|
90 |
|
|
86 | 91 |
// enable interrupt |
87 | 92 |
TIMSK4 = _BV(OCIE4A); |
88 | 93 |
} |
89 | 94 |
|
90 | 95 |
static void start_data_signal() { |
91 | 96 |
TCNT4 = 0; |
92 |
|
|
97 |
|
|
93 | 98 |
// start timer 4 at F_CPU/64 prescaling |
94 | 99 |
TCCR4B |= _BV(CS41) | _BV(CS40); |
95 | 100 |
} |
... | ... | |
124 | 129 |
DDRB &= ~ (_BV(DDB0) | _BV(DDB1) | _BV(DDB2) | _BV(DDB3)); |
125 | 130 |
PCMSK0 |= _BV(PCINT0) | _BV(PCINT1) | _BV(PCINT2) | _BV(PCINT3); |
126 | 131 |
PCICR |= _BV(PCIE0); |
127 |
|
|
132 |
|
|
128 | 133 |
// BOM_EMIT as output |
129 | 134 |
DDRF |= _BV(DDF4) | _BV(DDF5) | _BV(DDF6) | _BV(DDF7); |
130 | 135 |
|
... | ... | |
132 | 137 |
init_data_signal(); |
133 | 138 |
} |
134 | 139 |
|
140 |
static void stop_receiving(char dir) { |
|
141 |
switch (dir) { |
|
142 |
case BOM_FRONT: PCMSK0 &= ~_BV(PCINT0); break; |
|
143 |
case BOM_LEFT : PCMSK0 &= ~_BV(PCINT1); break; |
|
144 |
case BOM_RIGHT: PCMSK0 &= ~_BV(PCINT2); break; |
|
145 |
case BOM_BACK : PCMSK0 &= ~_BV(PCINT3); break; |
|
146 |
} |
|
147 |
} |
|
148 |
|
|
149 |
static void start_receiving(char dir) { |
|
150 |
// flush rx buffer before turning on the receiver |
|
151 |
bom_rx[(int)dir].bits = 0; |
|
152 |
bom_rx[(int)dir].count = 0; |
|
153 |
|
|
154 |
switch (dir) { |
|
155 |
case BOM_FRONT: PCMSK0 |= _BV(PCINT0); break; |
|
156 |
case BOM_LEFT : PCMSK0 |= _BV(PCINT1); break; |
|
157 |
case BOM_RIGHT: PCMSK0 |= _BV(PCINT2); break; |
|
158 |
case BOM_BACK : PCMSK0 |= _BV(PCINT3); break; |
|
159 |
} |
|
160 |
} |
|
161 |
|
|
135 | 162 |
void bom_send(char dir) { |
136 | 163 |
switch (dir) { |
137 | 164 |
case BOM_FRONT: out_pin_mask = _BV(P_BOM_EMIT0); break; |
... | ... | |
142 | 169 |
out_counter = 16; |
143 | 170 |
out_msg = sharp_msg_make(0x2A, bom_msg_make(robot_id, dir)); |
144 | 171 |
out_done = 0; |
172 |
|
|
173 |
stop_receiving(dir); // disable receiver |
|
174 |
start_38kHz_signal(); // enable the transmitter |
|
145 | 175 |
start_data_signal(); |
146 | 176 |
while (!out_done) { |
147 | 177 |
_delay_ms(0.1); |
148 | 178 |
} |
179 |
stop_data_signal(); // disable the transmitter |
|
180 |
stop_38kHz_signal(); |
|
181 |
start_receiving(dir); // enable the receiver |
|
149 | 182 |
} |
150 | 183 |
|
151 | 184 |
static void recv_edge(char is_rising, struct bom_rx_t *rx) { |
... | ... | |
159 | 192 |
int max_low = TIME_MICROS(MAX_LOW_PW, 64); |
160 | 193 |
int min_high = TIME_MICROS(MIN_HIGH_PW, 64); |
161 | 194 |
int max_high = TIME_MICROS(MAX_HIGH_PW, 64); |
162 |
|
|
195 |
|
|
163 | 196 |
if (rx->count) { |
164 | 197 |
int diff = (now - rx->last_time); |
165 | 198 |
rx->bits <<= 1; |
... | ... | |
184 | 217 |
rx->bits = 0; |
185 | 218 |
} |
186 | 219 |
} |
187 |
|
|
220 |
|
|
188 | 221 |
rx->count++; |
189 | 222 |
rx->last_time = now; |
190 | 223 |
} |
Also available in: Unified diff