blob: 581ddb4683b9a620f9bf4bfb337f2aabfda9c1d2 [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"
9
10// How long (in ms) to wait after a falling edge on the bottom indexer sensor
11// before reading the indexer encoder.
12static const int kBottomFallDelayTime = 32;
13
14#define ENC(gpio, a, b) readGPIO(gpio, a) * 2 + readGPIO(gpio, b)
15int encoder_bits(int channel) {
16 switch (channel) {
17 case 0:
18 return ENC(GPIO1, 20, 23);
19 case 1:
20 return ENC(GPIO2, 11, 12);
21 case 2:
22 return ENC(GPIO0, 21, 22);
23 case 3:
24 return ENC(GPIO0, 19, 20);
25 default:
26 return -1;
27 }
28 return -1;
29}
30#undef ENC
31
32// Uses EINT1 and EINT2 on 2.11 and 2.12.
33volatile int32_t encoder1_val;
34// On GPIO pins 0.22 and 0.21.
35volatile int32_t encoder2_val;
36// On GPIO pins 0.20 and 0.19.
37volatile int32_t encoder3_val;
38// On GPIO pins 2.0 and 2.1.
39volatile int32_t encoder4_val;
40// On GPIO pins 2.2 and 2.3.
41volatile int32_t encoder5_val;
42
Brian Silverman25aae9a2013-10-08 13:37:45 -070043// It is important to clear the various interrupt flags first thing in the ISRs.
44// It doesn't seem to work otherwise, possibly because of the reason that Brian
45// found poking around online: caches on the bus make it so that the clearing of
46// the interrupt gets to the NVIC after the ISR returns, so it runs the ISR a
47// second time. Also, by clearing them early, if a second interrupt arrives from
48// the same source it will still get handled instead of getting lost.
49
Brian Silvermanf92396c2013-09-12 20:13:13 -070050// ENC1A 2.11
51void EINT1_IRQHandler(void) {
Brian Silverman25aae9a2013-10-08 13:37:45 -070052 // Make sure to change this BEFORE clearing the interrupt like the datasheet
53 // says you have to.
Brian Silverman1623c332013-10-01 18:05:16 -070054 SC->EXTPOLAR ^= 0x2;
Brian Silvermanf92396c2013-09-12 20:13:13 -070055 SC->EXTINT = 0x2;
56 int fiopin = GPIO2->FIOPIN;
Brian Silverman25aae9a2013-10-08 13:37:45 -070057 // This looks like a weird way to XOR the 2 inputs, but it compiles down to
58 // just 2 instructions, which is hard to beat.
Brian Silvermanf92396c2013-09-12 20:13:13 -070059 if (((fiopin >> 1) ^ fiopin) & 0x800) {
60 ++encoder1_val;
61 } else {
62 --encoder1_val;
63 }
Brian Silvermanf92396c2013-09-12 20:13:13 -070064}
65// ENC1B 2.12
66void EINT2_IRQHandler(void) {
Brian Silverman1623c332013-10-01 18:05:16 -070067 SC->EXTPOLAR ^= 0x4;
Brian Silvermanf92396c2013-09-12 20:13:13 -070068 SC->EXTINT = 0x4;
69 int fiopin = GPIO2->FIOPIN;
70 if (((fiopin >> 1) ^ fiopin) & 0x800) {
71 --encoder1_val;
72 } else {
73 ++encoder1_val;
74 }
Brian Silvermanf92396c2013-09-12 20:13:13 -070075}
76
Brian Silverman1623c332013-10-01 18:05:16 -070077// TODO(brians): Have this indicate some kind of error instead of just looping
78// infinitely in the ISR because it never clears it.
79static void NoGPIO(void) {}
80static void Encoder2ARise(void) {
81 GPIOINT->IO0IntClr = (1 << 22);
Brian Silvermanf92396c2013-09-12 20:13:13 -070082 if (GPIO0->FIOPIN & (1 << 21)) {
83 ++encoder2_val;
84 } else {
85 --encoder2_val;
86 }
87}
Brian Silverman1623c332013-10-01 18:05:16 -070088static void Encoder2AFall(void) {
89 GPIOINT->IO0IntClr = (1 << 22);
Brian Silvermanf92396c2013-09-12 20:13:13 -070090 if (GPIO0->FIOPIN & (1 << 21)) {
91 --encoder2_val;
92 } else {
93 ++encoder2_val;
94 }
95}
Brian Silverman1623c332013-10-01 18:05:16 -070096static void Encoder2BRise(void) {
97 GPIOINT->IO0IntClr = (1 << 21);
Brian Silvermanf92396c2013-09-12 20:13:13 -070098 if (GPIO0->FIOPIN & (1 << 22)) {
99 --encoder2_val;
100 } else {
101 ++encoder2_val;
102 }
103}
Brian Silverman1623c332013-10-01 18:05:16 -0700104static void Encoder2BFall(void) {
105 GPIOINT->IO0IntClr = (1 << 21);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700106 if (GPIO0->FIOPIN & (1 << 22)) {
107 ++encoder2_val;
108 } else {
109 --encoder2_val;
110 }
111}
112
Brian Silverman1623c332013-10-01 18:05:16 -0700113static void Encoder3ARise(void) {
114 GPIOINT->IO0IntClr = (1 << 20);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700115 if (GPIO0->FIOPIN & (1 << 19)) {
116 ++encoder3_val;
117 } else {
118 --encoder3_val;
119 }
120}
Brian Silverman1623c332013-10-01 18:05:16 -0700121static void Encoder3AFall(void) {
122 GPIOINT->IO0IntClr = (1 << 20);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700123 if (GPIO0->FIOPIN & (1 << 19)) {
124 --encoder3_val;
125 } else {
126 ++encoder3_val;
127 }
128}
Brian Silverman1623c332013-10-01 18:05:16 -0700129static void Encoder3BRise(void) {
130 GPIOINT->IO0IntClr = (1 << 19);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700131 if (GPIO0->FIOPIN & (1 << 20)) {
132 --encoder3_val;
133 } else {
134 ++encoder3_val;
135 }
136}
Brian Silverman1623c332013-10-01 18:05:16 -0700137static void Encoder3BFall(void) {
138 GPIOINT->IO0IntClr = (1 << 19);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700139 if (GPIO0->FIOPIN & (1 << 20)) {
140 ++encoder3_val;
141 } else {
142 --encoder3_val;
143 }
144}
145
Brian Silverman1623c332013-10-01 18:05:16 -0700146static void Encoder4ARise(void) {
147 GPIOINT->IO2IntClr = (1 << 0);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700148 if (GPIO2->FIOPIN & (1 << 1)) {
149 ++encoder4_val;
150 } else {
151 --encoder4_val;
152 }
153}
Brian Silverman1623c332013-10-01 18:05:16 -0700154static void Encoder4AFall(void) {
155 GPIOINT->IO2IntClr = (1 << 0);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700156 if (GPIO2->FIOPIN & (1 << 1)) {
157 --encoder4_val;
158 } else {
159 ++encoder4_val;
160 }
161}
Brian Silverman1623c332013-10-01 18:05:16 -0700162static void Encoder4BRise(void) {
163 GPIOINT->IO2IntClr = (1 << 1);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700164 if (GPIO2->FIOPIN & (1 << 0)) {
165 --encoder4_val;
166 } else {
167 ++encoder4_val;
168 }
169}
Brian Silverman1623c332013-10-01 18:05:16 -0700170static void Encoder4BFall(void) {
171 GPIOINT->IO2IntClr = (1 << 1);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700172 if (GPIO2->FIOPIN & (1 << 0)) {
173 ++encoder4_val;
174 } else {
175 --encoder4_val;
176 }
177}
178
Brian Silverman1623c332013-10-01 18:05:16 -0700179static void Encoder5ARise(void) {
180 GPIOINT->IO2IntClr = (1 << 2);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700181 if (GPIO2->FIOPIN & (1 << 3)) {
182 ++encoder5_val;
183 } else {
184 --encoder5_val;
185 }
186}
Brian Silverman1623c332013-10-01 18:05:16 -0700187static void Encoder5AFall(void) {
188 GPIOINT->IO2IntClr = (1 << 2);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700189 if (GPIO2->FIOPIN & (1 << 3)) {
190 --encoder5_val;
191 } else {
192 ++encoder5_val;
193 }
194}
Brian Silverman1623c332013-10-01 18:05:16 -0700195static void Encoder5BRise(void) {
196 GPIOINT->IO2IntClr = (1 << 3);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700197 if (GPIO2->FIOPIN & (1 << 2)) {
198 --encoder5_val;
199 } else {
200 ++encoder5_val;
201 }
202}
Brian Silverman1623c332013-10-01 18:05:16 -0700203static void Encoder5BFall(void) {
204 GPIOINT->IO2IntClr = (1 << 3);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700205 if (GPIO2->FIOPIN & (1 << 2)) {
206 ++encoder5_val;
207 } else {
208 --encoder5_val;
209 }
210}
211
212volatile int32_t capture_top_rise;
213volatile int8_t top_rise_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700214static void IndexerTopRise(void) {
215 GPIOINT->IO0IntClr = (1 << 5);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700216 // edge counting encoder capture
217 ++top_rise_count;
218 capture_top_rise = encoder3_val;
219}
220volatile int32_t capture_top_fall;
221volatile int8_t top_fall_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700222static void IndexerTopFall(void) {
223 GPIOINT->IO0IntClr = (1 << 5);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700224 // edge counting encoder capture
225 ++top_fall_count;
226 capture_top_fall = encoder3_val;
227}
228volatile int8_t bottom_rise_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700229static void IndexerBottomRise(void) {
230 GPIOINT->IO0IntClr = (1 << 4);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700231 // edge counting
232 ++bottom_rise_count;
233}
234volatile int32_t capture_bottom_fall_delay;
235volatile int8_t bottom_fall_delay_count;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700236portTickType xDelayTimeFrom;
237static portTASK_FUNCTION(vDelayCapture, pvParameters)
238{
239 portTickType xSleepFrom = xTaskGetTickCount();
240
241 for (;;) {
Brian Silverman25aae9a2013-10-08 13:37:45 -0700242 // Atomically (wrt the ISR) switch xDelayTimeFrom to 0 and store its old
243 // value to use later.
Brian Silvermanf92396c2013-09-12 20:13:13 -0700244 NVIC_DisableIRQ(EINT3_IRQn);
Brian Silverman25aae9a2013-10-08 13:37:45 -0700245 portTickType new_time = xDelayTimeFrom;
246 xDelayTimeFrom = 0;
247 NVIC_EnableIRQ(EINT3_IRQn);
248
249 if (new_time != 0) {
250 xSleepFrom = new_time;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700251
252 vTaskDelayUntil(&xSleepFrom, kBottomFallDelayTime / portTICK_RATE_MS);
253
Brian Silverman25aae9a2013-10-08 13:37:45 -0700254 // Make sure that the USB ISR doesn't look at inconsistent values.
Brian Silverman1623c332013-10-01 18:05:16 -0700255 NVIC_DisableIRQ(USB_IRQn);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700256 capture_bottom_fall_delay = encoder3_val;
Brian Silverman1623c332013-10-01 18:05:16 -0700257 ++bottom_fall_delay_count;
258 NVIC_EnableIRQ(USB_IRQn);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700259 } else {
Brian Silverman25aae9a2013-10-08 13:37:45 -0700260 // Wait 10ms and then check again.
Brian Silvermanf92396c2013-09-12 20:13:13 -0700261 vTaskDelayUntil(&xSleepFrom, 10 / portTICK_RATE_MS);
262 }
263 }
264}
265
266volatile int8_t bottom_fall_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700267static void IndexerBottomFall(void) {
268 GPIOINT->IO0IntClr = (1 << 4);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700269 ++bottom_fall_count;
270 // edge counting start delayed capture
271 xDelayTimeFrom = xTaskGetTickCount();
Brian Silvermanf92396c2013-09-12 20:13:13 -0700272}
273volatile int32_t capture_wrist_rise;
274volatile int8_t wrist_rise_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700275static void WristHallRise(void) {
276 GPIOINT->IO0IntClr = (1 << 6);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700277 // edge counting encoder capture
278 ++wrist_rise_count;
279 capture_wrist_rise = (int32_t)QEI->QEIPOS;
280}
281volatile int32_t capture_shooter_angle_rise;
282volatile int8_t shooter_angle_rise_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700283static void ShooterHallRise(void) {
284 GPIOINT->IO0IntClr = (1 << 7);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700285 // edge counting encoder capture
286 ++shooter_angle_rise_count;
287 capture_shooter_angle_rise = encoder2_val;
288}
289
290// Count leading zeros.
291// Returns 0 if bit 31 is set etc.
292__attribute__((always_inline)) static __INLINE uint32_t __clz(uint32_t value) {
293 uint32_t result;
294 __asm__("clz %0, %1" : "=r" (result) : "r" (value));
295 return result;
296}
297inline static void IRQ_Dispatch(void) {
Brian Silverman25aae9a2013-10-08 13:37:45 -0700298 // There is no need to add a loop here to handle multiple interrupts at the
299 // same time because the processor has tail chaining of interrupts which we
300 // can't really beat with our own loop.
301 // It would actually be bad because a loop here would block EINT1/2 for longer
302 // lengths of time.
303
Brian Silvermanf92396c2013-09-12 20:13:13 -0700304 uint32_t index = __clz(GPIOINT->IO2IntStatR | GPIOINT->IO0IntStatR |
305 (GPIOINT->IO2IntStatF << 28) | (GPIOINT->IO0IntStatF << 4));
306
307 typedef void (*Handler)(void);
308 const static Handler table[] = {
309 Encoder5BFall, // index 0: P2.3 Fall #bit 31 //Encoder 5 B //Dio 10
310 Encoder5AFall, // index 1: P2.2 Fall #bit 30 //Encoder 5 A //Dio 9
311 Encoder4BFall, // index 2: P2.1 Fall #bit 29 //Encoder 4 B //Dio 8
312 Encoder4AFall, // index 3: P2.0 Fall #bit 28 //Encoder 4 A //Dio 7
313 NoGPIO, // index 4: NO GPIO #bit 27
314 Encoder2AFall, // index 5: P0.22 Fall #bit 26 //Encoder 2 A
315 Encoder2BFall, // index 6: P0.21 Fall #bit 25 //Encoder 2 B
316 Encoder3AFall, // index 7: P0.20 Fall #bit 24 //Encoder 3 A
317 Encoder3BFall, // index 8: P0.19 Fall #bit 23 //Encoder 3 B
318 Encoder2ARise, // index 9: P0.22 Rise #bit 22 //Encoder 2 A
319 Encoder2BRise, // index 10: P0.21 Rise #bit 21 //Encoder 2 B
320 Encoder3ARise, // index 11: P0.20 Rise #bit 20 //Encoder 3 A
321 Encoder3BRise, // index 12: P0.19 Rise #bit 19 //Encoder 3 B
322 NoGPIO, // index 13: NO GPIO #bit 18
323 NoGPIO, // index 14: NO GPIO #bit 17
324 NoGPIO, // index 15: NO GPIO #bit 16
325 NoGPIO, // index 16: NO GPIO #bit 15
326 NoGPIO, // index 17: NO GPIO #bit 14
327 NoGPIO, // index 18: NO GPIO #bit 13
328 NoGPIO, // index 19: NO GPIO #bit 12
329 ShooterHallRise, // index 20: P0.7 Fall #bit 11 //Shooter Hall //Dio 4
330 WristHallRise, // index 21: P0.6 Fall #bit 10 //Wrist Hall //Dio 3
331 IndexerTopRise, // index 22: P0.5 Fall #bit 9 //Indexer Top //Dio 2
332 IndexerBottomRise, // index 23: P0.4 Fall #bit 8 //Indexer Bottom //Dio 1
333 NoGPIO, // index 24: NO GPIO #bit 7
334 NoGPIO, // index 25: NO GPIO #bit 6
335 IndexerTopFall, // index 26: P0.5 Rise #bit 5 //Indexer Top //Dio 2
336 IndexerBottomFall, // index 27: P0.4 Rise #bit 4 //Indexer Bottom //Dio 1
337 Encoder5BRise, // index 28: P2.3 Rise #bit 3 //Encoder 5 B //Dio 10
338 Encoder5ARise, // index 29: P2.2 Rise #bit 2 //Encoder 5 A //Dio 9
339 Encoder4BRise, // index 30: P2.1 Rise #bit 1 //Encoder 4 B //Dio 8
340 Encoder4ARise, // index 31: P2.0 Rise #bit 0 //Encoder 4 A //Dio 7
341 NoGPIO // index 32: NO BITS SET #False Alarm
342 };
343 table[index]();
344}
345void EINT3_IRQHandler(void) {
Brian Silvermanf92396c2013-09-12 20:13:13 -0700346 IRQ_Dispatch();
Brian Silvermanf92396c2013-09-12 20:13:13 -0700347}
348int32_t encoder_val(int chan) {
349 int32_t val;
350 switch (chan) {
351 case 0: // Wrist
352 return (int32_t)QEI->QEIPOS;
353 case 1: // Shooter Wheel
354 NVIC_DisableIRQ(EINT1_IRQn);
355 NVIC_DisableIRQ(EINT2_IRQn);
356 val = encoder1_val;
357 NVIC_EnableIRQ(EINT2_IRQn);
358 NVIC_EnableIRQ(EINT1_IRQn);
359 return val;
360 case 2: // Shooter Angle
361 NVIC_DisableIRQ(EINT3_IRQn);
362 val = encoder2_val;
363 NVIC_EnableIRQ(EINT3_IRQn);
364 return val;
365 case 3: // Indexer
366 NVIC_DisableIRQ(EINT3_IRQn);
367 val = encoder3_val;
368 NVIC_EnableIRQ(EINT3_IRQn);
369 return val;
370 case 4: // Drive R
371 NVIC_DisableIRQ(EINT3_IRQn);
372 val = encoder4_val;
373 NVIC_EnableIRQ(EINT3_IRQn);
374 return val;
375 case 5: // Drive L
376 NVIC_DisableIRQ(EINT3_IRQn);
377 val = encoder5_val;
378 NVIC_EnableIRQ(EINT3_IRQn);
379 return val;
380 default:
381 return -1;
382 }
383}
384
385void encoder_init(void) {
386 // Setup the encoder interface.
387 SC->PCONP |= PCONP_PCQEI;
388 PINCON->PINSEL3 = ((PINCON->PINSEL3 & 0xffff3dff) | 0x00004100);
389 // Reset the count and velocity.
390 QEI->QEICON = 0x00000005;
391 QEI->QEICONF = 0x00000004;
392 // Wrap back to 0 when we wrap the int and vice versa.
393 QEI->QEIMAXPOS = 0xFFFFFFFF;
394
395 // Set up encoder 1.
396 // Make GPIOs 2.11 and 2.12 trigger EINT1 and EINT2 (respectively).
397 // PINSEL4[23:22] = {0 1}
398 // PINSEL4[25:24] = {0 1}
399 PINCON->PINSEL4 = (PINCON->PINSEL4 & ~(0x3 << 22)) | (0x1 << 22);
400 PINCON->PINSEL4 = (PINCON->PINSEL4 & ~(0x3 << 24)) | (0x1 << 24);
401 // Clear the interrupt flags for EINT1 and EINT2 (0x6 = 0b0110).
402 SC->EXTMODE = 0x6;
403 SC->EXTINT = 0x6;
404 NVIC_EnableIRQ(EINT1_IRQn);
405 NVIC_EnableIRQ(EINT2_IRQn);
406 encoder1_val = 0;
407
408 // Set up encoder 2.
409 GPIOINT->IO0IntEnF |= (1 << 22); // Set GPIO falling interrupt.
410 GPIOINT->IO0IntEnR |= (1 << 22); // Set GPIO rising interrupt.
411 GPIOINT->IO0IntEnF |= (1 << 21); // Set GPIO falling interrupt.
412 GPIOINT->IO0IntEnR |= (1 << 21); // Set GPIO rising interrupt.
413 // Make sure they're in mode 00 (the default, aka nothing special).
414 PINCON->PINSEL1 &= ~(0x3 << 12);
415 PINCON->PINSEL1 &= ~(0x3 << 10);
416 encoder2_val = 0;
417
418 // Set up encoder 3.
419 GPIOINT->IO0IntEnF |= (1 << 20); // Set GPIO falling interrupt.
420 GPIOINT->IO0IntEnR |= (1 << 20); // Set GPIO rising interrupt.
421 GPIOINT->IO0IntEnF |= (1 << 19); // Set GPIO falling interrupt.
422 GPIOINT->IO0IntEnR |= (1 << 19); // Set GPIO rising interrupt.
423 // Make sure they're in mode 00 (the default, aka nothing special).
424 PINCON->PINSEL1 &= ~(0x3 << 8);
425 PINCON->PINSEL1 &= ~(0x3 << 6);
426 encoder3_val = 0;
427
428 // Set up encoder 4.
429 GPIOINT->IO2IntEnF |= (1 << 0); // Set GPIO falling interrupt.
430 GPIOINT->IO2IntEnR |= (1 << 0); // Set GPIO rising interrupt.
431 GPIOINT->IO2IntEnF |= (1 << 1); // Set GPIO falling interrupt.
432 GPIOINT->IO2IntEnR |= (1 << 1); // Set GPIO rising interrupt.
433 // Make sure they're in mode 00 (the default, aka nothing special).
434 PINCON->PINSEL4 &= ~(0x3 << 0);
435 PINCON->PINSEL4 &= ~(0x3 << 2);
436 encoder4_val = 0;
437
438 // Set up encoder 5.
439 GPIOINT->IO2IntEnF |= (1 << 2); // Set GPIO falling interrupt.
440 GPIOINT->IO2IntEnR |= (1 << 2); // Set GPIO rising interrupt.
441 GPIOINT->IO2IntEnF |= (1 << 3); // Set GPIO falling interrupt.
442 GPIOINT->IO2IntEnR |= (1 << 3); // Set GPIO rising interrupt.
443 // Make sure they're in mode 00 (the default, aka nothing special).
444 PINCON->PINSEL4 &= ~(0x3 << 4);
445 PINCON->PINSEL4 &= ~(0x3 << 6);
446 encoder5_val = 0;
447
448 // Enable interrupts from the GPIO pins.
449 NVIC_EnableIRQ(EINT3_IRQn);
450
451 if (is_bot3) {
452 } else { // is main robot
453 xTaskCreate(vDelayCapture,
454 (signed char *) "SENSORs",
455 configMINIMAL_STACK_SIZE + 100,
456 NULL /*parameters*/,
457 tskIDLE_PRIORITY + 5,
458 NULL /*return task handle*/);
459
460 GPIOINT->IO0IntEnF |= (1 << 4); // Set GPIO falling interrupt
461 GPIOINT->IO0IntEnR |= (1 << 4); // Set GPIO rising interrupt
462 PINCON->PINSEL0 &= ~(0x3 << 8);
463
464 GPIOINT->IO0IntEnF |= (1 << 5); // Set GPIO falling interrupt
465 GPIOINT->IO0IntEnR |= (1 << 5); // Set GPIO rising interrupt
466 PINCON->PINSEL0 &= ~(0x3 << 10);
467
468 GPIOINT->IO0IntEnF |= (1 << 6);
469 PINCON->PINSEL0 &= ~(0x3 << 12);
470
471 GPIOINT->IO0IntEnF |= (1 << 7);
472 PINCON->PINSEL0 &= ~(0x3 << 14);
473 }
474}
475
476void fillSensorPacket(struct DataStruct *packet) {
477 packet->gyro_angle = gyro_angle;
478
479 packet->dip_switch0 = dip_switch(0);
480 packet->dip_switch1 = dip_switch(1);
481 packet->dip_switch2 = dip_switch(2);
482 packet->dip_switch3 = dip_switch(3);
483
Brian Silverman25aae9a2013-10-08 13:37:45 -0700484 // We disable EINT3 to avoid sending back inconsistent values. All of the
485 // aligned reads from the variables are atomic, so disabling it isn't
486 // necessary for just reading encoder values. We re-enable it periodically
487 // because disabling and enabling is cheap (2 instructions) and we really rely
488 // on low interrupt latencies.
489
Brian Silvermanf92396c2013-09-12 20:13:13 -0700490 if (is_bot3) {
491 packet->robot_id = 1;
492 } else { // is main robot
493 packet->robot_id = 0;
494
495 packet->main.shooter = encoder1_val;
Brian Silverman1623c332013-10-01 18:05:16 -0700496 packet->main.left_drive = encoder5_val;
497 packet->main.right_drive = encoder4_val;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700498 packet->main.indexer = encoder3_val;
499
Brian Silverman25aae9a2013-10-08 13:37:45 -0700500 NVIC_DisableIRQ(EINT3_IRQn);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700501
502 packet->main.wrist = (int32_t)QEI->QEIPOS;
503 packet->main.wrist_hall_effect = !digital(3);
504 packet->main.capture_wrist_rise = capture_wrist_rise;
505 packet->main.wrist_rise_count = wrist_rise_count;
506
Brian Silverman25aae9a2013-10-08 13:37:45 -0700507 NVIC_EnableIRQ(EINT3_IRQn);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700508 NVIC_DisableIRQ(EINT3_IRQn);
509
510 packet->main.capture_top_rise = capture_top_rise;
511 packet->main.top_rise_count = top_rise_count;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700512 packet->main.capture_top_fall = capture_top_fall;
513 packet->main.top_fall_count = top_fall_count;
514 packet->main.top_disc = !digital(2);
515
Brian Silverman25aae9a2013-10-08 13:37:45 -0700516 NVIC_EnableIRQ(EINT3_IRQn);
517 NVIC_DisableIRQ(EINT3_IRQn);
518
Brian Silvermanf92396c2013-09-12 20:13:13 -0700519 packet->main.capture_bottom_fall_delay = capture_bottom_fall_delay;
520 packet->main.bottom_fall_delay_count = bottom_fall_delay_count;
521 packet->main.bottom_fall_count = bottom_fall_count;
522 packet->main.bottom_disc = !digital(1);
523
Brian Silverman25aae9a2013-10-08 13:37:45 -0700524 NVIC_EnableIRQ(EINT3_IRQn);
525 NVIC_DisableIRQ(EINT3_IRQn);
526
Brian Silverman1623c332013-10-01 18:05:16 -0700527 packet->main.loader_top = !digital(5);
528 packet->main.loader_bottom = !digital(6);
529
Brian Silverman25aae9a2013-10-08 13:37:45 -0700530 NVIC_EnableIRQ(EINT3_IRQn);
531 NVIC_DisableIRQ(EINT3_IRQn);
532
533 packet->main.shooter_angle = encoder2_val;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700534 packet->main.capture_shooter_angle_rise = capture_shooter_angle_rise;
535 packet->main.shooter_angle_rise_count = shooter_angle_rise_count;
536 packet->main.angle_adjust_bottom_hall_effect = !digital(4);
537
538 NVIC_EnableIRQ(EINT3_IRQn);
539
540 packet->main.bottom_rise_count = bottom_rise_count;
541 }
542}