aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/protocol/chibios/chibios.c
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/protocol/chibios/chibios.c')
-rw-r--r--tmk_core/protocol/chibios/chibios.c255
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 */
63uint8_t keyboard_leds(void);
64void send_keyboard(report_keyboard_t *report);
65void send_mouse(report_mouse_t *report);
66void send_system(uint16_t data);
67void send_consumer(uint16_t data);
68void send_digitizer(report_digitizer_t *report);
69
70/* host struct */
71host_driver_t chibios_driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer};
72
73#ifdef VIRTSER_ENABLE
74void virtser_task(void);
75#endif
76
77#ifdef RAW_ENABLE
78void raw_hid_task(void);
79#endif
80
81#ifdef CONSOLE_ENABLE
82void console_task(void);
83#endif
84#ifdef MIDI_ENABLE
85void 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
122void __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
133void 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
141void protocol_setup(void) {
142 // TESTING
143 // chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
144
145 keyboard_setup();
146}
147
148void 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
208void 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}