blob: c735126a82f28563411ebcd40a4716dfead47dbc [file] [log] [blame]
Daniel Pettie7cb20f2013-10-20 05:00:51 +00001#include <string.h>
2
Brian Silvermanf92396c2013-09-12 20:13:13 -07003#include "fill_packet.h"
4#include "encoder.h"
5
6#include "FreeRTOS.h"
7#include "task.h"
8
9#include "digital.h"
10#include "analog.h"
Brian Silverman49876942013-10-11 17:50:26 -070011#include "gyro.h"
Brian Silvermanf92396c2013-09-12 20:13:13 -070012
13// How long (in ms) to wait after a falling edge on the bottom indexer sensor
14// before reading the indexer encoder.
15static const int kBottomFallDelayTime = 32;
Daniel Petti5003b772013-11-07 02:19:50 +000016
Brian Silvermanf92396c2013-09-12 20:13:13 -070017#define ENC(gpio, a, b) readGPIO(gpio, a) * 2 + readGPIO(gpio, b)
18int encoder_bits(int channel) {
19 switch (channel) {
20 case 0:
21 return ENC(GPIO1, 20, 23);
22 case 1:
23 return ENC(GPIO2, 11, 12);
24 case 2:
25 return ENC(GPIO0, 21, 22);
26 case 3:
27 return ENC(GPIO0, 19, 20);
28 default:
29 return -1;
30 }
31 return -1;
32}
33#undef ENC
34
35// Uses EINT1 and EINT2 on 2.11 and 2.12.
36volatile int32_t encoder1_val;
37// On GPIO pins 0.22 and 0.21.
38volatile int32_t encoder2_val;
39// On GPIO pins 0.20 and 0.19.
40volatile int32_t encoder3_val;
41// On GPIO pins 2.0 and 2.1.
42volatile int32_t encoder4_val;
43// On GPIO pins 2.2 and 2.3.
44volatile int32_t encoder5_val;
45
Brian Silverman25aae9a2013-10-08 13:37:45 -070046// It is important to clear the various interrupt flags first thing in the ISRs.
47// It doesn't seem to work otherwise, possibly because of the reason that Brian
48// found poking around online: caches on the bus make it so that the clearing of
49// the interrupt gets to the NVIC after the ISR returns, so it runs the ISR a
50// second time. Also, by clearing them early, if a second interrupt arrives from
51// the same source it will still get handled instead of getting lost.
52
Brian Silvermanf92396c2013-09-12 20:13:13 -070053// ENC1A 2.11
54void EINT1_IRQHandler(void) {
Brian Silverman25aae9a2013-10-08 13:37:45 -070055 // Make sure to change this BEFORE clearing the interrupt like the datasheet
56 // says you have to.
Brian Silverman1623c332013-10-01 18:05:16 -070057 SC->EXTPOLAR ^= 0x2;
Brian Silvermanf92396c2013-09-12 20:13:13 -070058 SC->EXTINT = 0x2;
59 int fiopin = GPIO2->FIOPIN;
Brian Silverman25aae9a2013-10-08 13:37:45 -070060 // This looks like a weird way to XOR the 2 inputs, but it compiles down to
61 // just 2 instructions, which is hard to beat.
Brian Silvermanf92396c2013-09-12 20:13:13 -070062 if (((fiopin >> 1) ^ fiopin) & 0x800) {
63 ++encoder1_val;
64 } else {
65 --encoder1_val;
66 }
Brian Silvermanf92396c2013-09-12 20:13:13 -070067}
68// ENC1B 2.12
69void EINT2_IRQHandler(void) {
Brian Silverman1623c332013-10-01 18:05:16 -070070 SC->EXTPOLAR ^= 0x4;
Brian Silvermanf92396c2013-09-12 20:13:13 -070071 SC->EXTINT = 0x4;
72 int fiopin = GPIO2->FIOPIN;
73 if (((fiopin >> 1) ^ fiopin) & 0x800) {
74 --encoder1_val;
75 } else {
76 ++encoder1_val;
77 }
Brian Silvermanf92396c2013-09-12 20:13:13 -070078}
79
Daniel Petti6300d682013-10-14 02:12:18 +000080static inline void reset_TC(void) {
Daniel Pettie7cb20f2013-10-20 05:00:51 +000081 TIM2->TCR |= (1 << 1); // Put it into reset.
Daniel Pettie7cb20f2013-10-20 05:00:51 +000082 TIM2->TCR = 1; // Take it out of reset + make sure it's enabled.
Daniel Petti6300d682013-10-14 02:12:18 +000083}
84
Daniel Pettie7cb20f2013-10-20 05:00:51 +000085// TIM2
Daniel Pettid9c84d42013-10-15 04:51:07 +000086volatile uint32_t shooter_cycle_ticks;
Daniel Pettie7cb20f2013-10-20 05:00:51 +000087void TIMER2_IRQHandler(void) {
Daniel Petti6300d682013-10-14 02:12:18 +000088 // Apparently, this handler runs regardless of a match or capture event.
Daniel Pettie7cb20f2013-10-20 05:00:51 +000089 if (TIM2->IR & (1 << 4)) {
Daniel Petti6300d682013-10-14 02:12:18 +000090 // Capture
Daniel Pettie7cb20f2013-10-20 05:00:51 +000091 TIM2->IR = (1 << 3); // Clear the interrupt.
Daniel Petti6300d682013-10-14 02:12:18 +000092
Daniel Pettie7cb20f2013-10-20 05:00:51 +000093 shooter_cycle_ticks = TIM2->CR0;
Daniel Petti6300d682013-10-14 02:12:18 +000094
95 reset_TC();
Daniel Pettie7cb20f2013-10-20 05:00:51 +000096 } else if (TIM2->IR & 1) {
Daniel Petti6300d682013-10-14 02:12:18 +000097 // Match
Daniel Pettie7cb20f2013-10-20 05:00:51 +000098 TIM2->IR = 1; // Clear the interrupt
Daniel Petti6300d682013-10-14 02:12:18 +000099
100 // Assume shooter is stopped.
101 shooter_cycle_ticks = 0;
102
103 // Disable timer.
Daniel Pettie7cb20f2013-10-20 05:00:51 +0000104 TIM2->TCR = 0;
Daniel Petti6300d682013-10-14 02:12:18 +0000105 }
106
107 // It will only handle one interrupt per run.
108 // If there is another interrupt pending, it won't be cleared, and the ISR
109 // will be run again to handle it.
110}
111
Brian Silverman1623c332013-10-01 18:05:16 -0700112// TODO(brians): Have this indicate some kind of error instead of just looping
113// infinitely in the ISR because it never clears it.
114static void NoGPIO(void) {}
115static void Encoder2ARise(void) {
116 GPIOINT->IO0IntClr = (1 << 22);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700117 if (GPIO0->FIOPIN & (1 << 21)) {
118 ++encoder2_val;
119 } else {
120 --encoder2_val;
121 }
122}
Brian Silverman1623c332013-10-01 18:05:16 -0700123static void Encoder2AFall(void) {
124 GPIOINT->IO0IntClr = (1 << 22);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700125 if (GPIO0->FIOPIN & (1 << 21)) {
126 --encoder2_val;
127 } else {
128 ++encoder2_val;
129 }
130}
Brian Silverman1623c332013-10-01 18:05:16 -0700131static void Encoder2BRise(void) {
132 GPIOINT->IO0IntClr = (1 << 21);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700133 if (GPIO0->FIOPIN & (1 << 22)) {
134 --encoder2_val;
135 } else {
136 ++encoder2_val;
137 }
138}
Brian Silverman1623c332013-10-01 18:05:16 -0700139static void Encoder2BFall(void) {
140 GPIOINT->IO0IntClr = (1 << 21);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700141 if (GPIO0->FIOPIN & (1 << 22)) {
142 ++encoder2_val;
143 } else {
144 --encoder2_val;
145 }
146}
147
Brian Silverman1623c332013-10-01 18:05:16 -0700148static void Encoder3ARise(void) {
149 GPIOINT->IO0IntClr = (1 << 20);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700150 if (GPIO0->FIOPIN & (1 << 19)) {
151 ++encoder3_val;
152 } else {
153 --encoder3_val;
154 }
155}
Brian Silverman1623c332013-10-01 18:05:16 -0700156static void Encoder3AFall(void) {
157 GPIOINT->IO0IntClr = (1 << 20);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700158 if (GPIO0->FIOPIN & (1 << 19)) {
159 --encoder3_val;
160 } else {
161 ++encoder3_val;
162 }
163}
Brian Silverman1623c332013-10-01 18:05:16 -0700164static void Encoder3BRise(void) {
165 GPIOINT->IO0IntClr = (1 << 19);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700166 if (GPIO0->FIOPIN & (1 << 20)) {
167 --encoder3_val;
168 } else {
169 ++encoder3_val;
170 }
171}
Brian Silverman1623c332013-10-01 18:05:16 -0700172static void Encoder3BFall(void) {
173 GPIOINT->IO0IntClr = (1 << 19);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700174 if (GPIO0->FIOPIN & (1 << 20)) {
175 ++encoder3_val;
176 } else {
177 --encoder3_val;
178 }
179}
180
Brian Silverman1623c332013-10-01 18:05:16 -0700181static void Encoder4ARise(void) {
182 GPIOINT->IO2IntClr = (1 << 0);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700183 if (GPIO2->FIOPIN & (1 << 1)) {
184 ++encoder4_val;
185 } else {
186 --encoder4_val;
187 }
188}
Brian Silverman1623c332013-10-01 18:05:16 -0700189static void Encoder4AFall(void) {
190 GPIOINT->IO2IntClr = (1 << 0);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700191 if (GPIO2->FIOPIN & (1 << 1)) {
192 --encoder4_val;
193 } else {
194 ++encoder4_val;
195 }
196}
Brian Silverman1623c332013-10-01 18:05:16 -0700197static void Encoder4BRise(void) {
198 GPIOINT->IO2IntClr = (1 << 1);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700199 if (GPIO2->FIOPIN & (1 << 0)) {
200 --encoder4_val;
201 } else {
202 ++encoder4_val;
203 }
204}
Brian Silverman1623c332013-10-01 18:05:16 -0700205static void Encoder4BFall(void) {
206 GPIOINT->IO2IntClr = (1 << 1);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700207 if (GPIO2->FIOPIN & (1 << 0)) {
208 ++encoder4_val;
209 } else {
210 --encoder4_val;
211 }
212}
213
Brian Silverman1623c332013-10-01 18:05:16 -0700214static void Encoder5ARise(void) {
215 GPIOINT->IO2IntClr = (1 << 2);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700216 if (GPIO2->FIOPIN & (1 << 3)) {
217 ++encoder5_val;
218 } else {
219 --encoder5_val;
220 }
221}
Brian Silverman1623c332013-10-01 18:05:16 -0700222static void Encoder5AFall(void) {
223 GPIOINT->IO2IntClr = (1 << 2);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700224 if (GPIO2->FIOPIN & (1 << 3)) {
225 --encoder5_val;
226 } else {
227 ++encoder5_val;
228 }
229}
Brian Silverman1623c332013-10-01 18:05:16 -0700230static void Encoder5BRise(void) {
231 GPIOINT->IO2IntClr = (1 << 3);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700232 if (GPIO2->FIOPIN & (1 << 2)) {
233 --encoder5_val;
234 } else {
235 ++encoder5_val;
236 }
237}
Brian Silverman1623c332013-10-01 18:05:16 -0700238static void Encoder5BFall(void) {
239 GPIOINT->IO2IntClr = (1 << 3);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700240 if (GPIO2->FIOPIN & (1 << 2)) {
241 ++encoder5_val;
242 } else {
243 --encoder5_val;
244 }
245}
246
247volatile int32_t capture_top_rise;
248volatile int8_t top_rise_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700249static void IndexerTopRise(void) {
250 GPIOINT->IO0IntClr = (1 << 5);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700251 // edge counting encoder capture
252 ++top_rise_count;
253 capture_top_rise = encoder3_val;
254}
255volatile int32_t capture_top_fall;
256volatile int8_t top_fall_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700257static void IndexerTopFall(void) {
258 GPIOINT->IO0IntClr = (1 << 5);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700259 // edge counting encoder capture
260 ++top_fall_count;
261 capture_top_fall = encoder3_val;
262}
263volatile int8_t bottom_rise_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700264static void IndexerBottomRise(void) {
265 GPIOINT->IO0IntClr = (1 << 4);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700266 // edge counting
267 ++bottom_rise_count;
268}
269volatile int32_t capture_bottom_fall_delay;
270volatile int8_t bottom_fall_delay_count;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700271portTickType xDelayTimeFrom;
272static portTASK_FUNCTION(vDelayCapture, pvParameters)
273{
274 portTickType xSleepFrom = xTaskGetTickCount();
275
276 for (;;) {
Brian Silverman25aae9a2013-10-08 13:37:45 -0700277 // Atomically (wrt the ISR) switch xDelayTimeFrom to 0 and store its old
278 // value to use later.
Brian Silvermanf92396c2013-09-12 20:13:13 -0700279 NVIC_DisableIRQ(EINT3_IRQn);
Brian Silverman25aae9a2013-10-08 13:37:45 -0700280 portTickType new_time = xDelayTimeFrom;
281 xDelayTimeFrom = 0;
282 NVIC_EnableIRQ(EINT3_IRQn);
283
284 if (new_time != 0) {
285 xSleepFrom = new_time;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700286
287 vTaskDelayUntil(&xSleepFrom, kBottomFallDelayTime / portTICK_RATE_MS);
288
Brian Silverman25aae9a2013-10-08 13:37:45 -0700289 // Make sure that the USB ISR doesn't look at inconsistent values.
Brian Silverman1623c332013-10-01 18:05:16 -0700290 NVIC_DisableIRQ(USB_IRQn);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700291 capture_bottom_fall_delay = encoder3_val;
Brian Silverman1623c332013-10-01 18:05:16 -0700292 ++bottom_fall_delay_count;
293 NVIC_EnableIRQ(USB_IRQn);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700294 } else {
Brian Silverman25aae9a2013-10-08 13:37:45 -0700295 // Wait 10ms and then check again.
Brian Silvermanf92396c2013-09-12 20:13:13 -0700296 vTaskDelayUntil(&xSleepFrom, 10 / portTICK_RATE_MS);
297 }
298 }
299}
300
301volatile int8_t bottom_fall_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700302static void IndexerBottomFall(void) {
303 GPIOINT->IO0IntClr = (1 << 4);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700304 ++bottom_fall_count;
305 // edge counting start delayed capture
306 xDelayTimeFrom = xTaskGetTickCount();
Brian Silvermanf92396c2013-09-12 20:13:13 -0700307}
308volatile int32_t capture_wrist_rise;
309volatile int8_t wrist_rise_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700310static void WristHallRise(void) {
311 GPIOINT->IO0IntClr = (1 << 6);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700312 // edge counting encoder capture
313 ++wrist_rise_count;
314 capture_wrist_rise = (int32_t)QEI->QEIPOS;
315}
316volatile int32_t capture_shooter_angle_rise;
317volatile int8_t shooter_angle_rise_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700318static void ShooterHallRise(void) {
319 GPIOINT->IO0IntClr = (1 << 7);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700320 // edge counting encoder capture
321 ++shooter_angle_rise_count;
322 capture_shooter_angle_rise = encoder2_val;
323}
Daniel Pettie7cb20f2013-10-20 05:00:51 +0000324
325// Third robot shooter.
Daniel Petti6300d682013-10-14 02:12:18 +0000326static void ShooterPhotoFall(void) {
327 GPIOINT->IO0IntClr = (1 << 23);
328 // We reset TC to make sure we don't get a crap
329 // value from CR0 when the capture interrupt occurs
Daniel Pettie7cb20f2013-10-20 05:00:51 +0000330 // if the shooter is just starting up again, and so
331 // that the match interrupt thing works right.
Daniel Petti6300d682013-10-14 02:12:18 +0000332 reset_TC();
333}
Brian Silvermanf92396c2013-09-12 20:13:13 -0700334
Daniel Pettie7cb20f2013-10-20 05:00:51 +0000335typedef void (*Handler)(void);
336// Contains default pointers for ISR functions.
337// (These can be used without modifications on the comp/practice bots.)
338Handler ISRTable[] = {
Brian Silvermanf92396c2013-09-12 20:13:13 -0700339 Encoder5BFall, // index 0: P2.3 Fall #bit 31 //Encoder 5 B //Dio 10
340 Encoder5AFall, // index 1: P2.2 Fall #bit 30 //Encoder 5 A //Dio 9
341 Encoder4BFall, // index 2: P2.1 Fall #bit 29 //Encoder 4 B //Dio 8
342 Encoder4AFall, // index 3: P2.0 Fall #bit 28 //Encoder 4 A //Dio 7
Daniel Pettie7cb20f2013-10-20 05:00:51 +0000343 NoGPIO, // index 4: NO GPIO #bit 27
Brian Silvermanf92396c2013-09-12 20:13:13 -0700344 Encoder2AFall, // index 5: P0.22 Fall #bit 26 //Encoder 2 A
345 Encoder2BFall, // index 6: P0.21 Fall #bit 25 //Encoder 2 B
346 Encoder3AFall, // index 7: P0.20 Fall #bit 24 //Encoder 3 A
347 Encoder3BFall, // index 8: P0.19 Fall #bit 23 //Encoder 3 B
348 Encoder2ARise, // index 9: P0.22 Rise #bit 22 //Encoder 2 A
349 Encoder2BRise, // index 10: P0.21 Rise #bit 21 //Encoder 2 B
350 Encoder3ARise, // index 11: P0.20 Rise #bit 20 //Encoder 3 A
351 Encoder3BRise, // index 12: P0.19 Rise #bit 19 //Encoder 3 B
352 NoGPIO, // index 13: NO GPIO #bit 18
353 NoGPIO, // index 14: NO GPIO #bit 17
354 NoGPIO, // index 15: NO GPIO #bit 16
355 NoGPIO, // index 16: NO GPIO #bit 15
356 NoGPIO, // index 17: NO GPIO #bit 14
357 NoGPIO, // index 18: NO GPIO #bit 13
358 NoGPIO, // index 19: NO GPIO #bit 12
359 ShooterHallRise, // index 20: P0.7 Fall #bit 11 //Shooter Hall //Dio 4
360 WristHallRise, // index 21: P0.6 Fall #bit 10 //Wrist Hall //Dio 3
361 IndexerTopRise, // index 22: P0.5 Fall #bit 9 //Indexer Top //Dio 2
362 IndexerBottomRise, // index 23: P0.4 Fall #bit 8 //Indexer Bottom //Dio 1
363 NoGPIO, // index 24: NO GPIO #bit 7
364 NoGPIO, // index 25: NO GPIO #bit 6
365 IndexerTopFall, // index 26: P0.5 Rise #bit 5 //Indexer Top //Dio 2
366 IndexerBottomFall, // index 27: P0.4 Rise #bit 4 //Indexer Bottom //Dio 1
367 Encoder5BRise, // index 28: P2.3 Rise #bit 3 //Encoder 5 B //Dio 10
368 Encoder5ARise, // index 29: P2.2 Rise #bit 2 //Encoder 5 A //Dio 9
369 Encoder4BRise, // index 30: P2.1 Rise #bit 1 //Encoder 4 B //Dio 8
370 Encoder4ARise, // index 31: P2.0 Rise #bit 0 //Encoder 4 A //Dio 7
371 NoGPIO // index 32: NO BITS SET #False Alarm
Daniel Pettie7cb20f2013-10-20 05:00:51 +0000372};
373
374// Count leading zeros.
375// Returns 0 if bit 31 is set etc.
376__attribute__((always_inline)) static __INLINE uint32_t __clz(uint32_t value) {
377 uint32_t result;
378 __asm__("clz %0, %1" : "=r" (result) : "r" (value));
379 return result;
380}
381inline static void IRQ_Dispatch(void) {
382 // There is no need to add a loop here to handle multiple interrupts at the
383 // same time because the processor has tail chaining of interrupts which we
384 // can't really beat with our own loop.
385 // It would actually be bad because a loop here would block EINT1/2 for longer
386 // lengths of time.
387
388 uint32_t index = __clz(GPIOINT->IO2IntStatR | GPIOINT->IO0IntStatR |
389 (GPIOINT->IO2IntStatF << 28) | (GPIOINT->IO0IntStatF << 4));
390
391 ISRTable[index]();
Brian Silvermanf92396c2013-09-12 20:13:13 -0700392}
393void EINT3_IRQHandler(void) {
Brian Silvermanf92396c2013-09-12 20:13:13 -0700394 IRQ_Dispatch();
Brian Silvermanf92396c2013-09-12 20:13:13 -0700395}
Daniel Pettie7cb20f2013-10-20 05:00:51 +0000396
Brian Silvermanf92396c2013-09-12 20:13:13 -0700397int32_t encoder_val(int chan) {
398 int32_t val;
399 switch (chan) {
400 case 0: // Wrist
401 return (int32_t)QEI->QEIPOS;
402 case 1: // Shooter Wheel
403 NVIC_DisableIRQ(EINT1_IRQn);
404 NVIC_DisableIRQ(EINT2_IRQn);
405 val = encoder1_val;
406 NVIC_EnableIRQ(EINT2_IRQn);
407 NVIC_EnableIRQ(EINT1_IRQn);
408 return val;
409 case 2: // Shooter Angle
410 NVIC_DisableIRQ(EINT3_IRQn);
411 val = encoder2_val;
412 NVIC_EnableIRQ(EINT3_IRQn);
413 return val;
414 case 3: // Indexer
415 NVIC_DisableIRQ(EINT3_IRQn);
416 val = encoder3_val;
417 NVIC_EnableIRQ(EINT3_IRQn);
418 return val;
419 case 4: // Drive R
420 NVIC_DisableIRQ(EINT3_IRQn);
421 val = encoder4_val;
422 NVIC_EnableIRQ(EINT3_IRQn);
423 return val;
424 case 5: // Drive L
425 NVIC_DisableIRQ(EINT3_IRQn);
426 val = encoder5_val;
427 NVIC_EnableIRQ(EINT3_IRQn);
428 return val;
429 default:
430 return -1;
431 }
432}
433
Brian Silvermana280ae02013-10-28 18:21:15 -0700434static volatile uint32_t sensor_timing_wraps = 0;
435
Brian Silvermanf92396c2013-09-12 20:13:13 -0700436void encoder_init(void) {
437 // Setup the encoder interface.
438 SC->PCONP |= PCONP_PCQEI;
439 PINCON->PINSEL3 = ((PINCON->PINSEL3 & 0xffff3dff) | 0x00004100);
440 // Reset the count and velocity.
441 QEI->QEICON = 0x00000005;
442 QEI->QEICONF = 0x00000004;
443 // Wrap back to 0 when we wrap the int and vice versa.
444 QEI->QEIMAXPOS = 0xFFFFFFFF;
Daniel Pettid9c84d42013-10-15 04:51:07 +0000445
Daniel Petti433d6432013-11-01 05:10:28 +0000446 // Set up encoder 2.
447 GPIOINT->IO0IntEnF |= (1 << 22); // Set GPIO falling interrupt.
448 GPIOINT->IO0IntEnR |= (1 << 22); // Set GPIO rising interrupt.
449 GPIOINT->IO0IntEnF |= (1 << 21); // Set GPIO falling interrupt.
450 GPIOINT->IO0IntEnR |= (1 << 21); // Set GPIO rising interrupt.
Brian Silvermanf92396c2013-09-12 20:13:13 -0700451 // Make sure they're in mode 00 (the default, aka nothing special).
Daniel Petti433d6432013-11-01 05:10:28 +0000452 PINCON->PINSEL1 &= ~(0x3 << 12);
453 PINCON->PINSEL1 &= ~(0x3 << 10);
454 encoder2_val = 0;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700455
Daniel Petti433d6432013-11-01 05:10:28 +0000456 // Set up encoder 3.
457 GPIOINT->IO0IntEnF |= (1 << 20); // Set GPIO falling interrupt.
458 GPIOINT->IO0IntEnR |= (1 << 20); // Set GPIO rising interrupt.
459 GPIOINT->IO0IntEnF |= (1 << 19); // Set GPIO falling interrupt.
460 GPIOINT->IO0IntEnR |= (1 << 19); // Set GPIO rising interrupt.
Brian Silvermanf92396c2013-09-12 20:13:13 -0700461 // Make sure they're in mode 00 (the default, aka nothing special).
Daniel Petti433d6432013-11-01 05:10:28 +0000462 PINCON->PINSEL1 &= ~(0x3 << 8);
463 PINCON->PINSEL1 &= ~(0x3 << 6);
464 encoder3_val = 0;
465
Brian Silvermanf92396c2013-09-12 20:13:13 -0700466 // Enable interrupts from the GPIO pins.
467 NVIC_EnableIRQ(EINT3_IRQn);
468
469 if (is_bot3) {
Daniel Pettie7cb20f2013-10-20 05:00:51 +0000470 // Modify robot handler table for third robot.
471 ISRTable[23] = ShooterPhotoFall;
472
Daniel Petti6300d682013-10-14 02:12:18 +0000473 // Set up timer for bot3 photosensor.
Daniel Pettie7cb20f2013-10-20 05:00:51 +0000474 // Make sure timer two is powered.
475 SC->PCONP |= (1 << 22);
Daniel Petti5003b772013-11-07 02:19:50 +0000476 // Rate of clock signal is just CCLK.
477 SC->PCLKSEL1 |= (1 << 12);
Daniel Pettie7cb20f2013-10-20 05:00:51 +0000478 // Select capture 2.0 function on pin 0.4.
479 PINCON->PINSEL0 |= (0x3 << 8);
Daniel Petti6300d682013-10-14 02:12:18 +0000480 // Set timer to capture and interrupt on rising edge.
Daniel Pettie7cb20f2013-10-20 05:00:51 +0000481 TIM2->CCR = 0x5;
Daniel Petti6300d682013-10-14 02:12:18 +0000482 // Set up match interrupt.
Daniel Petti5003b772013-11-07 02:19:50 +0000483 TIM2->MR0 = kWheelStopThreshold * (10 ^ 8);
Daniel Pettie7cb20f2013-10-20 05:00:51 +0000484 TIM2->MCR = 1;
Daniel Petti6300d682013-10-14 02:12:18 +0000485 // Enable timer IRQ, and make it lower priority than the encoders.
486 NVIC_SetPriority(TIMER3_IRQn, 1);
487 NVIC_EnableIRQ(TIMER3_IRQn);
488 // Set up GPIO interrupt on other edge.
Daniel Petti6300d682013-10-14 02:12:18 +0000489 GPIOINT->IO0IntEnF |= (1 << 23);
Daniel Pettid9c84d42013-10-15 04:51:07 +0000490
Brian Silvermanf92396c2013-09-12 20:13:13 -0700491 } else { // is main robot
Daniel Pettid9c84d42013-10-15 04:51:07 +0000492 // Set up encoder 1.
493 // Make GPIOs 2.11 and 2.12 trigger EINT1 and EINT2 (respectively).
494 // PINSEL4[23:22] = {0 1}
495 // PINSEL4[25:24] = {0 1}
496 PINCON->PINSEL4 = (PINCON->PINSEL4 & ~(0x3 << 22)) | (0x1 << 22);
497 PINCON->PINSEL4 = (PINCON->PINSEL4 & ~(0x3 << 24)) | (0x1 << 24);
498 // Clear the interrupt flags for EINT1 and EINT2 (0x6 = 0b0110).
499 SC->EXTMODE = 0x6;
500 SC->EXTINT = 0x6;
501 NVIC_EnableIRQ(EINT1_IRQn);
502 NVIC_EnableIRQ(EINT2_IRQn);
503 encoder1_val = 0;
504
Daniel Petti433d6432013-11-01 05:10:28 +0000505 // Set up encoder 4.
506 GPIOINT->IO2IntEnF |= (1 << 0); // Set GPIO falling interrupt.
507 GPIOINT->IO2IntEnR |= (1 << 0); // Set GPIO rising interrupt.
508 GPIOINT->IO2IntEnF |= (1 << 1); // Set GPIO falling interrupt.
509 GPIOINT->IO2IntEnR |= (1 << 1); // Set GPIO rising interrupt.
Daniel Pettid9c84d42013-10-15 04:51:07 +0000510 // Make sure they're in mode 00 (the default, aka nothing special).
Daniel Petti433d6432013-11-01 05:10:28 +0000511 PINCON->PINSEL4 &= ~(0x3 << 0);
512 PINCON->PINSEL4 &= ~(0x3 << 2);
513 encoder4_val = 0;
Daniel Pettid9c84d42013-10-15 04:51:07 +0000514
Daniel Petti433d6432013-11-01 05:10:28 +0000515 // Set up encoder 5.
516 GPIOINT->IO2IntEnF |= (1 << 2); // Set GPIO falling interrupt.
517 GPIOINT->IO2IntEnR |= (1 << 2); // Set GPIO rising interrupt.
518 GPIOINT->IO2IntEnF |= (1 << 3); // Set GPIO falling interrupt.
519 GPIOINT->IO2IntEnR |= (1 << 3); // Set GPIO rising interrupt.
Daniel Pettid9c84d42013-10-15 04:51:07 +0000520 // Make sure they're in mode 00 (the default, aka nothing special).
Daniel Petti433d6432013-11-01 05:10:28 +0000521 PINCON->PINSEL4 &= ~(0x3 << 4);
522 PINCON->PINSEL4 &= ~(0x3 << 6);
523 encoder5_val = 0;
524
Daniel Pettid9c84d42013-10-15 04:51:07 +0000525
Brian Silvermanf92396c2013-09-12 20:13:13 -0700526 xTaskCreate(vDelayCapture,
527 (signed char *) "SENSORs",
528 configMINIMAL_STACK_SIZE + 100,
529 NULL /*parameters*/,
530 tskIDLE_PRIORITY + 5,
531 NULL /*return task handle*/);
532
533 GPIOINT->IO0IntEnF |= (1 << 4); // Set GPIO falling interrupt
534 GPIOINT->IO0IntEnR |= (1 << 4); // Set GPIO rising interrupt
535 PINCON->PINSEL0 &= ~(0x3 << 8);
536
537 GPIOINT->IO0IntEnF |= (1 << 5); // Set GPIO falling interrupt
538 GPIOINT->IO0IntEnR |= (1 << 5); // Set GPIO rising interrupt
539 PINCON->PINSEL0 &= ~(0x3 << 10);
540
541 GPIOINT->IO0IntEnF |= (1 << 6);
542 PINCON->PINSEL0 &= ~(0x3 << 12);
543
544 GPIOINT->IO0IntEnF |= (1 << 7);
545 PINCON->PINSEL0 &= ~(0x3 << 14);
546 }
547}
548
549void fillSensorPacket(struct DataStruct *packet) {
Brian Silvermand36b7d32013-10-24 15:56:47 -0700550 if (gyro_output.initialized) {
551 packet->gyro_angle = gyro_output.angle;
552 packet->old_gyro_reading = gyro_output.last_reading_bad;
553 packet->bad_gyro = gyro_output.gyro_bad;
554 } else {
555 packet->gyro_angle = 0;
556 packet->old_gyro_reading = 1;
557 packet->bad_gyro = 0;
558 }
Brian Silvermanf92396c2013-09-12 20:13:13 -0700559
Brian Silverman28d97782013-10-31 17:33:52 -0700560 packet->checksum = DATA_STRUCT_CHECKSUM;
Brian Silvermana280ae02013-10-28 18:21:15 -0700561
Brian Silvermanf92396c2013-09-12 20:13:13 -0700562 packet->dip_switch0 = dip_switch(0);
563 packet->dip_switch1 = dip_switch(1);
564 packet->dip_switch2 = dip_switch(2);
565 packet->dip_switch3 = dip_switch(3);
566
Brian Silverman25aae9a2013-10-08 13:37:45 -0700567 // We disable EINT3 to avoid sending back inconsistent values. All of the
568 // aligned reads from the variables are atomic, so disabling it isn't
569 // necessary for just reading encoder values. We re-enable it periodically
570 // because disabling and enabling is cheap (2 instructions) and we really rely
571 // on low interrupt latencies.
572
Brian Silvermanf92396c2013-09-12 20:13:13 -0700573 if (is_bot3) {
574 packet->robot_id = 1;
Daniel Pettid9c84d42013-10-15 04:51:07 +0000575
Daniel Petti433d6432013-11-01 05:10:28 +0000576 packet->main.left_drive = encoder3_val;
577 packet->main.right_drive = encoder2_val;
578
Daniel Pettid9c84d42013-10-15 04:51:07 +0000579 packet->bot3.shooter_cycle_ticks = shooter_cycle_ticks;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700580 } else { // is main robot
Brian Silverman74acd622013-10-26 14:47:14 -0700581 packet->robot_id = 2;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700582
Daniel Petti433d6432013-11-01 05:10:28 +0000583 packet->main.left_drive = encoder5_val;
584 packet->main.right_drive = encoder4_val;
585
Brian Silvermanf92396c2013-09-12 20:13:13 -0700586 packet->main.shooter = encoder1_val;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700587 packet->main.indexer = encoder3_val;
588
Brian Silverman25aae9a2013-10-08 13:37:45 -0700589 NVIC_DisableIRQ(EINT3_IRQn);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700590
591 packet->main.wrist = (int32_t)QEI->QEIPOS;
592 packet->main.wrist_hall_effect = !digital(3);
593 packet->main.capture_wrist_rise = capture_wrist_rise;
594 packet->main.wrist_rise_count = wrist_rise_count;
595
Brian Silverman25aae9a2013-10-08 13:37:45 -0700596 NVIC_EnableIRQ(EINT3_IRQn);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700597 NVIC_DisableIRQ(EINT3_IRQn);
598
599 packet->main.capture_top_rise = capture_top_rise;
600 packet->main.top_rise_count = top_rise_count;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700601 packet->main.capture_top_fall = capture_top_fall;
602 packet->main.top_fall_count = top_fall_count;
603 packet->main.top_disc = !digital(2);
604
Brian Silverman25aae9a2013-10-08 13:37:45 -0700605 NVIC_EnableIRQ(EINT3_IRQn);
606 NVIC_DisableIRQ(EINT3_IRQn);
607
Brian Silvermanf92396c2013-09-12 20:13:13 -0700608 packet->main.capture_bottom_fall_delay = capture_bottom_fall_delay;
609 packet->main.bottom_fall_delay_count = bottom_fall_delay_count;
610 packet->main.bottom_fall_count = bottom_fall_count;
Brian Silverman3e9464f2013-11-01 15:36:08 -0700611 packet->main.bottom_rise_count = bottom_rise_count;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700612 packet->main.bottom_disc = !digital(1);
613
Brian Silverman25aae9a2013-10-08 13:37:45 -0700614 NVIC_EnableIRQ(EINT3_IRQn);
615 NVIC_DisableIRQ(EINT3_IRQn);
616
Brian Silverman1623c332013-10-01 18:05:16 -0700617 packet->main.loader_top = !digital(5);
618 packet->main.loader_bottom = !digital(6);
619
Brian Silverman25aae9a2013-10-08 13:37:45 -0700620 NVIC_EnableIRQ(EINT3_IRQn);
621 NVIC_DisableIRQ(EINT3_IRQn);
622
623 packet->main.shooter_angle = encoder2_val;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700624 packet->main.capture_shooter_angle_rise = capture_shooter_angle_rise;
625 packet->main.shooter_angle_rise_count = shooter_angle_rise_count;
626 packet->main.angle_adjust_bottom_hall_effect = !digital(4);
627
628 NVIC_EnableIRQ(EINT3_IRQn);
629
Brian Silverman3e9464f2013-11-01 15:36:08 -0700630 // Do all of the analogs last because they have the potential to be slow and
631 // jittery.
Brian Silvermandb85c9a2013-11-02 14:38:43 -0700632 packet->main.battery_voltage = analog(1);
633 packet->main.left_drive_hall = analog(3);
Brian Silverman3e9464f2013-11-01 15:36:08 -0700634 packet->main.right_drive_hall = analog(2);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700635 }
636}