Browse Source

core: Fix suspend/wake for converters #386

master
tmk 7 years ago
parent
commit
9818d54d26
2 changed files with 63 additions and 11 deletions
  1. 1
    0
      tmk_core/common/avr/suspend.c
  2. 62
    11
      tmk_core/protocol/lufa/lufa.c

+ 1
- 0
tmk_core/common/avr/suspend.c View File

void suspend_wakeup_init(void) void suspend_wakeup_init(void)
{ {
// clear keyboard state // clear keyboard state
matrix_init();
clear_keyboard(); clear_keyboard();
#ifdef BACKLIGHT_ENABLE #ifdef BACKLIGHT_ENABLE
backlight_init(); backlight_init();

+ 62
- 11
tmk_core/protocol/lufa/lufa.c View File

/*
/*
* Copyright 2012 Jun Wako <[email protected]> * Copyright 2012 Jun Wako <[email protected]>
* This file is based on: * This file is based on:
* LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse * LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse
#include "avr/suart.h" #include "avr/suart.h"
#endif #endif


#include "matrix.h"
#include "descriptor.h" #include "descriptor.h"
#include "lufa.h" #include "lufa.h"



//#define LUFA_DEBUG


uint8_t keyboard_idle = 0; uint8_t keyboard_idle = 0;
/* 0: Boot Protocol, 1: Report Protocol(default) */ /* 0: Boot Protocol, 1: Report Protocol(default) */
uint8_t keyboard_protocol = 1; uint8_t keyboard_protocol = 1;
{ {
/* Create a temporary buffer to hold the read in report from the host */ /* Create a temporary buffer to hold the read in report from the host */
uint8_t ConsoleData[CONSOLE_EPSIZE]; uint8_t ConsoleData[CONSOLE_EPSIZE];
/* Read Console Report Data */ /* Read Console Report Data */
Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL); Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
/* Process Console Report Data */ /* Process Console Report Data */
//ProcessConsoleHIDReport(ConsoleData); //ProcessConsoleHIDReport(ConsoleData);
} }
print("[D]"); print("[D]");
/* For battery powered device */ /* For battery powered device */
USB_IsInitialized = false; 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) { if (USB_IsInitialized) {
USB_Disable(); // Disable all interrupts USB_Disable(); // Disable all interrupts
USB_Controller_Enable(); USB_Controller_Enable();


void EVENT_USB_Device_Reset(void) void EVENT_USB_Device_Reset(void)
{ {
#ifdef LUFA_DEBUG
print("[R]"); print("[R]");
#endif
} }


void EVENT_USB_Device_Suspend() void EVENT_USB_Device_Suspend()
{ {
#ifdef LUFA_DEBUG
print("[S]"); print("[S]");
#endif
hook_usb_suspend_entry(); hook_usb_suspend_entry();
} }


void EVENT_USB_Device_WakeUp() void EVENT_USB_Device_WakeUp()
{ {
#ifdef LUFA_DEBUG
print("[W]"); print("[W]");
#endif
hook_usb_wakeup(); hook_usb_wakeup();
} }


*/ */
void EVENT_USB_Device_ConfigurationChanged(void) void EVENT_USB_Device_ConfigurationChanged(void)
{ {
#ifdef LUFA_DEBUG
print("[c]"); print("[c]");
#endif
bool ConfigSuccess = true; bool ConfigSuccess = true;


/* Setup Keyboard HID Report Endpoints */ /* Setup Keyboard HID Report Endpoints */
*/ */
void EVENT_USB_Device_ControlRequest(void) void EVENT_USB_Device_ControlRequest(void)
{ {
print("[r]");
uint8_t* ReportData = NULL; uint8_t* ReportData = NULL;
uint8_t ReportSize = 0; uint8_t ReportSize = 0;


/* Write the report data to the control endpoint */ /* Write the report data to the control endpoint */
Endpoint_Write_Control_Stream_LE(ReportData, ReportSize); Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
Endpoint_ClearOUT(); Endpoint_ClearOUT();
#ifdef LUFA_DEBUG
xprintf("[r%d]", USB_ControlRequest.wIndex);
#endif
} }


break; break;


Endpoint_ClearOUT(); Endpoint_ClearOUT();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
#ifdef LUFA_DEBUG
xprintf("[L%d]", USB_ControlRequest.wIndex);
#endif
break; break;
} }


Endpoint_Write_8(keyboard_protocol); Endpoint_Write_8(keyboard_protocol);
Endpoint_ClearIN(); Endpoint_ClearIN();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
#ifdef LUFA_DEBUG
print("[p]");
#endif
} }
} }




keyboard_protocol = (USB_ControlRequest.wValue & 0xFF); keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
clear_keyboard(); clear_keyboard();
#ifdef LUFA_DEBUG
print("[P]");
#endif
} }
} }


Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();


keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8); keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
#ifdef LUFA_DEBUG
xprintf("[I%d]%d", USB_ControlRequest.wIndex, (USB_ControlRequest.wValue & 0xFF00) >> 8);
#endif
} }


break; break;
Endpoint_Write_8(keyboard_idle); Endpoint_Write_8(keyboard_idle);
Endpoint_ClearIN(); Endpoint_ClearIN();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
#ifdef LUFA_DEBUG
print("[i]");
#endif
} }


break; break;
} }


/******************************************************************************* /*******************************************************************************
* Host driver
* Host driver
******************************************************************************/ ******************************************************************************/
static uint8_t keyboard_leds(void) static uint8_t keyboard_leds(void)
{ {
int main(void) __attribute__ ((weak)); int main(void) __attribute__ ((weak));
int main(void) int main(void)
{ {
setup_mcu();

#ifdef LUFA_DEBUG_SUART #ifdef LUFA_DEBUG_SUART
DDRD |= (1<<SUART_OUT_BIT);
SUART_OUT_DDR |= (1<<SUART_OUT_BIT);
SUART_OUT_PORT |= (1<<SUART_OUT_BIT);
#endif #endif
print_set_sendchar(sendchar); print_set_sendchar(sendchar);
setup_mcu();
print("\r\ninit\n");

hook_early_init(); hook_early_init();
keyboard_setup(); keyboard_setup();
setup_usb(); setup_usb();
hook_late_init(); hook_late_init();
while (1) { while (1) {
while (USB_DeviceState == DEVICE_STATE_Suspended) { while (USB_DeviceState == DEVICE_STATE_Suspended) {
#ifdef LUFA_DEBUG
print("[s]"); print("[s]");
#endif
hook_usb_suspend_loop(); hook_usb_suspend_loop();
} }


__attribute__((weak)) __attribute__((weak))
void hook_late_init(void) {} void hook_late_init(void) {}


static uint8_t _led_stats = 0;
__attribute__((weak)) __attribute__((weak))
void hook_usb_suspend_entry(void) 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 #ifdef SLEEP_LED_ENABLE
sleep_led_enable(); sleep_led_enable();
#endif #endif
{ {
suspend_power_down(); suspend_power_down();
if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
USB_Device_SendRemoteWakeup();
USB_Device_SendRemoteWakeup();
} }
} }


suspend_wakeup_init(); suspend_wakeup_init();
#ifdef SLEEP_LED_ENABLE #ifdef SLEEP_LED_ENABLE
sleep_led_disable(); sleep_led_disable();
// NOTE: converters may not accept this
led_set(host_keyboard_leds());
#endif #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;
} }

Loading…
Cancel
Save