blob: 676331b9e3ec92182a257292530f193b88345b11 [file] [log] [blame]
Brian Silverman259c4432018-01-15 14:34:21 -08001// This file has the main for the Teensy on the button board.
2
Brian Silverman259c4432018-01-15 14:34:21 -08003#include <inttypes.h>
Austin Schuh75c6af42018-03-09 21:16:07 -08004#include <stdio.h>
Brian Silverman259c4432018-01-15 14:34:21 -08005#include <atomic>
Austin Schuh75c6af42018-03-09 21:16:07 -08006#include <cmath>
Brian Silverman259c4432018-01-15 14:34:21 -08007
8#include "motors/core/time.h"
9#include "motors/core/kinetis.h"
10#include "motors/peripheral/adc.h"
11#include "motors/peripheral/can.h"
12#include "motors/usb/usb.h"
13#include "motors/usb/cdc.h"
14#include "motors/usb/hid.h"
15#include "motors/util.h"
16
17namespace frc971 {
18namespace motors {
19namespace {
20
Brian Silverman9ed2cf12018-05-12 13:06:38 -070021struct JoystickAdcReadings {
22 uint16_t analog0, analog1, analog2, analog3;
23};
24
25void AdcInitJoystick() {
26 AdcInitCommon();
27
28 // ANALOG0 ADC0_SE5b
29 PORTD_PCR1 = PORT_PCR_MUX(0);
30 // ANALOG1 ADC0_SE14
31 PORTC_PCR0 = PORT_PCR_MUX(0);
32 // ANALOG2 ADC0_SE13
33 PORTB_PCR3 = PORT_PCR_MUX(0);
34 // ANALOG3 ADC0_SE12
35 PORTB_PCR2 = PORT_PCR_MUX(0);
36}
37
38JoystickAdcReadings AdcReadJoystick(const DisableInterrupts &) {
39 JoystickAdcReadings r;
40
41 ADC0_SC1A = 5;
42 while (!(ADC0_SC1A & ADC_SC1_COCO)) {
43 }
44 ADC0_SC1A = 14;
45 r.analog0 = ADC0_RA;
46 while (!(ADC0_SC1A & ADC_SC1_COCO)) {
47 }
48 ADC0_SC1A = 13;
49 r.analog1 = ADC0_RA;
50 while (!(ADC0_SC1A & ADC_SC1_COCO)) {
51 }
52 ADC0_SC1A = 12;
53 r.analog2 = ADC0_RA;
54 while (!(ADC0_SC1A & ADC_SC1_COCO)) {
55 }
56 r.analog3 = ADC0_RA;
57
58 return r;
59}
60
Brian Silverman259c4432018-01-15 14:34:21 -080061::std::atomic<teensy::AcmTty *> global_stdout{nullptr};
62
63// The HID report descriptor we use.
Austin Schuh75c6af42018-03-09 21:16:07 -080064constexpr char kReportDescriptor1[] = {
Brian Silverman259c4432018-01-15 14:34:21 -080065 0x05, 0x01, // Usage Page (Generic Desktop),
66 0x09, 0x04, // Usage (Joystick),
67 0xA1, 0x01, // Collection (Application),
68 0x75, 0x08, // Report Size (8),
69 0x95, 0x04, // Report Count (4),
70 0x15, 0x00, // Logical Minimum (0),
71 0x26, 0xFF, 0x00, // Logical Maximum (255),
72 0x35, 0x00, // Physical Minimum (0),
73 0x46, 0xFF, 0x00, // Physical Maximum (255),
74 0x09, 0x30, // Usage (X),
75 0x09, 0x31, // Usage (Y),
76 0x09, 0x32, // Usage (Z),
77 0x09, 0x33, // Usage (Rz),
78 0x81, 0x02, // Input (Variable),
79 0x75, 0x01, // Report Size (1),
Austin Schuh75c6af42018-03-09 21:16:07 -080080 0x95, 0x10, // Report Count (16),
Brian Silverman259c4432018-01-15 14:34:21 -080081 0x25, 0x01, // Logical Maximum (1),
82 0x45, 0x01, // Physical Maximum (1),
83 0x05, 0x09, // Usage Page (Button),
84 0x19, 0x01, // Usage Minimum (01),
Austin Schuh75c6af42018-03-09 21:16:07 -080085 0x29, 0x10, // Usage Maximum (16),
Brian Silverman259c4432018-01-15 14:34:21 -080086 0x81, 0x02, // Input (Variable),
Brian Silverman259c4432018-01-15 14:34:21 -080087 0xC0 // End Collection
88};
89
Austin Schuh75c6af42018-03-09 21:16:07 -080090constexpr uint16_t report_size() { return 1 * 4 + 2; }
Brian Silverman259c4432018-01-15 14:34:21 -080091
Austin Schuh75c6af42018-03-09 21:16:07 -080092char DecodeAnalog(int analog) {
93 // None: 132
94 // Far: 71
95 // Near: 103
96 // Both: 0
97 if (analog < 30) {
98 return 0x3;
99 } else if (::std::abs(analog - 71) < 10) {
100 return 0x2;
101 } else if (::std::abs(analog - 103) < 10) {
102 return 0x1;
103 } else {
104 return 0x0;
105 }
106}
107
108void SendJoystickData(teensy::HidFunction *joystick0,
109 teensy::HidFunction *joystick1) {
Brian Silverman259c4432018-01-15 14:34:21 -0800110 uint32_t start = micros();
111 while (true) {
Brian Silvermana96c1a42018-05-12 12:11:31 -0700112 JoystickAdcReadings adc;
Austin Schuh75c6af42018-03-09 21:16:07 -0800113 char report0[report_size()];
114 char report1[report_size()];
Brian Silverman259c4432018-01-15 14:34:21 -0800115 {
116 DisableInterrupts disable_interrupts;
Brian Silvermana96c1a42018-05-12 12:11:31 -0700117 adc = AdcReadJoystick(disable_interrupts);
Brian Silverman259c4432018-01-15 14:34:21 -0800118 }
119
120 FTM0->C1V = adc.analog0 / 4;
121 FTM0->C0V = adc.analog1 / 4;
122 FTM0->C4V = adc.analog2 / 4;
123 FTM0->C3V = adc.analog3 / 4;
124 FTM0->PWMLOAD = FTM_PWMLOAD_LDOK;
Austin Schuh75c6af42018-03-09 21:16:07 -0800125 report0[0] = report1[0] = adc.analog0 / 16;
126 report0[1] = report1[1] = adc.analog1 / 16;
127 report0[2] = report1[2] = adc.analog2 / 16;
128 report0[3] = report1[3] = adc.analog3 / 16;
Brian Silverman259c4432018-01-15 14:34:21 -0800129
Brian Silverman33eb5fa2018-02-11 18:36:19 -0500130 report0[4] = ((PERIPHERAL_BITBAND(GPIOD_PDIR, 5) << 0) |
131 (PERIPHERAL_BITBAND(GPIOD_PDIR, 6) << 1) |
132 (PERIPHERAL_BITBAND(GPIOB_PDIR, 0) << 2) |
133 (PERIPHERAL_BITBAND(GPIOB_PDIR, 1) << 3) |
134 (PERIPHERAL_BITBAND(GPIOA_PDIR, 14) << 4) |
135 (PERIPHERAL_BITBAND(GPIOE_PDIR, 26) << 5) |
136 (PERIPHERAL_BITBAND(GPIOA_PDIR, 16) << 6) |
137 (PERIPHERAL_BITBAND(GPIOA_PDIR, 15) << 7)) ^
Austin Schuh75c6af42018-03-09 21:16:07 -0800138 0xff;
Brian Silverman259c4432018-01-15 14:34:21 -0800139
Brian Silverman33eb5fa2018-02-11 18:36:19 -0500140 report0[5] = ((PERIPHERAL_BITBAND(GPIOE_PDIR, 25) << 0) |
141 (PERIPHERAL_BITBAND(GPIOE_PDIR, 24) << 1) |
142 (PERIPHERAL_BITBAND(GPIOC_PDIR, 3) << 2) |
143 (PERIPHERAL_BITBAND(GPIOC_PDIR, 7) << 3) |
144 (PERIPHERAL_BITBAND(GPIOD_PDIR, 3) << 4) |
145 (PERIPHERAL_BITBAND(GPIOD_PDIR, 2) << 5) |
146 (PERIPHERAL_BITBAND(GPIOD_PDIR, 7) << 6) |
147 (PERIPHERAL_BITBAND(GPIOA_PDIR, 13) << 7)) ^
Austin Schuh75c6af42018-03-09 21:16:07 -0800148 0xff;
Brian Silverman259c4432018-01-15 14:34:21 -0800149
Austin Schuh75c6af42018-03-09 21:16:07 -0800150 report1[4] =
Brian Silverman33eb5fa2018-02-11 18:36:19 -0500151 ((PERIPHERAL_BITBAND(GPIOA_PDIR, 12) << 0) |
152 (PERIPHERAL_BITBAND(GPIOD_PDIR, 0) << 1) |
153 (PERIPHERAL_BITBAND(GPIOB_PDIR, 17) << 2) |
154 (PERIPHERAL_BITBAND(GPIOB_PDIR, 16) << 3) | (DecodeAnalog(report1[0]) << 4) |
Austin Schuh75c6af42018-03-09 21:16:07 -0800155 (DecodeAnalog(report1[1]) << 6)) ^
156 0x0f;
157 report1[5] = (DecodeAnalog(report1[2])) | (DecodeAnalog(report1[3]) << 2);
Brian Silverman259c4432018-01-15 14:34:21 -0800158
159 {
160 DisableInterrupts disable_interrupts;
Austin Schuh75c6af42018-03-09 21:16:07 -0800161 joystick0->UpdateReport(report0, sizeof(report0), disable_interrupts);
162 joystick1->UpdateReport(report1, sizeof(report1), disable_interrupts);
Brian Silverman259c4432018-01-15 14:34:21 -0800163 }
164
165 start = delay_from(start, 1);
166 }
167}
168
169void SetupLedFtm(BigFTM *ftm) {
170 // PWMSYNC doesn't matter because we set SYNCMODE down below.
171 ftm->MODE = FTM_MODE_WPDIS;
172 ftm->MODE = FTM_MODE_WPDIS | FTM_MODE_FTMEN;
173 ftm->SC = FTM_SC_CLKS(0) /* Disable counting for now */;
174
175 // Use center-aligned high-true for all the channels.
176 ftm->C0SC = FTM_CSC_ELSB;
177 ftm->C0V = 0;
178 ftm->C1SC = FTM_CSC_ELSB;
179 ftm->C1V = 0;
180 ftm->C2SC = FTM_CSC_ELSB;
181 ftm->C2V = 0;
182 ftm->C3SC = FTM_CSC_ELSB;
183 ftm->C3V = 0;
184 ftm->C4SC = FTM_CSC_ELSB;
185 ftm->C4V = 0;
186 ftm->C5SC = FTM_CSC_ELSB;
187 ftm->C5V = 0;
188 ftm->C6SC = FTM_CSC_ELSB;
189 ftm->C6V = 0;
190 ftm->C7SC = FTM_CSC_ELSB;
191 ftm->C7V = 0;
192
193 ftm->COMBINE = FTM_COMBINE_SYNCEN3 /* Synchronize updates usefully */ |
194 FTM_COMBINE_SYNCEN2 /* Synchronize updates usefully */ |
195 FTM_COMBINE_SYNCEN1 /* Synchronize updates usefully */ |
196 FTM_COMBINE_SYNCEN0 /* Synchronize updates usefully */;
197
198 ftm->CNTIN = 0;
199 ftm->CNT = 0;
200 ftm->MOD = 1024;
201 ftm->OUTINIT = 0;
202 ftm->POL = 0;
203 ftm->SYNCONF =
204 FTM_SYNCONF_HWWRBUF /* Hardware trigger flushes switching points */ |
205 FTM_SYNCONF_SWWRBUF /* Software trigger flushes switching points */ |
206 FTM_SYNCONF_SWRSTCNT /* Software trigger resets the count */ |
207 FTM_SYNCONF_SYNCMODE /* Use the new synchronization mode */;
208 // Don't want any intermediate loading points.
209 ftm->PWMLOAD = 0;
210
211 ftm->SYNC = FTM_SYNC_SWSYNC /* Flush everything out right now */;
212 // Wait for the software synchronization to finish.
213 while (ftm->SYNC & FTM_SYNC_SWSYNC) {
214 }
215 ftm->SC = FTM_SC_CPWMS /* Center-aligned PWM */ |
216 FTM_SC_CLKS(1) /* Use the system clock */ |
Brian Silverman5ffd2c22018-03-23 22:26:17 -0400217 FTM_SC_PS(6) /* Prescaler=64 */;
Brian Silverman259c4432018-01-15 14:34:21 -0800218
219 ftm->MODE &= ~FTM_MODE_WPDIS;
220}
221
222} // namespace
223
224extern "C" {
225
226void *__stack_chk_guard = (void *)0x67111971;
227
228int _write(int /*file*/, char *ptr, int len) {
229 teensy::AcmTty *const tty = global_stdout.load(::std::memory_order_acquire);
230 if (tty != nullptr) {
231 return tty->Write(ptr, len);
232 }
233 return 0;
234}
235
236void __stack_chk_fail(void);
237
238} // extern "C"
239
240extern "C" int main(void) {
241 // for background about this startup delay, please see these conversations
242 // https://forum.pjrc.com/threads/36606-startup-time-(400ms)?p=113980&viewfull=1#post113980
243 // https://forum.pjrc.com/threads/31290-Teensey-3-2-Teensey-Loader-1-24-Issues?p=87273&viewfull=1#post87273
244 delay(400);
245
246 // Set all interrupts to the second-lowest priority to start with.
247 for (int i = 0; i < NVIC_NUM_INTERRUPTS; i++) NVIC_SET_SANE_PRIORITY(i, 0xD);
248
249 // Now set priorities for all the ones we care about. They only have meaning
250 // relative to each other, which means centralizing them here makes it a lot
251 // more manageable.
252 NVIC_SET_SANE_PRIORITY(IRQ_USBOTG, 0x7);
253
254 // Set all the LED pins to output, slew rate controlled, high drive strength.
255 // Builtin
Brian Silverman33eb5fa2018-02-11 18:36:19 -0500256 PERIPHERAL_BITBAND(GPIOC_PDOR, 5) = 1;
Brian Silverman259c4432018-01-15 14:34:21 -0800257 PORTC_PCR5 = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(1);
Brian Silverman33eb5fa2018-02-11 18:36:19 -0500258 PERIPHERAL_BITBAND(GPIOC_PDDR, 5) = 1;
Brian Silverman259c4432018-01-15 14:34:21 -0800259 // LED0 FTM0_CH1
Brian Silverman33eb5fa2018-02-11 18:36:19 -0500260 PERIPHERAL_BITBAND(GPIOC_PDOR, 2) = 0;
Brian Silverman259c4432018-01-15 14:34:21 -0800261 PORTC_PCR2 = PORT_PCR_DSE | PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_MUX(4);
Brian Silverman33eb5fa2018-02-11 18:36:19 -0500262 PERIPHERAL_BITBAND(GPIOC_PDDR, 2) = 1;
Brian Silverman259c4432018-01-15 14:34:21 -0800263 // LED1 FTM0_CH0
Brian Silverman33eb5fa2018-02-11 18:36:19 -0500264 PERIPHERAL_BITBAND(GPIOC_PDOR, 1) = 0;
Brian Silverman259c4432018-01-15 14:34:21 -0800265 PORTC_PCR1 = PORT_PCR_DSE | PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_MUX(4);
Brian Silverman33eb5fa2018-02-11 18:36:19 -0500266 PERIPHERAL_BITBAND(GPIOC_PDDR, 1) = 1;
Brian Silverman259c4432018-01-15 14:34:21 -0800267 // LED2 FTM0_CH4
Brian Silverman33eb5fa2018-02-11 18:36:19 -0500268 PERIPHERAL_BITBAND(GPIOD_PDOR, 4) = 0;
Brian Silverman259c4432018-01-15 14:34:21 -0800269 PORTD_PCR4 = PORT_PCR_DSE | PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_MUX(4);
Brian Silverman33eb5fa2018-02-11 18:36:19 -0500270 PERIPHERAL_BITBAND(GPIOD_PDDR, 4) = 1;
Brian Silverman259c4432018-01-15 14:34:21 -0800271 // LED3 FTM0_CH3
Brian Silverman33eb5fa2018-02-11 18:36:19 -0500272 PERIPHERAL_BITBAND(GPIOC_PDOR, 4) = 0;
Brian Silverman259c4432018-01-15 14:34:21 -0800273 PORTC_PCR4 = PORT_PCR_DSE | PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_MUX(4);
Brian Silverman33eb5fa2018-02-11 18:36:19 -0500274 PERIPHERAL_BITBAND(GPIOC_PDDR, 4) = 1;
Brian Silverman259c4432018-01-15 14:34:21 -0800275 // LED4 FTM3_CH4 yellow
Brian Silverman33eb5fa2018-02-11 18:36:19 -0500276 PERIPHERAL_BITBAND(GPIOC_PDOR, 8) = 0;
Brian Silverman259c4432018-01-15 14:34:21 -0800277 PORTC_PCR8 = PORT_PCR_DSE | PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_MUX(1);
Brian Silverman33eb5fa2018-02-11 18:36:19 -0500278 PERIPHERAL_BITBAND(GPIOC_PDDR, 8) = 1;
Brian Silverman259c4432018-01-15 14:34:21 -0800279 // LED5 FTM3_CH5 green
Brian Silverman33eb5fa2018-02-11 18:36:19 -0500280 PERIPHERAL_BITBAND(GPIOC_PDOR, 9) = 0;
Brian Silverman259c4432018-01-15 14:34:21 -0800281 PORTC_PCR9 = PORT_PCR_DSE | PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_MUX(1);
Brian Silverman33eb5fa2018-02-11 18:36:19 -0500282 PERIPHERAL_BITBAND(GPIOC_PDDR, 9) = 1;
Brian Silverman259c4432018-01-15 14:34:21 -0800283 // LED6 FTM3_CH6 red
Brian Silverman33eb5fa2018-02-11 18:36:19 -0500284 PERIPHERAL_BITBAND(GPIOC_PDOR, 10) = 0;
Brian Silverman259c4432018-01-15 14:34:21 -0800285 PORTC_PCR10 = PORT_PCR_DSE | PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_MUX(1);
Brian Silverman33eb5fa2018-02-11 18:36:19 -0500286 PERIPHERAL_BITBAND(GPIOC_PDDR, 10) = 1;
Brian Silverman259c4432018-01-15 14:34:21 -0800287
288 // Set up the CAN pins.
289 PORTB_PCR18 = PORT_PCR_DSE | PORT_PCR_MUX(2);
290 PORTB_PCR19 = PORT_PCR_DSE | PORT_PCR_MUX(2);
291
Brian Silvermanff7b3872018-03-10 18:08:30 -0800292 // .1ms filter time.
293 PORTA_DFWR = PORTB_DFWR = PORTC_DFWR = PORTD_DFWR = PORTE_DFWR = 6000;
294
Brian Silverman259c4432018-01-15 14:34:21 -0800295 // Set up the buttons. The LEDs pull them up to 5V, so the Teensy needs to not
296 // be set to pull up.
297 // BTN0
298 PORTD_PCR5 = PORT_PCR_MUX(1);
Brian Silvermanff7b3872018-03-10 18:08:30 -0800299 PORTD_DFER |= 1 << 5;
Brian Silverman259c4432018-01-15 14:34:21 -0800300 // BTN1
301 PORTD_PCR6 = PORT_PCR_MUX(1);
Brian Silvermanff7b3872018-03-10 18:08:30 -0800302 PORTD_DFER |= 1 << 6;
Brian Silverman259c4432018-01-15 14:34:21 -0800303 // BTN2
Brian Silverman772a3482018-02-05 23:54:00 -0500304 PORTB_PCR0 = PORT_PCR_MUX(1);
Brian Silvermanff7b3872018-03-10 18:08:30 -0800305 PORTB_DFER |= 1 << 0;
Brian Silverman259c4432018-01-15 14:34:21 -0800306 // BTN3
307 PORTB_PCR1 = PORT_PCR_MUX(1);
Brian Silvermanff7b3872018-03-10 18:08:30 -0800308 PORTB_DFER |= 1 << 1;
Brian Silverman259c4432018-01-15 14:34:21 -0800309 // BTN4
310 PORTA_PCR14 = PORT_PCR_MUX(1);
Brian Silvermanff7b3872018-03-10 18:08:30 -0800311 PORTA_DFER |= 1 << 14;
Brian Silverman259c4432018-01-15 14:34:21 -0800312 // BTN5
313 PORTE_PCR26 = PORT_PCR_MUX(1);
Brian Silvermanff7b3872018-03-10 18:08:30 -0800314 PORTE_DFER |= 1 << 26;
Brian Silverman259c4432018-01-15 14:34:21 -0800315 // BTN6
316 PORTA_PCR16 = PORT_PCR_MUX(1);
Brian Silvermanff7b3872018-03-10 18:08:30 -0800317 PORTA_DFER |= 1 << 16;
Brian Silverman259c4432018-01-15 14:34:21 -0800318 // BTN7
319 PORTA_PCR15 = PORT_PCR_MUX(1);
Brian Silvermanff7b3872018-03-10 18:08:30 -0800320 PORTA_DFER |= 1 << 15;
Brian Silverman259c4432018-01-15 14:34:21 -0800321 // BTN8
322 PORTE_PCR25 = PORT_PCR_MUX(1);
Brian Silvermanff7b3872018-03-10 18:08:30 -0800323 PORTE_DFER |= 1 << 25;
Brian Silverman259c4432018-01-15 14:34:21 -0800324 // BTN9
325 PORTE_PCR24 = PORT_PCR_MUX(1);
Brian Silvermanff7b3872018-03-10 18:08:30 -0800326 PORTE_DFER |= 1 << 24;
Brian Silverman259c4432018-01-15 14:34:21 -0800327 // BTN10
328 PORTC_PCR3 = PORT_PCR_MUX(1);
Brian Silvermanff7b3872018-03-10 18:08:30 -0800329 PORTC_DFER |= 1 << 3;
Brian Silverman259c4432018-01-15 14:34:21 -0800330 // BTN11
331 PORTC_PCR7 = PORT_PCR_MUX(1);
Brian Silvermanff7b3872018-03-10 18:08:30 -0800332 PORTC_DFER |= 1 << 7;
Brian Silverman259c4432018-01-15 14:34:21 -0800333 // BTN12
334 PORTD_PCR3 = PORT_PCR_MUX(1);
Brian Silvermanff7b3872018-03-10 18:08:30 -0800335 PORTD_DFER |= 1 << 3;
Brian Silverman259c4432018-01-15 14:34:21 -0800336 // BTN13
337 PORTD_PCR2 = PORT_PCR_MUX(1);
Brian Silvermanff7b3872018-03-10 18:08:30 -0800338 PORTD_DFER |= 1 << 2;
Brian Silverman259c4432018-01-15 14:34:21 -0800339 // BTN14
340 PORTD_PCR7 = PORT_PCR_MUX(1);
Brian Silvermanff7b3872018-03-10 18:08:30 -0800341 PORTD_DFER |= 1 << 7;
Brian Silverman259c4432018-01-15 14:34:21 -0800342 // BTN15
343 PORTA_PCR13 = PORT_PCR_MUX(1);
Brian Silvermanff7b3872018-03-10 18:08:30 -0800344 PORTA_DFER |= 1 << 13;
Brian Silverman259c4432018-01-15 14:34:21 -0800345 // BTN16
346 PORTA_PCR12 = PORT_PCR_MUX(1);
Brian Silvermanff7b3872018-03-10 18:08:30 -0800347 PORTA_DFER |= 1 << 12;
Brian Silverman259c4432018-01-15 14:34:21 -0800348 // BTN17
349 PORTD_PCR0 = PORT_PCR_MUX(1);
Brian Silvermanff7b3872018-03-10 18:08:30 -0800350 PORTD_DFER |= 1 << 0;
Brian Silverman259c4432018-01-15 14:34:21 -0800351 // BTN18
352 PORTB_PCR17 = PORT_PCR_MUX(1);
Brian Silvermanff7b3872018-03-10 18:08:30 -0800353 PORTB_DFER |= 1 << 17;
Brian Silverman259c4432018-01-15 14:34:21 -0800354 // BTN19
355 PORTB_PCR16 = PORT_PCR_MUX(1);
Brian Silvermanff7b3872018-03-10 18:08:30 -0800356 PORTB_DFER |= 1 << 16;
Brian Silverman259c4432018-01-15 14:34:21 -0800357
358 delay(100);
359
360 teensy::UsbDevice usb_device(0, 0x16c0, 0x0492);
361 usb_device.SetManufacturer("FRC 971 Spartan Robotics");
362 usb_device.SetProduct("Spartan Joystick Board");
Austin Schuh75c6af42018-03-09 21:16:07 -0800363
364 teensy::HidFunction joystick0(&usb_device, report_size());
365 joystick0.set_report_descriptor(
366 ::std::string(kReportDescriptor1, sizeof(kReportDescriptor1)));
367
368 teensy::HidFunction joystick1(&usb_device, report_size());
369 joystick1.set_report_descriptor(
370 ::std::string(kReportDescriptor1, sizeof(kReportDescriptor1)));
371
Brian Silverman259c4432018-01-15 14:34:21 -0800372 teensy::AcmTty tty1(&usb_device);
373 global_stdout.store(&tty1, ::std::memory_order_release);
374 usb_device.Initialize();
375
376 can_init(0, 1);
Brian Silvermana96c1a42018-05-12 12:11:31 -0700377 AdcInitJoystick();
Brian Silverman259c4432018-01-15 14:34:21 -0800378 SetupLedFtm(FTM0);
379 SetupLedFtm(FTM3);
380
381 // Leave the LEDs on for a bit longer.
382 delay(300);
383 printf("Done starting up\n");
384
385 // Done starting up, now turn all the LEDs off.
Brian Silverman33eb5fa2018-02-11 18:36:19 -0500386 PERIPHERAL_BITBAND(GPIOC_PDOR, 5) = 0;
387 PERIPHERAL_BITBAND(GPIOC_PDOR, 2) = 1;
388 PERIPHERAL_BITBAND(GPIOC_PDOR, 1) = 1;
389 PERIPHERAL_BITBAND(GPIOD_PDOR, 4) = 1;
390 PERIPHERAL_BITBAND(GPIOC_PDOR, 4) = 1;
391 PERIPHERAL_BITBAND(GPIOC_PDOR, 8) = 1;
392 PERIPHERAL_BITBAND(GPIOC_PDOR, 9) = 1;
393 PERIPHERAL_BITBAND(GPIOC_PDOR, 10) = 1;
Brian Silverman259c4432018-01-15 14:34:21 -0800394
Austin Schuh75c6af42018-03-09 21:16:07 -0800395 SendJoystickData(&joystick0, &joystick1);
Brian Silverman259c4432018-01-15 14:34:21 -0800396
397 return 0;
398}
399
400void __stack_chk_fail(void) {
401 while (true) {
402 GPIOC_PSOR = (1 << 5);
403 printf("Stack corruption detected\n");
404 delay(1000);
405 GPIOC_PCOR = (1 << 5);
406 delay(1000);
407 }
408}
409
410} // namespace motors
411} // namespace frc971