diff options
Diffstat (limited to 'keyboards/bioi/main.c')
-rw-r--r-- | keyboards/bioi/main.c | 388 |
1 files changed, 388 insertions, 0 deletions
diff --git a/keyboards/bioi/main.c b/keyboards/bioi/main.c new file mode 100644 index 000000000..7c8922c0a --- /dev/null +++ b/keyboards/bioi/main.c | |||
@@ -0,0 +1,388 @@ | |||
1 | /* | ||
2 | Copyright 2019 Basic I/O Instruments(Scott Wei) <[email protected]> | ||
3 | This program is free software: you can redistribute it and/or modify | ||
4 | it under the terms of the GNU General Public License as published by | ||
5 | the Free Software Foundation, either version 2 of the License, or | ||
6 | (at your option) any later version. | ||
7 | This program is distributed in the hope that it will be useful, | ||
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | GNU General Public License for more details. | ||
11 | You should have received a copy of the GNU General Public License | ||
12 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
13 | */ | ||
14 | |||
15 | #include <avr/pgmspace.h> | ||
16 | #include <util/delay.h> | ||
17 | |||
18 | #include "report.h" | ||
19 | #include "host.h" | ||
20 | #include "host_driver.h" | ||
21 | #include "keyboard.h" | ||
22 | #include "action.h" | ||
23 | #include "led.h" | ||
24 | #include "sendchar.h" | ||
25 | #include "debug.h" | ||
26 | #include "print.h" | ||
27 | #ifdef SLEEP_LED_ENABLE | ||
28 | #include "sleep_led.h" | ||
29 | #endif | ||
30 | #include "suspend.h" | ||
31 | |||
32 | #include "usb_descriptor.h" | ||
33 | #include "lufa.h" | ||
34 | #include "quantum.h" | ||
35 | #include <util/atomic.h> | ||
36 | |||
37 | #ifdef NKRO_ENABLE | ||
38 | #include "keycode_config.h" | ||
39 | |||
40 | extern keymap_config_t keymap_config; | ||
41 | #endif | ||
42 | |||
43 | #ifdef AUDIO_ENABLE | ||
44 | #include <audio.h> | ||
45 | #endif | ||
46 | |||
47 | #ifdef BLUETOOTH_ENABLE | ||
48 | #ifdef MODULE_ADAFRUIT_BLE | ||
49 | #include "adafruit_ble.h" | ||
50 | #else | ||
51 | #include "bluetooth.h" | ||
52 | #endif | ||
53 | #endif | ||
54 | |||
55 | #ifdef VIRTSER_ENABLE | ||
56 | #include "virtser.h" | ||
57 | #endif | ||
58 | |||
59 | #if (defined(RGB_MIDI) | defined(RGBLIGHT_ANIMATIONS)) & defined(RGBLIGHT_ENABLE) | ||
60 | #include "rgblight.h" | ||
61 | #endif | ||
62 | |||
63 | #ifdef MIDI_ENABLE | ||
64 | #include "qmk_midi.h" | ||
65 | #endif | ||
66 | |||
67 | #ifdef RAW_ENABLE | ||
68 | #include "raw_hid.h" | ||
69 | #endif | ||
70 | |||
71 | #include "ble.h" | ||
72 | #include "usart.h" | ||
73 | |||
74 | #include <avr/power.h> | ||
75 | #include <avr/sleep.h> | ||
76 | |||
77 | bool force_usb = false; //Reserved for FORCE USB Mode function. | ||
78 | bool force_ble = false; //Reserved for FORCE USB Mode function. | ||
79 | |||
80 | bool usb_connected = false; | ||
81 | bool ble_enabled = false; | ||
82 | |||
83 | uint32_t kb_idle_timer = 0; | ||
84 | |||
85 | bool usb_state_sent = false; | ||
86 | |||
87 | uint8_t USB_DeviceLastState = 0; | ||
88 | |||
89 | #ifdef RAW_ENABLE | ||
90 | /** \brief Raw HID Task | ||
91 | * | ||
92 | * FIXME: Needs doc | ||
93 | */ | ||
94 | static void raw_hid_task(void) | ||
95 | { | ||
96 | // Create a temporary buffer to hold the read in data from the host | ||
97 | uint8_t data[RAW_EPSIZE]; | ||
98 | bool data_read = false; | ||
99 | |||
100 | // Device must be connected and configured for the task to run | ||
101 | if (USB_DeviceState != DEVICE_STATE_Configured) | ||
102 | return; | ||
103 | |||
104 | Endpoint_SelectEndpoint(RAW_OUT_EPNUM); | ||
105 | |||
106 | // Check to see if a packet has been sent from the host | ||
107 | if (Endpoint_IsOUTReceived()) | ||
108 | { | ||
109 | // Check to see if the packet contains data | ||
110 | if (Endpoint_IsReadWriteAllowed()) | ||
111 | { | ||
112 | /* Read data */ | ||
113 | Endpoint_Read_Stream_LE(data, sizeof(data), NULL); | ||
114 | data_read = true; | ||
115 | } | ||
116 | |||
117 | // Finalize the stream transfer to receive the last packet | ||
118 | Endpoint_ClearOUT(); | ||
119 | |||
120 | if (data_read) | ||
121 | { | ||
122 | raw_hid_receive(data, sizeof(data)); | ||
123 | } | ||
124 | } | ||
125 | } | ||
126 | #endif | ||
127 | |||
128 | static void setup_mcu(void) | ||
129 | { | ||
130 | /* Disable watchdog if enabled by bootloader/fuses */ | ||
131 | MCUSR &= ~(1 << WDRF); | ||
132 | wdt_disable(); | ||
133 | |||
134 | CLKPR = (1 << CLKPCE); | ||
135 | CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0); | ||
136 | } | ||
137 | |||
138 | static void setup_usb(void) | ||
139 | { | ||
140 | // Leonardo needs. Without this USB device is not recognized. | ||
141 | USB_Disable(); | ||
142 | |||
143 | USB_Init(); | ||
144 | |||
145 | // for Console_Task | ||
146 | USB_Device_EnableSOFEvents(); | ||
147 | print_set_sendchar(sendchar); | ||
148 | } | ||
149 | |||
150 | void power_saving(void) | ||
151 | { | ||
152 | power_adc_disable(); | ||
153 | power_usart0_disable(); | ||
154 | power_spi_disable(); | ||
155 | power_twi_disable(); | ||
156 | |||
157 | USBCON |= (1 << FRZCLK); // Freeze the USB Clock | ||
158 | PLLCSR &= ~(1 << PLLE); // Disable the USB Clock (PPL) | ||
159 | USBCON &= ~(1 << USBE); | ||
160 | } | ||
161 | |||
162 | void power_recover(void) | ||
163 | { | ||
164 | |||
165 | USBCON |= (1 << USBE); | ||
166 | PLLCSR |= (1 << PLLE); // Resume the USB Clock (PPL) | ||
167 | USBCON &= ~(1 << FRZCLK); // Resume the USB Clock | ||
168 | |||
169 | power_adc_enable(); | ||
170 | power_usart0_enable(); | ||
171 | power_spi_enable(); | ||
172 | power_twi_enable(); | ||
173 | } | ||
174 | |||
175 | void ble_task_init(void) | ||
176 | { | ||
177 | kb_idle_timer = timer_read32(); //Mark current time, reserved for further usage; | ||
178 | } | ||
179 | |||
180 | void ble_task(void) | ||
181 | { | ||
182 | |||
183 | if (USB_DeviceLastState != USB_DeviceState) | ||
184 | { | ||
185 | usb_state_sent = false; | ||
186 | #ifdef BLE_DEBUG | ||
187 | send_str(PSTR("USB State Changed\r\n")); | ||
188 | if (USB_DeviceState == DEVICE_STATE_Unattached) | ||
189 | { | ||
190 | send_str(PSTR("USB State Unattached\r\n")); | ||
191 | } | ||
192 | #endif | ||
193 | if (USB_DeviceState == DEVICE_STATE_Powered) | ||
194 | { | ||
195 | #ifdef BLE_DEBUG | ||
196 | send_str(PSTR("USB State Powered\r\n")); | ||
197 | #endif | ||
198 | power_recover(); | ||
199 | host_set_driver(&null_driver); | ||
200 | } | ||
201 | #ifdef BLE_DEBUG | ||
202 | if ((USB_DeviceState == DEVICE_STATE_Default)) | ||
203 | { | ||
204 | send_str(PSTR("USB State Default\r\n")); | ||
205 | } | ||
206 | if ((USB_DeviceState == DEVICE_STATE_Addressed)) | ||
207 | { | ||
208 | send_str(PSTR("USB State Addressed\r\n")); | ||
209 | } | ||
210 | if (USB_DeviceState == DEVICE_STATE_Configured) | ||
211 | { | ||
212 | send_str(PSTR("USB State Configured\r\n")); | ||
213 | } | ||
214 | if (USB_DeviceState > DEVICE_STATE_Unattached) | ||
215 | { | ||
216 | } | ||
217 | else | ||
218 | { | ||
219 | // | ||
220 | } | ||
221 | #endif | ||
222 | } | ||
223 | else | ||
224 | { | ||
225 | #ifdef BLE_DEBUG | ||
226 | if (!usb_state_sent) | ||
227 | { | ||
228 | if (USB_DeviceState == DEVICE_STATE_Unattached) | ||
229 | { | ||
230 | send_str(PSTR("USB State Stopped at Unattached\r\n")); | ||
231 | } | ||
232 | if (USB_DeviceState == DEVICE_STATE_Powered) | ||
233 | { | ||
234 | send_str(PSTR("USB State Stopped at Powered\r\n")); | ||
235 | } | ||
236 | if ((USB_DeviceState == DEVICE_STATE_Default)) | ||
237 | { | ||
238 | send_str(PSTR("USB State Stopped at Default\r\n")); | ||
239 | } | ||
240 | if ((USB_DeviceState == DEVICE_STATE_Addressed)) | ||
241 | { | ||
242 | send_str(PSTR("USB State Stopped at Addressed\r\n")); | ||
243 | } | ||
244 | if (USB_DeviceState == DEVICE_STATE_Configured) | ||
245 | { | ||
246 | send_str(PSTR("USB State Stopped at Configured\r\n")); | ||
247 | } | ||
248 | } | ||
249 | #endif | ||
250 | if (USB_DeviceState == DEVICE_STATE_Unattached) | ||
251 | { | ||
252 | if (host_get_driver() && host_get_driver() != &bluefruit_driver) | ||
253 | { | ||
254 | #ifdef BLE_DEBUG | ||
255 | send_str(PSTR("USB State stopped at Unattached\r\n")); | ||
256 | #endif | ||
257 | ble_task_init(); | ||
258 | |||
259 | force_usb = 0; | ||
260 | usb_connected = 0; | ||
261 | |||
262 | //Reinit USB to prepare for next connection. | ||
263 | USB_Init(); | ||
264 | USB_Detach(); | ||
265 | USB_Attach(); | ||
266 | |||
267 | #ifdef BLE_DEBUG | ||
268 | send_str(PSTR("Loading &bluefruit_driver\r\n")); | ||
269 | #endif | ||
270 | host_set_driver(&bluefruit_driver); | ||
271 | clear_keyboard(); | ||
272 | power_saving(); | ||
273 | } | ||
274 | else | ||
275 | { | ||
276 | //Do nothing if USB is unattached and the driver is &bluefruit_driver | ||
277 | } | ||
278 | } | ||
279 | if (USB_DeviceState == DEVICE_STATE_Configured) | ||
280 | { | ||
281 | if (host_get_driver() && host_get_driver() != &lufa_driver) | ||
282 | { | ||
283 | #ifdef BLE_DEBUG | ||
284 | send_str(PSTR("USB State stopped at Configured\r\n")); | ||
285 | #endif | ||
286 | power_recover(); | ||
287 | |||
288 | usb_connected = 1; | ||
289 | ble_enabled = 0; | ||
290 | #ifdef BLE_DEBUG | ||
291 | send_str(PSTR("Loading &lufa_driver\r\n")); | ||
292 | #endif | ||
293 | host_set_driver(&lufa_driver); | ||
294 | clear_keyboard(); | ||
295 | } | ||
296 | else | ||
297 | { | ||
298 | //Do nothing if the driver is &lufa_driver | ||
299 | } | ||
300 | } | ||
301 | |||
302 | usb_state_sent = true; | ||
303 | } | ||
304 | |||
305 | USB_DeviceLastState = USB_DeviceState; | ||
306 | } | ||
307 | |||
308 | // Use a custom main() function because the task logic is different from the common one. | ||
309 | int main(void) | ||
310 | { | ||
311 | #ifdef MIDI_ENABLE | ||
312 | setup_midi(); | ||
313 | #endif | ||
314 | |||
315 | setup_mcu(); | ||
316 | |||
317 | keyboard_setup(); | ||
318 | |||
319 | setup_usb(); | ||
320 | sei(); | ||
321 | |||
322 | #if defined(MODULE_ADAFRUIT_EZKEY) || defined(MODULE_RN42) | ||
323 | serial_init(); | ||
324 | #endif | ||
325 | |||
326 | /* wait for USB startup to get ready for debug output */ | ||
327 | uint8_t timeout = 255; // timeout when USB is not available(Bluetooth) | ||
328 | while (timeout-- && USB_DeviceState != DEVICE_STATE_Configured) | ||
329 | { | ||
330 | wait_ms(4); | ||
331 | #if defined(INTERRUPT_CONTROL_ENDPOINT) | ||
332 | ; | ||
333 | #else | ||
334 | USB_USBTask(); | ||
335 | #endif | ||
336 | } | ||
337 | |||
338 | print("\nUSB init\n"); | ||
339 | |||
340 | keyboard_init(); | ||
341 | host_set_driver(&lufa_driver); | ||
342 | |||
343 | backlight_disable(); | ||
344 | //host_set_driver(&lufa_driver); | ||
345 | print("Keyboard initialized.\n"); | ||
346 | |||
347 | //Init Hardware UART | ||
348 | usart_init(); | ||
349 | |||
350 | #ifdef BLE_DEBUG | ||
351 | send_str(PSTR("Keyboard has been setup up\r\n")); | ||
352 | |||
353 | if (usb_connected) | ||
354 | { | ||
355 | send_str(PSTR("usb_connected=1\r\n")); | ||
356 | } | ||
357 | else | ||
358 | { | ||
359 | send_str(PSTR("usb_connected=0\r\n")); | ||
360 | } | ||
361 | #endif | ||
362 | |||
363 | #ifdef SLEEP_LED_ENABLE | ||
364 | sleep_led_init(); | ||
365 | #endif | ||
366 | |||
367 | #ifdef VIRTSER_ENABLE | ||
368 | virtser_init(); | ||
369 | #endif | ||
370 | |||
371 | while (1) | ||
372 | { | ||
373 | ble_task(); | ||
374 | keyboard_task(); | ||
375 | |||
376 | #ifdef RAW_ENABLE | ||
377 | raw_hid_task(); | ||
378 | #endif | ||
379 | |||
380 | #if defined(RGBLIGHT_ANIMATIONS) && defined(RGBLIGHT_ENABLE) | ||
381 | rgblight_task(); | ||
382 | #endif | ||
383 | |||
384 | #if !defined(INTERRUPT_CONTROL_ENDPOINT) | ||
385 | USB_USBTask(); | ||
386 | #endif | ||
387 | } | ||
388 | } | ||