]> git.donarmstrong.com Git - qmk_firmware.git/blob - tmk_core/protocol/chibios/main.c
f2abc438d47d45d36976982bd540052957c52b13
[qmk_firmware.git] / tmk_core / protocol / chibios / main.c
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 "printf.h"
35 #ifdef SLEEP_LED_ENABLE
36 #include "sleep_led.h"
37 #endif
38 #ifdef SERIAL_LINK_ENABLE
39 #include "serial_link/system/serial_link.h"
40 #endif
41 #ifdef VISUALIZER_ENABLE
42 #include "visualizer/visualizer.h"
43 #endif
44 #ifdef MIDI_ENABLE
45 #include "qmk_midi.h"
46 #endif
47 #include "suspend.h"
48 #include "wait.h"
49
50 /* -------------------------
51  *   TMK host driver defs
52  * -------------------------
53  */
54
55 /* declarations */
56 uint8_t keyboard_leds(void);
57 void send_keyboard(report_keyboard_t *report);
58 void send_mouse(report_mouse_t *report);
59 void send_system(uint16_t data);
60 void send_consumer(uint16_t data);
61
62 /* host struct */
63 host_driver_t chibios_driver = {
64   keyboard_leds,
65   send_keyboard,
66   send_mouse,
67   send_system,
68   send_consumer
69 };
70
71 #ifdef VIRTSER_ENABLE
72 void virtser_task(void);
73 #endif
74
75 #ifdef RAW_HID_ENABLE
76 void raw_hid_task(void);
77 #endif
78
79 #ifdef CONSOLE_ENABLE
80 void console_task(void);
81 #endif
82
83 /* TESTING
84  * Amber LED blinker thread, times are in milliseconds.
85  */
86 /* set this variable to non-zero anywhere to blink once */
87 // static THD_WORKING_AREA(waThread1, 128);
88 // static THD_FUNCTION(Thread1, arg) {
89
90 //   (void)arg;
91 //   chRegSetThreadName("blinker");
92 //   while (true) {
93 //     systime_t time;
94
95 //     time = USB_DRIVER.state == USB_ACTIVE ? 250 : 500;
96 //     palClearLine(LINE_CAPS_LOCK);
97 //     chSysPolledDelayX(MS2RTC(STM32_HCLK, time));
98 //     palSetLine(LINE_CAPS_LOCK);
99 //     chSysPolledDelayX(MS2RTC(STM32_HCLK, time));
100 //   }
101 // }
102
103
104
105 /* Main thread
106  */
107 int main(void) {
108   /* ChibiOS/RT init */
109   halInit();
110   chSysInit();
111
112   // TESTING
113   // chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
114
115   /* Init USB */
116   init_usb_driver(&USB_DRIVER);
117
118   /* init printf */
119   init_printf(NULL,sendchar_pf);
120
121 #ifdef MIDI_ENABLE
122   setup_midi();
123 #endif
124
125 #ifdef SERIAL_LINK_ENABLE
126   init_serial_link();
127 #endif
128
129 #ifdef VISUALIZER_ENABLE
130   visualizer_init();
131 #endif
132
133
134   host_driver_t* driver = NULL;
135
136   /* Wait until the USB or serial link is active */
137   while (true) {
138     if(USB_DRIVER.state == USB_ACTIVE) {
139       driver = &chibios_driver;
140       break;
141     }
142 #ifdef SERIAL_LINK_ENABLE
143     if(is_serial_link_connected()) {
144       driver = get_serial_link_driver();
145       break;
146     }
147     serial_link_update();
148 #endif
149     wait_ms(50);
150   }
151
152   /* Do need to wait here!
153    * Otherwise the next print might start a transfer on console EP
154    * before the USB is completely ready, which sometimes causes
155    * HardFaults.
156    */
157   wait_ms(50);
158
159   print("USB configured.\n");
160
161   /* init TMK modules */
162   keyboard_init();
163   host_set_driver(driver);
164
165 #ifdef SLEEP_LED_ENABLE
166   sleep_led_init();
167 #endif
168
169   print("Keyboard start.\n");
170
171   /* Main loop */
172   while(true) {
173
174     if(USB_DRIVER.state == USB_SUSPENDED) {
175       print("[s]");
176 #ifdef VISUALIZER_ENABLE
177       visualizer_suspend();
178 #endif
179       while(USB_DRIVER.state == USB_SUSPENDED) {
180         /* Do this in the suspended state */
181 #ifdef SERIAL_LINK_ENABLE
182         serial_link_update();
183 #endif
184         suspend_power_down(); // on AVR this deep sleeps for 15ms
185         /* Remote wakeup */
186         if(suspend_wakeup_condition()) {
187           usbWakeupHost(&USB_DRIVER);
188         }
189       }
190       /* Woken up */
191       // variables has been already cleared by the wakeup hook
192       send_keyboard_report();
193 #ifdef MOUSEKEY_ENABLE
194       mousekey_send();
195 #endif /* MOUSEKEY_ENABLE */
196
197 #ifdef VISUALIZER_ENABLE
198       visualizer_resume();
199 #endif
200     }
201
202     keyboard_task();
203 #ifdef CONSOLE_ENABLE
204     console_task();
205 #endif
206 #ifdef VIRTSER_ENABLE
207     virtser_task();
208 #endif
209 #ifdef RAW_HID_ENABLE
210     raw_hid_task();
211 #endif
212   }
213 }