X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=tmk_core%2Fprotocol%2Flufa%2Flufa.c;h=ae6129d1a28dfe185129cbef44abdb4d2424f35d;hb=8994fca4eedeb465268b232e22ad904683e3efa9;hp=39d4824b6b9cb6a5b5c56394d720a021bb1cb70f;hpb=7edac212c8ed8442bf4207e70dc8194631b2bf27;p=qmk_firmware.git diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index 39d4824b6..ae6129d1a 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -52,6 +52,8 @@ #include "descriptor.h" #include "lufa.h" #include "quantum.h" +#include +#include "outputselect.h" #ifdef NKRO_ENABLE #include "keycode_config.h" @@ -65,7 +67,11 @@ #endif #ifdef BLUETOOTH_ENABLE + #ifdef MODULE_ADAFRUIT_BLE + #include "adafruit_ble.h" + #else #include "bluetooth.h" + #endif #endif #ifdef VIRTSER_ENABLE @@ -73,13 +79,17 @@ #endif #if (defined(RGB_MIDI) | defined(RGBLIGHT_ANIMATIONS)) & defined(RGBLIGHT_ENABLE) - #include "rgblight.h" + #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; /* 0: Boot Protocol, 1: Report Protocol(default) */ uint8_t keyboard_protocol = 1; @@ -175,6 +185,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 @@ -294,10 +378,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 @@ -311,6 +399,7 @@ void EVENT_USB_Device_StartOfFrame(void) Console_Task(); console_flush = false; } + #endif /** Event handler for the USB_ConfigurationChanged event. @@ -339,6 +428,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, @@ -494,7 +591,6 @@ void EVENT_USB_Device_ControlRequest(void) /******************************************************************************* * Host driver -p ******************************************************************************/ static uint8_t keyboard_leds(void) { @@ -503,18 +599,32 @@ static uint8_t keyboard_leds(void) static void send_keyboard(report_keyboard_t *report) { + uint8_t timeout = 255; + uint8_t where = where_to_send(); #ifdef BLUETOOTH_ENABLE - bluefruit_serial_send(0xFD); - for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) { + if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) { + #ifdef MODULE_ADAFRUIT_BLE + adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys)); + #elif MODULE_RN42 + bluefruit_serial_send(0xFD); + bluefruit_serial_send(0x09); + bluefruit_serial_send(0x01); + for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) { + bluefruit_serial_send(report->raw[i]); + } + #else + bluefruit_serial_send(0xFD); + for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) { bluefruit_serial_send(report->raw[i]); - } + } + #endif + } #endif - uint8_t timeout = 255; - - if (USB_DeviceState != DEVICE_STATE_Configured) - return; + if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) { + return; + } /* Select the Keyboard Report Endpoint */ #ifdef NKRO_ENABLE @@ -552,23 +662,31 @@ static void send_keyboard(report_keyboard_t *report) static void send_mouse(report_mouse_t *report) { #ifdef MOUSE_ENABLE + uint8_t timeout = 255; + uint8_t where = where_to_send(); #ifdef BLUETOOTH_ENABLE - bluefruit_serial_send(0xFD); - bluefruit_serial_send(0x00); - bluefruit_serial_send(0x03); - bluefruit_serial_send(report->buttons); - bluefruit_serial_send(report->x); - bluefruit_serial_send(report->y); - bluefruit_serial_send(report->v); // should try sending the wheel v here - bluefruit_serial_send(report->h); // should try sending the wheel h here - bluefruit_serial_send(0x00); + if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) { + #ifdef MODULE_ADAFRUIT_BLE + // FIXME: mouse buttons + adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h); + #else + bluefruit_serial_send(0xFD); + bluefruit_serial_send(0x00); + bluefruit_serial_send(0x03); + bluefruit_serial_send(report->buttons); + bluefruit_serial_send(report->x); + bluefruit_serial_send(report->y); + bluefruit_serial_send(report->v); // should try sending the wheel v here + bluefruit_serial_send(report->h); // should try sending the wheel h here + bluefruit_serial_send(0x00); + #endif + } #endif - uint8_t timeout = 255; - - if (USB_DeviceState != DEVICE_STATE_Configured) - return; + if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) { + return; + } /* Select the Mouse Report Endpoint */ Endpoint_SelectEndpoint(MOUSE_IN_EPNUM); @@ -594,7 +712,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); @@ -608,27 +726,44 @@ static void send_system(uint16_t data) static void send_consumer(uint16_t data) { + uint8_t timeout = 255; + uint8_t where = where_to_send(); #ifdef BLUETOOTH_ENABLE - static uint16_t last_data = 0; - if (data == last_data) return; - last_data = data; - uint16_t bitmap = CONSUMER2BLUEFRUIT(data); - bluefruit_serial_send(0xFD); - bluefruit_serial_send(0x00); - bluefruit_serial_send(0x02); - bluefruit_serial_send((bitmap>>8)&0xFF); - bluefruit_serial_send(bitmap&0xFF); - bluefruit_serial_send(0x00); - bluefruit_serial_send(0x00); - bluefruit_serial_send(0x00); - bluefruit_serial_send(0x00); + if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) { + #ifdef MODULE_ADAFRUIT_BLE + adafruit_ble_send_consumer_key(data, 0); + #elif MODULE_RN42 + static uint16_t last_data = 0; + if (data == last_data) return; + last_data = data; + uint16_t bitmap = CONSUMER2RN42(data); + bluefruit_serial_send(0xFD); + bluefruit_serial_send(0x03); + bluefruit_serial_send(0x03); + bluefruit_serial_send(bitmap&0xFF); + bluefruit_serial_send((bitmap>>8)&0xFF); + #else + static uint16_t last_data = 0; + if (data == last_data) return; + last_data = data; + uint16_t bitmap = CONSUMER2BLUEFRUIT(data); + bluefruit_serial_send(0xFD); + bluefruit_serial_send(0x00); + bluefruit_serial_send(0x02); + bluefruit_serial_send((bitmap>>8)&0xFF); + bluefruit_serial_send(bitmap&0xFF); + bluefruit_serial_send(0x00); + bluefruit_serial_send(0x00); + bluefruit_serial_send(0x00); + bluefruit_serial_send(0x00); + #endif + } #endif - uint8_t timeout = 255; - - if (USB_DeviceState != DEVICE_STATE_Configured) - return; + if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) { + return; + } report_extra_t r = { .report_id = REPORT_ID_CONSUMER, @@ -978,16 +1113,23 @@ void cc_callback(MidiDevice * device, uint8_t chan, uint8_t num, uint8_t val); void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data); + +void setup_midi(void) +{ +#ifdef MIDI_ADVANCED + midi_init(); +#endif + midi_device_init(&midi_device); + midi_device_set_send_func(&midi_device, usb_send_func); + midi_device_set_pre_input_process_func(&midi_device, usb_get_midi); +} #endif int main(void) __attribute__ ((weak)); int main(void) { - #ifdef MIDI_ENABLE - midi_device_init(&midi_device); - midi_device_set_send_func(&midi_device, usb_send_func); - midi_device_set_pre_input_process_func(&midi_device, usb_get_midi); + setup_midi(); #endif setup_mcu(); @@ -1007,7 +1149,7 @@ int main(void) // midi_send_noteoff(&midi_device, 0, 64, 127); #endif -#ifdef BLUETOOTH_ENABLE +#if defined(MODULE_ADAFRUIT_EZKEY) || defined(MODULE_RN42) serial_init(); #endif @@ -1038,7 +1180,7 @@ int main(void) print("Keyboard start.\n"); while (1) { - #ifndef BLUETOOTH_ENABLE + #if !defined(BLUETOOTH_ENABLE) while (USB_DeviceState == DEVICE_STATE_Suspended) { print("[s]"); suspend_power_down(); @@ -1052,21 +1194,32 @@ int main(void) #ifdef MIDI_ENABLE midi_device_process(&midi_device); - // MIDI_Task(); +#ifdef MIDI_ADVANCED + midi_task(); #endif - +#endif + #if defined(RGBLIGHT_ANIMATIONS) & defined(RGBLIGHT_ENABLE) rgblight_task(); #endif +#ifdef MODULE_ADAFRUIT_BLE + 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 + } } @@ -1098,28 +1251,40 @@ void cc_callback(MidiDevice * device, // midi_send_cc(device, (chan + 1) % 16, num, val); } +#ifdef API_SYSEX_ENABLE uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0}; +#endif 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(": "); + // Don't store the header + int16_t pos = start - 4; for (uint8_t place = 0; place < length; place++) { // send_byte(*data); - midi_buffer[start + place] = *data; - 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); + if (pos >= 0) { + if (*data == 0xF7) { + // SEND_STRING("\nRD: "); + // for (uint8_t i = 0; i < start + place + 1; i++){ + // send_byte(midi_buffer[i]); + // SEND_STRING(" "); + // } + const unsigned decoded_length = sysex_decoded_length(pos); + uint8_t decoded[API_SYSEX_MAX_SIZE]; + sysex_decode(decoded, midi_buffer, pos); + process_api(decoded_length, decoded); + return; + } + else if (pos >= MIDI_SYSEX_BUFFER) { + return; + } + midi_buffer[pos] = *data; } // SEND_STRING(" "); data++; + pos++; } #endif }