blob: 205f44e55134c8434332ec7b7db3f4cd218893cd [file] [log] [blame]
Brian Silvermanf92396c2013-09-12 20:13:13 -07001#include "fill_packet.h"
2#include "encoder.h"
3
4#include "FreeRTOS.h"
5#include "task.h"
6
7#include "digital.h"
8#include "analog.h"
Brian Silverman49876942013-10-11 17:50:26 -07009#include "gyro.h"
Brian Silvermanf92396c2013-09-12 20:13:13 -070010
11// How long (in ms) to wait after a falling edge on the bottom indexer sensor
12// before reading the indexer encoder.
13static const int kBottomFallDelayTime = 32;
14
15#define ENC(gpio, a, b) readGPIO(gpio, a) * 2 + readGPIO(gpio, b)
16int encoder_bits(int channel) {
17 switch (channel) {
18 case 0:
19 return ENC(GPIO1, 20, 23);
20 case 1:
21 return ENC(GPIO2, 11, 12);
22 case 2:
23 return ENC(GPIO0, 21, 22);
24 case 3:
25 return ENC(GPIO0, 19, 20);
26 default:
27 return -1;
28 }
29 return -1;
30}
31#undef ENC
32
33// Uses EINT1 and EINT2 on 2.11 and 2.12.
34volatile int32_t encoder1_val;
35// On GPIO pins 0.22 and 0.21.
36volatile int32_t encoder2_val;
37// On GPIO pins 0.20 and 0.19.
38volatile int32_t encoder3_val;
39// On GPIO pins 2.0 and 2.1.
40volatile int32_t encoder4_val;
41// On GPIO pins 2.2 and 2.3.
42volatile int32_t encoder5_val;
43
Brian Silverman25aae9a2013-10-08 13:37:45 -070044// It is important to clear the various interrupt flags first thing in the ISRs.
45// It doesn't seem to work otherwise, possibly because of the reason that Brian
46// found poking around online: caches on the bus make it so that the clearing of
47// the interrupt gets to the NVIC after the ISR returns, so it runs the ISR a
48// second time. Also, by clearing them early, if a second interrupt arrives from
49// the same source it will still get handled instead of getting lost.
50
Brian Silvermanf92396c2013-09-12 20:13:13 -070051// ENC1A 2.11
52void EINT1_IRQHandler(void) {
Brian Silverman25aae9a2013-10-08 13:37:45 -070053 // Make sure to change this BEFORE clearing the interrupt like the datasheet
54 // says you have to.
Brian Silverman1623c332013-10-01 18:05:16 -070055 SC->EXTPOLAR ^= 0x2;
Brian Silvermanf92396c2013-09-12 20:13:13 -070056 SC->EXTINT = 0x2;
57 int fiopin = GPIO2->FIOPIN;
Brian Silverman25aae9a2013-10-08 13:37:45 -070058 // This looks like a weird way to XOR the 2 inputs, but it compiles down to
59 // just 2 instructions, which is hard to beat.
Brian Silvermanf92396c2013-09-12 20:13:13 -070060 if (((fiopin >> 1) ^ fiopin) & 0x800) {
61 ++encoder1_val;
62 } else {
63 --encoder1_val;
64 }
Brian Silvermanf92396c2013-09-12 20:13:13 -070065}
66// ENC1B 2.12
67void EINT2_IRQHandler(void) {
Brian Silverman1623c332013-10-01 18:05:16 -070068 SC->EXTPOLAR ^= 0x4;
Brian Silvermanf92396c2013-09-12 20:13:13 -070069 SC->EXTINT = 0x4;
70 int fiopin = GPIO2->FIOPIN;
71 if (((fiopin >> 1) ^ fiopin) & 0x800) {
72 --encoder1_val;
73 } else {
74 ++encoder1_val;
75 }
Brian Silvermanf92396c2013-09-12 20:13:13 -070076}
77
Brian Silverman1623c332013-10-01 18:05:16 -070078// TODO(brians): Have this indicate some kind of error instead of just looping
79// infinitely in the ISR because it never clears it.
80static void NoGPIO(void) {}
81static void Encoder2ARise(void) {
82 GPIOINT->IO0IntClr = (1 << 22);
Brian Silvermanf92396c2013-09-12 20:13:13 -070083 if (GPIO0->FIOPIN & (1 << 21)) {
84 ++encoder2_val;
85 } else {
86 --encoder2_val;
87 }
88}
Brian Silverman1623c332013-10-01 18:05:16 -070089static void Encoder2AFall(void) {
90 GPIOINT->IO0IntClr = (1 << 22);
Brian Silvermanf92396c2013-09-12 20:13:13 -070091 if (GPIO0->FIOPIN & (1 << 21)) {
92 --encoder2_val;
93 } else {
94 ++encoder2_val;
95 }
96}
Brian Silverman1623c332013-10-01 18:05:16 -070097static void Encoder2BRise(void) {
98 GPIOINT->IO0IntClr = (1 << 21);
Brian Silvermanf92396c2013-09-12 20:13:13 -070099 if (GPIO0->FIOPIN & (1 << 22)) {
100 --encoder2_val;
101 } else {
102 ++encoder2_val;
103 }
104}
Brian Silverman1623c332013-10-01 18:05:16 -0700105static void Encoder2BFall(void) {
106 GPIOINT->IO0IntClr = (1 << 21);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700107 if (GPIO0->FIOPIN & (1 << 22)) {
108 ++encoder2_val;
109 } else {
110 --encoder2_val;
111 }
112}
113
Brian Silverman1623c332013-10-01 18:05:16 -0700114static void Encoder3ARise(void) {
115 GPIOINT->IO0IntClr = (1 << 20);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700116 if (GPIO0->FIOPIN & (1 << 19)) {
117 ++encoder3_val;
118 } else {
119 --encoder3_val;
120 }
121}
Brian Silverman1623c332013-10-01 18:05:16 -0700122static void Encoder3AFall(void) {
123 GPIOINT->IO0IntClr = (1 << 20);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700124 if (GPIO0->FIOPIN & (1 << 19)) {
125 --encoder3_val;
126 } else {
127 ++encoder3_val;
128 }
129}
Brian Silverman1623c332013-10-01 18:05:16 -0700130static void Encoder3BRise(void) {
131 GPIOINT->IO0IntClr = (1 << 19);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700132 if (GPIO0->FIOPIN & (1 << 20)) {
133 --encoder3_val;
134 } else {
135 ++encoder3_val;
136 }
137}
Brian Silverman1623c332013-10-01 18:05:16 -0700138static void Encoder3BFall(void) {
139 GPIOINT->IO0IntClr = (1 << 19);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700140 if (GPIO0->FIOPIN & (1 << 20)) {
141 ++encoder3_val;
142 } else {
143 --encoder3_val;
144 }
145}
146
Brian Silverman1623c332013-10-01 18:05:16 -0700147static void Encoder4ARise(void) {
148 GPIOINT->IO2IntClr = (1 << 0);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700149 if (GPIO2->FIOPIN & (1 << 1)) {
150 ++encoder4_val;
151 } else {
152 --encoder4_val;
153 }
154}
Brian Silverman1623c332013-10-01 18:05:16 -0700155static void Encoder4AFall(void) {
156 GPIOINT->IO2IntClr = (1 << 0);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700157 if (GPIO2->FIOPIN & (1 << 1)) {
158 --encoder4_val;
159 } else {
160 ++encoder4_val;
161 }
162}
Brian Silverman1623c332013-10-01 18:05:16 -0700163static void Encoder4BRise(void) {
164 GPIOINT->IO2IntClr = (1 << 1);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700165 if (GPIO2->FIOPIN & (1 << 0)) {
166 --encoder4_val;
167 } else {
168 ++encoder4_val;
169 }
170}
Brian Silverman1623c332013-10-01 18:05:16 -0700171static void Encoder4BFall(void) {
172 GPIOINT->IO2IntClr = (1 << 1);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700173 if (GPIO2->FIOPIN & (1 << 0)) {
174 ++encoder4_val;
175 } else {
176 --encoder4_val;
177 }
178}
179
Brian Silverman1623c332013-10-01 18:05:16 -0700180static void Encoder5ARise(void) {
181 GPIOINT->IO2IntClr = (1 << 2);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700182 if (GPIO2->FIOPIN & (1 << 3)) {
183 ++encoder5_val;
184 } else {
185 --encoder5_val;
186 }
187}
Brian Silverman1623c332013-10-01 18:05:16 -0700188static void Encoder5AFall(void) {
189 GPIOINT->IO2IntClr = (1 << 2);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700190 if (GPIO2->FIOPIN & (1 << 3)) {
191 --encoder5_val;
192 } else {
193 ++encoder5_val;
194 }
195}
Brian Silverman1623c332013-10-01 18:05:16 -0700196static void Encoder5BRise(void) {
197 GPIOINT->IO2IntClr = (1 << 3);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700198 if (GPIO2->FIOPIN & (1 << 2)) {
199 --encoder5_val;
200 } else {
201 ++encoder5_val;
202 }
203}
Brian Silverman1623c332013-10-01 18:05:16 -0700204static void Encoder5BFall(void) {
205 GPIOINT->IO2IntClr = (1 << 3);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700206 if (GPIO2->FIOPIN & (1 << 2)) {
207 ++encoder5_val;
208 } else {
209 --encoder5_val;
210 }
211}
212
213volatile int32_t capture_top_rise;
214volatile int8_t top_rise_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700215static void IndexerTopRise(void) {
216 GPIOINT->IO0IntClr = (1 << 5);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700217 // edge counting encoder capture
218 ++top_rise_count;
219 capture_top_rise = encoder3_val;
220}
221volatile int32_t capture_top_fall;
222volatile int8_t top_fall_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700223static void IndexerTopFall(void) {
224 GPIOINT->IO0IntClr = (1 << 5);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700225 // edge counting encoder capture
226 ++top_fall_count;
227 capture_top_fall = encoder3_val;
228}
229volatile int8_t bottom_rise_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700230static void IndexerBottomRise(void) {
231 GPIOINT->IO0IntClr = (1 << 4);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700232 // edge counting
233 ++bottom_rise_count;
234}
235volatile int32_t capture_bottom_fall_delay;
236volatile int8_t bottom_fall_delay_count;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700237portTickType xDelayTimeFrom;
238static portTASK_FUNCTION(vDelayCapture, pvParameters)
239{
240 portTickType xSleepFrom = xTaskGetTickCount();
241
242 for (;;) {
Brian Silverman25aae9a2013-10-08 13:37:45 -0700243 // Atomically (wrt the ISR) switch xDelayTimeFrom to 0 and store its old
244 // value to use later.
Brian Silvermanf92396c2013-09-12 20:13:13 -0700245 NVIC_DisableIRQ(EINT3_IRQn);
Brian Silverman25aae9a2013-10-08 13:37:45 -0700246 portTickType new_time = xDelayTimeFrom;
247 xDelayTimeFrom = 0;
248 NVIC_EnableIRQ(EINT3_IRQn);
249
250 if (new_time != 0) {
251 xSleepFrom = new_time;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700252
253 vTaskDelayUntil(&xSleepFrom, kBottomFallDelayTime / portTICK_RATE_MS);
254
Brian Silverman25aae9a2013-10-08 13:37:45 -0700255 // Make sure that the USB ISR doesn't look at inconsistent values.
Brian Silverman1623c332013-10-01 18:05:16 -0700256 NVIC_DisableIRQ(USB_IRQn);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700257 capture_bottom_fall_delay = encoder3_val;
Brian Silverman1623c332013-10-01 18:05:16 -0700258 ++bottom_fall_delay_count;
259 NVIC_EnableIRQ(USB_IRQn);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700260 } else {
Brian Silverman25aae9a2013-10-08 13:37:45 -0700261 // Wait 10ms and then check again.
Brian Silvermanf92396c2013-09-12 20:13:13 -0700262 vTaskDelayUntil(&xSleepFrom, 10 / portTICK_RATE_MS);
263 }
264 }
265}
266
267volatile int8_t bottom_fall_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700268static void IndexerBottomFall(void) {
269 GPIOINT->IO0IntClr = (1 << 4);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700270 ++bottom_fall_count;
271 // edge counting start delayed capture
272 xDelayTimeFrom = xTaskGetTickCount();
Brian Silvermanf92396c2013-09-12 20:13:13 -0700273}
274volatile int32_t capture_wrist_rise;
275volatile int8_t wrist_rise_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700276static void WristHallRise(void) {
277 GPIOINT->IO0IntClr = (1 << 6);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700278 // edge counting encoder capture
279 ++wrist_rise_count;
280 capture_wrist_rise = (int32_t)QEI->QEIPOS;
281}
282volatile int32_t capture_shooter_angle_rise;
283volatile int8_t shooter_angle_rise_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700284static void ShooterHallRise(void) {
285 GPIOINT->IO0IntClr = (1 << 7);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700286 // edge counting encoder capture
287 ++shooter_angle_rise_count;
288 capture_shooter_angle_rise = encoder2_val;
289}
290
291// Count leading zeros.
292// Returns 0 if bit 31 is set etc.
293__attribute__((always_inline)) static __INLINE uint32_t __clz(uint32_t value) {
294 uint32_t result;
295 __asm__("clz %0, %1" : "=r" (result) : "r" (value));
296 return result;
297}
298inline static void IRQ_Dispatch(void) {
Brian Silverman25aae9a2013-10-08 13:37:45 -0700299 // There is no need to add a loop here to handle multiple interrupts at the
300 // same time because the processor has tail chaining of interrupts which we
301 // can't really beat with our own loop.
302 // It would actually be bad because a loop here would block EINT1/2 for longer
303 // lengths of time.
304
Brian Silvermanf92396c2013-09-12 20:13:13 -0700305 uint32_t index = __clz(GPIOINT->IO2IntStatR | GPIOINT->IO0IntStatR |
306 (GPIOINT->IO2IntStatF << 28) | (GPIOINT->IO0IntStatF << 4));
307
308 typedef void (*Handler)(void);
309 const static Handler table[] = {
310 Encoder5BFall, // index 0: P2.3 Fall #bit 31 //Encoder 5 B //Dio 10
311 Encoder5AFall, // index 1: P2.2 Fall #bit 30 //Encoder 5 A //Dio 9
312 Encoder4BFall, // index 2: P2.1 Fall #bit 29 //Encoder 4 B //Dio 8
313 Encoder4AFall, // index 3: P2.0 Fall #bit 28 //Encoder 4 A //Dio 7
314 NoGPIO, // index 4: NO GPIO #bit 27
315 Encoder2AFall, // index 5: P0.22 Fall #bit 26 //Encoder 2 A
316 Encoder2BFall, // index 6: P0.21 Fall #bit 25 //Encoder 2 B
317 Encoder3AFall, // index 7: P0.20 Fall #bit 24 //Encoder 3 A
318 Encoder3BFall, // index 8: P0.19 Fall #bit 23 //Encoder 3 B
319 Encoder2ARise, // index 9: P0.22 Rise #bit 22 //Encoder 2 A
320 Encoder2BRise, // index 10: P0.21 Rise #bit 21 //Encoder 2 B
321 Encoder3ARise, // index 11: P0.20 Rise #bit 20 //Encoder 3 A
322 Encoder3BRise, // index 12: P0.19 Rise #bit 19 //Encoder 3 B
323 NoGPIO, // index 13: NO GPIO #bit 18
324 NoGPIO, // index 14: NO GPIO #bit 17
325 NoGPIO, // index 15: NO GPIO #bit 16
326 NoGPIO, // index 16: NO GPIO #bit 15
327 NoGPIO, // index 17: NO GPIO #bit 14
328 NoGPIO, // index 18: NO GPIO #bit 13
329 NoGPIO, // index 19: NO GPIO #bit 12
330 ShooterHallRise, // index 20: P0.7 Fall #bit 11 //Shooter Hall //Dio 4
331 WristHallRise, // index 21: P0.6 Fall #bit 10 //Wrist Hall //Dio 3
332 IndexerTopRise, // index 22: P0.5 Fall #bit 9 //Indexer Top //Dio 2
333 IndexerBottomRise, // index 23: P0.4 Fall #bit 8 //Indexer Bottom //Dio 1
334 NoGPIO, // index 24: NO GPIO #bit 7
335 NoGPIO, // index 25: NO GPIO #bit 6
336 IndexerTopFall, // index 26: P0.5 Rise #bit 5 //Indexer Top //Dio 2
337 IndexerBottomFall, // index 27: P0.4 Rise #bit 4 //Indexer Bottom //Dio 1
338 Encoder5BRise, // index 28: P2.3 Rise #bit 3 //Encoder 5 B //Dio 10
339 Encoder5ARise, // index 29: P2.2 Rise #bit 2 //Encoder 5 A //Dio 9
340 Encoder4BRise, // index 30: P2.1 Rise #bit 1 //Encoder 4 B //Dio 8
341 Encoder4ARise, // index 31: P2.0 Rise #bit 0 //Encoder 4 A //Dio 7
342 NoGPIO // index 32: NO BITS SET #False Alarm
343 };
344 table[index]();
345}
346void EINT3_IRQHandler(void) {
Brian Silvermanf92396c2013-09-12 20:13:13 -0700347 IRQ_Dispatch();
Brian Silvermanf92396c2013-09-12 20:13:13 -0700348}
349int32_t encoder_val(int chan) {
350 int32_t val;
351 switch (chan) {
352 case 0: // Wrist
353 return (int32_t)QEI->QEIPOS;
354 case 1: // Shooter Wheel
355 NVIC_DisableIRQ(EINT1_IRQn);
356 NVIC_DisableIRQ(EINT2_IRQn);
357 val = encoder1_val;
358 NVIC_EnableIRQ(EINT2_IRQn);
359 NVIC_EnableIRQ(EINT1_IRQn);
360 return val;
361 case 2: // Shooter Angle
362 NVIC_DisableIRQ(EINT3_IRQn);
363 val = encoder2_val;
364 NVIC_EnableIRQ(EINT3_IRQn);
365 return val;
366 case 3: // Indexer
367 NVIC_DisableIRQ(EINT3_IRQn);
368 val = encoder3_val;
369 NVIC_EnableIRQ(EINT3_IRQn);
370 return val;
371 case 4: // Drive R
372 NVIC_DisableIRQ(EINT3_IRQn);
373 val = encoder4_val;
374 NVIC_EnableIRQ(EINT3_IRQn);
375 return val;
376 case 5: // Drive L
377 NVIC_DisableIRQ(EINT3_IRQn);
378 val = encoder5_val;
379 NVIC_EnableIRQ(EINT3_IRQn);
380 return val;
381 default:
382 return -1;
383 }
384}
385
386void encoder_init(void) {
387 // Setup the encoder interface.
388 SC->PCONP |= PCONP_PCQEI;
389 PINCON->PINSEL3 = ((PINCON->PINSEL3 & 0xffff3dff) | 0x00004100);
390 // Reset the count and velocity.
391 QEI->QEICON = 0x00000005;
392 QEI->QEICONF = 0x00000004;
393 // Wrap back to 0 when we wrap the int and vice versa.
394 QEI->QEIMAXPOS = 0xFFFFFFFF;
395
396 // Set up encoder 1.
397 // Make GPIOs 2.11 and 2.12 trigger EINT1 and EINT2 (respectively).
398 // PINSEL4[23:22] = {0 1}
399 // PINSEL4[25:24] = {0 1}
400 PINCON->PINSEL4 = (PINCON->PINSEL4 & ~(0x3 << 22)) | (0x1 << 22);
401 PINCON->PINSEL4 = (PINCON->PINSEL4 & ~(0x3 << 24)) | (0x1 << 24);
402 // Clear the interrupt flags for EINT1 and EINT2 (0x6 = 0b0110).
403 SC->EXTMODE = 0x6;
404 SC->EXTINT = 0x6;
405 NVIC_EnableIRQ(EINT1_IRQn);
406 NVIC_EnableIRQ(EINT2_IRQn);
407 encoder1_val = 0;
408
409 // Set up encoder 2.
410 GPIOINT->IO0IntEnF |= (1 << 22); // Set GPIO falling interrupt.
411 GPIOINT->IO0IntEnR |= (1 << 22); // Set GPIO rising interrupt.
412 GPIOINT->IO0IntEnF |= (1 << 21); // Set GPIO falling interrupt.
413 GPIOINT->IO0IntEnR |= (1 << 21); // Set GPIO rising interrupt.
414 // Make sure they're in mode 00 (the default, aka nothing special).
415 PINCON->PINSEL1 &= ~(0x3 << 12);
416 PINCON->PINSEL1 &= ~(0x3 << 10);
417 encoder2_val = 0;
418
419 // Set up encoder 3.
420 GPIOINT->IO0IntEnF |= (1 << 20); // Set GPIO falling interrupt.
421 GPIOINT->IO0IntEnR |= (1 << 20); // Set GPIO rising interrupt.
422 GPIOINT->IO0IntEnF |= (1 << 19); // Set GPIO falling interrupt.
423 GPIOINT->IO0IntEnR |= (1 << 19); // Set GPIO rising interrupt.
424 // Make sure they're in mode 00 (the default, aka nothing special).
425 PINCON->PINSEL1 &= ~(0x3 << 8);
426 PINCON->PINSEL1 &= ~(0x3 << 6);
427 encoder3_val = 0;
428
429 // Set up encoder 4.
430 GPIOINT->IO2IntEnF |= (1 << 0); // Set GPIO falling interrupt.
431 GPIOINT->IO2IntEnR |= (1 << 0); // Set GPIO rising interrupt.
432 GPIOINT->IO2IntEnF |= (1 << 1); // Set GPIO falling interrupt.
433 GPIOINT->IO2IntEnR |= (1 << 1); // Set GPIO rising interrupt.
434 // Make sure they're in mode 00 (the default, aka nothing special).
435 PINCON->PINSEL4 &= ~(0x3 << 0);
436 PINCON->PINSEL4 &= ~(0x3 << 2);
437 encoder4_val = 0;
438
439 // Set up encoder 5.
440 GPIOINT->IO2IntEnF |= (1 << 2); // Set GPIO falling interrupt.
441 GPIOINT->IO2IntEnR |= (1 << 2); // Set GPIO rising interrupt.
442 GPIOINT->IO2IntEnF |= (1 << 3); // Set GPIO falling interrupt.
443 GPIOINT->IO2IntEnR |= (1 << 3); // Set GPIO rising interrupt.
444 // Make sure they're in mode 00 (the default, aka nothing special).
445 PINCON->PINSEL4 &= ~(0x3 << 4);
446 PINCON->PINSEL4 &= ~(0x3 << 6);
447 encoder5_val = 0;
448
449 // Enable interrupts from the GPIO pins.
450 NVIC_EnableIRQ(EINT3_IRQn);
451
452 if (is_bot3) {
453 } else { // is main robot
454 xTaskCreate(vDelayCapture,
455 (signed char *) "SENSORs",
456 configMINIMAL_STACK_SIZE + 100,
457 NULL /*parameters*/,
458 tskIDLE_PRIORITY + 5,
459 NULL /*return task handle*/);
460
461 GPIOINT->IO0IntEnF |= (1 << 4); // Set GPIO falling interrupt
462 GPIOINT->IO0IntEnR |= (1 << 4); // Set GPIO rising interrupt
463 PINCON->PINSEL0 &= ~(0x3 << 8);
464
465 GPIOINT->IO0IntEnF |= (1 << 5); // Set GPIO falling interrupt
466 GPIOINT->IO0IntEnR |= (1 << 5); // Set GPIO rising interrupt
467 PINCON->PINSEL0 &= ~(0x3 << 10);
468
469 GPIOINT->IO0IntEnF |= (1 << 6);
470 PINCON->PINSEL0 &= ~(0x3 << 12);
471
472 GPIOINT->IO0IntEnF |= (1 << 7);
473 PINCON->PINSEL0 &= ~(0x3 << 14);
474 }
475}
476
477void fillSensorPacket(struct DataStruct *packet) {
Brian Silvermand36b7d32013-10-24 15:56:47 -0700478 if (gyro_output.initialized) {
479 packet->gyro_angle = gyro_output.angle;
480 packet->old_gyro_reading = gyro_output.last_reading_bad;
481 packet->bad_gyro = gyro_output.gyro_bad;
482 } else {
483 packet->gyro_angle = 0;
484 packet->old_gyro_reading = 1;
485 packet->bad_gyro = 0;
486 }
Brian Silvermanf92396c2013-09-12 20:13:13 -0700487
488 packet->dip_switch0 = dip_switch(0);
489 packet->dip_switch1 = dip_switch(1);
490 packet->dip_switch2 = dip_switch(2);
491 packet->dip_switch3 = dip_switch(3);
492
Brian Silverman25aae9a2013-10-08 13:37:45 -0700493 // We disable EINT3 to avoid sending back inconsistent values. All of the
494 // aligned reads from the variables are atomic, so disabling it isn't
495 // necessary for just reading encoder values. We re-enable it periodically
496 // because disabling and enabling is cheap (2 instructions) and we really rely
497 // on low interrupt latencies.
498
Brian Silvermanf92396c2013-09-12 20:13:13 -0700499 if (is_bot3) {
500 packet->robot_id = 1;
501 } else { // is main robot
502 packet->robot_id = 0;
503
504 packet->main.shooter = encoder1_val;
Brian Silverman1623c332013-10-01 18:05:16 -0700505 packet->main.left_drive = encoder5_val;
506 packet->main.right_drive = encoder4_val;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700507 packet->main.indexer = encoder3_val;
508
Brian Silverman25aae9a2013-10-08 13:37:45 -0700509 NVIC_DisableIRQ(EINT3_IRQn);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700510
511 packet->main.wrist = (int32_t)QEI->QEIPOS;
512 packet->main.wrist_hall_effect = !digital(3);
513 packet->main.capture_wrist_rise = capture_wrist_rise;
514 packet->main.wrist_rise_count = wrist_rise_count;
515
Brian Silverman25aae9a2013-10-08 13:37:45 -0700516 NVIC_EnableIRQ(EINT3_IRQn);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700517 NVIC_DisableIRQ(EINT3_IRQn);
518
519 packet->main.capture_top_rise = capture_top_rise;
520 packet->main.top_rise_count = top_rise_count;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700521 packet->main.capture_top_fall = capture_top_fall;
522 packet->main.top_fall_count = top_fall_count;
523 packet->main.top_disc = !digital(2);
524
Brian Silverman25aae9a2013-10-08 13:37:45 -0700525 NVIC_EnableIRQ(EINT3_IRQn);
526 NVIC_DisableIRQ(EINT3_IRQn);
527
Brian Silvermanf92396c2013-09-12 20:13:13 -0700528 packet->main.capture_bottom_fall_delay = capture_bottom_fall_delay;
529 packet->main.bottom_fall_delay_count = bottom_fall_delay_count;
530 packet->main.bottom_fall_count = bottom_fall_count;
531 packet->main.bottom_disc = !digital(1);
532
Brian Silverman25aae9a2013-10-08 13:37:45 -0700533 NVIC_EnableIRQ(EINT3_IRQn);
534 NVIC_DisableIRQ(EINT3_IRQn);
535
Brian Silverman1623c332013-10-01 18:05:16 -0700536 packet->main.loader_top = !digital(5);
537 packet->main.loader_bottom = !digital(6);
538
Brian Silverman25aae9a2013-10-08 13:37:45 -0700539 NVIC_EnableIRQ(EINT3_IRQn);
540 NVIC_DisableIRQ(EINT3_IRQn);
541
542 packet->main.shooter_angle = encoder2_val;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700543 packet->main.capture_shooter_angle_rise = capture_shooter_angle_rise;
544 packet->main.shooter_angle_rise_count = shooter_angle_rise_count;
545 packet->main.angle_adjust_bottom_hall_effect = !digital(4);
546
547 NVIC_EnableIRQ(EINT3_IRQn);
548
549 packet->main.bottom_rise_count = bottom_rise_count;
550 }
551}