core: Fix suspend/wake for converters #386
authortmk <hasu@tmk-kbd.com>
Wed, 28 Sep 2016 07:57:24 +0000 (16:57 +0900)
committertmk <hasu@tmk-kbd.com>
Tue, 4 Oct 2016 07:02:24 +0000 (16:02 +0900)
tmk_core/common/avr/suspend.c
tmk_core/protocol/lufa/lufa.c

index af99f52b5ee18336f4f332eddf5c37bd9ab5b108..580d69e4f117f9e1ecf1f5bf2428abdf85482063 100644 (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();
index c16fd1775b83cc1c85066da8a53c1a97fc69b8c0..f5fc4cb790935c7678cc17210054c7f341ca4592 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright 2012 Jun Wako <wakojun@gmail.com>
  * This file is based on:
  *     LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse
 #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;
 }
Imprint / Impressum