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