blob: ef5af7fce487d9899182fa0ff6f58820ca6dfa9d [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
Brian Silvermana280ae02013-10-28 18:21:15 -070015// The timer to use for timestamping sensor readings.
16// This is a constant to avoid hard-coding it in a lot of places, but there ARE
17// things (PCONP bits, IRQ numbers, etc) that have this value in them
18// implicitly.
19#define SENSOR_TIMING_TIMER TIM1
20// How many counts per second SENSOR_TIMING_TIMER should be.
21// This will wrap the counter about every 1/3 of a second.
22static const int kSensorTimingRate = 100000;
23
Brian Silvermanf92396c2013-09-12 20:13:13 -070024#define ENC(gpio, a, b) readGPIO(gpio, a) * 2 + readGPIO(gpio, b)
25int encoder_bits(int channel) {
26 switch (channel) {
27 case 0:
28 return ENC(GPIO1, 20, 23);
29 case 1:
30 return ENC(GPIO2, 11, 12);
31 case 2:
32 return ENC(GPIO0, 21, 22);
33 case 3:
34 return ENC(GPIO0, 19, 20);
35 default:
36 return -1;
37 }
38 return -1;
39}
40#undef ENC
41
42// Uses EINT1 and EINT2 on 2.11 and 2.12.
43volatile int32_t encoder1_val;
44// On GPIO pins 0.22 and 0.21.
45volatile int32_t encoder2_val;
46// On GPIO pins 0.20 and 0.19.
47volatile int32_t encoder3_val;
48// On GPIO pins 2.0 and 2.1.
49volatile int32_t encoder4_val;
50// On GPIO pins 2.2 and 2.3.
51volatile int32_t encoder5_val;
52
Brian Silverman25aae9a2013-10-08 13:37:45 -070053// It is important to clear the various interrupt flags first thing in the ISRs.
54// It doesn't seem to work otherwise, possibly because of the reason that Brian
55// found poking around online: caches on the bus make it so that the clearing of
56// the interrupt gets to the NVIC after the ISR returns, so it runs the ISR a
57// second time. Also, by clearing them early, if a second interrupt arrives from
58// the same source it will still get handled instead of getting lost.
59
Brian Silvermanf92396c2013-09-12 20:13:13 -070060// ENC1A 2.11
61void EINT1_IRQHandler(void) {
Brian Silverman25aae9a2013-10-08 13:37:45 -070062 // Make sure to change this BEFORE clearing the interrupt like the datasheet
63 // says you have to.
Brian Silverman1623c332013-10-01 18:05:16 -070064 SC->EXTPOLAR ^= 0x2;
Brian Silvermanf92396c2013-09-12 20:13:13 -070065 SC->EXTINT = 0x2;
66 int fiopin = GPIO2->FIOPIN;
Brian Silverman25aae9a2013-10-08 13:37:45 -070067 // This looks like a weird way to XOR the 2 inputs, but it compiles down to
68 // just 2 instructions, which is hard to beat.
Brian Silvermanf92396c2013-09-12 20:13:13 -070069 if (((fiopin >> 1) ^ fiopin) & 0x800) {
70 ++encoder1_val;
71 } else {
72 --encoder1_val;
73 }
Brian Silvermanf92396c2013-09-12 20:13:13 -070074}
75// ENC1B 2.12
76void EINT2_IRQHandler(void) {
Brian Silverman1623c332013-10-01 18:05:16 -070077 SC->EXTPOLAR ^= 0x4;
Brian Silvermanf92396c2013-09-12 20:13:13 -070078 SC->EXTINT = 0x4;
79 int fiopin = GPIO2->FIOPIN;
80 if (((fiopin >> 1) ^ fiopin) & 0x800) {
81 --encoder1_val;
82 } else {
83 ++encoder1_val;
84 }
Brian Silvermanf92396c2013-09-12 20:13:13 -070085}
86
Brian Silverman1623c332013-10-01 18:05:16 -070087// TODO(brians): Have this indicate some kind of error instead of just looping
88// infinitely in the ISR because it never clears it.
89static void NoGPIO(void) {}
90static void Encoder2ARise(void) {
91 GPIOINT->IO0IntClr = (1 << 22);
Brian Silvermanf92396c2013-09-12 20:13:13 -070092 if (GPIO0->FIOPIN & (1 << 21)) {
93 ++encoder2_val;
94 } else {
95 --encoder2_val;
96 }
97}
Brian Silverman1623c332013-10-01 18:05:16 -070098static void Encoder2AFall(void) {
99 GPIOINT->IO0IntClr = (1 << 22);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700100 if (GPIO0->FIOPIN & (1 << 21)) {
101 --encoder2_val;
102 } else {
103 ++encoder2_val;
104 }
105}
Brian Silverman1623c332013-10-01 18:05:16 -0700106static void Encoder2BRise(void) {
107 GPIOINT->IO0IntClr = (1 << 21);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700108 if (GPIO0->FIOPIN & (1 << 22)) {
109 --encoder2_val;
110 } else {
111 ++encoder2_val;
112 }
113}
Brian Silverman1623c332013-10-01 18:05:16 -0700114static void Encoder2BFall(void) {
115 GPIOINT->IO0IntClr = (1 << 21);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700116 if (GPIO0->FIOPIN & (1 << 22)) {
117 ++encoder2_val;
118 } else {
119 --encoder2_val;
120 }
121}
122
Brian Silverman1623c332013-10-01 18:05:16 -0700123static void Encoder3ARise(void) {
124 GPIOINT->IO0IntClr = (1 << 20);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700125 if (GPIO0->FIOPIN & (1 << 19)) {
126 ++encoder3_val;
127 } else {
128 --encoder3_val;
129 }
130}
Brian Silverman1623c332013-10-01 18:05:16 -0700131static void Encoder3AFall(void) {
132 GPIOINT->IO0IntClr = (1 << 20);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700133 if (GPIO0->FIOPIN & (1 << 19)) {
134 --encoder3_val;
135 } else {
136 ++encoder3_val;
137 }
138}
Brian Silverman1623c332013-10-01 18:05:16 -0700139static void Encoder3BRise(void) {
140 GPIOINT->IO0IntClr = (1 << 19);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700141 if (GPIO0->FIOPIN & (1 << 20)) {
142 --encoder3_val;
143 } else {
144 ++encoder3_val;
145 }
146}
Brian Silverman1623c332013-10-01 18:05:16 -0700147static void Encoder3BFall(void) {
148 GPIOINT->IO0IntClr = (1 << 19);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700149 if (GPIO0->FIOPIN & (1 << 20)) {
150 ++encoder3_val;
151 } else {
152 --encoder3_val;
153 }
154}
155
Brian Silverman1623c332013-10-01 18:05:16 -0700156static void Encoder4ARise(void) {
157 GPIOINT->IO2IntClr = (1 << 0);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700158 if (GPIO2->FIOPIN & (1 << 1)) {
159 ++encoder4_val;
160 } else {
161 --encoder4_val;
162 }
163}
Brian Silverman1623c332013-10-01 18:05:16 -0700164static void Encoder4AFall(void) {
165 GPIOINT->IO2IntClr = (1 << 0);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700166 if (GPIO2->FIOPIN & (1 << 1)) {
167 --encoder4_val;
168 } else {
169 ++encoder4_val;
170 }
171}
Brian Silverman1623c332013-10-01 18:05:16 -0700172static void Encoder4BRise(void) {
173 GPIOINT->IO2IntClr = (1 << 1);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700174 if (GPIO2->FIOPIN & (1 << 0)) {
175 --encoder4_val;
176 } else {
177 ++encoder4_val;
178 }
179}
Brian Silverman1623c332013-10-01 18:05:16 -0700180static void Encoder4BFall(void) {
181 GPIOINT->IO2IntClr = (1 << 1);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700182 if (GPIO2->FIOPIN & (1 << 0)) {
183 ++encoder4_val;
184 } else {
185 --encoder4_val;
186 }
187}
188
Brian Silverman1623c332013-10-01 18:05:16 -0700189static void Encoder5ARise(void) {
190 GPIOINT->IO2IntClr = (1 << 2);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700191 if (GPIO2->FIOPIN & (1 << 3)) {
192 ++encoder5_val;
193 } else {
194 --encoder5_val;
195 }
196}
Brian Silverman1623c332013-10-01 18:05:16 -0700197static void Encoder5AFall(void) {
198 GPIOINT->IO2IntClr = (1 << 2);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700199 if (GPIO2->FIOPIN & (1 << 3)) {
200 --encoder5_val;
201 } else {
202 ++encoder5_val;
203 }
204}
Brian Silverman1623c332013-10-01 18:05:16 -0700205static void Encoder5BRise(void) {
206 GPIOINT->IO2IntClr = (1 << 3);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700207 if (GPIO2->FIOPIN & (1 << 2)) {
208 --encoder5_val;
209 } else {
210 ++encoder5_val;
211 }
212}
Brian Silverman1623c332013-10-01 18:05:16 -0700213static void Encoder5BFall(void) {
214 GPIOINT->IO2IntClr = (1 << 3);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700215 if (GPIO2->FIOPIN & (1 << 2)) {
216 ++encoder5_val;
217 } else {
218 --encoder5_val;
219 }
220}
221
222volatile int32_t capture_top_rise;
223volatile int8_t top_rise_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700224static void IndexerTopRise(void) {
225 GPIOINT->IO0IntClr = (1 << 5);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700226 // edge counting encoder capture
227 ++top_rise_count;
228 capture_top_rise = encoder3_val;
229}
230volatile int32_t capture_top_fall;
231volatile int8_t top_fall_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700232static void IndexerTopFall(void) {
233 GPIOINT->IO0IntClr = (1 << 5);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700234 // edge counting encoder capture
235 ++top_fall_count;
236 capture_top_fall = encoder3_val;
237}
238volatile int8_t bottom_rise_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700239static void IndexerBottomRise(void) {
240 GPIOINT->IO0IntClr = (1 << 4);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700241 // edge counting
242 ++bottom_rise_count;
243}
244volatile int32_t capture_bottom_fall_delay;
245volatile int8_t bottom_fall_delay_count;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700246portTickType xDelayTimeFrom;
247static portTASK_FUNCTION(vDelayCapture, pvParameters)
248{
249 portTickType xSleepFrom = xTaskGetTickCount();
250
251 for (;;) {
Brian Silverman25aae9a2013-10-08 13:37:45 -0700252 // Atomically (wrt the ISR) switch xDelayTimeFrom to 0 and store its old
253 // value to use later.
Brian Silvermanf92396c2013-09-12 20:13:13 -0700254 NVIC_DisableIRQ(EINT3_IRQn);
Brian Silverman25aae9a2013-10-08 13:37:45 -0700255 portTickType new_time = xDelayTimeFrom;
256 xDelayTimeFrom = 0;
257 NVIC_EnableIRQ(EINT3_IRQn);
258
259 if (new_time != 0) {
260 xSleepFrom = new_time;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700261
262 vTaskDelayUntil(&xSleepFrom, kBottomFallDelayTime / portTICK_RATE_MS);
263
Brian Silverman25aae9a2013-10-08 13:37:45 -0700264 // Make sure that the USB ISR doesn't look at inconsistent values.
Brian Silverman1623c332013-10-01 18:05:16 -0700265 NVIC_DisableIRQ(USB_IRQn);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700266 capture_bottom_fall_delay = encoder3_val;
Brian Silverman1623c332013-10-01 18:05:16 -0700267 ++bottom_fall_delay_count;
268 NVIC_EnableIRQ(USB_IRQn);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700269 } else {
Brian Silverman25aae9a2013-10-08 13:37:45 -0700270 // Wait 10ms and then check again.
Brian Silvermanf92396c2013-09-12 20:13:13 -0700271 vTaskDelayUntil(&xSleepFrom, 10 / portTICK_RATE_MS);
272 }
273 }
274}
275
276volatile int8_t bottom_fall_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700277static void IndexerBottomFall(void) {
278 GPIOINT->IO0IntClr = (1 << 4);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700279 ++bottom_fall_count;
280 // edge counting start delayed capture
281 xDelayTimeFrom = xTaskGetTickCount();
Brian Silvermanf92396c2013-09-12 20:13:13 -0700282}
283volatile int32_t capture_wrist_rise;
284volatile int8_t wrist_rise_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700285static void WristHallRise(void) {
286 GPIOINT->IO0IntClr = (1 << 6);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700287 // edge counting encoder capture
288 ++wrist_rise_count;
289 capture_wrist_rise = (int32_t)QEI->QEIPOS;
290}
291volatile int32_t capture_shooter_angle_rise;
292volatile int8_t shooter_angle_rise_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700293static void ShooterHallRise(void) {
294 GPIOINT->IO0IntClr = (1 << 7);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700295 // edge counting encoder capture
296 ++shooter_angle_rise_count;
297 capture_shooter_angle_rise = encoder2_val;
298}
299
300// Count leading zeros.
301// Returns 0 if bit 31 is set etc.
302__attribute__((always_inline)) static __INLINE uint32_t __clz(uint32_t value) {
303 uint32_t result;
304 __asm__("clz %0, %1" : "=r" (result) : "r" (value));
305 return result;
306}
307inline static void IRQ_Dispatch(void) {
Brian Silverman25aae9a2013-10-08 13:37:45 -0700308 // There is no need to add a loop here to handle multiple interrupts at the
309 // same time because the processor has tail chaining of interrupts which we
310 // can't really beat with our own loop.
311 // It would actually be bad because a loop here would block EINT1/2 for longer
312 // lengths of time.
313
Brian Silvermanf92396c2013-09-12 20:13:13 -0700314 uint32_t index = __clz(GPIOINT->IO2IntStatR | GPIOINT->IO0IntStatR |
315 (GPIOINT->IO2IntStatF << 28) | (GPIOINT->IO0IntStatF << 4));
316
317 typedef void (*Handler)(void);
318 const static Handler table[] = {
319 Encoder5BFall, // index 0: P2.3 Fall #bit 31 //Encoder 5 B //Dio 10
320 Encoder5AFall, // index 1: P2.2 Fall #bit 30 //Encoder 5 A //Dio 9
321 Encoder4BFall, // index 2: P2.1 Fall #bit 29 //Encoder 4 B //Dio 8
322 Encoder4AFall, // index 3: P2.0 Fall #bit 28 //Encoder 4 A //Dio 7
323 NoGPIO, // index 4: NO GPIO #bit 27
324 Encoder2AFall, // index 5: P0.22 Fall #bit 26 //Encoder 2 A
325 Encoder2BFall, // index 6: P0.21 Fall #bit 25 //Encoder 2 B
326 Encoder3AFall, // index 7: P0.20 Fall #bit 24 //Encoder 3 A
327 Encoder3BFall, // index 8: P0.19 Fall #bit 23 //Encoder 3 B
328 Encoder2ARise, // index 9: P0.22 Rise #bit 22 //Encoder 2 A
329 Encoder2BRise, // index 10: P0.21 Rise #bit 21 //Encoder 2 B
330 Encoder3ARise, // index 11: P0.20 Rise #bit 20 //Encoder 3 A
331 Encoder3BRise, // index 12: P0.19 Rise #bit 19 //Encoder 3 B
332 NoGPIO, // index 13: NO GPIO #bit 18
333 NoGPIO, // index 14: NO GPIO #bit 17
334 NoGPIO, // index 15: NO GPIO #bit 16
335 NoGPIO, // index 16: NO GPIO #bit 15
336 NoGPIO, // index 17: NO GPIO #bit 14
337 NoGPIO, // index 18: NO GPIO #bit 13
338 NoGPIO, // index 19: NO GPIO #bit 12
339 ShooterHallRise, // index 20: P0.7 Fall #bit 11 //Shooter Hall //Dio 4
340 WristHallRise, // index 21: P0.6 Fall #bit 10 //Wrist Hall //Dio 3
341 IndexerTopRise, // index 22: P0.5 Fall #bit 9 //Indexer Top //Dio 2
342 IndexerBottomRise, // index 23: P0.4 Fall #bit 8 //Indexer Bottom //Dio 1
343 NoGPIO, // index 24: NO GPIO #bit 7
344 NoGPIO, // index 25: NO GPIO #bit 6
345 IndexerTopFall, // index 26: P0.5 Rise #bit 5 //Indexer Top //Dio 2
346 IndexerBottomFall, // index 27: P0.4 Rise #bit 4 //Indexer Bottom //Dio 1
347 Encoder5BRise, // index 28: P2.3 Rise #bit 3 //Encoder 5 B //Dio 10
348 Encoder5ARise, // index 29: P2.2 Rise #bit 2 //Encoder 5 A //Dio 9
349 Encoder4BRise, // index 30: P2.1 Rise #bit 1 //Encoder 4 B //Dio 8
350 Encoder4ARise, // index 31: P2.0 Rise #bit 0 //Encoder 4 A //Dio 7
351 NoGPIO // index 32: NO BITS SET #False Alarm
352 };
353 table[index]();
354}
355void EINT3_IRQHandler(void) {
Brian Silvermanf92396c2013-09-12 20:13:13 -0700356 IRQ_Dispatch();
Brian Silvermanf92396c2013-09-12 20:13:13 -0700357}
358int32_t encoder_val(int chan) {
359 int32_t val;
360 switch (chan) {
361 case 0: // Wrist
362 return (int32_t)QEI->QEIPOS;
363 case 1: // Shooter Wheel
364 NVIC_DisableIRQ(EINT1_IRQn);
365 NVIC_DisableIRQ(EINT2_IRQn);
366 val = encoder1_val;
367 NVIC_EnableIRQ(EINT2_IRQn);
368 NVIC_EnableIRQ(EINT1_IRQn);
369 return val;
370 case 2: // Shooter Angle
371 NVIC_DisableIRQ(EINT3_IRQn);
372 val = encoder2_val;
373 NVIC_EnableIRQ(EINT3_IRQn);
374 return val;
375 case 3: // Indexer
376 NVIC_DisableIRQ(EINT3_IRQn);
377 val = encoder3_val;
378 NVIC_EnableIRQ(EINT3_IRQn);
379 return val;
380 case 4: // Drive R
381 NVIC_DisableIRQ(EINT3_IRQn);
382 val = encoder4_val;
383 NVIC_EnableIRQ(EINT3_IRQn);
384 return val;
385 case 5: // Drive L
386 NVIC_DisableIRQ(EINT3_IRQn);
387 val = encoder5_val;
388 NVIC_EnableIRQ(EINT3_IRQn);
389 return val;
390 default:
391 return -1;
392 }
393}
394
Brian Silvermana280ae02013-10-28 18:21:15 -0700395static volatile uint32_t sensor_timing_wraps = 0;
396
397void TIMER1_IRQHandler(void) {
398 SENSOR_TIMING_TIMER->IR = 1 << 0; // clear channel 0 match
399 ++sensor_timing_wraps;
400}
401
Brian Silvermanf92396c2013-09-12 20:13:13 -0700402void encoder_init(void) {
Brian Silvermana280ae02013-10-28 18:21:15 -0700403 // Set up the timer for timestamping sensor readings.
404 SC->PCONP |= 1 << 2;
405 SENSOR_TIMING_TIMER->PR = (configCPU_CLOCK_HZ / kSensorTimingRate) - 1UL;
406 SENSOR_TIMING_TIMER->TC = 1; // don't match the first time around
407 SENSOR_TIMING_TIMER->MR0 = 0; // match every time it wraps
408 SENSOR_TIMING_TIMER->MCR = 1 << 0; // interrupt on match channel 0
409 // Priority 4 is higher than any FreeRTOS-managed stuff (ie USB), but lower
410 // than encoders etc.
411 NVIC_SetPriority(TIMER1_IRQn, 4);
412 NVIC_EnableIRQ(TIMER1_IRQn);
413 SENSOR_TIMING_TIMER->TCR = 1; // enable it
414
Brian Silvermanf92396c2013-09-12 20:13:13 -0700415 // Setup the encoder interface.
416 SC->PCONP |= PCONP_PCQEI;
417 PINCON->PINSEL3 = ((PINCON->PINSEL3 & 0xffff3dff) | 0x00004100);
418 // Reset the count and velocity.
419 QEI->QEICON = 0x00000005;
420 QEI->QEICONF = 0x00000004;
421 // Wrap back to 0 when we wrap the int and vice versa.
422 QEI->QEIMAXPOS = 0xFFFFFFFF;
423
424 // Set up encoder 1.
425 // Make GPIOs 2.11 and 2.12 trigger EINT1 and EINT2 (respectively).
426 // PINSEL4[23:22] = {0 1}
427 // PINSEL4[25:24] = {0 1}
428 PINCON->PINSEL4 = (PINCON->PINSEL4 & ~(0x3 << 22)) | (0x1 << 22);
429 PINCON->PINSEL4 = (PINCON->PINSEL4 & ~(0x3 << 24)) | (0x1 << 24);
430 // Clear the interrupt flags for EINT1 and EINT2 (0x6 = 0b0110).
431 SC->EXTMODE = 0x6;
432 SC->EXTINT = 0x6;
433 NVIC_EnableIRQ(EINT1_IRQn);
434 NVIC_EnableIRQ(EINT2_IRQn);
435 encoder1_val = 0;
436
437 // Set up encoder 2.
438 GPIOINT->IO0IntEnF |= (1 << 22); // Set GPIO falling interrupt.
439 GPIOINT->IO0IntEnR |= (1 << 22); // Set GPIO rising interrupt.
440 GPIOINT->IO0IntEnF |= (1 << 21); // Set GPIO falling interrupt.
441 GPIOINT->IO0IntEnR |= (1 << 21); // Set GPIO rising interrupt.
442 // Make sure they're in mode 00 (the default, aka nothing special).
443 PINCON->PINSEL1 &= ~(0x3 << 12);
444 PINCON->PINSEL1 &= ~(0x3 << 10);
445 encoder2_val = 0;
446
447 // Set up encoder 3.
448 GPIOINT->IO0IntEnF |= (1 << 20); // Set GPIO falling interrupt.
449 GPIOINT->IO0IntEnR |= (1 << 20); // Set GPIO rising interrupt.
450 GPIOINT->IO0IntEnF |= (1 << 19); // Set GPIO falling interrupt.
451 GPIOINT->IO0IntEnR |= (1 << 19); // Set GPIO rising interrupt.
452 // Make sure they're in mode 00 (the default, aka nothing special).
453 PINCON->PINSEL1 &= ~(0x3 << 8);
454 PINCON->PINSEL1 &= ~(0x3 << 6);
455 encoder3_val = 0;
456
457 // Set up encoder 4.
458 GPIOINT->IO2IntEnF |= (1 << 0); // Set GPIO falling interrupt.
459 GPIOINT->IO2IntEnR |= (1 << 0); // Set GPIO rising interrupt.
460 GPIOINT->IO2IntEnF |= (1 << 1); // Set GPIO falling interrupt.
461 GPIOINT->IO2IntEnR |= (1 << 1); // Set GPIO rising interrupt.
462 // Make sure they're in mode 00 (the default, aka nothing special).
463 PINCON->PINSEL4 &= ~(0x3 << 0);
464 PINCON->PINSEL4 &= ~(0x3 << 2);
465 encoder4_val = 0;
466
467 // Set up encoder 5.
468 GPIOINT->IO2IntEnF |= (1 << 2); // Set GPIO falling interrupt.
469 GPIOINT->IO2IntEnR |= (1 << 2); // Set GPIO rising interrupt.
470 GPIOINT->IO2IntEnF |= (1 << 3); // Set GPIO falling interrupt.
471 GPIOINT->IO2IntEnR |= (1 << 3); // Set GPIO rising interrupt.
472 // Make sure they're in mode 00 (the default, aka nothing special).
473 PINCON->PINSEL4 &= ~(0x3 << 4);
474 PINCON->PINSEL4 &= ~(0x3 << 6);
475 encoder5_val = 0;
476
477 // Enable interrupts from the GPIO pins.
478 NVIC_EnableIRQ(EINT3_IRQn);
479
480 if (is_bot3) {
481 } else { // is main robot
482 xTaskCreate(vDelayCapture,
483 (signed char *) "SENSORs",
484 configMINIMAL_STACK_SIZE + 100,
485 NULL /*parameters*/,
486 tskIDLE_PRIORITY + 5,
487 NULL /*return task handle*/);
488
489 GPIOINT->IO0IntEnF |= (1 << 4); // Set GPIO falling interrupt
490 GPIOINT->IO0IntEnR |= (1 << 4); // Set GPIO rising interrupt
491 PINCON->PINSEL0 &= ~(0x3 << 8);
492
493 GPIOINT->IO0IntEnF |= (1 << 5); // Set GPIO falling interrupt
494 GPIOINT->IO0IntEnR |= (1 << 5); // Set GPIO rising interrupt
495 PINCON->PINSEL0 &= ~(0x3 << 10);
496
497 GPIOINT->IO0IntEnF |= (1 << 6);
498 PINCON->PINSEL0 &= ~(0x3 << 12);
499
500 GPIOINT->IO0IntEnF |= (1 << 7);
501 PINCON->PINSEL0 &= ~(0x3 << 14);
502 }
503}
504
505void fillSensorPacket(struct DataStruct *packet) {
Brian Silvermand36b7d32013-10-24 15:56:47 -0700506 if (gyro_output.initialized) {
507 packet->gyro_angle = gyro_output.angle;
508 packet->old_gyro_reading = gyro_output.last_reading_bad;
509 packet->bad_gyro = gyro_output.gyro_bad;
510 } else {
511 packet->gyro_angle = 0;
512 packet->old_gyro_reading = 1;
513 packet->bad_gyro = 0;
514 }
Brian Silvermanf92396c2013-09-12 20:13:13 -0700515
Brian Silvermana280ae02013-10-28 18:21:15 -0700516 NVIC_DisableIRQ(TIMER1_IRQn);
517 packet->timestamp = ((uint64_t)sensor_timing_wraps << 32) | TIM1->TC;
518 NVIC_EnableIRQ(TIMER1_IRQn);
519
Brian Silverman28d97782013-10-31 17:33:52 -0700520 packet->checksum = DATA_STRUCT_CHECKSUM;
521
Brian Silvermanf92396c2013-09-12 20:13:13 -0700522 packet->dip_switch0 = dip_switch(0);
523 packet->dip_switch1 = dip_switch(1);
524 packet->dip_switch2 = dip_switch(2);
525 packet->dip_switch3 = dip_switch(3);
526
Brian Silverman25aae9a2013-10-08 13:37:45 -0700527 // We disable EINT3 to avoid sending back inconsistent values. All of the
528 // aligned reads from the variables are atomic, so disabling it isn't
529 // necessary for just reading encoder values. We re-enable it periodically
530 // because disabling and enabling is cheap (2 instructions) and we really rely
531 // on low interrupt latencies.
532
Brian Silvermanf92396c2013-09-12 20:13:13 -0700533 if (is_bot3) {
534 packet->robot_id = 1;
535 } else { // is main robot
Brian Silverman74acd622013-10-26 14:47:14 -0700536 packet->robot_id = 2;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700537
538 packet->main.shooter = encoder1_val;
Brian Silverman1623c332013-10-01 18:05:16 -0700539 packet->main.left_drive = encoder5_val;
540 packet->main.right_drive = encoder4_val;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700541 packet->main.indexer = encoder3_val;
Brian Silverman1ba46c72013-10-31 16:05:57 -0700542 packet->main.battery_voltage = analog(3);
Brian Silverman74acd622013-10-26 14:47:14 -0700543 packet->main.left_drive_hall = analog(1);
Brian Silverman1ba46c72013-10-31 16:05:57 -0700544 packet->main.right_drive_hall = analog(2);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700545
Brian Silverman25aae9a2013-10-08 13:37:45 -0700546 NVIC_DisableIRQ(EINT3_IRQn);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700547
548 packet->main.wrist = (int32_t)QEI->QEIPOS;
549 packet->main.wrist_hall_effect = !digital(3);
550 packet->main.capture_wrist_rise = capture_wrist_rise;
551 packet->main.wrist_rise_count = wrist_rise_count;
552
Brian Silverman25aae9a2013-10-08 13:37:45 -0700553 NVIC_EnableIRQ(EINT3_IRQn);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700554 NVIC_DisableIRQ(EINT3_IRQn);
555
556 packet->main.capture_top_rise = capture_top_rise;
557 packet->main.top_rise_count = top_rise_count;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700558 packet->main.capture_top_fall = capture_top_fall;
559 packet->main.top_fall_count = top_fall_count;
560 packet->main.top_disc = !digital(2);
561
Brian Silverman25aae9a2013-10-08 13:37:45 -0700562 NVIC_EnableIRQ(EINT3_IRQn);
563 NVIC_DisableIRQ(EINT3_IRQn);
564
Brian Silvermanf92396c2013-09-12 20:13:13 -0700565 packet->main.capture_bottom_fall_delay = capture_bottom_fall_delay;
566 packet->main.bottom_fall_delay_count = bottom_fall_delay_count;
567 packet->main.bottom_fall_count = bottom_fall_count;
568 packet->main.bottom_disc = !digital(1);
569
Brian Silverman25aae9a2013-10-08 13:37:45 -0700570 NVIC_EnableIRQ(EINT3_IRQn);
571 NVIC_DisableIRQ(EINT3_IRQn);
572
Brian Silverman1623c332013-10-01 18:05:16 -0700573 packet->main.loader_top = !digital(5);
574 packet->main.loader_bottom = !digital(6);
575
Brian Silverman25aae9a2013-10-08 13:37:45 -0700576 NVIC_EnableIRQ(EINT3_IRQn);
577 NVIC_DisableIRQ(EINT3_IRQn);
578
579 packet->main.shooter_angle = encoder2_val;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700580 packet->main.capture_shooter_angle_rise = capture_shooter_angle_rise;
581 packet->main.shooter_angle_rise_count = shooter_angle_rise_count;
582 packet->main.angle_adjust_bottom_hall_effect = !digital(4);
583
584 NVIC_EnableIRQ(EINT3_IRQn);
585
586 packet->main.bottom_rise_count = bottom_rise_count;
587 }
588}