X-Git-Url: https://git.friedersdorff.com/?a=blobdiff_plain;f=protocol%2Flufa%2Flufa.c;h=98c3a68ffbdc30fa1c0128072070e5f4a5c15abc;hb=821563417565776d2dc3a02b0265e6fcd5218739;hp=10511ba67b27339177740065f280a403a38cceba;hpb=8947029950ba19c16bedd3d4618d4227f4714564;p=max%2Ftmk_keyboard.git diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c index 10511ba6..98c3a68f 100644 --- a/protocol/lufa/lufa.c +++ b/protocol/lufa/lufa.c @@ -59,7 +59,7 @@ static void send_keyboard(report_keyboard_t *report); static void send_mouse(report_mouse_t *report); static void send_system(uint16_t data); static void send_consumer(uint16_t data); -static host_driver_t lufa_driver = { +host_driver_t lufa_driver = { keyboard_leds, send_keyboard, send_mouse, @@ -68,54 +68,15 @@ static host_driver_t lufa_driver = { }; -static void SetupHardware(void); -static void Console_Task(void); - -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"); - - keyboard_init(); - host_set_driver(&lufa_driver); - while (1) { - keyboard_proc(); - -#if !defined(INTERRUPT_CONTROL_ENDPOINT) - USB_USBTask(); -#endif - } -} - -void SetupHardware(void) -{ - /* Disable watchdog if enabled by bootloader/fuses */ - MCUSR &= ~(1 << WDRF); - wdt_disable(); - - /* Disable clock division */ - clock_prescale_set(clock_div_1); - - USB_Init(); - - // for Console_Task - USB_Device_EnableSOFEvents(); -} - +/******************************************************************************* + * Console + ******************************************************************************/ +#ifdef CONSOLE_ENABLE static void Console_Task(void) { /* Device must be connected and configured for the task to run */ if (USB_DeviceState != DEVICE_STATE_Configured) - return; + return; uint8_t ep = Endpoint_GetCurrentEndpoint(); @@ -146,6 +107,15 @@ static void Console_Task(void) /* IN packet */ Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM); + if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) { + Endpoint_SelectEndpoint(ep); + return; + } + + // fill empty bank + while (Endpoint_IsReadWriteAllowed()) + Endpoint_Write_8(0); + // flash senchar packet if (Endpoint_IsINReady()) { Endpoint_ClearIN(); @@ -153,6 +123,11 @@ static void Console_Task(void) Endpoint_SelectEndpoint(ep); } +#else +static void Console_Task(void) +{ +} +#endif /******************************************************************************* @@ -168,44 +143,50 @@ void EVENT_USB_Device_Disconnect(void) { } -#define CONSOLE_TASK_INTERVAL 50 void EVENT_USB_Device_StartOfFrame(void) { - static uint8_t interval; - if (++interval == CONSOLE_TASK_INTERVAL) { - Console_Task(); - interval = 0; - } + Console_Task(); } /** Event handler for the USB_ConfigurationChanged event. * This is fired when the host sets the current configuration of the USB device after enumeration. */ +#if LUFA_VERSION_INTEGER < 0x120730 + /* old API 120219 */ + #define ENDPOINT_CONFIG(epnum, eptype, epdir, epsize, epbank) Endpoint_ConfigureEndpoint(epnum, eptype, epdir, epsize, epbank) +#else + /* new API >= 120730 */ + #define ENDPOINT_BANK_SINGLE 1 + #define ENDPOINT_BANK_DOUBLE 2 + #define ENDPOINT_CONFIG(epnum, eptype, epdir, epsize, epbank) Endpoint_ConfigureEndpoint((epdir) | (epnum) , eptype, epsize, epbank) +#endif 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(EXTRA_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, - EXTRA_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); + ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT, + CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE); +#endif } /* @@ -331,77 +312,99 @@ static uint8_t keyboard_leds(void) static void send_keyboard(report_keyboard_t *report) { + uint8_t timeout = 0; + // TODO: handle NKRO report /* Select the Keyboard Report Endpoint */ Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM); /* Check if Keyboard Endpoint Ready for Read/Write */ - if (Endpoint_IsReadWriteAllowed()) - { - /* Write Keyboard Report Data */ - Endpoint_Write_Stream_LE(report, sizeof(report_keyboard_t), NULL); + while (--timeout && !Endpoint_IsReadWriteAllowed()) ; + + /* Write Keyboard Report Data */ + Endpoint_Write_Stream_LE(report, sizeof(report_keyboard_t), NULL); + + /* Finalize the stream transfer to send the last packet */ + Endpoint_ClearIN(); - /* Finalize the stream transfer to send the last packet */ - Endpoint_ClearIN(); - } keyboard_report_sent = *report; } static void send_mouse(report_mouse_t *report) { #ifdef MOUSE_ENABLE + uint8_t timeout = 0; + /* Select the Mouse Report Endpoint */ Endpoint_SelectEndpoint(MOUSE_IN_EPNUM); /* Check if Mouse Endpoint Ready for Read/Write */ - if (Endpoint_IsReadWriteAllowed()) - { - /* Write Mouse Report Data */ - Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL); + while (--timeout && !Endpoint_IsReadWriteAllowed()) ; - /* Finalize the stream transfer to send the last packet */ - Endpoint_ClearIN(); - } + /* Write Mouse Report Data */ + Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL); + + /* Finalize the stream transfer to send the last packet */ + Endpoint_ClearIN(); #endif } static void send_system(uint16_t data) { + uint8_t timeout = 0; + report_extra_t r = { .report_id = REPORT_ID_SYSTEM, .usage = data }; - Endpoint_SelectEndpoint(EXTRA_IN_EPNUM); - if (Endpoint_IsReadWriteAllowed()) { - Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL); - Endpoint_ClearIN(); - } + Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM); + while (--timeout && !Endpoint_IsReadWriteAllowed()) ; + Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL); + Endpoint_ClearIN(); } static void send_consumer(uint16_t data) { + uint8_t timeout = 0; + report_extra_t r = { .report_id = REPORT_ID_CONSUMER, .usage = data }; - Endpoint_SelectEndpoint(EXTRA_IN_EPNUM); - if (Endpoint_IsReadWriteAllowed()) { - Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL); - Endpoint_ClearIN(); - } + Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM); + while (--timeout && !Endpoint_IsReadWriteAllowed()) ; + Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL); + Endpoint_ClearIN(); } /******************************************************************************* * sendchar ******************************************************************************/ -#define SEND_TIMEOUT 10 +#ifdef CONSOLE_ENABLE +#define SEND_TIMEOUT 5 int8_t sendchar(uint8_t c) { + // Not wait once timeouted. + // Because sendchar() is called so many times, waiting each call causes big lag. + static bool timeouted = false; + if (USB_DeviceState != DEVICE_STATE_Configured) - return -1; + return -1; + uint8_t ep = Endpoint_GetCurrentEndpoint(); Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM); + if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) { + Endpoint_SelectEndpoint(ep); + return -1; + } + + if (timeouted && !Endpoint_IsReadWriteAllowed()) { + Endpoint_SelectEndpoint(ep); + return - 1; + } + + timeouted = false; uint8_t timeout = SEND_TIMEOUT; uint16_t prevFN = USB_Device_GetFrameNumber(); @@ -411,11 +414,16 @@ int8_t sendchar(uint8_t c) case DEVICE_STATE_Suspended: return -1; } - if (Endpoint_IsStalled()) + if (Endpoint_IsStalled()) { + Endpoint_SelectEndpoint(ep); return -1; + } if (prevFN != USB_Device_GetFrameNumber()) { - if (!(timeout--)) + if (!(timeout--)) { + timeouted = true; + Endpoint_SelectEndpoint(ep); return -1; + } prevFN = USB_Device_GetFrameNumber(); } } @@ -426,5 +434,53 @@ int8_t sendchar(uint8_t c) if (!Endpoint_IsReadWriteAllowed()) Endpoint_ClearIN(); + Endpoint_SelectEndpoint(ep); return 0; } +#else +int8_t sendchar(uint8_t c) +{ + return 0; +} +#endif + + +/******************************************************************************* + * main + ******************************************************************************/ +static void SetupHardware(void) +{ + /* Disable watchdog if enabled by bootloader/fuses */ + MCUSR &= ~(1 << WDRF); + wdt_disable(); + + /* Disable clock division */ + clock_prescale_set(clock_div_1); + + // Leonardo needs. Without this USB device is not recognized. + USB_Disable(); + + USB_Init(); + + // for Console_Task + USB_Device_EnableSOFEvents(); +} + +int main(void) __attribute__ ((weak)); +int main(void) +{ + SetupHardware(); + keyboard_init(); + host_set_driver(&lufa_driver); + sei(); + + // TODO: can't print here + debug("LUFA init\n"); + while (1) { + keyboard_task(); + +#if !defined(INTERRUPT_CONTROL_ENDPOINT) + USB_USBTask(); +#endif + } +}