Move rgblight and backlight task to common location (#7733)
[jackhill/qmk/firmware.git] / tmk_core / protocol / lufa / lufa.c
1 /*
2 * Copyright 2012 Jun Wako <wakojun@gmail.com>
3 * This file is based on:
4 * LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse
5 * LUFA-120219/Demos/Device/Lowlevel/GenericHID
6 */
7
8 /*
9 LUFA Library
10 Copyright (C) Dean Camera, 2012.
11
12 dean [at] fourwalledcubicle [dot] com
13 www.lufa-lib.org
14 */
15
16 /*
17 Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
18 Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com)
19
20 Permission to use, copy, modify, distribute, and sell this
21 software and its documentation for any purpose is hereby granted
22 without fee, provided that the above copyright notice appear in
23 all copies and that both that the copyright notice and this
24 permission notice and warranty disclaimer appear in supporting
25 documentation, and that the name of the author not be used in
26 advertising or publicity pertaining to distribution of the
27 software without specific, written prior permission.
28
29 The author disclaim all warranties with regard to this
30 software, including all implied warranties of merchantability
31 and fitness. In no event shall the author be liable for any
32 special, indirect or consequential damages or any damages
33 whatsoever resulting from loss of use, data or profits, whether
34 in an action of contract, negligence or other tortious action,
35 arising out of or in connection with the use or performance of
36 this software.
37 */
38
39 #include "report.h"
40 #include "host.h"
41 #include "host_driver.h"
42 #include "keyboard.h"
43 #include "action.h"
44 #include "led.h"
45 #include "sendchar.h"
46 #include "debug.h"
47 #ifdef SLEEP_LED_ENABLE
48 # include "sleep_led.h"
49 #endif
50 #include "suspend.h"
51
52 #include "usb_descriptor.h"
53 #include "lufa.h"
54 #include "quantum.h"
55 #include <util/atomic.h>
56 #include "outputselect.h"
57 #include "rgblight_reconfig.h"
58
59 #ifdef NKRO_ENABLE
60 # include "keycode_config.h"
61
62 extern keymap_config_t keymap_config;
63 #endif
64
65 #ifdef AUDIO_ENABLE
66 # include <audio.h>
67 #endif
68
69 #ifdef BLUETOOTH_ENABLE
70 # ifdef MODULE_ADAFRUIT_BLE
71 # include "adafruit_ble.h"
72 # else
73 # include "bluetooth.h"
74 # endif
75 #endif
76
77 #ifdef VIRTSER_ENABLE
78 # include "virtser.h"
79 #endif
80
81 #if (defined(RGB_MIDI) || defined(RGBLIGHT_ANIMATIONS)) && defined(RGBLIGHT_ENABLE)
82 # include "rgblight.h"
83 #endif
84
85 #ifdef MIDI_ENABLE
86 # include "qmk_midi.h"
87 #endif
88
89 #ifdef RAW_ENABLE
90 # include "raw_hid.h"
91 #endif
92
93 uint8_t keyboard_idle = 0;
94 /* 0: Boot Protocol, 1: Report Protocol(default) */
95 uint8_t keyboard_protocol = 1;
96 static uint8_t keyboard_led_stats = 0;
97
98 static report_keyboard_t keyboard_report_sent;
99
100 /* Host driver */
101 static uint8_t keyboard_leds(void);
102 static void send_keyboard(report_keyboard_t *report);
103 static void send_mouse(report_mouse_t *report);
104 static void send_system(uint16_t data);
105 static void send_consumer(uint16_t data);
106 host_driver_t lufa_driver = {
107 keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer,
108 };
109
110 #ifdef VIRTSER_ENABLE
111 USB_ClassInfo_CDC_Device_t cdc_device = {
112 .Config =
113 {
114 .ControlInterfaceNumber = CCI_INTERFACE,
115 .DataINEndpoint =
116 {
117 .Address = CDC_IN_EPADDR,
118 .Size = CDC_EPSIZE,
119 .Banks = 1,
120 },
121 .DataOUTEndpoint =
122 {
123 .Address = CDC_OUT_EPADDR,
124 .Size = CDC_EPSIZE,
125 .Banks = 1,
126 },
127 .NotificationEndpoint =
128 {
129 .Address = CDC_NOTIFICATION_EPADDR,
130 .Size = CDC_NOTIFICATION_EPSIZE,
131 .Banks = 1,
132 },
133 },
134 };
135 #endif
136
137 #ifdef RAW_ENABLE
138
139 /** \brief Raw HID Send
140 *
141 * FIXME: Needs doc
142 */
143 void raw_hid_send(uint8_t *data, uint8_t length) {
144 // TODO: implement variable size packet
145 if (length != RAW_EPSIZE) {
146 return;
147 }
148
149 if (USB_DeviceState != DEVICE_STATE_Configured) {
150 return;
151 }
152
153 // TODO: decide if we allow calls to raw_hid_send() in the middle
154 // of other endpoint usage.
155 uint8_t ep = Endpoint_GetCurrentEndpoint();
156
157 Endpoint_SelectEndpoint(RAW_IN_EPNUM);
158
159 // Check to see if the host is ready to accept another packet
160 if (Endpoint_IsINReady()) {
161 // Write data
162 Endpoint_Write_Stream_LE(data, RAW_EPSIZE, NULL);
163 // Finalize the stream transfer to send the last packet
164 Endpoint_ClearIN();
165 }
166
167 Endpoint_SelectEndpoint(ep);
168 }
169
170 /** \brief Raw HID Receive
171 *
172 * FIXME: Needs doc
173 */
174 __attribute__((weak)) void raw_hid_receive(uint8_t *data, uint8_t length) {
175 // Users should #include "raw_hid.h" in their own code
176 // and implement this function there. Leave this as weak linkage
177 // so users can opt to not handle data coming in.
178 }
179
180 /** \brief Raw HID Task
181 *
182 * FIXME: Needs doc
183 */
184 static void raw_hid_task(void) {
185 // Create a temporary buffer to hold the read in data from the host
186 uint8_t data[RAW_EPSIZE];
187 bool data_read = false;
188
189 // Device must be connected and configured for the task to run
190 if (USB_DeviceState != DEVICE_STATE_Configured) return;
191
192 Endpoint_SelectEndpoint(RAW_OUT_EPNUM);
193
194 // Check to see if a packet has been sent from the host
195 if (Endpoint_IsOUTReceived()) {
196 // Check to see if the packet contains data
197 if (Endpoint_IsReadWriteAllowed()) {
198 /* Read data */
199 Endpoint_Read_Stream_LE(data, sizeof(data), NULL);
200 data_read = true;
201 }
202
203 // Finalize the stream transfer to receive the last packet
204 Endpoint_ClearOUT();
205
206 if (data_read) {
207 raw_hid_receive(data, sizeof(data));
208 }
209 }
210 }
211 #endif
212
213 /*******************************************************************************
214 * Console
215 ******************************************************************************/
216 #ifdef CONSOLE_ENABLE
217 /** \brief Console Task
218 *
219 * FIXME: Needs doc
220 */
221 static void Console_Task(void) {
222 /* Device must be connected and configured for the task to run */
223 if (USB_DeviceState != DEVICE_STATE_Configured) return;
224
225 uint8_t ep = Endpoint_GetCurrentEndpoint();
226
227 # if 0
228 // TODO: impl receivechar()/recvchar()
229 Endpoint_SelectEndpoint(CONSOLE_OUT_EPNUM);
230
231 /* Check to see if a packet has been sent from the host */
232 if (Endpoint_IsOUTReceived())
233 {
234 /* Check to see if the packet contains data */
235 if (Endpoint_IsReadWriteAllowed())
236 {
237 /* Create a temporary buffer to hold the read in report from the host */
238 uint8_t ConsoleData[CONSOLE_EPSIZE];
239
240 /* Read Console Report Data */
241 Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
242
243 /* Process Console Report Data */
244 //ProcessConsoleHIDReport(ConsoleData);
245 }
246
247 /* Finalize the stream transfer to send the last packet */
248 Endpoint_ClearOUT();
249 }
250 # endif
251
252 /* IN packet */
253 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
254 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
255 Endpoint_SelectEndpoint(ep);
256 return;
257 }
258
259 // fill empty bank
260 while (Endpoint_IsReadWriteAllowed()) Endpoint_Write_8(0);
261
262 // flash senchar packet
263 if (Endpoint_IsINReady()) {
264 Endpoint_ClearIN();
265 }
266
267 Endpoint_SelectEndpoint(ep);
268 }
269 #endif
270
271 /*******************************************************************************
272 * USB Events
273 ******************************************************************************/
274 /*
275 * Event Order of Plug in:
276 * 0) EVENT_USB_Device_Connect
277 * 1) EVENT_USB_Device_Suspend
278 * 2) EVENT_USB_Device_Reset
279 * 3) EVENT_USB_Device_Wake
280 */
281 /** \brief Event USB Device Connect
282 *
283 * FIXME: Needs doc
284 */
285 void EVENT_USB_Device_Connect(void) {
286 print("[C]");
287 /* For battery powered device */
288 if (!USB_IsInitialized) {
289 USB_Disable();
290 USB_Init();
291 USB_Device_EnableSOFEvents();
292 }
293 }
294
295 /** \brief Event USB Device Connect
296 *
297 * FIXME: Needs doc
298 */
299 void EVENT_USB_Device_Disconnect(void) {
300 print("[D]");
301 /* For battery powered device */
302 USB_IsInitialized = false;
303 /* TODO: This doesn't work. After several plug in/outs can not be enumerated.
304 if (USB_IsInitialized) {
305 USB_Disable(); // Disable all interrupts
306 USB_Controller_Enable();
307 USB_INT_Enable(USB_INT_VBUSTI);
308 }
309 */
310 }
311
312 /** \brief Event USB Device Connect
313 *
314 * FIXME: Needs doc
315 */
316 void EVENT_USB_Device_Reset(void) { print("[R]"); }
317
318 /** \brief Event USB Device Connect
319 *
320 * FIXME: Needs doc
321 */
322 void EVENT_USB_Device_Suspend() {
323 print("[S]");
324 #ifdef SLEEP_LED_ENABLE
325 sleep_led_enable();
326 #endif
327 }
328
329 /** \brief Event USB Device Connect
330 *
331 * FIXME: Needs doc
332 */
333 void EVENT_USB_Device_WakeUp() {
334 print("[W]");
335 suspend_wakeup_init();
336
337 #ifdef SLEEP_LED_ENABLE
338 sleep_led_disable();
339 // NOTE: converters may not accept this
340 led_set(host_keyboard_leds());
341 #endif
342 }
343
344 #ifdef CONSOLE_ENABLE
345 static bool console_flush = false;
346 # define CONSOLE_FLUSH_SET(b) \
347 do { \
348 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { console_flush = b; } \
349 } while (0)
350
351 /** \brief Event USB Device Start Of Frame
352 *
353 * FIXME: Needs doc
354 * called every 1ms
355 */
356 void EVENT_USB_Device_StartOfFrame(void) {
357 static uint8_t count;
358 if (++count % 50) return;
359 count = 0;
360
361 if (!console_flush) return;
362 Console_Task();
363 console_flush = false;
364 }
365
366 #endif
367
368 /** \brief Event handler for the USB_ConfigurationChanged event.
369 *
370 * This is fired when the host sets the current configuration of the USB device after enumeration.
371 *
372 * ATMega32u2 supports dual bank(ping-pong mode) only on endpoint 3 and 4,
373 * it is safe to use single bank for all endpoints.
374 */
375 void EVENT_USB_Device_ConfigurationChanged(void) {
376 bool ConfigSuccess = true;
377
378 /* Setup Keyboard HID Report Endpoints */
379 #ifndef KEYBOARD_SHARED_EP
380 ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE);
381 #endif
382
383 #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
384 /* Setup Mouse HID Report Endpoint */
385 ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE);
386 #endif
387
388 #ifdef SHARED_EP_ENABLE
389 /* Setup Shared HID Report Endpoint */
390 ConfigSuccess &= ENDPOINT_CONFIG(SHARED_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, SHARED_EPSIZE, ENDPOINT_BANK_SINGLE);
391 #endif
392
393 #ifdef RAW_ENABLE
394 /* Setup Raw HID Report Endpoints */
395 ConfigSuccess &= ENDPOINT_CONFIG(RAW_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, RAW_EPSIZE, ENDPOINT_BANK_SINGLE);
396 ConfigSuccess &= ENDPOINT_CONFIG(RAW_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT, RAW_EPSIZE, ENDPOINT_BANK_SINGLE);
397 #endif
398
399 #ifdef CONSOLE_ENABLE
400 /* Setup Console HID Report Endpoints */
401 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
402 # if 0
403 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
404 CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
405 # endif
406 #endif
407
408 #ifdef MIDI_ENABLE
409 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_IN_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
410 ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_OUT_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
411 #endif
412
413 #ifdef VIRTSER_ENABLE
414 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPADDR, EP_TYPE_INTERRUPT, CDC_NOTIFICATION_EPSIZE, ENDPOINT_BANK_SINGLE);
415 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_OUT_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
416 ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC_IN_EPADDR, EP_TYPE_BULK, CDC_EPSIZE, ENDPOINT_BANK_SINGLE);
417 #endif
418 }
419
420 /* FIXME: Expose this table in the docs somehow
421 Appendix G: HID Request Support Requirements
422
423 The following table enumerates the requests that need to be supported by various types of HID class devices.
424
425 Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol
426 ------------------------------------------------------------------------------------------
427 Boot Mouse Required Optional Optional Optional Required Required
428 Non-Boot Mouse Required Optional Optional Optional Optional Optional
429 Boot Keyboard Required Optional Required Required Required Required
430 Non-Boot Keybrd Required Optional Required Required Optional Optional
431 Other Device Required Optional Optional Optional Optional Optional
432 */
433 /** \brief Event handler for the USB_ControlRequest event.
434 *
435 * This is fired before passing along unhandled control requests to the library for processing internally.
436 */
437 void EVENT_USB_Device_ControlRequest(void) {
438 uint8_t *ReportData = NULL;
439 uint8_t ReportSize = 0;
440
441 /* Handle HID Class specific requests */
442 switch (USB_ControlRequest.bRequest) {
443 case HID_REQ_GetReport:
444 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) {
445 Endpoint_ClearSETUP();
446
447 // Interface
448 switch (USB_ControlRequest.wIndex) {
449 case KEYBOARD_INTERFACE:
450 // TODO: test/check
451 ReportData = (uint8_t *)&keyboard_report_sent;
452 ReportSize = sizeof(keyboard_report_sent);
453 break;
454 }
455
456 /* Write the report data to the control endpoint */
457 Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
458 Endpoint_ClearOUT();
459 }
460
461 break;
462 case HID_REQ_SetReport:
463 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) {
464 // Interface
465 switch (USB_ControlRequest.wIndex) {
466 case KEYBOARD_INTERFACE:
467 #if defined(SHARED_EP_ENABLE) && !defined(KEYBOARD_SHARED_EP)
468 case SHARED_INTERFACE:
469 #endif
470 Endpoint_ClearSETUP();
471
472 while (!(Endpoint_IsOUTReceived())) {
473 if (USB_DeviceState == DEVICE_STATE_Unattached) return;
474 }
475
476 if (Endpoint_BytesInEndpoint() == 2) {
477 uint8_t report_id = Endpoint_Read_8();
478
479 if (report_id == REPORT_ID_KEYBOARD || report_id == REPORT_ID_NKRO) {
480 keyboard_led_stats = Endpoint_Read_8();
481 }
482 } else {
483 keyboard_led_stats = Endpoint_Read_8();
484 }
485
486 Endpoint_ClearOUT();
487 Endpoint_ClearStatusStage();
488 break;
489 }
490 }
491
492 break;
493
494 case HID_REQ_GetProtocol:
495 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) {
496 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
497 Endpoint_ClearSETUP();
498 while (!(Endpoint_IsINReady()))
499 ;
500 Endpoint_Write_8(keyboard_protocol);
501 Endpoint_ClearIN();
502 Endpoint_ClearStatusStage();
503 }
504 }
505
506 break;
507 case HID_REQ_SetProtocol:
508 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) {
509 if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) {
510 Endpoint_ClearSETUP();
511 Endpoint_ClearStatusStage();
512
513 keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
514 clear_keyboard();
515 }
516 }
517
518 break;
519 case HID_REQ_SetIdle:
520 if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) {
521 Endpoint_ClearSETUP();
522 Endpoint_ClearStatusStage();
523
524 keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
525 }
526
527 break;
528 case HID_REQ_GetIdle:
529 if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) {
530 Endpoint_ClearSETUP();
531 while (!(Endpoint_IsINReady()))
532 ;
533 Endpoint_Write_8(keyboard_idle);
534 Endpoint_ClearIN();
535 Endpoint_ClearStatusStage();
536 }
537
538 break;
539 }
540
541 #ifdef VIRTSER_ENABLE
542 CDC_Device_ProcessControlRequest(&cdc_device);
543 #endif
544 }
545
546 /*******************************************************************************
547 * Host driver
548 ******************************************************************************/
549 /** \brief Keyboard LEDs
550 *
551 * FIXME: Needs doc
552 */
553 static uint8_t keyboard_leds(void) { return keyboard_led_stats; }
554
555 /** \brief Send Keyboard
556 *
557 * FIXME: Needs doc
558 */
559 static void send_keyboard(report_keyboard_t *report) {
560 uint8_t timeout = 255;
561 uint8_t where = where_to_send();
562
563 #ifdef BLUETOOTH_ENABLE
564 if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
565 # ifdef MODULE_ADAFRUIT_BLE
566 adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys));
567 # elif MODULE_RN42
568 bluefruit_serial_send(0xFD);
569 bluefruit_serial_send(0x09);
570 bluefruit_serial_send(0x01);
571 bluefruit_serial_send(report->mods);
572 bluefruit_serial_send(report->reserved);
573 for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
574 bluefruit_serial_send(report->keys[i]);
575 }
576 # else
577 bluefruit_serial_send(0xFD);
578 bluefruit_serial_send(report->mods);
579 bluefruit_serial_send(report->reserved);
580 for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
581 bluefruit_serial_send(report->keys[i]);
582 }
583 # endif
584 }
585 #endif
586
587 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
588 return;
589 }
590
591 /* Select the Keyboard Report Endpoint */
592 uint8_t ep = KEYBOARD_IN_EPNUM;
593 uint8_t size = KEYBOARD_REPORT_SIZE;
594 #ifdef NKRO_ENABLE
595 if (keyboard_protocol && keymap_config.nkro) {
596 ep = SHARED_IN_EPNUM;
597 size = sizeof(struct nkro_report);
598 }
599 #endif
600 Endpoint_SelectEndpoint(ep);
601 /* Check if write ready for a polling interval around 10ms */
602 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
603 if (!Endpoint_IsReadWriteAllowed()) return;
604
605 /* If we're in Boot Protocol, don't send any report ID or other funky fields */
606 if (!keyboard_protocol) {
607 Endpoint_Write_Stream_LE(&report->mods, 8, NULL);
608 } else {
609 Endpoint_Write_Stream_LE(report, size, NULL);
610 }
611
612 /* Finalize the stream transfer to send the last packet */
613 Endpoint_ClearIN();
614
615 keyboard_report_sent = *report;
616 }
617
618 /** \brief Send Mouse
619 *
620 * FIXME: Needs doc
621 */
622 static void send_mouse(report_mouse_t *report) {
623 #ifdef MOUSE_ENABLE
624 uint8_t timeout = 255;
625 uint8_t where = where_to_send();
626
627 # ifdef BLUETOOTH_ENABLE
628 if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
629 # ifdef MODULE_ADAFRUIT_BLE
630 // FIXME: mouse buttons
631 adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h, report->buttons);
632 # else
633 bluefruit_serial_send(0xFD);
634 bluefruit_serial_send(0x00);
635 bluefruit_serial_send(0x03);
636 bluefruit_serial_send(report->buttons);
637 bluefruit_serial_send(report->x);
638 bluefruit_serial_send(report->y);
639 bluefruit_serial_send(report->v); // should try sending the wheel v here
640 bluefruit_serial_send(report->h); // should try sending the wheel h here
641 bluefruit_serial_send(0x00);
642 # endif
643 }
644 # endif
645
646 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
647 return;
648 }
649
650 /* Select the Mouse Report Endpoint */
651 Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
652
653 /* Check if write ready for a polling interval around 10ms */
654 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
655 if (!Endpoint_IsReadWriteAllowed()) return;
656
657 /* Write Mouse Report Data */
658 Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
659
660 /* Finalize the stream transfer to send the last packet */
661 Endpoint_ClearIN();
662 #endif
663 }
664
665 /** \brief Send System
666 *
667 * FIXME: Needs doc
668 */
669 static void send_system(uint16_t data) {
670 #ifdef EXTRAKEY_ENABLE
671 uint8_t timeout = 255;
672
673 if (USB_DeviceState != DEVICE_STATE_Configured) return;
674
675 report_extra_t r = {.report_id = REPORT_ID_SYSTEM, .usage = data - SYSTEM_POWER_DOWN + 1};
676 Endpoint_SelectEndpoint(SHARED_IN_EPNUM);
677
678 /* Check if write ready for a polling interval around 10ms */
679 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
680 if (!Endpoint_IsReadWriteAllowed()) return;
681
682 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
683 Endpoint_ClearIN();
684 #endif
685 }
686
687 /** \brief Send Consumer
688 *
689 * FIXME: Needs doc
690 */
691 static void send_consumer(uint16_t data) {
692 #ifdef EXTRAKEY_ENABLE
693 uint8_t timeout = 255;
694 uint8_t where = where_to_send();
695
696 # ifdef BLUETOOTH_ENABLE
697 if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
698 # ifdef MODULE_ADAFRUIT_BLE
699 adafruit_ble_send_consumer_key(data, 0);
700 # elif MODULE_RN42
701 static uint16_t last_data = 0;
702 if (data == last_data) return;
703 last_data = data;
704 uint16_t bitmap = CONSUMER2RN42(data);
705 bluefruit_serial_send(0xFD);
706 bluefruit_serial_send(0x03);
707 bluefruit_serial_send(0x03);
708 bluefruit_serial_send(bitmap & 0xFF);
709 bluefruit_serial_send((bitmap >> 8) & 0xFF);
710 # else
711 static uint16_t last_data = 0;
712 if (data == last_data) return;
713 last_data = data;
714 uint16_t bitmap = CONSUMER2BLUEFRUIT(data);
715 bluefruit_serial_send(0xFD);
716 bluefruit_serial_send(0x00);
717 bluefruit_serial_send(0x02);
718 bluefruit_serial_send((bitmap >> 8) & 0xFF);
719 bluefruit_serial_send(bitmap & 0xFF);
720 bluefruit_serial_send(0x00);
721 bluefruit_serial_send(0x00);
722 bluefruit_serial_send(0x00);
723 bluefruit_serial_send(0x00);
724 # endif
725 }
726 # endif
727
728 if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
729 return;
730 }
731
732 report_extra_t r = {.report_id = REPORT_ID_CONSUMER, .usage = data};
733 Endpoint_SelectEndpoint(SHARED_IN_EPNUM);
734
735 /* Check if write ready for a polling interval around 10ms */
736 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
737 if (!Endpoint_IsReadWriteAllowed()) return;
738
739 Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
740 Endpoint_ClearIN();
741 #endif
742 }
743
744 /*******************************************************************************
745 * sendchar
746 ******************************************************************************/
747 #ifdef CONSOLE_ENABLE
748 # define SEND_TIMEOUT 5
749 /** \brief Send Char
750 *
751 * FIXME: Needs doc
752 */
753 int8_t sendchar(uint8_t c) {
754 // Not wait once timeouted.
755 // Because sendchar() is called so many times, waiting each call causes big lag.
756 static bool timeouted = false;
757
758 // prevents Console_Task() from running during sendchar() runs.
759 // or char will be lost. These two function is mutually exclusive.
760 CONSOLE_FLUSH_SET(false);
761
762 if (USB_DeviceState != DEVICE_STATE_Configured) return -1;
763
764 uint8_t ep = Endpoint_GetCurrentEndpoint();
765 Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
766 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
767 goto ERROR_EXIT;
768 }
769
770 if (timeouted && !Endpoint_IsReadWriteAllowed()) {
771 goto ERROR_EXIT;
772 }
773
774 timeouted = false;
775
776 uint8_t timeout = SEND_TIMEOUT;
777 while (!Endpoint_IsReadWriteAllowed()) {
778 if (USB_DeviceState != DEVICE_STATE_Configured) {
779 goto ERROR_EXIT;
780 }
781 if (Endpoint_IsStalled()) {
782 goto ERROR_EXIT;
783 }
784 if (!(timeout--)) {
785 timeouted = true;
786 goto ERROR_EXIT;
787 }
788 _delay_ms(1);
789 }
790
791 Endpoint_Write_8(c);
792
793 // send when bank is full
794 if (!Endpoint_IsReadWriteAllowed()) {
795 while (!(Endpoint_IsINReady()))
796 ;
797 Endpoint_ClearIN();
798 } else {
799 CONSOLE_FLUSH_SET(true);
800 }
801
802 Endpoint_SelectEndpoint(ep);
803 return 0;
804 ERROR_EXIT:
805 Endpoint_SelectEndpoint(ep);
806 return -1;
807 }
808 #else
809 int8_t sendchar(uint8_t c) { return 0; }
810 #endif
811
812 /*******************************************************************************
813 * MIDI
814 ******************************************************************************/
815
816 #ifdef MIDI_ENABLE
817 USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface = {
818 .Config =
819 {
820 .StreamingInterfaceNumber = AS_INTERFACE,
821 .DataINEndpoint =
822 {
823 .Address = MIDI_STREAM_IN_EPADDR,
824 .Size = MIDI_STREAM_EPSIZE,
825 .Banks = 1,
826 },
827 .DataOUTEndpoint =
828 {
829 .Address = MIDI_STREAM_OUT_EPADDR,
830 .Size = MIDI_STREAM_EPSIZE,
831 .Banks = 1,
832 },
833 },
834 };
835
836 void send_midi_packet(MIDI_EventPacket_t *event) { MIDI_Device_SendEventPacket(&USB_MIDI_Interface, event); }
837
838 bool recv_midi_packet(MIDI_EventPacket_t *const event) { return MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, event); }
839
840 #endif
841
842 /*******************************************************************************
843 * VIRTUAL SERIAL
844 ******************************************************************************/
845
846 #ifdef VIRTSER_ENABLE
847 /** \brief Virtual Serial Init
848 *
849 * FIXME: Needs doc
850 */
851 void virtser_init(void) {
852 cdc_device.State.ControlLineStates.DeviceToHost = CDC_CONTROL_LINE_IN_DSR;
853 CDC_Device_SendControlLineStateChange(&cdc_device);
854 }
855
856 /** \brief Virtual Serial Receive
857 *
858 * FIXME: Needs doc
859 */
860 void virtser_recv(uint8_t c) __attribute__((weak));
861 void virtser_recv(uint8_t c) {
862 // Ignore by default
863 }
864
865 /** \brief Virtual Serial Task
866 *
867 * FIXME: Needs doc
868 */
869 void virtser_task(void) {
870 uint16_t count = CDC_Device_BytesReceived(&cdc_device);
871 uint8_t ch;
872 if (count) {
873 ch = CDC_Device_ReceiveByte(&cdc_device);
874 virtser_recv(ch);
875 }
876 }
877 /** \brief Virtual Serial Send
878 *
879 * FIXME: Needs doc
880 */
881 void virtser_send(const uint8_t byte) {
882 uint8_t timeout = 255;
883 uint8_t ep = Endpoint_GetCurrentEndpoint();
884
885 if (cdc_device.State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR) {
886 /* IN packet */
887 Endpoint_SelectEndpoint(cdc_device.Config.DataINEndpoint.Address);
888
889 if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
890 Endpoint_SelectEndpoint(ep);
891 return;
892 }
893
894 while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
895
896 Endpoint_Write_8(byte);
897 CDC_Device_Flush(&cdc_device);
898
899 if (Endpoint_IsINReady()) {
900 Endpoint_ClearIN();
901 }
902
903 Endpoint_SelectEndpoint(ep);
904 }
905 }
906 #endif
907
908 /*******************************************************************************
909 * main
910 ******************************************************************************/
911 /** \brief Setup MCU
912 *
913 * FIXME: Needs doc
914 */
915 static void setup_mcu(void) {
916 /* Disable watchdog if enabled by bootloader/fuses */
917 MCUSR &= ~_BV(WDRF);
918 wdt_disable();
919
920 /* Disable clock division */
921 clock_prescale_set(clock_div_1);
922 }
923
924 /** \brief Setup USB
925 *
926 * FIXME: Needs doc
927 */
928 static void setup_usb(void) {
929 // Leonardo needs. Without this USB device is not recognized.
930 USB_Disable();
931
932 USB_Init();
933
934 // for Console_Task
935 USB_Device_EnableSOFEvents();
936 print_set_sendchar(sendchar);
937 }
938
939 /** \brief Main
940 *
941 * FIXME: Needs doc
942 */
943 int main(void) __attribute__((weak));
944 int main(void) {
945 #ifdef MIDI_ENABLE
946 setup_midi();
947 #endif
948
949 setup_mcu();
950 keyboard_setup();
951 setup_usb();
952 sei();
953
954 #if defined(MODULE_ADAFRUIT_EZKEY) || defined(MODULE_RN42)
955 serial_init();
956 #endif
957
958 /* wait for USB startup & debug output */
959
960 #ifdef WAIT_FOR_USB
961 while (USB_DeviceState != DEVICE_STATE_Configured) {
962 # if defined(INTERRUPT_CONTROL_ENDPOINT)
963 ;
964 # else
965 USB_USBTask();
966 # endif
967 }
968 print("USB configured.\n");
969 #else
970 USB_USBTask();
971 #endif
972 /* init modules */
973 keyboard_init();
974 host_set_driver(&lufa_driver);
975 #ifdef SLEEP_LED_ENABLE
976 sleep_led_init();
977 #endif
978
979 #ifdef VIRTSER_ENABLE
980 virtser_init();
981 #endif
982
983 print("Keyboard start.\n");
984 while (1) {
985 #if !defined(NO_USB_STARTUP_CHECK)
986 while (USB_DeviceState == DEVICE_STATE_Suspended) {
987 print("[s]");
988 suspend_power_down();
989 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
990 USB_Device_SendRemoteWakeup();
991 }
992 }
993 #endif
994
995 keyboard_task();
996
997 #ifdef MIDI_ENABLE
998 MIDI_Device_USBTask(&USB_MIDI_Interface);
999 #endif
1000
1001 #ifdef MODULE_ADAFRUIT_BLE
1002 adafruit_ble_task();
1003 #endif
1004
1005 #ifdef VIRTSER_ENABLE
1006 virtser_task();
1007 CDC_Device_USBTask(&cdc_device);
1008 #endif
1009
1010 #ifdef RAW_ENABLE
1011 raw_hid_task();
1012 #endif
1013
1014 #if !defined(INTERRUPT_CONTROL_ENDPOINT)
1015 USB_USBTask();
1016 #endif
1017 }
1018 }
1019
1020 uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint16_t wIndex, const void **const DescriptorAddress) { return get_usb_descriptor(wValue, wIndex, DescriptorAddress); }