blob: ecc534756c19d484e74656dc33fd78290923caa2 [file] [log] [blame]
Brian Silvermanf91524f2017-09-23 13:15:55 -04001// This file has the main for the Teensy in the driver's station that
2// communicates over CAN with the one in the pistol grip controller.
3
4#include <stdio.h>
Brian Silvermand930f282017-11-04 23:09:12 -04005#include <atomic>
Brian Silvermanf91524f2017-09-23 13:15:55 -04006
7#include "motors/core/time.h"
8#include "motors/core/kinetis.h"
9#include "motors/usb/usb.h"
Brian Silvermaneda63f32017-10-08 18:57:33 -040010#include "motors/usb/cdc.h"
Brian Silvermand930f282017-11-04 23:09:12 -040011#include "motors/usb/hid.h"
Brian Silvermanf91524f2017-09-23 13:15:55 -040012#include "motors/util.h"
13
14namespace frc971 {
15namespace motors {
Brian Silvermaneda63f32017-10-08 18:57:33 -040016namespace {
17
Brian Silvermand930f282017-11-04 23:09:12 -040018::std::atomic<teensy::AcmTty *> global_stdout{nullptr};
19
Brian Silvermaneda63f32017-10-08 18:57:33 -040020void EchoChunks(teensy::AcmTty *tty1) {
21 while (true) {
22 char buffer[512];
23 size_t buffered = 0;
24 while (buffered < sizeof(buffer)) {
25 const size_t chunk =
26 tty1->Read(&buffer[buffered], sizeof(buffer) - buffered);
27 buffered += chunk;
28 }
29 size_t written = 0;
30 while (written < buffered) {
31 const size_t chunk = tty1->Write(&buffer[written], buffered - written);
32 written += chunk;
33 }
34
35 GPIOC_PTOR = 1 << 5;
36 for (int i = 0; i < 100000000; ++i) {
37 GPIOC_PSOR = 0;
38 }
39 GPIOC_PTOR = 1 << 5;
40 }
41}
42
43void EchoImmediately(teensy::AcmTty *tty1) {
44 while (true) {
45 if (false) {
46 // Delay for a while.
47 for (int i = 0; i < 100000000; ++i) {
48 GPIOC_PSOR = 0;
49 }
50 }
51
52 char buffer[64];
53 const size_t chunk = tty1->Read(buffer, sizeof(buffer));
54 size_t written = 0;
55 while (written < chunk) {
56 written += tty1->Write(&buffer[written], chunk - written);
57 }
58 }
59}
60
61void WriteData(teensy::AcmTty *tty1) {
62 GPIOC_PTOR = 1 << 5;
63 for (int i = 0; i < 100000000; ++i) {
64 GPIOC_PSOR = 0;
65 }
66 GPIOC_PTOR = 1 << 5;
67 for (int i = 0; i < 100000000; ++i) {
68 GPIOC_PSOR = 0;
69 }
70
71 const char data[] =
72 "Running command lineRunning command lineRunning command lineRunning "
73 "command lineRunning command lineRunning command lineRunning command "
74 "lineRunning command lineRunning command lineRunning command lineRunning "
75 "command lineRunning command lineRunning command lineRunning command "
76 "lineRunning command lineRunning command lineRunning command lineRunning "
77 "command lineRunning command lineRunning command lineRunning command "
78 "lineRunning command lineRunning command lineRunning command lineRunning "
79 "command lineRunning command lineRunning command lineRunning command "
80 "lineRunning command lineRunning command lineRunning command lineRunning "
81 "command lineRunning command lineRunning command lineRunning command "
82 "lineRunning command lineRunning command lineRunning command lineRunning "
83 "command lineRunning command lineRunning command lineRunning command "
84 "lineRunning command lineRunning command lineRunning command lineRunning "
85 "command lineRunning command lineRunning command lineRunning command "
86 "lineRunning command lineRunning command lineRunning command lineRunning "
87 "command lineRunning command lineRunning command lineRunning command "
88 "lineRunning command lineRunning command lineRunning command lineRunning "
89 "command lineRunning command lineRunning command lineRunning command "
90 "lineRunning command line\n";
91 size_t written = 0;
92 while (written < sizeof(data)) {
93 written += tty1->Write(&data[written], sizeof(data) - written);
94 }
95 GPIOC_PSOR = 1 << 5;
96 while (true) {
97 }
98}
99
Brian Silvermand930f282017-11-04 23:09:12 -0400100void MoveJoysticks(teensy::HidFunction *joysticks) {
101 static uint8_t x_axis = 0, y_axis = 97, z_axis = 5, rz_axis = 8;
102 while (true) {
103 {
104 DisableInterrupts disable_interrupts;
105 uint8_t buttons = 0;
106 if (x_axis % 8u) {
107 buttons = 2;
108 }
109 uint8_t report[10] = {x_axis, 0, y_axis, 0, z_axis,
110 rz_axis, 0, 0, buttons, 0};
111 joysticks->UpdateReport(report, 10, disable_interrupts);
112 }
113 delay(1);
114 x_axis += 1;
115 y_axis += 3;
116 z_axis += 5;
117 rz_axis += 8;
118 }
119}
120
Brian Silvermaneda63f32017-10-08 18:57:33 -0400121} // namespace
Brian Silvermanf91524f2017-09-23 13:15:55 -0400122
123extern "C" {
Brian Silvermand930f282017-11-04 23:09:12 -0400124
Brian Silvermanf91524f2017-09-23 13:15:55 -0400125void *__stack_chk_guard = (void *)0x67111971;
Brian Silvermand930f282017-11-04 23:09:12 -0400126
127int _write(int /*file*/, char *ptr, int len) {
128 teensy::AcmTty *const tty = global_stdout.load(::std::memory_order_acquire);
129 if (tty != nullptr) {
130 return tty->Write(ptr, len);
131 }
132 return 0;
Brian Silvermanf91524f2017-09-23 13:15:55 -0400133}
Brian Silvermand930f282017-11-04 23:09:12 -0400134
Brian Silvermanf91524f2017-09-23 13:15:55 -0400135void __stack_chk_fail(void);
136
Brian Silverman19ea60f2018-01-03 21:43:15 -0800137} // extern "C"
138
Brian Silvermanf91524f2017-09-23 13:15:55 -0400139extern "C" int main(void) {
140 // for background about this startup delay, please see these conversations
141 // https://forum.pjrc.com/threads/36606-startup-time-(400ms)?p=113980&viewfull=1#post113980
142 // https://forum.pjrc.com/threads/31290-Teensey-3-2-Teensey-Loader-1-24-Issues?p=87273&viewfull=1#post87273
143 delay(400);
144
145 // Set all interrupts to the second-lowest priority to start with.
146 for (int i = 0; i < NVIC_NUM_INTERRUPTS; i++) NVIC_SET_SANE_PRIORITY(i, 0xD);
147
148 // Now set priorities for all the ones we care about. They only have meaning
149 // relative to each other, which means centralizing them here makes it a lot
150 // more manageable.
151 NVIC_SET_SANE_PRIORITY(IRQ_USBOTG, 0x7);
152
153 // Set the LED's pin to output mode.
154 GPIO_BITBAND(GPIOC_PDDR, 5) = 1;
155 PORTC_PCR5 = PORT_PCR_DSE | PORT_PCR_MUX(1);
156
157 delay(100);
158
Brian Silvermand930f282017-11-04 23:09:12 -0400159 teensy::UsbDevice usb_device(0, 0x16c0, 0x0492);
Brian Silvermaneda63f32017-10-08 18:57:33 -0400160 usb_device.SetManufacturer("FRC 971 Spartan Robotics");
161 usb_device.SetProduct("Pistol Grip Controller interface");
Brian Silvermand930f282017-11-04 23:09:12 -0400162 teensy::HidFunction joysticks(&usb_device, 10);
163 // TODO(Brian): Figure out why Windows refuses to recognize the joystick along
164 // with a TTY or two.
165#if 0
Brian Silvermaneda63f32017-10-08 18:57:33 -0400166 teensy::AcmTty tty1(&usb_device);
Brian Silvermand930f282017-11-04 23:09:12 -0400167 teensy::AcmTty tty2(&usb_device);
168 global_stdout.store(&tty2, ::std::memory_order_release);
169#endif
Brian Silvermanf91524f2017-09-23 13:15:55 -0400170 usb_device.Initialize();
171
Brian Silvermand930f282017-11-04 23:09:12 -0400172 MoveJoysticks(&joysticks);
Brian Silvermanf91524f2017-09-23 13:15:55 -0400173
174 return 0;
175}
176
177void __stack_chk_fail(void) {
178 while (true) {
179 GPIOC_PSOR = (1 << 5);
180 printf("Stack corruption detected\n");
181 delay(1000);
182 GPIOC_PCOR = (1 << 5);
183 delay(1000);
184 }
185}
186
187} // namespace motors
188} // namespace frc971