]> git.donarmstrong.com Git - tmk_firmware.git/blobdiff - protocol/pjrc/usb.c
Fix remotewakeup of PJRC stack(Fix #121)
[tmk_firmware.git] / protocol / pjrc / usb.c
index 89087218f3c719e7c296dd799811805a4c14a127..1e6ba8719a2a124ef687e63916bc30dd037df120 100644 (file)
 #include "usb_mouse.h"
 #include "usb_debug.h"
 #include "usb_extra.h"
+#include "led.h"
 #include "print.h"
 #include "util.h"
+#ifdef SLEEP_LED_ENABLE
+#include "sleep_led.h"
+#endif
+#include "suspend.h"
+#include "action.h"
+#include "action_util.h"
 
 
 /**************************************************************************
@@ -100,7 +107,11 @@ static const uint8_t PROGMEM endpoint_config_table[] = {
 #else
         0,                                                                  // 2
 #endif
+#ifdef CONSOLE_ENABLE
        1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER, // 3
+#else
+        0,
+#endif
 #ifdef EXTRAKEY_ENABLE
        1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(EXTRA_SIZE)    | EXTRA_BUFFER,    // 4
 #else
@@ -128,7 +139,7 @@ static const uint8_t PROGMEM endpoint_config_table[] = {
 // spec and relevant portions of any USB class specifications!
 
 
-static uint8_t PROGMEM device_descriptor[] = {
+static const uint8_t PROGMEM device_descriptor[] = {
        18,                                     // bLength
        1,                                      // bDescriptorType
        0x00, 0x02,                             // bcdUSB
@@ -146,7 +157,7 @@ static uint8_t PROGMEM device_descriptor[] = {
 };
 
 // Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60
-static uint8_t PROGMEM keyboard_hid_report_desc[] = {
+static const uint8_t PROGMEM keyboard_hid_report_desc[] = {
         0x05, 0x01,          // Usage Page (Generic Desktop),
         0x09, 0x06,          // Usage (Keyboard),
         0xA1, 0x01,          // Collection (Application),
@@ -181,7 +192,7 @@ static uint8_t PROGMEM keyboard_hid_report_desc[] = {
         0xc0                 // End Collection
 };
 #ifdef NKRO_ENABLE
-static uint8_t PROGMEM keyboard2_hid_report_desc[] = {
+static const uint8_t PROGMEM keyboard2_hid_report_desc[] = {
         0x05, 0x01,                     // Usage Page (Generic Desktop),
         0x09, 0x06,                     // Usage (Keyboard),
         0xA1, 0x01,                     // Collection (Application),
@@ -222,7 +233,7 @@ static uint8_t PROGMEM keyboard2_hid_report_desc[] = {
 // http://www.microchip.com/forums/tm.aspx?high=&m=391435&mpage=1#391521
 // http://www.keil.com/forum/15671/
 // http://www.microsoft.com/whdc/device/input/wheel.mspx
-static uint8_t PROGMEM mouse_hid_report_desc[] = {
+static const uint8_t PROGMEM mouse_hid_report_desc[] = {
     /* mouse */
     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
     0x09, 0x02,                    // USAGE (Mouse)
@@ -273,7 +284,7 @@ static uint8_t PROGMEM mouse_hid_report_desc[] = {
 };
 #endif
 
-static uint8_t PROGMEM debug_hid_report_desc[] = {
+static const uint8_t PROGMEM debug_hid_report_desc[] = {
        0x06, 0x31, 0xFF,                       // Usage Page 0xFF31 (vendor defined)
        0x09, 0x74,                             // Usage 0x74
        0xA1, 0x53,                             // Collection 0x53
@@ -289,7 +300,7 @@ static uint8_t PROGMEM debug_hid_report_desc[] = {
 #ifdef EXTRAKEY_ENABLE
 // audio controls & system controls
 // http://www.microsoft.com/whdc/archive/w2kbd.mspx
-static uint8_t PROGMEM extra_hid_report_desc[] = {
+static const uint8_t PROGMEM extra_hid_report_desc[] = {
     /* system control */
     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
     0x09, 0x80,                    // USAGE (System Control)
@@ -329,8 +340,12 @@ static uint8_t PROGMEM extra_hid_report_desc[] = {
 #   define MOUSE_HID_DESC_NUM           (KBD_HID_DESC_NUM + 0)
 #endif
 
+#ifdef CONSOLE_ENABLE
 #define DEBUG_HID_DESC_NUM              (MOUSE_HID_DESC_NUM + 1)
 #define DEBUG_HID_DESC_OFFSET           (9+(9+9+7)*DEBUG_HID_DESC_NUM+9)
+#else
+#   define DEBUG_HID_DESC_NUM           (MOUSE_HID_DESC_NUM + 0)
+#endif
 
 #ifdef EXTRAKEY_ENABLE
 #   define EXTRA_HID_DESC_NUM           (DEBUG_HID_DESC_NUM + 1)
@@ -348,7 +363,7 @@ static uint8_t PROGMEM extra_hid_report_desc[] = {
 
 #define NUM_INTERFACES                  (KBD2_HID_DESC_NUM + 1)
 #define CONFIG1_DESC_SIZE               (9+(9+9+7)*NUM_INTERFACES)
-static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
+static const uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
        // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
        9,                                      // bLength;
        2,                                      // bDescriptorType;
@@ -421,6 +436,7 @@ static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
        1,                                      // bInterval
 #endif
 
+#ifdef CONSOLE_ENABLE
        // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
        9,                                      // bLength
        4,                                      // bDescriptorType
@@ -447,6 +463,7 @@ static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
        0x03,                                   // bmAttributes (0x03=intr)
        DEBUG_TX_SIZE, 0,                       // wMaxPacketSize
        1,                                      // bInterval
+#endif
 
 #ifdef EXTRAKEY_ENABLE
        // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
@@ -515,17 +532,17 @@ struct usb_string_descriptor_struct {
        uint8_t bDescriptorType;
        int16_t wString[];
 };
-static struct usb_string_descriptor_struct PROGMEM string0 = {
+static const struct usb_string_descriptor_struct PROGMEM string0 = {
        4,
        3,
        {0x0409}
 };
-static struct usb_string_descriptor_struct PROGMEM string1 = {
+static const struct usb_string_descriptor_struct PROGMEM string1 = {
        sizeof(STR_MANUFACTURER),
        3,
        STR_MANUFACTURER
 };
-static struct usb_string_descriptor_struct PROGMEM string2 = {
+static const struct usb_string_descriptor_struct PROGMEM string2 = {
        sizeof(STR_PRODUCT),
        3,
        STR_PRODUCT
@@ -533,7 +550,7 @@ static struct usb_string_descriptor_struct PROGMEM string2 = {
 
 // This table defines which descriptor data is sent for each specific
 // request from the host (in wValue and wIndex).
-static struct descriptor_list_struct {
+static const struct descriptor_list_struct {
        uint16_t        wValue;     // descriptor type
        uint16_t        wIndex;
        const uint8_t   *addr;
@@ -550,8 +567,10 @@ static struct descriptor_list_struct {
        {0x2100, MOUSE_INTERFACE, config1_descriptor+MOUSE_HID_DESC_OFFSET, 9},
        {0x2200, MOUSE_INTERFACE, mouse_hid_report_desc, sizeof(mouse_hid_report_desc)},
 #endif
+#ifdef CONSOLE_ENABLE
        {0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9},
        {0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)},
+#endif
 #ifdef EXTRAKEY_ENABLE
        {0x2100, EXTRA_INTERFACE, config1_descriptor+EXTRA_HID_DESC_OFFSET, 9},
        {0x2200, EXTRA_INTERFACE, extra_hid_report_desc, sizeof(extra_hid_report_desc)},
@@ -595,7 +614,8 @@ void usb_init(void)
         USB_CONFIG();                          // start USB clock
         UDCON = 0;                             // enable attach resistor
        usb_configuration = 0;
-        UDIEN = (1<<EORSTE)|(1<<SOFE)|(1<<SUSPE);
+        suspend = false;
+        UDIEN = (1<<EORSTE)|(1<<SOFE)|(1<<SUSPE)|(1<<WAKEUPE);
        sei();
 }
 
@@ -609,6 +629,7 @@ uint8_t usb_configured(void)
 void usb_remote_wakeup(void)
 {
     UDCON |= (1<<RMWKUP);
+    while (UDCON & (1<<RMWKUP));
 }
 
 
@@ -631,9 +652,24 @@ ISR(USB_GEN_vect)
 
         intbits = UDINT;
         UDINT = 0;
-        if (intbits & (1<<SUSPI)) {
+        if ((intbits & (1<<SUSPI)) && (UDIEN & (1<<SUSPE)) && usb_configuration) {
+#ifdef SLEEP_LED_ENABLE
+            sleep_led_enable();
+#endif
+            UDIEN &= ~(1<<SUSPE);
+            UDIEN |= (1<<WAKEUPE);
             suspend = true;
-        } else {
+        }
+        if ((intbits & (1<<WAKEUPI)) && (UDIEN & (1<<WAKEUPE)) && usb_configuration) {
+            suspend_wakeup_init();
+#ifdef SLEEP_LED_ENABLE
+            sleep_led_disable();
+            // NOTE: converters may not accept this
+            led_set(host_keyboard_leds());
+#endif
+
+            UDIEN |= (1<<SUSPE);
+            UDIEN &= ~(1<<WAKEUPE);
             suspend = false;
         }
         if (intbits & (1<<EORSTI)) {
@@ -658,20 +694,20 @@ ISR(USB_GEN_vect)
                }
                 /* TODO: should keep IDLE rate on each keyboard interface */
 #ifdef NKRO_ENABLE
-               if (!keyboard_nkro && usb_keyboard_idle_config && (++div4 & 3) == 0) {
+               if (!keyboard_nkro && keyboard_idle && (++div4 & 3) == 0) {
 #else
-               if (usb_keyboard_idle_config && (++div4 & 3) == 0) {
+               if (keyboard_idle && (++div4 & 3) == 0) {
 #endif
                        UENUM = KBD_ENDPOINT;
                        if (UEINTX & (1<<RWAL)) {
                                usb_keyboard_idle_count++;
-                               if (usb_keyboard_idle_count == usb_keyboard_idle_config) {
+                               if (usb_keyboard_idle_count == keyboard_idle) {
                                        usb_keyboard_idle_count = 0;
                                         /* TODO: fix keyboard_report inconsistency */
 /* To avoid Mac SET_IDLE behaviour.
                                        UEDATX = keyboard_report_prev->mods;
                                        UEDATX = 0;
-                                        uint8_t keys = usb_keyboard_protocol ? KBD_REPORT_KEYS : 6;
+                                        uint8_t keys = keyboard_protocol ? KBD_REPORT_KEYS : 6;
                                        for (uint8_t i=0; i<keys; i++) {
                                                UEDATX = keyboard_report_prev->keys[i];
                                        }
@@ -867,13 +903,13 @@ ISR(USB_COM_vect)
                                }
                                if (bRequest == HID_GET_IDLE) {
                                        usb_wait_in_ready();
-                                       UEDATX = usb_keyboard_idle_config;
+                                       UEDATX = keyboard_idle;
                                        usb_send_in();
                                        return;
                                }
                                if (bRequest == HID_GET_PROTOCOL) {
                                        usb_wait_in_ready();
-                                       UEDATX = usb_keyboard_protocol;
+                                       UEDATX = keyboard_protocol;
                                        usb_send_in();
                                        return;
                                }
@@ -887,14 +923,18 @@ ISR(USB_COM_vect)
                                        return;
                                }
                                if (bRequest == HID_SET_IDLE) {
-                                       usb_keyboard_idle_config = (wValue >> 8);
+                                       keyboard_idle = (wValue >> 8);
                                        usb_keyboard_idle_count = 0;
                                        //usb_wait_in_ready();
                                        usb_send_in();
                                        return;
                                }
                                if (bRequest == HID_SET_PROTOCOL) {
-                                       usb_keyboard_protocol = wValue;
+                                       keyboard_protocol = wValue;
+#ifdef NKRO_ENABLE
+                                        keyboard_nkro = !!keyboard_protocol;
+#endif
+                                        clear_keyboard();
                                        //usb_wait_in_ready();
                                        usb_send_in();
                                        return;