blob: cbbee637e4c2e154ad249d7be8eacc7d0c63b6c3 [file] [log] [blame]
brians0ab60bb2013-01-31 02:21:51 +00001// ****************************************************************************
2// CopyLeft qwerk Robotics unINC. 2010 All Rights Reserved.
3// ****************************************************************************
4
5// ****************************************************************************
6// **************** IO Pin Setup
7// ****************************************************************************
8
9#include "FreeRTOS.h"
Austin Schuh63d0e9b2013-03-27 04:43:14 +000010#include "queue.h"
11#include "task.h"
12
13#include "analog.h"
brians0ab60bb2013-01-31 02:21:51 +000014
Brian Silvermand2411482013-03-28 21:36:32 -070015// How long (in ms) to wait after a falling edge on the bottom indexer sensor
16// before reading the indexer encoder.
17static const int kBottomFallDelayTime = 32;
18
Brian Silverman6ad00b82013-03-27 19:02:38 -070019void analog_init(void) {
20 // b[1:0] CAN RD1 p0.0
21 // b[3:2] CAN TD1 p0.1
22 //PINCON->PINSEL0 = 0x00000005;
brians0ab60bb2013-01-31 02:21:51 +000023
Brian Silverman6ad00b82013-03-27 19:02:38 -070024 // b[29:28] USB_DMIN p0.30
25 // b[27:26] USB_DPLUS p0.29
26 // b[21:20] AD0.3 p0.26
27 // b[19:18] AD0.2 p0.25
28 // PINCON->PINSEL1 = 0x14140000;
brians0ab60bb2013-01-31 02:21:51 +000029
Brian Silverman6ad00b82013-03-27 19:02:38 -070030 // PINCON->PINSEL2 = 0x0;
brians0ab60bb2013-01-31 02:21:51 +000031
Brian Silverman6ad00b82013-03-27 19:02:38 -070032 // b[31:30] AD0.5 p1.31
33 // b[29:28] V_BUS p1.30
34 // b[21:20] MCOB1 p1.26
35 // b[19:18] MCOA1 p1.25
36 // b[15:14] MCI1 p1.23
37 // b[13:12] MCOB0 p1.22
38 // b[09:08] MCI0 p1.20
39 // b[07:06] MCOA0 p1.19
40 // b[05:04] USB_UP_LED p1.18
41 //PINCON->PINSEL3 = 0xE0145150;
42 SC->PCONP |= PCONP_PCAD;
brians0ab60bb2013-01-31 02:21:51 +000043
Brian Silverman6ad00b82013-03-27 19:02:38 -070044 // Enable AD0.0, AD0.1, AD0.2, AD0.3
45 PINCON->PINSEL1 &= 0xFFC03FFF;
46 PINCON->PINSEL1 |= 0x00D54000;
47 ADC->ADCR = 0x00200500;
brians0ab60bb2013-01-31 02:21:51 +000048}
49
50// ****************************************************************************
51// **************** ADC Functions
52// ****************************************************************************
53
54
55// **************** macros
Brian Silverman6ad00b82013-03-27 19:02:38 -070056// starts conversion [26:24] = 001
brians0ab60bb2013-01-31 02:21:51 +000057
58// **************** functions
Brian Silverman6ad00b82013-03-27 19:02:38 -070059int analog(int channel) {
60 ADC->ADCR = ((ADC->ADCR & 0xF8FFFF00) | (0x01000000 | (1 << channel)));
brians0ab60bb2013-01-31 02:21:51 +000061
Brian Silverman6ad00b82013-03-27 19:02:38 -070062 // Poll until it is done.
63 while(!(ADC->ADGDR & 0x80000000));
brians0ab60bb2013-01-31 02:21:51 +000064
Brian Silverman6ad00b82013-03-27 19:02:38 -070065 return ((ADC->ADGDR & 0x0000FFF0) >> 4);
brians0ab60bb2013-01-31 02:21:51 +000066}
67// GPIO1 P0.4
68// GPIO2 P0.5
69// GPIO3 P0.6
70// GPIO4 P0.7
71// GPIO5 P0.8
72// GPIO6 P0.9
73// GPIO7 P2.0
74// GPIO8 P2.1
75// GPIO9 P2.2
76// GPIO10 P2.3
77// GPIO11 P2.4
78// GPIO12 P2.5
79
80// DIP0 P1.29
81// DIP1 P2.13
82// DIP2 P0.11
83// DIP3 P0.10
Brian Silvermand2411482013-03-28 21:36:32 -070084#define readGPIO(gpio, chan) ((((gpio)->FIOPIN) >> (chan)) & 1)
Brian Silverman6ad00b82013-03-27 19:02:38 -070085inline int readGPIO_inline(int major, int minor) {
86 switch (major) {
87 case 0:
88 return readGPIO(GPIO0, minor);
89 case 1:
90 return readGPIO(GPIO1, minor);
91 case 2:
92 return readGPIO(GPIO2, minor);
93 default:
94 return -1;
95 }
brians0ab60bb2013-01-31 02:21:51 +000096}
Brian Silverman6ad00b82013-03-27 19:02:38 -070097int digital(int channel) {
98 if (channel < 1) {
99 return -1;
100 } else if (channel < 7) {
101 int chan = channel + 3;
Brian Silvermand2411482013-03-28 21:36:32 -0700102 return readGPIO(GPIO0, chan);
Brian Silverman6ad00b82013-03-27 19:02:38 -0700103 } else if (channel < 13) {
104 int chan = channel - 7;
Brian Silvermand2411482013-03-28 21:36:32 -0700105 return readGPIO(GPIO2, chan);
Brian Silverman6ad00b82013-03-27 19:02:38 -0700106 }
107 return -1;
brians0ab60bb2013-01-31 02:21:51 +0000108}
Brian Silverman6ad00b82013-03-27 19:02:38 -0700109int dip(int channel) {
110 switch (channel) {
111 case 0:
112 return readGPIO(GPIO1, 29);
113 case 1:
114 return readGPIO(GPIO2, 13);
115 case 2:
116 return readGPIO(GPIO0, 11);
117 case 3:
118 return readGPIO(GPIO0, 10);
119 default:
120 return -1;
Brian Silverman6ad00b82013-03-27 19:02:38 -0700121 }
brians0ab60bb2013-01-31 02:21:51 +0000122}
Brian Silvermand2411482013-03-28 21:36:32 -0700123// ENC0A 1.20
124// ENC0B 1.23
125// ENC1A 2.11
126// ENC1B 2.12
127// ENC2A 0.21
128// ENC2B 0.22
129// ENC3A 0.19
130// ENC3B 0.20
brians0ab60bb2013-01-31 02:21:51 +0000131
Brian Silvermand2411482013-03-28 21:36:32 -0700132#define ENC(gpio, a, b) readGPIO(gpio, a) * 2 + readGPIO(gpio, b)
Brian Silverman6ad00b82013-03-27 19:02:38 -0700133int encoder_bits(int channel) {
134 switch (channel) {
135 case 0:
136 return ENC(GPIO1, 20, 23);
137 case 1:
138 return ENC(GPIO2, 11, 12);
139 case 2:
140 return ENC(GPIO0, 21, 22);
141 case 3:
142 return ENC(GPIO0, 19, 20);
143 default:
144 return -1;
145 }
146 return -1;
brians0ab60bb2013-01-31 02:21:51 +0000147}
Brian Silverman6ad00b82013-03-27 19:02:38 -0700148#undef ENC
brians0ab60bb2013-01-31 02:21:51 +0000149
Brian Silvermand2411482013-03-28 21:36:32 -0700150// Uses EINT1 and EINT2 on 2.11 and 2.12.
brians0ab60bb2013-01-31 02:21:51 +0000151volatile int32_t encoder1_val;
Brian Silverman6ad00b82013-03-27 19:02:38 -0700152// On GPIO pins 0.22 and 0.21.
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000153volatile int32_t encoder2_val;
Brian Silverman6ad00b82013-03-27 19:02:38 -0700154// On GPIO pins 0.20 and 0.19.
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000155volatile int32_t encoder3_val;
Brian Silverman6ad00b82013-03-27 19:02:38 -0700156// On GPIO pins 2.0 and 2.1.
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000157volatile int32_t encoder4_val;
Brian Silverman6ad00b82013-03-27 19:02:38 -0700158// On GPIO pins 2.2 and 2.3.
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000159volatile int32_t encoder5_val;
160
Brian Silverman6ad00b82013-03-27 19:02:38 -0700161// ENC1A 2.11
Brian Silvermand2411482013-03-28 21:36:32 -0700162static void EINT1_IRQHandler(void) {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700163 SC->EXTINT = 0x2;
Brian Silvermand2411482013-03-28 21:36:32 -0700164 // TODO(brians): figure out whether this style or the style in all the rest
165 // generates nicer code and then make them all the same
Brian Silverman6ad00b82013-03-27 19:02:38 -0700166 int stored_val = encoder1_val;
167 int fiopin = GPIO2->FIOPIN;
168 if (((fiopin >> 1) ^ fiopin) & 0x800) {
169 ++stored_val;
170 } else {
171 --stored_val;
172 }
173 encoder1_val = stored_val;
174 SC->EXTPOLAR ^= 0x2;
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000175}
Brian Silverman6ad00b82013-03-27 19:02:38 -0700176// ENC1B 2.12
Brian Silvermand2411482013-03-28 21:36:32 -0700177static void EINT2_IRQHandler(void) {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700178 SC->EXTINT = 0x4;
179 int stored_val = encoder1_val;
180 int fiopin = GPIO2->FIOPIN;
181 if (((fiopin >> 1) ^ fiopin) & 0x800) {
182 --stored_val;
183 } else {
184 ++stored_val;
185 }
186 encoder1_val = stored_val;
187 SC->EXTPOLAR ^= 0x4;
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000188}
189
Brian Silverman6ad00b82013-03-27 19:02:38 -0700190// GPIO Interrupt handlers
Brian Silvermand2411482013-03-28 21:36:32 -0700191static void NoGPIO() {}
192static void Encoder2ARise() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700193 GPIOINT->IO0IntClr |= (1 << 22);
194 if (GPIO0->FIOPIN & (1 << 21)) {
195 ++encoder2_val;
196 } else {
197 --encoder2_val;
198 }
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000199}
Brian Silvermand2411482013-03-28 21:36:32 -0700200static void Encoder2AFall() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700201 GPIOINT->IO0IntClr |= (1 << 22);
202 if (GPIO0->FIOPIN & (1 << 21)) {
203 --encoder2_val;
204 } else {
205 ++encoder2_val;
206 }
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000207}
Brian Silvermand2411482013-03-28 21:36:32 -0700208static void Encoder2BRise() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700209 GPIOINT->IO0IntClr |= (1 << 21);
210 if (GPIO0->FIOPIN & (1 << 22)) {
211 --encoder2_val;
212 } else {
213 ++encoder2_val;
214 }
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000215}
Brian Silvermand2411482013-03-28 21:36:32 -0700216static void Encoder2BFall() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700217 GPIOINT->IO0IntClr |= (1 << 21);
218 if (GPIO0->FIOPIN & (1 << 22)) {
219 ++encoder2_val;
220 } else {
221 --encoder2_val;
222 }
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000223}
224
Brian Silvermand2411482013-03-28 21:36:32 -0700225static void Encoder3ARise() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700226 GPIOINT->IO0IntClr |= (1 << 20);
227 if (GPIO0->FIOPIN & (1 << 19)) {
228 ++encoder3_val;
229 } else {
230 --encoder3_val;
231 }
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000232}
Brian Silvermand2411482013-03-28 21:36:32 -0700233static void Encoder3AFall() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700234 GPIOINT->IO0IntClr |= (1 << 20);
235 if (GPIO0->FIOPIN & (1 << 19)) {
236 --encoder3_val;
237 } else {
238 ++encoder3_val;
239 }
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000240}
Brian Silvermand2411482013-03-28 21:36:32 -0700241static void Encoder3BRise() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700242 GPIOINT->IO0IntClr |= (1 << 19);
243 if (GPIO0->FIOPIN & (1 << 20)) {
244 --encoder3_val;
245 } else {
246 ++encoder3_val;
247 }
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000248}
Brian Silvermand2411482013-03-28 21:36:32 -0700249static void Encoder3BFall() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700250 GPIOINT->IO0IntClr |= (1 << 19);
251 if (GPIO0->FIOPIN & (1 << 20)) {
252 ++encoder3_val;
253 } else {
254 --encoder3_val;
255 }
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000256}
257
Brian Silvermand2411482013-03-28 21:36:32 -0700258static void Encoder4ARise() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700259 GPIOINT->IO2IntClr |= (1 << 0);
260 if (GPIO2->FIOPIN & (1 << 1)) {
261 ++encoder4_val;
262 } else {
263 --encoder4_val;
264 }
265}
Brian Silvermand2411482013-03-28 21:36:32 -0700266static void Encoder4AFall() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700267 GPIOINT->IO2IntClr |= (1 << 0);
268 if (GPIO2->FIOPIN & (1 << 1)) {
269 --encoder4_val;
270 } else {
271 ++encoder4_val;
272 }
273}
Brian Silvermand2411482013-03-28 21:36:32 -0700274static void Encoder4BRise() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700275 GPIOINT->IO2IntClr |= (1 << 1);
276 if (GPIO2->FIOPIN & (1 << 0)) {
277 --encoder4_val;
278 } else {
279 ++encoder4_val;
280 }
281}
Brian Silvermand2411482013-03-28 21:36:32 -0700282static void Encoder4BFall() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700283 GPIOINT->IO2IntClr |= (1 << 1);
284 if (GPIO2->FIOPIN & (1 << 0)) {
285 ++encoder4_val;
286 } else {
287 --encoder4_val;
288 }
289}
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000290
Brian Silvermand2411482013-03-28 21:36:32 -0700291static void Encoder5ARise() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700292 GPIOINT->IO2IntClr |= (1 << 2);
293 if (GPIO2->FIOPIN & (1 << 3)) {
294 ++encoder5_val;
295 } else {
296 --encoder5_val;
297 }
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000298}
Brian Silvermand2411482013-03-28 21:36:32 -0700299static void Encoder5AFall() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700300 GPIOINT->IO2IntClr |= (1 << 2);
301 if (GPIO2->FIOPIN & (1 << 3)) {
302 --encoder5_val;
303 } else {
304 ++encoder5_val;
305 }
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000306}
Brian Silvermand2411482013-03-28 21:36:32 -0700307static void Encoder5BRise() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700308 GPIOINT->IO2IntClr |= (1 << 3);
309 if (GPIO2->FIOPIN & (1 << 2)) {
310 --encoder5_val;
311 } else {
312 ++encoder5_val;
313 }
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000314}
Brian Silvermand2411482013-03-28 21:36:32 -0700315static void Encoder5BFall() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700316 GPIOINT->IO2IntClr |= (1 << 3);
317 if (GPIO2->FIOPIN & (1 << 2)) {
318 ++encoder5_val;
319 } else {
320 --encoder5_val;
321 }
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000322}
323
324volatile int32_t capture_top_rise;
Brian Silverman6ad00b82013-03-27 19:02:38 -0700325volatile int8_t top_rise_count;
Brian Silvermand2411482013-03-28 21:36:32 -0700326static void IndexerTopRise() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700327 GPIOINT->IO0IntClr |= (1 << 5);
328 // edge counting encoder capture
329 ++top_rise_count;
330 capture_top_rise = encoder3_val;
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000331}
332volatile int32_t capture_top_fall;
333volatile int8_t top_fall_count;
Brian Silvermand2411482013-03-28 21:36:32 -0700334static void IndexerTopFall() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700335 GPIOINT->IO0IntClr |= (1 << 5);
336 // edge counting encoder capture
337 ++top_fall_count;
338 capture_top_fall = encoder3_val;
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000339}
340volatile int8_t bottom_rise_count;
Brian Silvermand2411482013-03-28 21:36:32 -0700341static void IndexerBottomRise() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700342 GPIOINT->IO0IntClr |= (1 << 4);
343 // edge counting
344 ++bottom_rise_count;
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000345}
346volatile int32_t capture_bottom_fall_delay;
347volatile int8_t bottom_fall_delay_count;
348volatile int32_t dirty_delay;
349portTickType xDelayTimeFrom;
350static portTASK_FUNCTION(vDelayCapture, pvParameters)
351{
Brian Silvermand2411482013-03-28 21:36:32 -0700352 portTickType xSleepFrom = xTaskGetTickCount();
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000353
Brian Silvermand2411482013-03-28 21:36:32 -0700354 for (;;) {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700355 NVIC_DisableIRQ(EINT3_IRQn);
Brian Silvermand2411482013-03-28 21:36:32 -0700356 if (dirty_delay != 0) {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700357 xSleepFrom = xDelayTimeFrom;
358 dirty_delay = 0;
359 NVIC_EnableIRQ(EINT3_IRQn);
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000360
Brian Silvermand2411482013-03-28 21:36:32 -0700361 vTaskDelayUntil(&xSleepFrom, kBottomFallDelayTime / portTICK_RATE_MS);
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000362
Brian Silverman6ad00b82013-03-27 19:02:38 -0700363 NVIC_DisableIRQ(EINT3_IRQn);
Brian Silvermand2411482013-03-28 21:36:32 -0700364 ++bottom_fall_delay_count;
Brian Silverman6ad00b82013-03-27 19:02:38 -0700365 capture_bottom_fall_delay = encoder3_val;
366 NVIC_EnableIRQ(EINT3_IRQn);
367 } else {
368 NVIC_EnableIRQ(EINT3_IRQn);
369 vTaskDelayUntil(&xSleepFrom, 10 / portTICK_RATE_MS);
370 }
371 }
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000372}
373
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000374volatile int8_t bottom_fall_count;
Brian Silvermand2411482013-03-28 21:36:32 -0700375static void IndexerBottomFall() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700376 GPIOINT->IO0IntClr |= (1 << 4);
Brian Silvermand2411482013-03-28 21:36:32 -0700377 ++bottom_fall_count;
Brian Silverman6ad00b82013-03-27 19:02:38 -0700378 // edge counting start delayed capture
379 xDelayTimeFrom = xTaskGetTickCount();
380 dirty_delay = 1;
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000381}
382volatile int32_t capture_wrist_rise;
383volatile int8_t wrist_rise_count;
Brian Silvermand2411482013-03-28 21:36:32 -0700384static void WristHallRise() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700385 GPIOINT->IO0IntClr |= (1 << 6);
386 // edge counting encoder capture
Brian Silvermand2411482013-03-28 21:36:32 -0700387 ++wrist_rise_count;
Brian Silverman6ad00b82013-03-27 19:02:38 -0700388 capture_wrist_rise = (int32_t)QEI->QEIPOS;
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000389}
390volatile int32_t capture_shooter_angle_rise;
391volatile int8_t shooter_angle_rise_count;
Brian Silvermand2411482013-03-28 21:36:32 -0700392static void ShooterHallRise() {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700393 GPIOINT->IO0IntClr |= (1 << 7);
394 // edge counting encoder capture
Brian Silvermand2411482013-03-28 21:36:32 -0700395 ++shooter_angle_rise_count;
Brian Silverman6ad00b82013-03-27 19:02:38 -0700396 capture_shooter_angle_rise = encoder2_val;
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000397}
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000398
Brian Silverman6ad00b82013-03-27 19:02:38 -0700399// Count leading zeros.
400// Returns 0 if bit 31 is set etc.
401__attribute__((always_inline)) static __INLINE uint8_t __clz(uint32_t value) {
402 uint8_t result;
403 __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value));
404 return result;
405}
406inline static void IRQ_Dispatch(void) {
Brian Silvermand2411482013-03-28 21:36:32 -0700407 // TODO(brians): think about adding a loop here so that we can handle multiple
408 // interrupts right on top of each other faster
Brian Silverman6ad00b82013-03-27 19:02:38 -0700409 uint8_t index = __clz(GPIOINT->IO2IntStatR | GPIOINT->IO0IntStatR |
410 (GPIOINT->IO2IntStatF << 28) | (GPIOINT->IO0IntStatF << 4));
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000411
Brian Silverman6ad00b82013-03-27 19:02:38 -0700412 typedef void (*Handler)(void);
413 const static Handler table[] = {
414 Encoder5BFall, // index 0: P2.3 Fall #bit 31 //Encoder 5 B //Dio 10
415 Encoder5AFall, // index 1: P2.2 Fall #bit 30 //Encoder 5 A //Dio 9
416 Encoder4BFall, // index 2: P2.1 Fall #bit 29 //Encoder 4 B //Dio 8
417 Encoder4AFall, // index 3: P2.0 Fall #bit 28 //Encoder 4 A //Dio 7
418 NoGPIO, // index 4: NO GPIO #bit 27
419 Encoder2AFall, // index 5: P0.22 Fall #bit 26 //Encoder 2 A
420 Encoder2BFall, // index 6: P0.21 Fall #bit 25 //Encoder 2 B
421 Encoder3AFall, // index 7: P0.20 Fall #bit 24 //Encoder 3 A
422 Encoder3BFall, // index 8: P0.19 Fall #bit 23 //Encoder 3 B
423 Encoder2ARise, // index 9: P0.22 Rise #bit 22 //Encoder 2 A
424 Encoder2BRise, // index 10: P0.21 Rise #bit 21 //Encoder 2 B
425 Encoder3ARise, // index 11: P0.20 Rise #bit 20 //Encoder 3 A
426 Encoder3BRise, // index 12: P0.19 Rise #bit 19 //Encoder 3 B
427 NoGPIO, // index 13: NO GPIO #bit 18
428 NoGPIO, // index 14: NO GPIO #bit 17
429 NoGPIO, // index 15: NO GPIO #bit 16
430 NoGPIO, // index 16: NO GPIO #bit 15
431 NoGPIO, // index 17: NO GPIO #bit 14
432 NoGPIO, // index 18: NO GPIO #bit 13
433 NoGPIO, // index 19: NO GPIO #bit 12
434 NoGPIO, // index 20: NO GPIO #bit 11
435 NoGPIO, // index 21: NO GPIO #bit 10
436 IndexerTopFall, // index 22: P0.5 Fall #bit 9 //Indexer Top //Dio 2
437 IndexerBottomFall, // index 23: P0.4 Fall #bit 8 //Indexer Bottom //Dio 1
438 ShooterHallRise, // index 24: P0.7 Rise #bit 7 //Shooter Hall //Dio 4
439 WristHallRise, // index 25: P0.6 Rise #bit 6 //Wrist Hall //Dio 3
440 IndexerTopRise, // index 26: P0.5 Rise #bit 5 //Indexer Top //Dio 2
441 IndexerBottomRise, // index 27: P0.4 Rise #bit 4 //Indexer Bottom //Dio 1
442 Encoder5BRise, // index 28: P2.3 Rise #bit 3 //Encoder 5 B //Dio 10
443 Encoder5ARise, // index 29: P2.2 Rise #bit 2 //Encoder 5 A //Dio 9
444 Encoder4BRise, // index 30: P2.1 Rise #bit 1 //Encoder 4 B //Dio 8
445 Encoder4ARise, // index 31: P2.0 Rise #bit 0 //Encoder 4 A //Dio 7
446 NoGPIO // index 32: NO BITS SET #False Alarm
447 };
448 table[index]();
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000449}
Brian Silverman6ad00b82013-03-27 19:02:38 -0700450void EINT3_IRQHandler(void) {
Brian Silvermand2411482013-03-28 21:36:32 -0700451 // Have to disable it here or else it re-fires the interrupt while the code
452 // reads to figure out which pin the interrupt is for.
453 // TODO(brians): figure out details + look for an alternative
Brian Silverman6ad00b82013-03-27 19:02:38 -0700454 NVIC_DisableIRQ(EINT3_IRQn);
455 IRQ_Dispatch();
456 NVIC_EnableIRQ(EINT3_IRQn);
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000457}
Brian Silvermand2411482013-03-28 21:36:32 -0700458int32_t encoder_val(int chan) {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700459 int32_t val;
Brian Silvermand2411482013-03-28 21:36:32 -0700460 switch (chan) {
461 case 0: // Wrist
Brian Silverman6ad00b82013-03-27 19:02:38 -0700462 return (int32_t)QEI->QEIPOS;
Brian Silvermand2411482013-03-28 21:36:32 -0700463 case 1: // Shooter Wheel
Brian Silverman6ad00b82013-03-27 19:02:38 -0700464 NVIC_DisableIRQ(EINT1_IRQn);
465 NVIC_DisableIRQ(EINT2_IRQn);
466 val = encoder1_val;
467 NVIC_EnableIRQ(EINT2_IRQn);
468 NVIC_EnableIRQ(EINT1_IRQn);
469 return val;
Brian Silvermand2411482013-03-28 21:36:32 -0700470 case 2: // Shooter Angle
Brian Silverman6ad00b82013-03-27 19:02:38 -0700471 NVIC_DisableIRQ(EINT3_IRQn);
472 val = encoder2_val;
473 NVIC_EnableIRQ(EINT3_IRQn);
474 return val;
Brian Silvermand2411482013-03-28 21:36:32 -0700475 case 3: // Indexer
Brian Silverman6ad00b82013-03-27 19:02:38 -0700476 NVIC_DisableIRQ(EINT3_IRQn);
477 val = encoder3_val;
478 NVIC_EnableIRQ(EINT3_IRQn);
479 return val;
Brian Silvermand2411482013-03-28 21:36:32 -0700480 case 4: // Drive R
Brian Silverman6ad00b82013-03-27 19:02:38 -0700481 NVIC_DisableIRQ(EINT3_IRQn);
482 val = encoder4_val;
483 NVIC_EnableIRQ(EINT3_IRQn);
484 return val;
Brian Silvermand2411482013-03-28 21:36:32 -0700485 case 5: // Drive L
Brian Silverman6ad00b82013-03-27 19:02:38 -0700486 NVIC_DisableIRQ(EINT3_IRQn);
487 val = encoder5_val;
488 NVIC_EnableIRQ(EINT3_IRQn);
489 return val;
490 default:
491 return -1;
492 }
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000493}
Brian Silverman6ad00b82013-03-27 19:02:38 -0700494void fillSensorPacket(struct DataStruct *packet) {
495 packet->gyro_angle = gyro_angle;
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000496
Brian Silverman6ad00b82013-03-27 19:02:38 -0700497 packet->shooter = encoder1_val;
Brian Silverman6ad00b82013-03-27 19:02:38 -0700498 packet->right_drive = encoder4_val;
499 packet->left_drive = encoder5_val;
500 packet->shooter_angle = encoder2_val;
501 packet->indexer = encoder3_val;
Brian Silvermand2411482013-03-28 21:36:32 -0700502 packet->wrist = (int32_t)QEI->QEIPOS;
503
504 // TODO(brians): should we re-enable it in between here so that it's disabled
505 // for shorter chunks?
506 NVIC_DisableIRQ(EINT3_IRQn);
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000507
Brian Silverman6ad00b82013-03-27 19:02:38 -0700508 packet->capture_top_rise = capture_top_rise;
509 packet->top_rise_count = top_rise_count;
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000510
Brian Silverman6ad00b82013-03-27 19:02:38 -0700511 packet->capture_top_fall = capture_top_fall;
512 packet->top_fall_count = top_fall_count;
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000513
Brian Silverman6ad00b82013-03-27 19:02:38 -0700514 packet->capture_bottom_fall_delay = capture_bottom_fall_delay;
515 packet->bottom_fall_delay_count = bottom_fall_delay_count;
516 packet->bottom_fall_count = bottom_fall_count;
517
518 packet->capture_wrist_rise = capture_wrist_rise;
519 packet->wrist_rise_count = wrist_rise_count;
520
521 packet->capture_shooter_angle_rise = capture_shooter_angle_rise;
522 packet->shooter_angle_rise_count = shooter_angle_rise_count;
523
524 NVIC_EnableIRQ(EINT3_IRQn);
525
Brian Silvermand2411482013-03-28 21:36:32 -0700526 packet->bottom_rise_count = bottom_rise_count;
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000527}
528
Brian Silvermand2411482013-03-28 21:36:32 -0700529void encoder_init(void) {
Brian Silverman6ad00b82013-03-27 19:02:38 -0700530 // Setup the encoder interface.
531 SC->PCONP |= PCONP_PCQEI;
532 PINCON->PINSEL3 = ((PINCON->PINSEL3 & 0xffff3dff) | 0x00004100);
533 // Reset the count and velocity.
534 QEI->QEICON = 0x00000005;
535 QEI->QEICONF = 0x00000004;
536 // Wrap back to 0 when we wrap the int and vice versa.
537 QEI->QEIMAXPOS = 0xFFFFFFFF;
brians0ab60bb2013-01-31 02:21:51 +0000538
Brian Silverman6ad00b82013-03-27 19:02:38 -0700539 // Set up encoder 1.
540 // Make GPIOs 2.11 and 2.12 trigger EINT1 and EINT2 (respectively).
541 // PINSEL4[23:22] = {0 1}
542 // PINSEL4[25:24] = {0 1}
543 PINCON->PINSEL4 = (PINCON->PINSEL4 & ~(0x3 << 22)) | (0x1 << 22);
544 PINCON->PINSEL4 = (PINCON->PINSEL4 & ~(0x3 << 24)) | (0x1 << 24);
545 // Clear the interrupt flags for EINT1 and EINT2 (0x6 = 0b0110).
546 SC->EXTMODE = 0x6;
547 SC->EXTINT = 0x6;
548 NVIC_EnableIRQ(EINT1_IRQn);
549 NVIC_EnableIRQ(EINT2_IRQn);
550 encoder1_val = 0;
brians0ab60bb2013-01-31 02:21:51 +0000551
Brian Silverman6ad00b82013-03-27 19:02:38 -0700552 // Set up encoder 2.
553 GPIOINT->IO0IntEnF |= (1 << 22); // Set GPIO falling interrupt.
554 GPIOINT->IO0IntEnR |= (1 << 22); // Set GPIO rising interrupt.
555 GPIOINT->IO0IntEnF |= (1 << 21); // Set GPIO falling interrupt.
556 GPIOINT->IO0IntEnR |= (1 << 21); // Set GPIO rising interrupt.
Brian Silvermand2411482013-03-28 21:36:32 -0700557 // Make sure they're in mode 00 (the default, aka nothing special).
Brian Silverman6ad00b82013-03-27 19:02:38 -0700558 PINCON->PINSEL1 &= ~(0x3 << 12);
559 PINCON->PINSEL1 &= ~(0x3 << 10);
560 encoder2_val = 0;
brians0ab60bb2013-01-31 02:21:51 +0000561
Brian Silverman6ad00b82013-03-27 19:02:38 -0700562 // Set up encoder 3.
563 GPIOINT->IO0IntEnF |= (1 << 20); // Set GPIO falling interrupt.
564 GPIOINT->IO0IntEnR |= (1 << 20); // Set GPIO rising interrupt.
565 GPIOINT->IO0IntEnF |= (1 << 19); // Set GPIO falling interrupt.
566 GPIOINT->IO0IntEnR |= (1 << 19); // Set GPIO rising interrupt.
Brian Silvermand2411482013-03-28 21:36:32 -0700567 // Make sure they're in mode 00 (the default, aka nothing special).
Brian Silverman6ad00b82013-03-27 19:02:38 -0700568 PINCON->PINSEL1 &= ~(0x3 << 8);
569 PINCON->PINSEL1 &= ~(0x3 << 6);
570 encoder3_val = 0;
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000571
Brian Silverman6ad00b82013-03-27 19:02:38 -0700572 // Set up encoder 4.
573 GPIOINT->IO2IntEnF |= (1 << 0); // Set GPIO falling interrupt.
574 GPIOINT->IO2IntEnR |= (1 << 0); // Set GPIO rising interrupt.
575 GPIOINT->IO2IntEnF |= (1 << 1); // Set GPIO falling interrupt.
576 GPIOINT->IO2IntEnR |= (1 << 1); // Set GPIO rising interrupt.
Brian Silvermand2411482013-03-28 21:36:32 -0700577 // Make sure they're in mode 00 (the default, aka nothing special).
Brian Silverman6ad00b82013-03-27 19:02:38 -0700578 PINCON->PINSEL4 &= ~(0x3 << 0);
579 PINCON->PINSEL4 &= ~(0x3 << 2);
580 encoder4_val = 0;
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000581
Brian Silverman6ad00b82013-03-27 19:02:38 -0700582 // Set up encoder 5.
583 GPIOINT->IO2IntEnF |= (1 << 2); // Set GPIO falling interrupt.
584 GPIOINT->IO2IntEnR |= (1 << 2); // Set GPIO rising interrupt.
585 GPIOINT->IO2IntEnF |= (1 << 3); // Set GPIO falling interrupt.
586 GPIOINT->IO2IntEnR |= (1 << 3); // Set GPIO rising interrupt.
Brian Silvermand2411482013-03-28 21:36:32 -0700587 // Make sure they're in mode 00 (the default, aka nothing special).
Brian Silverman6ad00b82013-03-27 19:02:38 -0700588 PINCON->PINSEL4 &= ~(0x3 << 4);
589 PINCON->PINSEL4 &= ~(0x3 << 6);
590 encoder5_val = 0;
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000591
Brian Silverman6ad00b82013-03-27 19:02:38 -0700592 // Enable interrupts from the GPIO pins.
593 NVIC_EnableIRQ(EINT3_IRQn);
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000594
Brian Silverman6ad00b82013-03-27 19:02:38 -0700595 xTaskCreate(vDelayCapture,
596 (signed char *) "SENSORs",
597 configMINIMAL_STACK_SIZE + 100,
598 NULL /*parameters*/,
599 tskIDLE_PRIORITY + 5,
600 NULL /*return task handle*/);
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000601
Brian Silverman6ad00b82013-03-27 19:02:38 -0700602 GPIOINT->IO0IntEnF |= (1 << 4); // Set GPIO falling interrupt
603 GPIOINT->IO0IntEnR |= (1 << 4); // Set GPIO rising interrupt
604 PINCON->PINSEL0 &= ~(0x3 << 8);
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000605
Brian Silverman6ad00b82013-03-27 19:02:38 -0700606 GPIOINT->IO0IntEnF |= (1 << 5); // Set GPIO falling interrupt
607 GPIOINT->IO0IntEnR |= (1 << 5); // Set GPIO rising interrupt
608 PINCON->PINSEL0 &= ~(0x3 << 10);
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000609
Brian Silverman6ad00b82013-03-27 19:02:38 -0700610 GPIOINT->IO0IntEnR |= (1 << 6); // Set GPIO rising interrupt
611 PINCON->PINSEL0 &= ~(0x3 << 12);
Austin Schuh63d0e9b2013-03-27 04:43:14 +0000612
Brian Silverman6ad00b82013-03-27 19:02:38 -0700613 GPIOINT->IO0IntEnR |= (1 << 7); // Set GPIO rising interrupt
614 PINCON->PINSEL0 &= ~(0x3 << 14);
brians0ab60bb2013-01-31 02:21:51 +0000615}