aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/protocol/lufa/lufa.c
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/protocol/lufa/lufa.c')
-rw-r--r--tmk_core/protocol/lufa/lufa.c235
1 files changed, 213 insertions, 22 deletions
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index 01c0e45b0..dd78fe621 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -51,6 +51,8 @@
51 51
52#include "descriptor.h" 52#include "descriptor.h"
53#include "lufa.h" 53#include "lufa.h"
54#include "quantum.h"
55#include <util/atomic.h>
54 56
55#ifdef NKRO_ENABLE 57#ifdef NKRO_ENABLE
56 #include "keycode_config.h" 58 #include "keycode_config.h"
@@ -66,11 +68,26 @@
66#ifdef BLUETOOTH_ENABLE 68#ifdef BLUETOOTH_ENABLE
67 #include "bluetooth.h" 69 #include "bluetooth.h"
68#endif 70#endif
71#ifdef ADAFRUIT_BLE_ENABLE
72 #include "adafruit_ble.h"
73#endif
69 74
70#ifdef VIRTSER_ENABLE 75#ifdef VIRTSER_ENABLE
71 #include "virtser.h" 76 #include "virtser.h"
72#endif 77#endif
73 78
79#if (defined(RGB_MIDI) | defined(RGBLIGHT_ANIMATIONS)) & defined(RGBLIGHT_ENABLE)
80 #include "rgblight.h"
81#endif
82
83#ifdef MIDI_ENABLE
84 #include "sysex_tools.h"
85#endif
86
87#ifdef RAW_ENABLE
88 #include "raw_hid.h"
89#endif
90
74uint8_t keyboard_idle = 0; 91uint8_t keyboard_idle = 0;
75/* 0: Boot Protocol, 1: Report Protocol(default) */ 92/* 0: Boot Protocol, 1: Report Protocol(default) */
76uint8_t keyboard_protocol = 1; 93uint8_t keyboard_protocol = 1;
@@ -79,9 +96,9 @@ static uint8_t keyboard_led_stats = 0;
79static report_keyboard_t keyboard_report_sent; 96static report_keyboard_t keyboard_report_sent;
80 97
81#ifdef MIDI_ENABLE 98#ifdef MIDI_ENABLE
82void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2); 99static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
83void usb_get_midi(MidiDevice * device); 100static void usb_get_midi(MidiDevice * device);
84void midi_usb_init(MidiDevice * device); 101static void midi_usb_init(MidiDevice * device);
85#endif 102#endif
86 103
87/* Host driver */ 104/* Host driver */
@@ -166,6 +183,80 @@ USB_ClassInfo_CDC_Device_t cdc_device =
166}; 183};
167#endif 184#endif
168 185
186#ifdef RAW_ENABLE
187
188void raw_hid_send( uint8_t *data, uint8_t length )
189{
190 // TODO: implement variable size packet
191 if ( length != RAW_EPSIZE )
192 {
193 return;
194 }
195
196 if (USB_DeviceState != DEVICE_STATE_Configured)
197 {
198 return;
199 }
200
201 // TODO: decide if we allow calls to raw_hid_send() in the middle
202 // of other endpoint usage.
203 uint8_t ep = Endpoint_GetCurrentEndpoint();
204
205 Endpoint_SelectEndpoint(RAW_IN_EPNUM);
206
207 // Check to see if the host is ready to accept another packet
208 if (Endpoint_IsINReady())
209 {
210 // Write data
211 Endpoint_Write_Stream_LE(data, RAW_EPSIZE, NULL);
212 // Finalize the stream transfer to send the last packet
213 Endpoint_ClearIN();
214 }
215
216 Endpoint_SelectEndpoint(ep);
217}
218
219__attribute__ ((weak))
220void raw_hid_receive( uint8_t *data, uint8_t length )
221{
222 // Users should #include "raw_hid.h" in their own code
223 // and implement this function there. Leave this as weak linkage
224 // so users can opt to not handle data coming in.
225}
226
227static void raw_hid_task(void)
228{
229 // Create a temporary buffer to hold the read in data from the host
230 uint8_t data[RAW_EPSIZE];
231 bool data_read = false;
232
233 // Device must be connected and configured for the task to run
234 if (USB_DeviceState != DEVICE_STATE_Configured)
235 return;
236
237 Endpoint_SelectEndpoint(RAW_OUT_EPNUM);
238
239 // Check to see if a packet has been sent from the host
240 if (Endpoint_IsOUTReceived())
241 {
242 // Check to see if the packet contains data
243 if (Endpoint_IsReadWriteAllowed())
244 {
245 /* Read data */
246 Endpoint_Read_Stream_LE(data, sizeof(data), NULL);
247 data_read = true;
248 }
249
250 // Finalize the stream transfer to receive the last packet
251 Endpoint_ClearOUT();
252
253 if ( data_read )
254 {
255 raw_hid_receive( data, sizeof(data) );
256 }
257 }
258}
259#endif
169 260
170/******************************************************************************* 261/*******************************************************************************
171 * Console 262 * Console
@@ -285,10 +376,14 @@ void EVENT_USB_Device_WakeUp()
285#endif 376#endif
286} 377}
287 378
379
380
288#ifdef CONSOLE_ENABLE 381#ifdef CONSOLE_ENABLE
289static bool console_flush = false; 382static bool console_flush = false;
290#define CONSOLE_FLUSH_SET(b) do { \ 383#define CONSOLE_FLUSH_SET(b) do { \
291 uint8_t sreg = SREG; cli(); console_flush = b; SREG = sreg; \ 384 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {\
385 console_flush = b; \
386 } \
292} while (0) 387} while (0)
293 388
294// called every 1ms 389// called every 1ms
@@ -302,6 +397,7 @@ void EVENT_USB_Device_StartOfFrame(void)
302 Console_Task(); 397 Console_Task();
303 console_flush = false; 398 console_flush = false;
304} 399}
400
305#endif 401#endif
306 402
307/** Event handler for the USB_ConfigurationChanged event. 403/** Event handler for the USB_ConfigurationChanged event.
@@ -330,6 +426,14 @@ void EVENT_USB_Device_ConfigurationChanged(void)
330 EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE); 426 EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE);
331#endif 427#endif
332 428
429#ifdef RAW_ENABLE
430 /* Setup Raw HID Report Endpoints */
431 ConfigSuccess &= ENDPOINT_CONFIG(RAW_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
432 RAW_EPSIZE, ENDPOINT_BANK_SINGLE);
433 ConfigSuccess &= ENDPOINT_CONFIG(RAW_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
434 RAW_EPSIZE, ENDPOINT_BANK_SINGLE);
435#endif
436
333#ifdef CONSOLE_ENABLE 437#ifdef CONSOLE_ENABLE
334 /* Setup Console HID Report Endpoints */ 438 /* Setup Console HID Report Endpoints */
335 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, 439 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
@@ -492,9 +596,35 @@ static uint8_t keyboard_leds(void)
492 return keyboard_led_stats; 596 return keyboard_led_stats;
493} 597}
494 598
599#define SendToUSB 1
600#define SendToBT 2
601#define SendToBLE 4
602
603static inline uint8_t where_to_send(void) {
604#ifdef ADAFRUIT_BLE_ENABLE
605#if 0
606 if (adafruit_ble_is_connected()) {
607 // For testing, send to BLE as a priority
608 return SendToBLE;
609 }
610#endif
611
612 // This is the real policy
613 if (USB_DeviceState != DEVICE_STATE_Configured) {
614 if (adafruit_ble_is_connected()) {
615 return SendToBLE;
616 }
617 }
618#endif
619 return ((USB_DeviceState == DEVICE_STATE_Configured) ? SendToUSB : 0)
620#ifdef BLUETOOTH_ENABLE
621 || SendToBT
622#endif
623 ;
624}
625
495static void send_keyboard(report_keyboard_t *report) 626static void send_keyboard(report_keyboard_t *report)
496{ 627{
497
498#ifdef BLUETOOTH_ENABLE 628#ifdef BLUETOOTH_ENABLE
499 bluefruit_serial_send(0xFD); 629 bluefruit_serial_send(0xFD);
500 for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) { 630 for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
@@ -503,9 +633,17 @@ static void send_keyboard(report_keyboard_t *report)
503#endif 633#endif
504 634
505 uint8_t timeout = 255; 635 uint8_t timeout = 255;
636 uint8_t where = where_to_send();
506 637
507 if (USB_DeviceState != DEVICE_STATE_Configured) 638#ifdef ADAFRUIT_BLE_ENABLE
508 return; 639 if (where & SendToBLE) {
640 adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys));
641 }
642#endif
643
644 if (!(where & SendToUSB)) {
645 return;
646 }
509 647
510 /* Select the Keyboard Report Endpoint */ 648 /* Select the Keyboard Report Endpoint */
511#ifdef NKRO_ENABLE 649#ifdef NKRO_ENABLE
@@ -558,8 +696,17 @@ static void send_mouse(report_mouse_t *report)
558 696
559 uint8_t timeout = 255; 697 uint8_t timeout = 255;
560 698
561 if (USB_DeviceState != DEVICE_STATE_Configured) 699 uint8_t where = where_to_send();
562 return; 700
701#ifdef ADAFRUIT_BLE_ENABLE
702 if (where & SendToBLE) {
703 // FIXME: mouse buttons
704 adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h);
705 }
706#endif
707 if (!(where & SendToUSB)) {
708 return;
709 }
563 710
564 /* Select the Mouse Report Endpoint */ 711 /* Select the Mouse Report Endpoint */
565 Endpoint_SelectEndpoint(MOUSE_IN_EPNUM); 712 Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
@@ -617,9 +764,16 @@ static void send_consumer(uint16_t data)
617#endif 764#endif
618 765
619 uint8_t timeout = 255; 766 uint8_t timeout = 255;
767 uint8_t where = where_to_send();
620 768
621 if (USB_DeviceState != DEVICE_STATE_Configured) 769#ifdef ADAFRUIT_BLE_ENABLE
622 return; 770 if (where & SendToBLE) {
771 adafruit_ble_send_consumer_key(data, 0);
772 }
773#endif
774 if (!(where & SendToUSB)) {
775 return;
776 }
623 777
624 report_extra_t r = { 778 report_extra_t r = {
625 .report_id = REPORT_ID_CONSUMER, 779 .report_id = REPORT_ID_CONSUMER,
@@ -709,7 +863,7 @@ int8_t sendchar(uint8_t c)
709 ******************************************************************************/ 863 ******************************************************************************/
710 864
711#ifdef MIDI_ENABLE 865#ifdef MIDI_ENABLE
712void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) { 866static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
713 MIDI_EventPacket_t event; 867 MIDI_EventPacket_t event;
714 event.Data1 = byte0; 868 event.Data1 = byte0;
715 event.Data2 = byte1; 869 event.Data2 = byte1;
@@ -769,7 +923,7 @@ void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byt
769 USB_USBTask(); 923 USB_USBTask();
770} 924}
771 925
772void usb_get_midi(MidiDevice * device) { 926static void usb_get_midi(MidiDevice * device) {
773 MIDI_EventPacket_t event; 927 MIDI_EventPacket_t event;
774 while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) { 928 while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {
775 929
@@ -799,12 +953,12 @@ void usb_get_midi(MidiDevice * device) {
799 USB_USBTask(); 953 USB_USBTask();
800} 954}
801 955
802void midi_usb_init(MidiDevice * device){ 956static void midi_usb_init(MidiDevice * device){
803 midi_device_init(device); 957 midi_device_init(device);
804 midi_device_set_send_func(device, usb_send_func); 958 midi_device_set_send_func(device, usb_send_func);
805 midi_device_set_pre_input_process_func(device, usb_get_midi); 959 midi_device_set_pre_input_process_func(device, usb_get_midi);
806 960
807 SetupHardware(); 961 // SetupHardware();
808 sei(); 962 sei();
809} 963}
810 964
@@ -1029,7 +1183,7 @@ int main(void)
1029 1183
1030 print("Keyboard start.\n"); 1184 print("Keyboard start.\n");
1031 while (1) { 1185 while (1) {
1032 #ifndef BLUETOOTH_ENABLE 1186 #if !defined(BLUETOOTH_ENABLE) && !defined(ADAFRUIT_BLE_ENABLE)
1033 while (USB_DeviceState == DEVICE_STATE_Suspended) { 1187 while (USB_DeviceState == DEVICE_STATE_Suspended) {
1034 print("[s]"); 1188 print("[s]");
1035 suspend_power_down(); 1189 suspend_power_down();
@@ -1039,20 +1193,34 @@ int main(void)
1039 } 1193 }
1040 #endif 1194 #endif
1041 1195
1196 keyboard_task();
1197
1042#ifdef MIDI_ENABLE 1198#ifdef MIDI_ENABLE
1043 midi_device_process(&midi_device); 1199 midi_device_process(&midi_device);
1044 // MIDI_Task(); 1200 // MIDI_Task();
1045#endif 1201#endif
1046 keyboard_task(); 1202
1203#if defined(RGBLIGHT_ANIMATIONS) & defined(RGBLIGHT_ENABLE)
1204 rgblight_task();
1205#endif
1206
1207#ifdef ADAFRUIT_BLE_ENABLE
1208 adafruit_ble_task();
1209#endif
1047 1210
1048#ifdef VIRTSER_ENABLE 1211#ifdef VIRTSER_ENABLE
1049 virtser_task(); 1212 virtser_task();
1050 CDC_Device_USBTask(&cdc_device); 1213 CDC_Device_USBTask(&cdc_device);
1051#endif 1214#endif
1052 1215
1216#ifdef RAW_ENABLE
1217 raw_hid_task();
1218#endif
1219
1053#if !defined(INTERRUPT_CONTROL_ENDPOINT) 1220#if !defined(INTERRUPT_CONTROL_ENDPOINT)
1054 USB_USBTask(); 1221 USB_USBTask();
1055#endif 1222#endif
1223
1056 } 1224 }
1057} 1225}
1058 1226
@@ -1077,15 +1245,38 @@ void fallthrough_callback(MidiDevice * device,
1077#endif 1245#endif
1078} 1246}
1079 1247
1248
1080void cc_callback(MidiDevice * device, 1249void cc_callback(MidiDevice * device,
1081 uint8_t chan, uint8_t num, uint8_t val) { 1250 uint8_t chan, uint8_t num, uint8_t val) {
1082 //sending it back on the next channel 1251 //sending it back on the next channel
1083 midi_send_cc(device, (chan + 1) % 16, num, val); 1252 // midi_send_cc(device, (chan + 1) % 16, num, val);
1084} 1253}
1085 1254
1086void sysex_callback(MidiDevice * device, 1255uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0};
1087 uint16_t start, uint8_t length, uint8_t * data) { 1256
1088 for (int i = 0; i < length; i++) 1257void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) {
1089 midi_send_cc(device, 15, 0x7F & data[i], 0x7F & (start + i)); 1258 #ifdef API_SYSEX_ENABLE
1259 // SEND_STRING("\n");
1260 // send_word(start);
1261 // SEND_STRING(": ");
1262 for (uint8_t place = 0; place < length; place++) {
1263 // send_byte(*data);
1264 midi_buffer[start + place] = *data;
1265 if (*data == 0xF7) {
1266 // SEND_STRING("\nRD: ");
1267 // for (uint8_t i = 0; i < start + place + 1; i++){
1268 // send_byte(midi_buffer[i]);
1269 // SEND_STRING(" ");
1270 // }
1271 uint8_t * decoded = malloc(sizeof(uint8_t) * (sysex_decoded_length(start + place - 4)));
1272 uint16_t decode_length = sysex_decode(decoded, midi_buffer + 4, start + place - 4);
1273 process_api(decode_length, decoded);
1274 }
1275 // SEND_STRING(" ");
1276 data++;
1277 }
1278 #endif
1090} 1279}
1280
1281
1091#endif 1282#endif