X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=protocol%2Flufa%2Flufa.c;h=16a602df13f76d7bd4485ac273af01fbc90dd50a;hb=8f5f25fcd50d93da0f6ad53d0b622a258387c6a1;hp=bff1f5e8b28bf5caa0286a80fb05608d1cd48662;hpb=4ae979f6ef8dbf9e1d1f35be15322ad6d02e2958;p=tmk_firmware.git diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c index bff1f5e..16a602d 100644 --- a/protocol/lufa/lufa.c +++ b/protocol/lufa/lufa.c @@ -40,14 +40,20 @@ #include "host.h" #include "host_driver.h" #include "keyboard.h" +#include "action.h" +#include "led.h" #include "sendchar.h" #include "debug.h" +#ifdef SLEEP_LED_ENABLE +#include "sleep_led.h" +#endif +#include "suspend.h" #include "descriptor.h" #include "lufa.h" -static uint8_t idle_duration = 0; -static uint8_t protocol_report = 1; +uint8_t keyboard_idle = 0; +uint8_t keyboard_protocol = 1; static uint8_t keyboard_led_stats = 0; static report_keyboard_t keyboard_report_sent; @@ -133,16 +139,43 @@ static void Console_Task(void) /******************************************************************************* * USB Events ******************************************************************************/ -/** Event handler for the USB_Connect event. */ +/* + * Event Order of Plug in: + * 0) EVENT_USB_Device_Connect + * 1) EVENT_USB_Device_Suspend + * 2) EVENT_USB_Device_Reset + * 3) EVENT_USB_Device_Wake +*/ void EVENT_USB_Device_Connect(void) { } -/** Event handler for the USB_Disconnect event. */ void EVENT_USB_Device_Disconnect(void) { } +void EVENT_USB_Device_Reset(void) +{ +} + +void EVENT_USB_Device_Suspend() +{ +#ifdef SLEEP_LED_ENABLE + sleep_led_enable(); +#endif +} + +void EVENT_USB_Device_WakeUp() +{ + suspend_wakeup_init(); + +#ifdef SLEEP_LED_ENABLE + sleep_led_disable(); + // NOTE: converters may not accept this + led_set(host_keyboard_leds()); +#endif +} + void EVENT_USB_Device_StartOfFrame(void) { Console_Task(); @@ -156,27 +189,35 @@ void EVENT_USB_Device_ConfigurationChanged(void) bool ConfigSuccess = true; /* Setup Keyboard HID Report Endpoints */ - ConfigSuccess &= Endpoint_ConfigureEndpoint(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, - KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE); + ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, + KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE); #ifdef MOUSE_ENABLE /* Setup Mouse HID Report Endpoint */ - ConfigSuccess &= Endpoint_ConfigureEndpoint(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, - MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE); + ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, + MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE); #endif #ifdef EXTRAKEY_ENABLE /* Setup Extra HID Report Endpoint */ - ConfigSuccess &= Endpoint_ConfigureEndpoint(EXTRAKEY_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, - EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE); + ConfigSuccess &= ENDPOINT_CONFIG(EXTRAKEY_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, + EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE); #endif #ifdef CONSOLE_ENABLE /* Setup Console HID Report Endpoints */ - ConfigSuccess &= Endpoint_ConfigureEndpoint(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, - CONSOLE_EPSIZE, ENDPOINT_BANK_DOUBLE); - ConfigSuccess &= Endpoint_ConfigureEndpoint(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT, - CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE); + ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, + CONSOLE_EPSIZE, ENDPOINT_BANK_DOUBLE); +#if 0 + ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT, + CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE); +#endif +#endif + +#ifdef NKRO_ENABLE + /* Setup NKRO HID Report Endpoints */ + ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, + NKRO_EPSIZE, ENDPOINT_BANK_SINGLE); #endif } @@ -231,6 +272,9 @@ void EVENT_USB_Device_ControlRequest(void) // Interface switch (USB_ControlRequest.wIndex) { case KEYBOARD_INTERFACE: +#ifdef NKRO_ENABLE + case NKRO_INTERFACE: +#endif Endpoint_ClearSETUP(); while (!(Endpoint_IsOUTReceived())) { @@ -251,21 +295,29 @@ void EVENT_USB_Device_ControlRequest(void) case HID_REQ_GetProtocol: if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) { - Endpoint_ClearSETUP(); - while (!(Endpoint_IsINReady())); - Endpoint_Write_8(protocol_report); - Endpoint_ClearIN(); - Endpoint_ClearStatusStage(); + if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) { + Endpoint_ClearSETUP(); + while (!(Endpoint_IsINReady())); + Endpoint_Write_8(keyboard_protocol); + Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); + } } break; case HID_REQ_SetProtocol: if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) { - Endpoint_ClearSETUP(); - Endpoint_ClearStatusStage(); + if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) { + Endpoint_ClearSETUP(); + Endpoint_ClearStatusStage(); - protocol_report = ((USB_ControlRequest.wValue & 0xFF) != 0x00); + keyboard_protocol = ((USB_ControlRequest.wValue & 0xFF) != 0x00); +#ifdef NKRO_ENABLE + keyboard_nkro = !!keyboard_protocol; +#endif + clear_keyboard(); + } } break; @@ -275,7 +327,7 @@ void EVENT_USB_Device_ControlRequest(void) Endpoint_ClearSETUP(); Endpoint_ClearStatusStage(); - idle_duration = ((USB_ControlRequest.wValue & 0xFF00) >> 8); + keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8); } break; @@ -284,7 +336,7 @@ void EVENT_USB_Device_ControlRequest(void) { Endpoint_ClearSETUP(); while (!(Endpoint_IsINReady())); - Endpoint_Write_8(idle_duration); + Endpoint_Write_8(keyboard_idle); Endpoint_ClearIN(); Endpoint_ClearStatusStage(); } @@ -303,17 +355,37 @@ static uint8_t keyboard_leds(void) static void send_keyboard(report_keyboard_t *report) { - uint8_t timeout = 0; + uint8_t timeout = 255; + + if (USB_DeviceState != DEVICE_STATE_Configured) + return; - // TODO: handle NKRO report /* Select the Keyboard Report Endpoint */ - Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM); +#ifdef NKRO_ENABLE + if (keyboard_nkro) { + /* Report protocol - NKRO */ + Endpoint_SelectEndpoint(NKRO_IN_EPNUM); + + /* Check if write ready for a polling interval around 1ms */ + while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(4); + if (!Endpoint_IsReadWriteAllowed()) return; + + /* Write Keyboard Report Data */ + Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL); + } + else +#endif + { + /* Boot protocol */ + Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM); - /* Check if Keyboard Endpoint Ready for Read/Write */ - while (--timeout && !Endpoint_IsReadWriteAllowed()) ; + /* Check if write ready for a polling interval around 10ms */ + while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40); + if (!Endpoint_IsReadWriteAllowed()) return; - /* Write Keyboard Report Data */ - Endpoint_Write_Stream_LE(report, sizeof(report_keyboard_t), NULL); + /* Write Keyboard Report Data */ + Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL); + } /* Finalize the stream transfer to send the last packet */ Endpoint_ClearIN(); @@ -324,13 +396,17 @@ static void send_keyboard(report_keyboard_t *report) static void send_mouse(report_mouse_t *report) { #ifdef MOUSE_ENABLE - uint8_t timeout = 0; + uint8_t timeout = 255; + + if (USB_DeviceState != DEVICE_STATE_Configured) + return; /* Select the Mouse Report Endpoint */ Endpoint_SelectEndpoint(MOUSE_IN_EPNUM); - /* Check if Mouse Endpoint Ready for Read/Write */ - while (--timeout && !Endpoint_IsReadWriteAllowed()) ; + /* Check if write ready for a polling interval around 10ms */ + while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40); + if (!Endpoint_IsReadWriteAllowed()) return; /* Write Mouse Report Data */ Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL); @@ -342,28 +418,42 @@ static void send_mouse(report_mouse_t *report) static void send_system(uint16_t data) { - uint8_t timeout = 0; + uint8_t timeout = 255; + + if (USB_DeviceState != DEVICE_STATE_Configured) + return; report_extra_t r = { .report_id = REPORT_ID_SYSTEM, .usage = data }; Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM); - while (--timeout && !Endpoint_IsReadWriteAllowed()) ; + + /* Check if write ready for a polling interval around 10ms */ + while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40); + if (!Endpoint_IsReadWriteAllowed()) return; + Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL); Endpoint_ClearIN(); } static void send_consumer(uint16_t data) { - uint8_t timeout = 0; + uint8_t timeout = 255; + + if (USB_DeviceState != DEVICE_STATE_Configured) + return; report_extra_t r = { .report_id = REPORT_ID_CONSUMER, .usage = data }; Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM); - while (--timeout && !Endpoint_IsReadWriteAllowed()) ; + + /* Check if write ready for a polling interval around 10ms */ + while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40); + if (!Endpoint_IsReadWriteAllowed()) return; + Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL); Endpoint_ClearIN(); } @@ -455,6 +545,7 @@ static void SetupHardware(void) // for Console_Task USB_Device_EnableSOFEvents(); + print_set_sendchar(sendchar); } int main(void) __attribute__ ((weak)); @@ -463,18 +554,32 @@ int main(void) SetupHardware(); sei(); - print_enable = true; - debug_enable = true; - debug_matrix = true; - debug_keyboard = true; - debug_mouse = true; - - // TODO: can't print here - debug("LUFA init\n"); + /* wait for USB startup & debug output */ + while (USB_DeviceState != DEVICE_STATE_Configured) { +#if defined(INTERRUPT_CONTROL_ENDPOINT) + ; +#else + USB_USBTask(); +#endif + } + print("USB configured.\n"); + /* init modules */ keyboard_init(); host_set_driver(&lufa_driver); +#ifdef SLEEP_LED_ENABLE + sleep_led_init(); +#endif + + print("Keyboard start.\n"); while (1) { + while (USB_DeviceState == DEVICE_STATE_Suspended) { + suspend_power_down(); + if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { + USB_Device_SendRemoteWakeup(); + } + } + keyboard_task(); #if !defined(INTERRUPT_CONTROL_ENDPOINT)