blob: 14b9d55fd93f63eceb5a435be92a8fcbf7f2ee49 [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;
Daniel Petti6300d682013-10-14 02:12:18 +000014// How long to wait for a revolution of the shooter wheel (on the third robot)
15// before said wheel is deemed "stopped". (In secs)
16static const uint8_t kWheelStopThreshold = 1;
Brian Silvermanf92396c2013-09-12 20:13:13 -070017
18#define ENC(gpio, a, b) readGPIO(gpio, a) * 2 + readGPIO(gpio, b)
19int encoder_bits(int channel) {
20 switch (channel) {
21 case 0:
22 return ENC(GPIO1, 20, 23);
23 case 1:
24 return ENC(GPIO2, 11, 12);
25 case 2:
26 return ENC(GPIO0, 21, 22);
27 case 3:
28 return ENC(GPIO0, 19, 20);
29 default:
30 return -1;
31 }
32 return -1;
33}
34#undef ENC
35
36// Uses EINT1 and EINT2 on 2.11 and 2.12.
37volatile int32_t encoder1_val;
38// On GPIO pins 0.22 and 0.21.
39volatile int32_t encoder2_val;
40// On GPIO pins 0.20 and 0.19.
41volatile int32_t encoder3_val;
42// On GPIO pins 2.0 and 2.1.
43volatile int32_t encoder4_val;
44// On GPIO pins 2.2 and 2.3.
45volatile int32_t encoder5_val;
46
Brian Silverman25aae9a2013-10-08 13:37:45 -070047// It is important to clear the various interrupt flags first thing in the ISRs.
48// It doesn't seem to work otherwise, possibly because of the reason that Brian
49// found poking around online: caches on the bus make it so that the clearing of
50// the interrupt gets to the NVIC after the ISR returns, so it runs the ISR a
51// second time. Also, by clearing them early, if a second interrupt arrives from
52// the same source it will still get handled instead of getting lost.
53
Brian Silvermanf92396c2013-09-12 20:13:13 -070054// ENC1A 2.11
55void EINT1_IRQHandler(void) {
Brian Silverman25aae9a2013-10-08 13:37:45 -070056 // Make sure to change this BEFORE clearing the interrupt like the datasheet
57 // says you have to.
Brian Silverman1623c332013-10-01 18:05:16 -070058 SC->EXTPOLAR ^= 0x2;
Brian Silvermanf92396c2013-09-12 20:13:13 -070059 SC->EXTINT = 0x2;
60 int fiopin = GPIO2->FIOPIN;
Brian Silverman25aae9a2013-10-08 13:37:45 -070061 // This looks like a weird way to XOR the 2 inputs, but it compiles down to
62 // just 2 instructions, which is hard to beat.
Brian Silvermanf92396c2013-09-12 20:13:13 -070063 if (((fiopin >> 1) ^ fiopin) & 0x800) {
64 ++encoder1_val;
65 } else {
66 --encoder1_val;
67 }
Brian Silvermanf92396c2013-09-12 20:13:13 -070068}
69// ENC1B 2.12
70void EINT2_IRQHandler(void) {
Brian Silverman1623c332013-10-01 18:05:16 -070071 SC->EXTPOLAR ^= 0x4;
Brian Silvermanf92396c2013-09-12 20:13:13 -070072 SC->EXTINT = 0x4;
73 int fiopin = GPIO2->FIOPIN;
74 if (((fiopin >> 1) ^ fiopin) & 0x800) {
75 --encoder1_val;
76 } else {
77 ++encoder1_val;
78 }
Brian Silvermanf92396c2013-09-12 20:13:13 -070079}
80
Daniel Petti6300d682013-10-14 02:12:18 +000081static inline void reset_TC(void) {
82 TIM3->TCR |= (1 << 1); // Put it into reset.
83 while (TIM3->TC != 0) { // Wait for reset.
84 continue;
85 }
86 TIM3->TCR = 1; // Take it out of reset + make sure it's enabled.
87}
88
89// TIM3
Daniel Pettid9c84d42013-10-15 04:51:07 +000090volatile uint32_t shooter_cycle_ticks;
Daniel Petti6300d682013-10-14 02:12:18 +000091void TIMER3_IRQHandler(void) {
92 // Apparently, this handler runs regardless of a match or capture event.
93 if (TIM3->IR & (1 << 4)) {
94 // Capture
95 TIM3->IR = (1 << 3); // Clear the interrupt.
96
97 shooter_cycle_ticks = TIM3->CR0;
98
99 reset_TC();
100 } else if (TIM3->IR & 1) {
101 // Match
102 TIM3->IR = 1; // Clear the interrupt
103
104 // Assume shooter is stopped.
105 shooter_cycle_ticks = 0;
106
107 // Disable timer.
108 TIM3->TCR = 0;
109 } else {
110 // TODO (danielp): This should not happen.
111 // Indicate that something strange occurred, and perhaps clear interrupts.
112 }
113
114 // It will only handle one interrupt per run.
115 // If there is another interrupt pending, it won't be cleared, and the ISR
116 // will be run again to handle it.
117}
118
Brian Silverman1623c332013-10-01 18:05:16 -0700119// TODO(brians): Have this indicate some kind of error instead of just looping
120// infinitely in the ISR because it never clears it.
121static void NoGPIO(void) {}
122static void Encoder2ARise(void) {
123 GPIOINT->IO0IntClr = (1 << 22);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700124 if (GPIO0->FIOPIN & (1 << 21)) {
125 ++encoder2_val;
126 } else {
127 --encoder2_val;
128 }
129}
Brian Silverman1623c332013-10-01 18:05:16 -0700130static void Encoder2AFall(void) {
131 GPIOINT->IO0IntClr = (1 << 22);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700132 if (GPIO0->FIOPIN & (1 << 21)) {
133 --encoder2_val;
134 } else {
135 ++encoder2_val;
136 }
137}
Brian Silverman1623c332013-10-01 18:05:16 -0700138static void Encoder2BRise(void) {
139 GPIOINT->IO0IntClr = (1 << 21);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700140 if (GPIO0->FIOPIN & (1 << 22)) {
141 --encoder2_val;
142 } else {
143 ++encoder2_val;
144 }
145}
Brian Silverman1623c332013-10-01 18:05:16 -0700146static void Encoder2BFall(void) {
147 GPIOINT->IO0IntClr = (1 << 21);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700148 if (GPIO0->FIOPIN & (1 << 22)) {
149 ++encoder2_val;
150 } else {
151 --encoder2_val;
152 }
153}
154
Brian Silverman1623c332013-10-01 18:05:16 -0700155static void Encoder3ARise(void) {
156 GPIOINT->IO0IntClr = (1 << 20);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700157 if (GPIO0->FIOPIN & (1 << 19)) {
158 ++encoder3_val;
159 } else {
160 --encoder3_val;
161 }
162}
Brian Silverman1623c332013-10-01 18:05:16 -0700163static void Encoder3AFall(void) {
164 GPIOINT->IO0IntClr = (1 << 20);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700165 if (GPIO0->FIOPIN & (1 << 19)) {
166 --encoder3_val;
167 } else {
168 ++encoder3_val;
169 }
170}
Brian Silverman1623c332013-10-01 18:05:16 -0700171static void Encoder3BRise(void) {
172 GPIOINT->IO0IntClr = (1 << 19);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700173 if (GPIO0->FIOPIN & (1 << 20)) {
174 --encoder3_val;
175 } else {
176 ++encoder3_val;
177 }
178}
Brian Silverman1623c332013-10-01 18:05:16 -0700179static void Encoder3BFall(void) {
180 GPIOINT->IO0IntClr = (1 << 19);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700181 if (GPIO0->FIOPIN & (1 << 20)) {
182 ++encoder3_val;
183 } else {
184 --encoder3_val;
185 }
186}
187
Brian Silverman1623c332013-10-01 18:05:16 -0700188static void Encoder4ARise(void) {
189 GPIOINT->IO2IntClr = (1 << 0);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700190 if (GPIO2->FIOPIN & (1 << 1)) {
191 ++encoder4_val;
192 } else {
193 --encoder4_val;
194 }
195}
Brian Silverman1623c332013-10-01 18:05:16 -0700196static void Encoder4AFall(void) {
197 GPIOINT->IO2IntClr = (1 << 0);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700198 if (GPIO2->FIOPIN & (1 << 1)) {
199 --encoder4_val;
200 } else {
201 ++encoder4_val;
202 }
203}
Brian Silverman1623c332013-10-01 18:05:16 -0700204static void Encoder4BRise(void) {
205 GPIOINT->IO2IntClr = (1 << 1);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700206 if (GPIO2->FIOPIN & (1 << 0)) {
207 --encoder4_val;
208 } else {
209 ++encoder4_val;
210 }
211}
Brian Silverman1623c332013-10-01 18:05:16 -0700212static void Encoder4BFall(void) {
213 GPIOINT->IO2IntClr = (1 << 1);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700214 if (GPIO2->FIOPIN & (1 << 0)) {
215 ++encoder4_val;
216 } else {
217 --encoder4_val;
218 }
219}
220
Brian Silverman1623c332013-10-01 18:05:16 -0700221static void Encoder5ARise(void) {
222 GPIOINT->IO2IntClr = (1 << 2);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700223 if (GPIO2->FIOPIN & (1 << 3)) {
224 ++encoder5_val;
225 } else {
226 --encoder5_val;
227 }
228}
Brian Silverman1623c332013-10-01 18:05:16 -0700229static void Encoder5AFall(void) {
230 GPIOINT->IO2IntClr = (1 << 2);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700231 if (GPIO2->FIOPIN & (1 << 3)) {
232 --encoder5_val;
233 } else {
234 ++encoder5_val;
235 }
236}
Brian Silverman1623c332013-10-01 18:05:16 -0700237static void Encoder5BRise(void) {
238 GPIOINT->IO2IntClr = (1 << 3);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700239 if (GPIO2->FIOPIN & (1 << 2)) {
240 --encoder5_val;
241 } else {
242 ++encoder5_val;
243 }
244}
Brian Silverman1623c332013-10-01 18:05:16 -0700245static void Encoder5BFall(void) {
246 GPIOINT->IO2IntClr = (1 << 3);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700247 if (GPIO2->FIOPIN & (1 << 2)) {
248 ++encoder5_val;
249 } else {
250 --encoder5_val;
251 }
252}
253
254volatile int32_t capture_top_rise;
255volatile int8_t top_rise_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700256static void IndexerTopRise(void) {
257 GPIOINT->IO0IntClr = (1 << 5);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700258 // edge counting encoder capture
259 ++top_rise_count;
260 capture_top_rise = encoder3_val;
261}
262volatile int32_t capture_top_fall;
263volatile int8_t top_fall_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700264static void IndexerTopFall(void) {
265 GPIOINT->IO0IntClr = (1 << 5);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700266 // edge counting encoder capture
267 ++top_fall_count;
268 capture_top_fall = encoder3_val;
269}
270volatile int8_t bottom_rise_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700271static void IndexerBottomRise(void) {
272 GPIOINT->IO0IntClr = (1 << 4);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700273 // edge counting
274 ++bottom_rise_count;
275}
276volatile int32_t capture_bottom_fall_delay;
277volatile int8_t bottom_fall_delay_count;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700278portTickType xDelayTimeFrom;
279static portTASK_FUNCTION(vDelayCapture, pvParameters)
280{
281 portTickType xSleepFrom = xTaskGetTickCount();
282
283 for (;;) {
Brian Silverman25aae9a2013-10-08 13:37:45 -0700284 // Atomically (wrt the ISR) switch xDelayTimeFrom to 0 and store its old
285 // value to use later.
Brian Silvermanf92396c2013-09-12 20:13:13 -0700286 NVIC_DisableIRQ(EINT3_IRQn);
Brian Silverman25aae9a2013-10-08 13:37:45 -0700287 portTickType new_time = xDelayTimeFrom;
288 xDelayTimeFrom = 0;
289 NVIC_EnableIRQ(EINT3_IRQn);
290
291 if (new_time != 0) {
292 xSleepFrom = new_time;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700293
294 vTaskDelayUntil(&xSleepFrom, kBottomFallDelayTime / portTICK_RATE_MS);
295
Brian Silverman25aae9a2013-10-08 13:37:45 -0700296 // Make sure that the USB ISR doesn't look at inconsistent values.
Brian Silverman1623c332013-10-01 18:05:16 -0700297 NVIC_DisableIRQ(USB_IRQn);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700298 capture_bottom_fall_delay = encoder3_val;
Brian Silverman1623c332013-10-01 18:05:16 -0700299 ++bottom_fall_delay_count;
300 NVIC_EnableIRQ(USB_IRQn);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700301 } else {
Brian Silverman25aae9a2013-10-08 13:37:45 -0700302 // Wait 10ms and then check again.
Brian Silvermanf92396c2013-09-12 20:13:13 -0700303 vTaskDelayUntil(&xSleepFrom, 10 / portTICK_RATE_MS);
304 }
305 }
306}
307
308volatile int8_t bottom_fall_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700309static void IndexerBottomFall(void) {
310 GPIOINT->IO0IntClr = (1 << 4);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700311 ++bottom_fall_count;
312 // edge counting start delayed capture
313 xDelayTimeFrom = xTaskGetTickCount();
Brian Silvermanf92396c2013-09-12 20:13:13 -0700314}
315volatile int32_t capture_wrist_rise;
316volatile int8_t wrist_rise_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700317static void WristHallRise(void) {
318 GPIOINT->IO0IntClr = (1 << 6);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700319 // edge counting encoder capture
320 ++wrist_rise_count;
321 capture_wrist_rise = (int32_t)QEI->QEIPOS;
322}
323volatile int32_t capture_shooter_angle_rise;
324volatile int8_t shooter_angle_rise_count;
Brian Silverman1623c332013-10-01 18:05:16 -0700325static void ShooterHallRise(void) {
326 GPIOINT->IO0IntClr = (1 << 7);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700327 // edge counting encoder capture
328 ++shooter_angle_rise_count;
329 capture_shooter_angle_rise = encoder2_val;
330}
Daniel Petti6300d682013-10-14 02:12:18 +0000331static void ShooterPhotoFall(void) {
332 GPIOINT->IO0IntClr = (1 << 23);
333 // We reset TC to make sure we don't get a crap
334 // value from CR0 when the capture interrupt occurs
335 // if the shooter is just starting up again.
336 reset_TC();
337}
Brian Silvermanf92396c2013-09-12 20:13:13 -0700338
339// Count leading zeros.
340// Returns 0 if bit 31 is set etc.
341__attribute__((always_inline)) static __INLINE uint32_t __clz(uint32_t value) {
342 uint32_t result;
343 __asm__("clz %0, %1" : "=r" (result) : "r" (value));
344 return result;
345}
346inline static void IRQ_Dispatch(void) {
Brian Silverman25aae9a2013-10-08 13:37:45 -0700347 // There is no need to add a loop here to handle multiple interrupts at the
348 // same time because the processor has tail chaining of interrupts which we
349 // can't really beat with our own loop.
350 // It would actually be bad because a loop here would block EINT1/2 for longer
351 // lengths of time.
352
Brian Silvermanf92396c2013-09-12 20:13:13 -0700353 uint32_t index = __clz(GPIOINT->IO2IntStatR | GPIOINT->IO0IntStatR |
354 (GPIOINT->IO2IntStatF << 28) | (GPIOINT->IO0IntStatF << 4));
355
356 typedef void (*Handler)(void);
357 const static Handler table[] = {
358 Encoder5BFall, // index 0: P2.3 Fall #bit 31 //Encoder 5 B //Dio 10
359 Encoder5AFall, // index 1: P2.2 Fall #bit 30 //Encoder 5 A //Dio 9
360 Encoder4BFall, // index 2: P2.1 Fall #bit 29 //Encoder 4 B //Dio 8
361 Encoder4AFall, // index 3: P2.0 Fall #bit 28 //Encoder 4 A //Dio 7
Daniel Petti6300d682013-10-14 02:12:18 +0000362 ShooterPhotoFall, // index 4: P0.23 Fall #bit 27 //Bot3 Shooter
Brian Silvermanf92396c2013-09-12 20:13:13 -0700363 Encoder2AFall, // index 5: P0.22 Fall #bit 26 //Encoder 2 A
364 Encoder2BFall, // index 6: P0.21 Fall #bit 25 //Encoder 2 B
365 Encoder3AFall, // index 7: P0.20 Fall #bit 24 //Encoder 3 A
366 Encoder3BFall, // index 8: P0.19 Fall #bit 23 //Encoder 3 B
367 Encoder2ARise, // index 9: P0.22 Rise #bit 22 //Encoder 2 A
368 Encoder2BRise, // index 10: P0.21 Rise #bit 21 //Encoder 2 B
369 Encoder3ARise, // index 11: P0.20 Rise #bit 20 //Encoder 3 A
370 Encoder3BRise, // index 12: P0.19 Rise #bit 19 //Encoder 3 B
371 NoGPIO, // index 13: NO GPIO #bit 18
372 NoGPIO, // index 14: NO GPIO #bit 17
373 NoGPIO, // index 15: NO GPIO #bit 16
374 NoGPIO, // index 16: NO GPIO #bit 15
375 NoGPIO, // index 17: NO GPIO #bit 14
376 NoGPIO, // index 18: NO GPIO #bit 13
377 NoGPIO, // index 19: NO GPIO #bit 12
378 ShooterHallRise, // index 20: P0.7 Fall #bit 11 //Shooter Hall //Dio 4
379 WristHallRise, // index 21: P0.6 Fall #bit 10 //Wrist Hall //Dio 3
380 IndexerTopRise, // index 22: P0.5 Fall #bit 9 //Indexer Top //Dio 2
381 IndexerBottomRise, // index 23: P0.4 Fall #bit 8 //Indexer Bottom //Dio 1
382 NoGPIO, // index 24: NO GPIO #bit 7
383 NoGPIO, // index 25: NO GPIO #bit 6
384 IndexerTopFall, // index 26: P0.5 Rise #bit 5 //Indexer Top //Dio 2
385 IndexerBottomFall, // index 27: P0.4 Rise #bit 4 //Indexer Bottom //Dio 1
386 Encoder5BRise, // index 28: P2.3 Rise #bit 3 //Encoder 5 B //Dio 10
387 Encoder5ARise, // index 29: P2.2 Rise #bit 2 //Encoder 5 A //Dio 9
388 Encoder4BRise, // index 30: P2.1 Rise #bit 1 //Encoder 4 B //Dio 8
389 Encoder4ARise, // index 31: P2.0 Rise #bit 0 //Encoder 4 A //Dio 7
390 NoGPIO // index 32: NO BITS SET #False Alarm
391 };
392 table[index]();
393}
394void EINT3_IRQHandler(void) {
Brian Silvermanf92396c2013-09-12 20:13:13 -0700395 IRQ_Dispatch();
Brian Silvermanf92396c2013-09-12 20:13:13 -0700396}
397int32_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
434void encoder_init(void) {
435 // Setup the encoder interface.
436 SC->PCONP |= PCONP_PCQEI;
437 PINCON->PINSEL3 = ((PINCON->PINSEL3 & 0xffff3dff) | 0x00004100);
438 // Reset the count and velocity.
439 QEI->QEICON = 0x00000005;
440 QEI->QEICONF = 0x00000004;
441 // Wrap back to 0 when we wrap the int and vice versa.
442 QEI->QEIMAXPOS = 0xFFFFFFFF;
Daniel Pettid9c84d42013-10-15 04:51:07 +0000443
Brian Silvermanf92396c2013-09-12 20:13:13 -0700444 // Set up encoder 4.
445 GPIOINT->IO2IntEnF |= (1 << 0); // Set GPIO falling interrupt.
446 GPIOINT->IO2IntEnR |= (1 << 0); // Set GPIO rising interrupt.
447 GPIOINT->IO2IntEnF |= (1 << 1); // Set GPIO falling interrupt.
448 GPIOINT->IO2IntEnR |= (1 << 1); // Set GPIO rising interrupt.
449 // Make sure they're in mode 00 (the default, aka nothing special).
450 PINCON->PINSEL4 &= ~(0x3 << 0);
451 PINCON->PINSEL4 &= ~(0x3 << 2);
452 encoder4_val = 0;
453
454 // Set up encoder 5.
455 GPIOINT->IO2IntEnF |= (1 << 2); // Set GPIO falling interrupt.
456 GPIOINT->IO2IntEnR |= (1 << 2); // Set GPIO rising interrupt.
457 GPIOINT->IO2IntEnF |= (1 << 3); // Set GPIO falling interrupt.
458 GPIOINT->IO2IntEnR |= (1 << 3); // Set GPIO rising interrupt.
459 // Make sure they're in mode 00 (the default, aka nothing special).
460 PINCON->PINSEL4 &= ~(0x3 << 4);
461 PINCON->PINSEL4 &= ~(0x3 << 6);
462 encoder5_val = 0;
463
464 // Enable interrupts from the GPIO pins.
465 NVIC_EnableIRQ(EINT3_IRQn);
466
467 if (is_bot3) {
Daniel Petti6300d682013-10-14 02:12:18 +0000468 // Set up timer for bot3 photosensor.
469 // Make sure timer three is powered.
470 SC->PCONP |= (1 << 23);
471 // We don't need all the precision the CCLK can provide.
472 // We'll use CCLK/8. (12.5 mhz).
473 SC->PCLKSEL1 |= (0x3 << 14);
474 // Use timer prescale to get that freq down to 500 hz.
475 TIM3->PR = 25000;
476 // Select capture 3.0 function on pin 0.23.
477 PINCON->PINSEL1 |= (0x3 << 14);
478 // Set timer to capture and interrupt on rising edge.
479 TIM3->CCR = 0x5;
480 // Set up match interrupt.
481 TIM3->MR0 = kWheelStopThreshold * 500;
482 TIM3->MCR = 1;
483 // Enable timer IRQ, and make it lower priority than the encoders.
484 NVIC_SetPriority(TIMER3_IRQn, 1);
485 NVIC_EnableIRQ(TIMER3_IRQn);
486 // Set up GPIO interrupt on other edge.
487 NVIC_DisableIRQ(EINT3_IRQn);
488 GPIOINT->IO0IntEnF |= (1 << 23);
489 NVIC_EnableIRQ(EINT3_IRQn);
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
505 // Set up encoder 2.
506 GPIOINT->IO0IntEnF |= (1 << 22); // Set GPIO falling interrupt.
507 GPIOINT->IO0IntEnR |= (1 << 22); // Set GPIO rising interrupt.
508 GPIOINT->IO0IntEnF |= (1 << 21); // Set GPIO falling interrupt.
509 GPIOINT->IO0IntEnR |= (1 << 21); // Set GPIO rising interrupt.
510 // Make sure they're in mode 00 (the default, aka nothing special).
511 PINCON->PINSEL1 &= ~(0x3 << 12);
512 PINCON->PINSEL1 &= ~(0x3 << 10);
513 encoder2_val = 0;
514
515 // Set up encoder 3.
516 GPIOINT->IO0IntEnF |= (1 << 20); // Set GPIO falling interrupt.
517 GPIOINT->IO0IntEnR |= (1 << 20); // Set GPIO rising interrupt.
518 GPIOINT->IO0IntEnF |= (1 << 19); // Set GPIO falling interrupt.
519 GPIOINT->IO0IntEnR |= (1 << 19); // Set GPIO rising interrupt.
520 // Make sure they're in mode 00 (the default, aka nothing special).
521 PINCON->PINSEL1 &= ~(0x3 << 8);
522 PINCON->PINSEL1 &= ~(0x3 << 6);
523 encoder3_val = 0;
524
Brian Silvermanf92396c2013-09-12 20:13:13 -0700525 xTaskCreate(vDelayCapture,
526 (signed char *) "SENSORs",
527 configMINIMAL_STACK_SIZE + 100,
528 NULL /*parameters*/,
529 tskIDLE_PRIORITY + 5,
530 NULL /*return task handle*/);
531
532 GPIOINT->IO0IntEnF |= (1 << 4); // Set GPIO falling interrupt
533 GPIOINT->IO0IntEnR |= (1 << 4); // Set GPIO rising interrupt
534 PINCON->PINSEL0 &= ~(0x3 << 8);
535
536 GPIOINT->IO0IntEnF |= (1 << 5); // Set GPIO falling interrupt
537 GPIOINT->IO0IntEnR |= (1 << 5); // Set GPIO rising interrupt
538 PINCON->PINSEL0 &= ~(0x3 << 10);
539
540 GPIOINT->IO0IntEnF |= (1 << 6);
541 PINCON->PINSEL0 &= ~(0x3 << 12);
542
543 GPIOINT->IO0IntEnF |= (1 << 7);
544 PINCON->PINSEL0 &= ~(0x3 << 14);
545 }
546}
547
548void fillSensorPacket(struct DataStruct *packet) {
Brian Silverman49876942013-10-11 17:50:26 -0700549 packet->gyro_angle = gyro_output.angle;
550 packet->old_gyro_reading = gyro_output.last_reading_bad;
551 packet->bad_gyro = gyro_output.gyro_bad;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700552
553 packet->dip_switch0 = dip_switch(0);
554 packet->dip_switch1 = dip_switch(1);
555 packet->dip_switch2 = dip_switch(2);
556 packet->dip_switch3 = dip_switch(3);
557
Brian Silverman25aae9a2013-10-08 13:37:45 -0700558 // We disable EINT3 to avoid sending back inconsistent values. All of the
559 // aligned reads from the variables are atomic, so disabling it isn't
560 // necessary for just reading encoder values. We re-enable it periodically
561 // because disabling and enabling is cheap (2 instructions) and we really rely
562 // on low interrupt latencies.
563
Daniel Pettid9c84d42013-10-15 04:51:07 +0000564 packet->main.left_drive = encoder5_val;
565 packet->main.right_drive = encoder4_val;
566
Brian Silvermanf92396c2013-09-12 20:13:13 -0700567 if (is_bot3) {
568 packet->robot_id = 1;
Daniel Pettid9c84d42013-10-15 04:51:07 +0000569
570 packet->bot3.shooter_cycle_ticks = shooter_cycle_ticks;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700571 } else { // is main robot
572 packet->robot_id = 0;
573
574 packet->main.shooter = encoder1_val;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700575 packet->main.indexer = encoder3_val;
576
Brian Silverman25aae9a2013-10-08 13:37:45 -0700577 NVIC_DisableIRQ(EINT3_IRQn);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700578
579 packet->main.wrist = (int32_t)QEI->QEIPOS;
580 packet->main.wrist_hall_effect = !digital(3);
581 packet->main.capture_wrist_rise = capture_wrist_rise;
582 packet->main.wrist_rise_count = wrist_rise_count;
583
Brian Silverman25aae9a2013-10-08 13:37:45 -0700584 NVIC_EnableIRQ(EINT3_IRQn);
Brian Silvermanf92396c2013-09-12 20:13:13 -0700585 NVIC_DisableIRQ(EINT3_IRQn);
586
587 packet->main.capture_top_rise = capture_top_rise;
588 packet->main.top_rise_count = top_rise_count;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700589 packet->main.capture_top_fall = capture_top_fall;
590 packet->main.top_fall_count = top_fall_count;
591 packet->main.top_disc = !digital(2);
592
Brian Silverman25aae9a2013-10-08 13:37:45 -0700593 NVIC_EnableIRQ(EINT3_IRQn);
594 NVIC_DisableIRQ(EINT3_IRQn);
595
Brian Silvermanf92396c2013-09-12 20:13:13 -0700596 packet->main.capture_bottom_fall_delay = capture_bottom_fall_delay;
597 packet->main.bottom_fall_delay_count = bottom_fall_delay_count;
598 packet->main.bottom_fall_count = bottom_fall_count;
599 packet->main.bottom_disc = !digital(1);
600
Brian Silverman25aae9a2013-10-08 13:37:45 -0700601 NVIC_EnableIRQ(EINT3_IRQn);
602 NVIC_DisableIRQ(EINT3_IRQn);
603
Brian Silverman1623c332013-10-01 18:05:16 -0700604 packet->main.loader_top = !digital(5);
605 packet->main.loader_bottom = !digital(6);
606
Brian Silverman25aae9a2013-10-08 13:37:45 -0700607 NVIC_EnableIRQ(EINT3_IRQn);
608 NVIC_DisableIRQ(EINT3_IRQn);
609
610 packet->main.shooter_angle = encoder2_val;
Brian Silvermanf92396c2013-09-12 20:13:13 -0700611 packet->main.capture_shooter_angle_rise = capture_shooter_angle_rise;
612 packet->main.shooter_angle_rise_count = shooter_angle_rise_count;
613 packet->main.angle_adjust_bottom_hall_effect = !digital(4);
614
615 NVIC_EnableIRQ(EINT3_IRQn);
616
617 packet->main.bottom_rise_count = bottom_rise_count;
618 }
619}