diff options
Diffstat (limited to 'tmk_core/protocol/chibios/chibios.c')
-rw-r--r-- | tmk_core/protocol/chibios/chibios.c | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/tmk_core/protocol/chibios/chibios.c b/tmk_core/protocol/chibios/chibios.c new file mode 100644 index 000000000..78a2e3fcb --- /dev/null +++ b/tmk_core/protocol/chibios/chibios.c | |||
@@ -0,0 +1,255 @@ | |||
1 | /* | ||
2 | * (c) 2015 flabberast <s3+flabbergast@sdfeu.org> | ||
3 | * | ||
4 | * Based on the following work: | ||
5 | * - Guillaume Duc's raw hid example (MIT License) | ||
6 | * https://github.com/guiduc/usb-hid-chibios-example | ||
7 | * - PJRC Teensy examples (MIT License) | ||
8 | * https://www.pjrc.com/teensy/usb_keyboard.html | ||
9 | * - hasu's TMK keyboard code (GPL v2 and some code Modified BSD) | ||
10 | * https://github.com/tmk/tmk_keyboard/ | ||
11 | * - ChibiOS demo code (Apache 2.0 License) | ||
12 | * http://www.chibios.org | ||
13 | * | ||
14 | * Since some GPL'd code is used, this work is licensed under | ||
15 | * GPL v2 or later. | ||
16 | */ | ||
17 | |||
18 | #include <ch.h> | ||
19 | #include <hal.h> | ||
20 | |||
21 | #include "usb_main.h" | ||
22 | |||
23 | /* TMK includes */ | ||
24 | #include "report.h" | ||
25 | #include "host.h" | ||
26 | #include "host_driver.h" | ||
27 | #include "keyboard.h" | ||
28 | #include "action.h" | ||
29 | #include "action_util.h" | ||
30 | #include "mousekey.h" | ||
31 | #include "led.h" | ||
32 | #include "sendchar.h" | ||
33 | #include "debug.h" | ||
34 | #include "print.h" | ||
35 | |||
36 | #ifndef EARLY_INIT_PERFORM_BOOTLOADER_JUMP | ||
37 | // Change this to be TRUE once we've migrated keyboards to the new init system | ||
38 | // Remember to change docs/platformdev_chibios_earlyinit.md as well. | ||
39 | # define EARLY_INIT_PERFORM_BOOTLOADER_JUMP FALSE | ||
40 | #endif | ||
41 | |||
42 | #ifdef SLEEP_LED_ENABLE | ||
43 | # include "sleep_led.h" | ||
44 | #endif | ||
45 | #ifdef SERIAL_LINK_ENABLE | ||
46 | # include "serial_link/system/serial_link.h" | ||
47 | #endif | ||
48 | #ifdef VISUALIZER_ENABLE | ||
49 | # include "visualizer/visualizer.h" | ||
50 | #endif | ||
51 | #ifdef MIDI_ENABLE | ||
52 | # include "qmk_midi.h" | ||
53 | #endif | ||
54 | #include "suspend.h" | ||
55 | #include "wait.h" | ||
56 | |||
57 | /* ------------------------- | ||
58 | * TMK host driver defs | ||
59 | * ------------------------- | ||
60 | */ | ||
61 | |||
62 | /* declarations */ | ||
63 | uint8_t keyboard_leds(void); | ||
64 | void send_keyboard(report_keyboard_t *report); | ||
65 | void send_mouse(report_mouse_t *report); | ||
66 | void send_system(uint16_t data); | ||
67 | void send_consumer(uint16_t data); | ||
68 | void send_digitizer(report_digitizer_t *report); | ||
69 | |||
70 | /* host struct */ | ||
71 | host_driver_t chibios_driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer}; | ||
72 | |||
73 | #ifdef VIRTSER_ENABLE | ||
74 | void virtser_task(void); | ||
75 | #endif | ||
76 | |||
77 | #ifdef RAW_ENABLE | ||
78 | void raw_hid_task(void); | ||
79 | #endif | ||
80 | |||
81 | #ifdef CONSOLE_ENABLE | ||
82 | void console_task(void); | ||
83 | #endif | ||
84 | #ifdef MIDI_ENABLE | ||
85 | void midi_ep_task(void); | ||
86 | #endif | ||
87 | |||
88 | /* TESTING | ||
89 | * Amber LED blinker thread, times are in milliseconds. | ||
90 | */ | ||
91 | /* set this variable to non-zero anywhere to blink once */ | ||
92 | // static THD_WORKING_AREA(waThread1, 128); | ||
93 | // static THD_FUNCTION(Thread1, arg) { | ||
94 | |||
95 | // (void)arg; | ||
96 | // chRegSetThreadName("blinker"); | ||
97 | // while (true) { | ||
98 | // systime_t time; | ||
99 | |||
100 | // time = USB_DRIVER.state == USB_ACTIVE ? 250 : 500; | ||
101 | // palClearLine(LINE_CAPS_LOCK); | ||
102 | // chSysPolledDelayX(MS2RTC(STM32_HCLK, time)); | ||
103 | // palSetLine(LINE_CAPS_LOCK); | ||
104 | // chSysPolledDelayX(MS2RTC(STM32_HCLK, time)); | ||
105 | // } | ||
106 | // } | ||
107 | |||
108 | /* Early initialisation | ||
109 | */ | ||
110 | __attribute__((weak)) void early_hardware_init_pre(void) { | ||
111 | #if EARLY_INIT_PERFORM_BOOTLOADER_JUMP | ||
112 | void enter_bootloader_mode_if_requested(void); | ||
113 | enter_bootloader_mode_if_requested(); | ||
114 | #endif // EARLY_INIT_PERFORM_BOOTLOADER_JUMP | ||
115 | } | ||
116 | |||
117 | __attribute__((weak)) void early_hardware_init_post(void) {} | ||
118 | |||
119 | __attribute__((weak)) void board_init(void) {} | ||
120 | |||
121 | // This overrides what's normally in ChibiOS board definitions | ||
122 | void __early_init(void) { | ||
123 | early_hardware_init_pre(); | ||
124 | |||
125 | // This is the renamed equivalent of __early_init in the board.c file | ||
126 | void __chibios_override___early_init(void); | ||
127 | __chibios_override___early_init(); | ||
128 | |||
129 | early_hardware_init_post(); | ||
130 | } | ||
131 | |||
132 | // This overrides what's normally in ChibiOS board definitions | ||
133 | void boardInit(void) { | ||
134 | // This is the renamed equivalent of boardInit in the board.c file | ||
135 | void __chibios_override_boardInit(void); | ||
136 | __chibios_override_boardInit(); | ||
137 | |||
138 | board_init(); | ||
139 | } | ||
140 | |||
141 | void protocol_setup(void) { | ||
142 | // TESTING | ||
143 | // chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL); | ||
144 | |||
145 | keyboard_setup(); | ||
146 | } | ||
147 | |||
148 | void protocol_init(void) { | ||
149 | /* Init USB */ | ||
150 | usb_event_queue_init(); | ||
151 | init_usb_driver(&USB_DRIVER); | ||
152 | |||
153 | #ifdef MIDI_ENABLE | ||
154 | setup_midi(); | ||
155 | #endif | ||
156 | |||
157 | #ifdef SERIAL_LINK_ENABLE | ||
158 | init_serial_link(); | ||
159 | #endif | ||
160 | |||
161 | #ifdef VISUALIZER_ENABLE | ||
162 | visualizer_init(); | ||
163 | #endif | ||
164 | |||
165 | host_driver_t *driver = NULL; | ||
166 | |||
167 | /* Wait until the USB or serial link is active */ | ||
168 | while (true) { | ||
169 | #if defined(WAIT_FOR_USB) || defined(SERIAL_LINK_ENABLE) | ||
170 | if (USB_DRIVER.state == USB_ACTIVE) { | ||
171 | driver = &chibios_driver; | ||
172 | break; | ||
173 | } | ||
174 | #else | ||
175 | driver = &chibios_driver; | ||
176 | break; | ||
177 | #endif | ||
178 | #ifdef SERIAL_LINK_ENABLE | ||
179 | if (is_serial_link_connected()) { | ||
180 | driver = get_serial_link_driver(); | ||
181 | break; | ||
182 | } | ||
183 | serial_link_update(); | ||
184 | #endif | ||
185 | wait_ms(50); | ||
186 | } | ||
187 | |||
188 | /* Do need to wait here! | ||
189 | * Otherwise the next print might start a transfer on console EP | ||
190 | * before the USB is completely ready, which sometimes causes | ||
191 | * HardFaults. | ||
192 | */ | ||
193 | wait_ms(50); | ||
194 | |||
195 | print("USB configured.\n"); | ||
196 | |||
197 | /* init TMK modules */ | ||
198 | keyboard_init(); | ||
199 | host_set_driver(driver); | ||
200 | |||
201 | #ifdef SLEEP_LED_ENABLE | ||
202 | sleep_led_init(); | ||
203 | #endif | ||
204 | |||
205 | print("Keyboard start.\n"); | ||
206 | } | ||
207 | |||
208 | void protocol_task(void) { | ||
209 | usb_event_queue_task(); | ||
210 | |||
211 | #if !defined(NO_USB_STARTUP_CHECK) | ||
212 | if (USB_DRIVER.state == USB_SUSPENDED) { | ||
213 | print("[s]"); | ||
214 | # ifdef VISUALIZER_ENABLE | ||
215 | visualizer_suspend(); | ||
216 | # endif | ||
217 | while (USB_DRIVER.state == USB_SUSPENDED) { | ||
218 | /* Do this in the suspended state */ | ||
219 | # ifdef SERIAL_LINK_ENABLE | ||
220 | serial_link_update(); | ||
221 | # endif | ||
222 | suspend_power_down(); // on AVR this deep sleeps for 15ms | ||
223 | /* Remote wakeup */ | ||
224 | if (suspend_wakeup_condition()) { | ||
225 | usbWakeupHost(&USB_DRIVER); | ||
226 | restart_usb_driver(&USB_DRIVER); | ||
227 | } | ||
228 | } | ||
229 | /* Woken up */ | ||
230 | // variables has been already cleared by the wakeup hook | ||
231 | send_keyboard_report(); | ||
232 | # ifdef MOUSEKEY_ENABLE | ||
233 | mousekey_send(); | ||
234 | # endif /* MOUSEKEY_ENABLE */ | ||
235 | |||
236 | # ifdef VISUALIZER_ENABLE | ||
237 | visualizer_resume(); | ||
238 | # endif | ||
239 | } | ||
240 | #endif | ||
241 | |||
242 | keyboard_task(); | ||
243 | #ifdef CONSOLE_ENABLE | ||
244 | console_task(); | ||
245 | #endif | ||
246 | #ifdef MIDI_ENABLE | ||
247 | midi_ep_task(); | ||
248 | #endif | ||
249 | #ifdef VIRTSER_ENABLE | ||
250 | virtser_task(); | ||
251 | #endif | ||
252 | #ifdef RAW_ENABLE | ||
253 | raw_hid_task(); | ||
254 | #endif | ||
255 | } | ||