1
0

core: Fix suspend/wake for converters #386

This commit is contained in:
tmk 2016-09-28 16:57:24 +09:00
parent 435a1d3341
commit 9818d54d26
2 changed files with 63 additions and 11 deletions

View File

@ -102,6 +102,7 @@ bool suspend_wakeup_condition(void)
void suspend_wakeup_init(void)
{
// clear keyboard state
matrix_init();
clear_keyboard();
#ifdef BACKLIGHT_ENABLE
backlight_init();

View File

@ -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;
@ -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;
@ -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;
}