diff options
Diffstat (limited to 'tmk_core/protocol/lufa/lufa.c')
| -rw-r--r-- | tmk_core/protocol/lufa/lufa.c | 235 |
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 | |||
| 74 | uint8_t keyboard_idle = 0; | 91 | uint8_t keyboard_idle = 0; |
| 75 | /* 0: Boot Protocol, 1: Report Protocol(default) */ | 92 | /* 0: Boot Protocol, 1: Report Protocol(default) */ |
| 76 | uint8_t keyboard_protocol = 1; | 93 | uint8_t keyboard_protocol = 1; |
| @@ -79,9 +96,9 @@ static uint8_t keyboard_led_stats = 0; | |||
| 79 | static report_keyboard_t keyboard_report_sent; | 96 | static report_keyboard_t keyboard_report_sent; |
| 80 | 97 | ||
| 81 | #ifdef MIDI_ENABLE | 98 | #ifdef MIDI_ENABLE |
| 82 | void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2); | 99 | static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2); |
| 83 | void usb_get_midi(MidiDevice * device); | 100 | static void usb_get_midi(MidiDevice * device); |
| 84 | void midi_usb_init(MidiDevice * device); | 101 | static 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 | |||
| 188 | void 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)) | ||
| 220 | void 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 | |||
| 227 | static 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 |
| 289 | static bool console_flush = false; | 382 | static 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 | |||
| 603 | static 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 | |||
| 495 | static void send_keyboard(report_keyboard_t *report) | 626 | static 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 |
| 712 | void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) { | 866 | static 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 | ||
| 772 | void usb_get_midi(MidiDevice * device) { | 926 | static 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 | ||
| 802 | void midi_usb_init(MidiDevice * device){ | 956 | static 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 | |||
| 1080 | void cc_callback(MidiDevice * device, | 1249 | void 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 | ||
| 1086 | void sysex_callback(MidiDevice * device, | 1255 | uint8_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++) | 1257 | void 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 |
