diff options
Diffstat (limited to 'protocol/lufa/lufa.c')
-rw-r--r-- | protocol/lufa/lufa.c | 605 |
1 files changed, 0 insertions, 605 deletions
diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c deleted file mode 100644 index cdfc7bc6ad..0000000000 --- a/protocol/lufa/lufa.c +++ /dev/null @@ -1,605 +0,0 @@ -/* - * Copyright 2012 Jun Wako <wakojun@gmail.com> - * This file is based on: - * LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse - * LUFA-120219/Demos/Device/Lowlevel/GenericHID - */ - -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) - Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com) - - Permission to use, copy, modify, distribute, and sell this - software and its documentation for any purpose is hereby granted - without fee, provided that the above copyright notice appear in - all copies and that both that the copyright notice and this - permission notice and warranty disclaimer appear in supporting - documentation, and that the name of the author not be used in - advertising or publicity pertaining to distribution of the - software without specific, written prior permission. - - The author disclaim all warranties with regard to this - software, including all implied warranties of merchantability - and fitness. In no event shall the author be liable for any - special, indirect or consequential damages or any damages - whatsoever resulting from loss of use, data or profits, whether - in an action of contract, negligence or other tortious action, - arising out of or in connection with the use or performance of - this software. -*/ - -#include "report.h" -#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" - -uint8_t keyboard_idle = 0; -uint8_t keyboard_protocol = 1; -static uint8_t keyboard_led_stats = 0; - -static report_keyboard_t keyboard_report_sent; - - -/* Host driver */ -static uint8_t keyboard_leds(void); -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); -host_driver_t lufa_driver = { - keyboard_leds, - send_keyboard, - send_mouse, - send_system, - send_consumer -}; - - -/******************************************************************************* - * 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; - - uint8_t ep = Endpoint_GetCurrentEndpoint(); - -#if 0 - // TODO: impl receivechar()/recvchar() - Endpoint_SelectEndpoint(CONSOLE_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()) - { - /* Create a temporary buffer to hold the read in report from the host */ - uint8_t ConsoleData[CONSOLE_EPSIZE]; - - /* Read Console Report Data */ - Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL); - - /* Process Console Report Data */ - //ProcessConsoleHIDReport(ConsoleData); - } - - /* Finalize the stream transfer to send the last packet */ - Endpoint_ClearOUT(); - } -#endif - - /* 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(); - } - - Endpoint_SelectEndpoint(ep); -} -#else -static void Console_Task(void) -{ -} -#endif - - -/******************************************************************************* - * USB Events - ******************************************************************************/ -/* - * 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) -{ - print("[C]"); - /* For battery powered device */ - if (!USB_IsInitialized) { - USB_Disable(); - USB_Init(); - USB_Device_EnableSOFEvents(); - } -} - -void EVENT_USB_Device_Disconnect(void) -{ - print("[D]"); - /* For battery powered device */ - USB_IsInitialized = false; -/* TODO: This doesn't work. After several plug in/outs can not be enumerated. - if (USB_IsInitialized) { - USB_Disable(); // Disable all interrupts - USB_Controller_Enable(); - USB_INT_Enable(USB_INT_VBUSTI); - } -*/ -} - -void EVENT_USB_Device_Reset(void) -{ - print("[R]"); -} - -void EVENT_USB_Device_Suspend() -{ - print("[S]"); - matrix_power_down(); -#ifdef SLEEP_LED_ENABLE - sleep_led_enable(); -#endif -} - -void EVENT_USB_Device_WakeUp() -{ - print("[W]"); - 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(); -} - -/** Event handler for the USB_ConfigurationChanged event. - * This is fired when the host sets the current configuration of the USB device after enumeration. - */ -void EVENT_USB_Device_ConfigurationChanged(void) -{ - bool ConfigSuccess = true; - - /* Setup Keyboard HID Report Endpoints */ - 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_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_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_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 -} - -/* -Appendix G: HID Request Support Requirements - -The following table enumerates the requests that need to be supported by various types of HID class devices. - -Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol ------------------------------------------------------------------------------------------- -Boot Mouse Required Optional Optional Optional Required Required -Non-Boot Mouse Required Optional Optional Optional Optional Optional -Boot Keyboard Required Optional Required Required Required Required -Non-Boot Keybrd Required Optional Required Required Optional Optional -Other Device Required Optional Optional Optional Optional Optional -*/ -/** Event handler for the USB_ControlRequest event. - * This is fired before passing along unhandled control requests to the library for processing internally. - */ -void EVENT_USB_Device_ControlRequest(void) -{ - uint8_t* ReportData = NULL; - uint8_t ReportSize = 0; - - /* Handle HID Class specific requests */ - switch (USB_ControlRequest.bRequest) - { - case HID_REQ_GetReport: - if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) - { - Endpoint_ClearSETUP(); - - // Interface - switch (USB_ControlRequest.wIndex) { - case KEYBOARD_INTERFACE: - // TODO: test/check - ReportData = (uint8_t*)&keyboard_report_sent; - ReportSize = sizeof(keyboard_report_sent); - break; - } - - /* Write the report data to the control endpoint */ - Endpoint_Write_Control_Stream_LE(ReportData, ReportSize); - Endpoint_ClearOUT(); - } - - break; - case HID_REQ_SetReport: - if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) - { - - // Interface - switch (USB_ControlRequest.wIndex) { - case KEYBOARD_INTERFACE: -#ifdef NKRO_ENABLE - case NKRO_INTERFACE: -#endif - Endpoint_ClearSETUP(); - - while (!(Endpoint_IsOUTReceived())) { - if (USB_DeviceState == DEVICE_STATE_Unattached) - return; - } - keyboard_led_stats = Endpoint_Read_8(); - - Endpoint_ClearOUT(); - Endpoint_ClearStatusStage(); - break; - } - - } - - break; - - case HID_REQ_GetProtocol: - if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) - { - 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)) - { - if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) { - Endpoint_ClearSETUP(); - Endpoint_ClearStatusStage(); - - keyboard_protocol = ((USB_ControlRequest.wValue & 0xFF) != 0x00); -#ifdef NKRO_ENABLE - keyboard_nkro = !!keyboard_protocol; -#endif - clear_keyboard(); - } - } - - break; - case HID_REQ_SetIdle: - if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) - { - Endpoint_ClearSETUP(); - Endpoint_ClearStatusStage(); - - keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8); - } - - break; - case HID_REQ_GetIdle: - if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) - { - Endpoint_ClearSETUP(); - while (!(Endpoint_IsINReady())); - Endpoint_Write_8(keyboard_idle); - Endpoint_ClearIN(); - Endpoint_ClearStatusStage(); - } - - break; - } -} - -/******************************************************************************* - * Host driver - ******************************************************************************/ -static uint8_t keyboard_leds(void) -{ - return keyboard_led_stats; -} - -static void send_keyboard(report_keyboard_t *report) -{ - uint8_t timeout = 255; - - if (USB_DeviceState != DEVICE_STATE_Configured) - return; - - /* Select the Keyboard Report Endpoint */ -#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 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, KEYBOARD_EPSIZE, NULL); - } - - /* 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 = 255; - - if (USB_DeviceState != DEVICE_STATE_Configured) - return; - - /* Select the Mouse Report Endpoint */ - Endpoint_SelectEndpoint(MOUSE_IN_EPNUM); - - /* 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); - - /* Finalize the stream transfer to send the last packet */ - Endpoint_ClearIN(); -#endif -} - -static void send_system(uint16_t data) -{ - 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); - - /* 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 = 255; - - if (USB_DeviceState != DEVICE_STATE_Configured) - return; - - report_extra_t r = { - .report_id = REPORT_ID_CONSUMER, - .usage = data - }; - Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM); - - /* 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(); -} - - -/******************************************************************************* - * sendchar - ******************************************************************************/ -#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; - - uint8_t ep = Endpoint_GetCurrentEndpoint(); - Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM); - if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) { - goto ERROR_EXIT; - } - - if (timeouted && !Endpoint_IsReadWriteAllowed()) { - goto ERROR_EXIT; - } - - timeouted = false; - - uint8_t timeout = SEND_TIMEOUT; - while (!Endpoint_IsReadWriteAllowed()) { - if (USB_DeviceState != DEVICE_STATE_Configured) { - goto ERROR_EXIT; - } - if (Endpoint_IsStalled()) { - goto ERROR_EXIT; - } - if (!(timeout--)) { - timeouted = true; - goto ERROR_EXIT; - } - _delay_ms(1); - } - - Endpoint_Write_8(c); - - // send when bank is full - if (!Endpoint_IsReadWriteAllowed()) - Endpoint_ClearIN(); - - Endpoint_SelectEndpoint(ep); - return 0; -ERROR_EXIT: - Endpoint_SelectEndpoint(ep); - return -1; -} -#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(); - print_set_sendchar(sendchar); -} - -int main(void) __attribute__ ((weak)); -int main(void) -{ - SetupHardware(); - sei(); - - /* 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) { - print("[s]"); - suspend_power_down(); - if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { - USB_Device_SendRemoteWakeup(); - } - } - - keyboard_task(); - -#if !defined(INTERRUPT_CONTROL_ENDPOINT) - USB_USBTask(); -#endif - } -} |