X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=tmk_core%2Fprotocol%2Flufa%2Flufa.c;h=097189770668460ad3e817a64babc039fd1c64fd;hb=a305da2bc9ca5fbca7564d931088271048751d4b;hp=ae9cc2f962f631ef941d310a69b5beeeb85b028b;hpb=161bd5596b5d8199f2e56246a27ccbdb8c80bb36;p=qmk_firmware.git diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index ae9cc2f96..097189770 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -52,6 +52,7 @@ #include "descriptor.h" #include "lufa.h" #include "quantum.h" +#include #ifdef NKRO_ENABLE #include "keycode_config.h" @@ -67,13 +68,24 @@ #ifdef BLUETOOTH_ENABLE #include "bluetooth.h" #endif +#ifdef ADAFRUIT_BLE_ENABLE + #include "adafruit_ble.h" +#endif #ifdef VIRTSER_ENABLE #include "virtser.h" #endif -#ifdef RGB_MIDI - #include "rgblight.h" +#if (defined(RGB_MIDI) | defined(RGBLIGHT_ANIMATIONS)) & defined(RGBLIGHT_ENABLE) + #include "rgblight.h" +#endif + +#ifdef MIDI_ENABLE + #include "sysex_tools.h" +#endif + +#ifdef RAW_ENABLE + #include "raw_hid.h" #endif uint8_t keyboard_idle = 0; @@ -84,9 +96,9 @@ static uint8_t keyboard_led_stats = 0; static report_keyboard_t keyboard_report_sent; #ifdef MIDI_ENABLE -void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2); -void usb_get_midi(MidiDevice * device); -void midi_usb_init(MidiDevice * device); +static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2); +static void usb_get_midi(MidiDevice * device); +static void midi_usb_init(MidiDevice * device); #endif /* Host driver */ @@ -171,6 +183,80 @@ USB_ClassInfo_CDC_Device_t cdc_device = }; #endif +#ifdef RAW_ENABLE + +void raw_hid_send( uint8_t *data, uint8_t length ) +{ + // TODO: implement variable size packet + if ( length != RAW_EPSIZE ) + { + return; + } + + if (USB_DeviceState != DEVICE_STATE_Configured) + { + return; + } + + // TODO: decide if we allow calls to raw_hid_send() in the middle + // of other endpoint usage. + uint8_t ep = Endpoint_GetCurrentEndpoint(); + + Endpoint_SelectEndpoint(RAW_IN_EPNUM); + + // Check to see if the host is ready to accept another packet + if (Endpoint_IsINReady()) + { + // Write data + Endpoint_Write_Stream_LE(data, RAW_EPSIZE, NULL); + // Finalize the stream transfer to send the last packet + Endpoint_ClearIN(); + } + + Endpoint_SelectEndpoint(ep); +} + +__attribute__ ((weak)) +void raw_hid_receive( uint8_t *data, uint8_t length ) +{ + // Users should #include "raw_hid.h" in their own code + // and implement this function there. Leave this as weak linkage + // so users can opt to not handle data coming in. +} + +static void raw_hid_task(void) +{ + // Create a temporary buffer to hold the read in data from the host + uint8_t data[RAW_EPSIZE]; + bool data_read = false; + + // Device must be connected and configured for the task to run + if (USB_DeviceState != DEVICE_STATE_Configured) + return; + + Endpoint_SelectEndpoint(RAW_OUT_EPNUM); + + // Check to see if a packet has been sent from the host + if (Endpoint_IsOUTReceived()) + { + // Check to see if the packet contains data + if (Endpoint_IsReadWriteAllowed()) + { + /* Read data */ + Endpoint_Read_Stream_LE(data, sizeof(data), NULL); + data_read = true; + } + + // Finalize the stream transfer to receive the last packet + Endpoint_ClearOUT(); + + if ( data_read ) + { + raw_hid_receive( data, sizeof(data) ); + } + } +} +#endif /******************************************************************************* * Console @@ -290,10 +376,14 @@ void EVENT_USB_Device_WakeUp() #endif } + + #ifdef CONSOLE_ENABLE static bool console_flush = false; #define CONSOLE_FLUSH_SET(b) do { \ - uint8_t sreg = SREG; cli(); console_flush = b; SREG = sreg; \ + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {\ + console_flush = b; \ + } \ } while (0) // called every 1ms @@ -307,6 +397,7 @@ void EVENT_USB_Device_StartOfFrame(void) Console_Task(); console_flush = false; } + #endif /** Event handler for the USB_ConfigurationChanged event. @@ -335,6 +426,14 @@ void EVENT_USB_Device_ConfigurationChanged(void) EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE); #endif +#ifdef RAW_ENABLE + /* Setup Raw HID Report Endpoints */ + ConfigSuccess &= ENDPOINT_CONFIG(RAW_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, + RAW_EPSIZE, ENDPOINT_BANK_SINGLE); + ConfigSuccess &= ENDPOINT_CONFIG(RAW_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT, + RAW_EPSIZE, ENDPOINT_BANK_SINGLE); +#endif + #ifdef CONSOLE_ENABLE /* Setup Console HID Report Endpoints */ ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, @@ -497,9 +596,35 @@ static uint8_t keyboard_leds(void) return keyboard_led_stats; } +#define SendToUSB 1 +#define SendToBT 2 +#define SendToBLE 4 + +static inline uint8_t where_to_send(void) { +#ifdef ADAFRUIT_BLE_ENABLE +#if 0 + if (adafruit_ble_is_connected()) { + // For testing, send to BLE as a priority + return SendToBLE; + } +#endif + + // This is the real policy + if (USB_DeviceState != DEVICE_STATE_Configured) { + if (adafruit_ble_is_connected()) { + return SendToBLE; + } + } +#endif + return ((USB_DeviceState == DEVICE_STATE_Configured) ? SendToUSB : 0) +#ifdef BLUETOOTH_ENABLE + || SendToBT +#endif + ; +} + static void send_keyboard(report_keyboard_t *report) { - #ifdef BLUETOOTH_ENABLE bluefruit_serial_send(0xFD); for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) { @@ -508,9 +633,17 @@ static void send_keyboard(report_keyboard_t *report) #endif uint8_t timeout = 255; + uint8_t where = where_to_send(); - if (USB_DeviceState != DEVICE_STATE_Configured) - return; +#ifdef ADAFRUIT_BLE_ENABLE + if (where & SendToBLE) { + adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys)); + } +#endif + + if (!(where & SendToUSB)) { + return; + } /* Select the Keyboard Report Endpoint */ #ifdef NKRO_ENABLE @@ -563,8 +696,17 @@ static void send_mouse(report_mouse_t *report) uint8_t timeout = 255; - if (USB_DeviceState != DEVICE_STATE_Configured) - return; + uint8_t where = where_to_send(); + +#ifdef ADAFRUIT_BLE_ENABLE + if (where & SendToBLE) { + // FIXME: mouse buttons + adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h); + } +#endif + if (!(where & SendToUSB)) { + return; + } /* Select the Mouse Report Endpoint */ Endpoint_SelectEndpoint(MOUSE_IN_EPNUM); @@ -590,7 +732,7 @@ static void send_system(uint16_t data) report_extra_t r = { .report_id = REPORT_ID_SYSTEM, - .usage = data + .usage = data - SYSTEM_POWER_DOWN + 1 }; Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM); @@ -622,9 +764,16 @@ static void send_consumer(uint16_t data) #endif uint8_t timeout = 255; + uint8_t where = where_to_send(); - if (USB_DeviceState != DEVICE_STATE_Configured) - return; +#ifdef ADAFRUIT_BLE_ENABLE + if (where & SendToBLE) { + adafruit_ble_send_consumer_key(data, 0); + } +#endif + if (!(where & SendToUSB)) { + return; + } report_extra_t r = { .report_id = REPORT_ID_CONSUMER, @@ -714,7 +863,7 @@ int8_t sendchar(uint8_t c) ******************************************************************************/ #ifdef MIDI_ENABLE -void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) { +static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) { MIDI_EventPacket_t event; event.Data1 = byte0; event.Data2 = byte1; @@ -774,7 +923,7 @@ void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byt USB_USBTask(); } -void usb_get_midi(MidiDevice * device) { +static void usb_get_midi(MidiDevice * device) { MIDI_EventPacket_t event; while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) { @@ -804,12 +953,12 @@ void usb_get_midi(MidiDevice * device) { USB_USBTask(); } -void midi_usb_init(MidiDevice * device){ +static void midi_usb_init(MidiDevice * device){ midi_device_init(device); midi_device_set_send_func(device, usb_send_func); midi_device_set_pre_input_process_func(device, usb_get_midi); - SetupHardware(); + // SetupHardware(); sei(); } @@ -1034,7 +1183,7 @@ int main(void) print("Keyboard start.\n"); while (1) { - #ifndef BLUETOOTH_ENABLE + #if !defined(BLUETOOTH_ENABLE) && !defined(ADAFRUIT_BLE_ENABLE) while (USB_DeviceState == DEVICE_STATE_Suspended) { print("[s]"); suspend_power_down(); @@ -1050,19 +1199,28 @@ int main(void) midi_device_process(&midi_device); // MIDI_Task(); #endif - -#ifdef RGBLIGHT_ENABLE + +#if defined(RGBLIGHT_ANIMATIONS) & defined(RGBLIGHT_ENABLE) rgblight_task(); #endif +#ifdef ADAFRUIT_BLE_ENABLE + adafruit_ble_task(); +#endif + #ifdef VIRTSER_ENABLE virtser_task(); CDC_Device_USBTask(&cdc_device); #endif +#ifdef RAW_ENABLE + raw_hid_task(); +#endif + #if !defined(INTERRUPT_CONTROL_ENDPOINT) USB_USBTask(); #endif + } } @@ -1087,157 +1245,38 @@ void fallthrough_callback(MidiDevice * device, #endif } -#ifdef RGB_MIDI - rgblight_config_t rgblight_config; -#endif void cc_callback(MidiDevice * device, uint8_t chan, uint8_t num, uint8_t val) { //sending it back on the next channel // midi_send_cc(device, (chan + 1) % 16, num, val); - #ifdef RGB_MIDI - rgblight_config.raw = eeconfig_read_rgblight(); - switch (num) { - case 14: - rgblight_config.hue = val * 360 / 127; - break; - case 15: - rgblight_config.sat = val << 1; - break; - case 16: - rgblight_config.val = val << 1; - break; - } - rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val); - #endif -} - -void send_dword(uint32_t number) { - uint16_t word = (number >> 16); - send_word(word); - send_word(number & 0xFFFFUL); -} - -void send_word(uint16_t number) { - uint8_t byte = number >> 8; - send_byte(byte); - send_byte(number & 0xFF); -} - -void send_byte(uint8_t number) { - uint8_t nibble = number >> 4; - send_nibble(nibble); - send_nibble(number & 0xF); -} - -void send_nibble(uint8_t number) { - switch (number) { - case 0: - register_code(KC_0); - unregister_code(KC_0); - break; - case 1 ... 9: - register_code(KC_1 + (number - 1)); - unregister_code(KC_1 + (number - 1)); - break; - case 0xA ... 0xF: - register_code(KC_A + (number - 0xA)); - unregister_code(KC_A + (number - 0xA)); - break; - } } -uint8_t midi_buffer[16] = {0}; +uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0}; -void sysex_callback(MidiDevice * device, - uint16_t start, uint8_t length, uint8_t * data) { - // for (int i = 0; i < length; i++) - // midi_send_cc(device, 15, 0x7F & data[i], 0x7F & (start + i)); - // if (start == 0x27) { +void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) { + #ifdef API_SYSEX_ENABLE // SEND_STRING("\n"); // send_word(start); // SEND_STRING(": "); for (uint8_t place = 0; place < length; place++) { // send_byte(*data); midi_buffer[start + place] = *data; - if (*data == 0xF7) - sysex_buffer_callback(device, start + place, &midi_buffer); + if (*data == 0xF7) { + // SEND_STRING("\nRD: "); + // for (uint8_t i = 0; i < start + place + 1; i++){ + // send_byte(midi_buffer[i]); + // SEND_STRING(" "); + // } + uint8_t * decoded = malloc(sizeof(uint8_t) * (sysex_decoded_length(start + place - 4))); + uint16_t decode_length = sysex_decode(decoded, midi_buffer + 4, start + place - 4); + process_api(decode_length, decoded); + } // SEND_STRING(" "); data++; } - // } - -} - -uint32_t decode_4byte_chunk(uint8_t * data) { - uint32_t part1 = *data++; - uint32_t part2 = *data++; - uint32_t part3 = *data++; - uint32_t part4 = *data++; - uint32_t part5 = *data++; - return ((part1 & 0x1FUL) << 28) | (part2 << 21) | (part3 << 14) | (part4 << 7) | part5; -} - -void encode_4byte_chunk(uint32_t data, uint8_t * pointer) { - *pointer++ = (data >> 28) & 0x7F; - *pointer++ = (data >> 21) & 0x7F; - *pointer++ = (data >> 14) & 0x7F; - *pointer++ = (data >> 7) & 0x7F; - *pointer++ = (data) & 0x7F; -} - -void sysex_buffer_callback(MidiDevice * device, uint8_t length, uint8_t * data) { - uint8_t * pointer_copy = data; - - if (*data++ != 0xF0) - return - data++; - data++; - data++; - data++; - - switch (*data++) { - case 0x13: ; // Get info from keyboard - switch (*data++) { - case 0x00: ; // Get layer state - // send_dword(layer_state); - uint8_t chunk[5]; - encode_4byte_chunk(layer_state | default_layer_state, &chunk); - - uint8_t array[] = {0xF0, 0x00, 0x00, 0x00, 0x00, chunk[0], chunk[1], chunk[2], chunk[3], chunk[4], 0xF7}; - midi_send_array(&midi_device, 11, &array); - // midi_send_data(device, 3, 0x00, layer_state >> 24 & 0x7f, layer_state >> 16 & 0x7f); - // midi_send_data(device, 6, layer_state >> 8 & 0x7f, layer_state & 0x7f, 0xF7); - break; - } - #ifdef RGBLIGHT_ENABLE - case 0x27: ; // RGB LED functions - switch (*data++) { - case 0x00: ; // Update HSV - uint32_t chunk = decode_4byte_chunk(data); - rgblight_sethsv(((chunk >> 16) & 0xFFFF) % 360, (chunk >> 8) & 0xFF, chunk & 0xFF); - break; - case 0x01: ; // Update RGB - break; - } - break; - #endif - } - - // SEND_STRING("\nDATA:\n"); - // while (*pointer_copy != 0xF7) { - // send_byte(*pointer_copy++); - // SEND_STRING(" "); - // } - + #endif } -void send_unicode_midi(uint32_t unicode) { - uint8_t chunk[5]; - encode_4byte_chunk(unicode, &chunk); - - uint8_t array[] = {0xF0, 0x00, 0x00, 0x00, 0x05, chunk[0], chunk[1], chunk[2], chunk[3], chunk[4], 0xF7}; - midi_send_array(&midi_device, 11, &array); -} #endif