|
|
@@ -1,4 +1,4 @@ |
|
|
|
/* |
|
|
|
/* |
|
|
|
* Copyright 2012 Jun Wako <[email protected]> |
|
|
|
* This file is based on: |
|
|
|
* LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse |
|
|
@@ -54,9 +54,14 @@ |
|
|
|
#include "avr/suart.h" |
|
|
|
#endif |
|
|
|
|
|
|
|
#include "matrix.h" |
|
|
|
#include "descriptor.h" |
|
|
|
#include "lufa.h" |
|
|
|
|
|
|
|
|
|
|
|
//#define LUFA_DEBUG |
|
|
|
|
|
|
|
|
|
|
|
uint8_t keyboard_idle = 0; |
|
|
|
/* 0: Boot Protocol, 1: Report Protocol(default) */ |
|
|
|
uint8_t keyboard_protocol = 1; |
|
|
@@ -104,10 +109,10 @@ static void Console_Task(void) |
|
|
|
{ |
|
|
|
/* 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); |
|
|
|
} |
|
|
@@ -168,7 +173,7 @@ 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. |
|
|
|
/* 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(); |
|
|
@@ -179,18 +184,24 @@ void EVENT_USB_Device_Disconnect(void) |
|
|
|
|
|
|
|
void EVENT_USB_Device_Reset(void) |
|
|
|
{ |
|
|
|
#ifdef LUFA_DEBUG |
|
|
|
print("[R]"); |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
void EVENT_USB_Device_Suspend() |
|
|
|
{ |
|
|
|
#ifdef LUFA_DEBUG |
|
|
|
print("[S]"); |
|
|
|
#endif |
|
|
|
hook_usb_suspend_entry(); |
|
|
|
} |
|
|
|
|
|
|
|
void EVENT_USB_Device_WakeUp() |
|
|
|
{ |
|
|
|
#ifdef LUFA_DEBUG |
|
|
|
print("[W]"); |
|
|
|
#endif |
|
|
|
hook_usb_wakeup(); |
|
|
|
} |
|
|
|
|
|
|
@@ -221,7 +232,9 @@ void EVENT_USB_Device_StartOfFrame(void) |
|
|
|
*/ |
|
|
|
void EVENT_USB_Device_ConfigurationChanged(void) |
|
|
|
{ |
|
|
|
#ifdef LUFA_DEBUG |
|
|
|
print("[c]"); |
|
|
|
#endif |
|
|
|
bool ConfigSuccess = true; |
|
|
|
|
|
|
|
/* Setup Keyboard HID Report Endpoints */ |
|
|
@@ -275,7 +288,6 @@ Other Device Required Optional Optional Optional Optional Opti |
|
|
|
*/ |
|
|
|
void EVENT_USB_Device_ControlRequest(void) |
|
|
|
{ |
|
|
|
print("[r]"); |
|
|
|
uint8_t* ReportData = NULL; |
|
|
|
uint8_t ReportSize = 0; |
|
|
|
|
|
|
@@ -299,6 +311,9 @@ void EVENT_USB_Device_ControlRequest(void) |
|
|
|
/* Write the report data to the control endpoint */ |
|
|
|
Endpoint_Write_Control_Stream_LE(ReportData, ReportSize); |
|
|
|
Endpoint_ClearOUT(); |
|
|
|
#ifdef LUFA_DEBUG |
|
|
|
xprintf("[r%d]", USB_ControlRequest.wIndex); |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
@@ -322,6 +337,9 @@ void EVENT_USB_Device_ControlRequest(void) |
|
|
|
|
|
|
|
Endpoint_ClearOUT(); |
|
|
|
Endpoint_ClearStatusStage(); |
|
|
|
#ifdef LUFA_DEBUG |
|
|
|
xprintf("[L%d]", USB_ControlRequest.wIndex); |
|
|
|
#endif |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
@@ -338,6 +356,9 @@ void EVENT_USB_Device_ControlRequest(void) |
|
|
|
Endpoint_Write_8(keyboard_protocol); |
|
|
|
Endpoint_ClearIN(); |
|
|
|
Endpoint_ClearStatusStage(); |
|
|
|
#ifdef LUFA_DEBUG |
|
|
|
print("[p]"); |
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -351,6 +372,9 @@ void EVENT_USB_Device_ControlRequest(void) |
|
|
|
|
|
|
|
keyboard_protocol = (USB_ControlRequest.wValue & 0xFF); |
|
|
|
clear_keyboard(); |
|
|
|
#ifdef LUFA_DEBUG |
|
|
|
print("[P]"); |
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -362,6 +386,9 @@ void EVENT_USB_Device_ControlRequest(void) |
|
|
|
Endpoint_ClearStatusStage(); |
|
|
|
|
|
|
|
keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8); |
|
|
|
#ifdef LUFA_DEBUG |
|
|
|
xprintf("[I%d]%d", USB_ControlRequest.wIndex, (USB_ControlRequest.wValue & 0xFF00) >> 8); |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
@@ -373,6 +400,9 @@ void EVENT_USB_Device_ControlRequest(void) |
|
|
|
Endpoint_Write_8(keyboard_idle); |
|
|
|
Endpoint_ClearIN(); |
|
|
|
Endpoint_ClearStatusStage(); |
|
|
|
#ifdef LUFA_DEBUG |
|
|
|
print("[i]"); |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
@@ -380,7 +410,7 @@ void EVENT_USB_Device_ControlRequest(void) |
|
|
|
} |
|
|
|
|
|
|
|
/******************************************************************************* |
|
|
|
* Host driver |
|
|
|
* Host driver |
|
|
|
******************************************************************************/ |
|
|
|
static uint8_t keyboard_leds(void) |
|
|
|
{ |
|
|
@@ -595,11 +625,15 @@ static void setup_usb(void) |
|
|
|
int main(void) __attribute__ ((weak)); |
|
|
|
int main(void) |
|
|
|
{ |
|
|
|
setup_mcu(); |
|
|
|
|
|
|
|
#ifdef LUFA_DEBUG_SUART |
|
|
|
DDRD |= (1<<SUART_OUT_BIT); |
|
|
|
SUART_OUT_DDR |= (1<<SUART_OUT_BIT); |
|
|
|
SUART_OUT_PORT |= (1<<SUART_OUT_BIT); |
|
|
|
#endif |
|
|
|
print_set_sendchar(sendchar); |
|
|
|
setup_mcu(); |
|
|
|
print("\r\ninit\n"); |
|
|
|
|
|
|
|
hook_early_init(); |
|
|
|
keyboard_setup(); |
|
|
|
setup_usb(); |
|
|
@@ -626,7 +660,9 @@ int main(void) |
|
|
|
hook_late_init(); |
|
|
|
while (1) { |
|
|
|
while (USB_DeviceState == DEVICE_STATE_Suspended) { |
|
|
|
#ifdef LUFA_DEBUG |
|
|
|
print("[s]"); |
|
|
|
#endif |
|
|
|
hook_usb_suspend_loop(); |
|
|
|
} |
|
|
|
|
|
|
@@ -646,9 +682,19 @@ void hook_early_init(void) {} |
|
|
|
__attribute__((weak)) |
|
|
|
void hook_late_init(void) {} |
|
|
|
|
|
|
|
static uint8_t _led_stats = 0; |
|
|
|
__attribute__((weak)) |
|
|
|
void hook_usb_suspend_entry(void) |
|
|
|
{ |
|
|
|
// Turn LED off to save power |
|
|
|
// Set 0 with putting aside status before suspend and restore |
|
|
|
// it after wakeup, then LED is updated at keyboard_task() in main loop |
|
|
|
_led_stats = keyboard_led_stats; |
|
|
|
keyboard_led_stats = 0; |
|
|
|
led_set(keyboard_led_stats); |
|
|
|
|
|
|
|
matrix_init(); |
|
|
|
clear_keyboard(); |
|
|
|
#ifdef SLEEP_LED_ENABLE |
|
|
|
sleep_led_enable(); |
|
|
|
#endif |
|
|
@@ -659,7 +705,7 @@ void hook_usb_suspend_loop(void) |
|
|
|
{ |
|
|
|
suspend_power_down(); |
|
|
|
if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { |
|
|
|
USB_Device_SendRemoteWakeup(); |
|
|
|
USB_Device_SendRemoteWakeup(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -669,7 +715,12 @@ void hook_usb_wakeup(void) |
|
|
|
suspend_wakeup_init(); |
|
|
|
#ifdef SLEEP_LED_ENABLE |
|
|
|
sleep_led_disable(); |
|
|
|
// NOTE: converters may not accept this |
|
|
|
led_set(host_keyboard_leds()); |
|
|
|
#endif |
|
|
|
|
|
|
|
// Restore LED status |
|
|
|
// BIOS/grub won't recognize/enumerate if led_set() takes long(around 40ms?) |
|
|
|
// Converters fall into the case and miss wakeup event(timeout to reply?) in the end. |
|
|
|
//led_set(host_keyboard_leds()); |
|
|
|
// Instead, restore stats and update at keyboard_task() in main loop |
|
|
|
keyboard_led_stats = _led_stats; |
|
|
|
} |