From a112f3614e0e3204ce35dcdfbf2723c3382c4c35 Mon Sep 17 00:00:00 2001
From: tmk <nobody@nowhere>
Date: Fri, 29 Jun 2012 16:48:36 +0900
Subject: [PATCH] confirm SetReport LED.

---
 common/command.c           |   1 +
 common/host.c              |   5 +-
 keyboard/macway/keymap.c   |   2 +-
 protocol/lufa/descriptor.h |   7 +++
 protocol/lufa/lufa.c       | 122 +++++++++++++++++++------------------
 protocol/lufa/lufa.h       |  15 ++++-
 6 files changed, 91 insertions(+), 61 deletions(-)

diff --git a/common/command.c b/common/command.c
index e325a5d847..13d37242d9 100644
--- a/common/command.c
+++ b/common/command.c
@@ -138,6 +138,7 @@ static uint8_t command_common(void)
             }
             break;
         case KB_S:
+            print("host_keyboard_leds:"); phex(host_keyboard_leds()); print("\n");
 #ifdef HOST_PJRC
             print("UDCON: "); phex(UDCON); print("\n");
             print("UDIEN: "); phex(UDIEN); print("\n");
diff --git a/common/host.c b/common/host.c
index cc26d55c22..8dd2abbee8 100644
--- a/common/host.c
+++ b/common/host.c
@@ -168,13 +168,16 @@ void host_mouse_send(report_mouse_t *report)
 
 void host_system_send(uint16_t data)
 {
+    static uint16_t last_data = 0;
+    if (data == last_data) return;
+    last_data = data;
+
     if (!driver) return;
     (*driver->send_system)(data);
 }
 
 void host_consumer_send(uint16_t data)
 {
-    // TODO: this is needed?
     static uint16_t last_data = 0;
     if (data == last_data) return;
     last_data = data;
diff --git a/keyboard/macway/keymap.c b/keyboard/macway/keymap.c
index 5ecea2569f..76c0d8b724 100644
--- a/keyboard/macway/keymap.c
+++ b/keyboard/macway/keymap.c
@@ -111,7 +111,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
      * `-----------------------------------------------------------'
      */ 
     KEYMAP(PWR, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, DEL, \
-           CAPS,NO,  NO,  NO,  NO,  NO,  NO,  NO,  PSCR,SLCK,BRK, UP,  NO,  NO,  \
+           CAPS,NO,  NO,  NO,  NO,  NO,  NO,  NO,  PSCR,SLCK,BRK, UP,  NO,  NLCK,\
            LCTL,VOLD,VOLU,MUTE,NO,  NO,  PAST,PSLS,HOME,PGUP,LEFT,RGHT,ENT, \
            LSFT,NO,  NO,  NO,  NO,  NO,  PPLS,PMNS,END, PGDN,DOWN,RSFT,FN1, \
            NO,  LGUI,LALT,SPC, RALT,NO,  NO,  NO,  RCTL),
diff --git a/protocol/lufa/descriptor.h b/protocol/lufa/descriptor.h
index 19bce999f2..001e072e6a 100644
--- a/protocol/lufa/descriptor.h
+++ b/protocol/lufa/descriptor.h
@@ -1,3 +1,10 @@
+/* 
+ * Copyright 2012 Jun Wako <wakojun@gmail.com>
+ * This file is based on:
+ *     LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse
+ *     LUFA-120219/Demos/Device/Lowlevel/GenericHID
+ */
+
 /*
              LUFA Library
      Copyright (C) Dean Camera, 2012.
diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c
index f485e24bf0..8fa719bc95 100644
--- a/protocol/lufa/lufa.c
+++ b/protocol/lufa/lufa.c
@@ -46,13 +46,12 @@
 #include "descriptor.h"
 #include "lufa.h"
 
+static uint8_t idle_duration = 0;
+static uint8_t protocol_report = 1;
 static uint8_t keyboard_led_stats = 0;
 
-// TODO: impl Control Request GET_REPORT
 static report_keyboard_t keyboard_report_sent;
-#ifdef MOUSE_ENABLE
-static report_mouse_t mouse_report_sent;
-#endif
+
 
 /* Host driver */
 static uint8_t keyboard_leds(void);
@@ -83,12 +82,8 @@ int main(void)
     debug_keyboard = true;
     debug_mouse = true;
 
-/* TODO: can't print here
-    _delay_ms(5000);
-    USB_USBTask();
-    print("abcdefg\n");
-    USB_USBTask();
-*/
+    // TODO: can't print here
+    debug("LUFA init\n");
 
     keyboard_init();
     host_set_driver(&lufa_driver);
@@ -228,19 +223,6 @@ void EVENT_USB_Device_ControlRequest(void)
                     ReportData = (uint8_t*)&keyboard_report_sent;
                     ReportSize = sizeof(keyboard_report_sent);
                     break;
-#ifdef MOUSE_ENABLE
-                case MOUSE_INTERFACE:
-                    // TODO: test/check
-                    ReportData = (uint8_t*)&mouse_report_sent;
-                    ReportSize = sizeof(mouse_report_sent);
-                    break;
-#endif
-#ifdef EXTRAKEY_ENABLE
-                case EXTRA_INTERFACE:
-                    break;
-#endif
-                case CONSOLE_INTERFACE:
-                    break;
                 }
 
                 /* Write the report data to the control endpoint */
@@ -252,35 +234,65 @@ void EVENT_USB_Device_ControlRequest(void)
         case HID_REQ_SetReport:
             if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
             {
-                Endpoint_ClearSETUP();
-
-                /* Wait until the LED report has been sent by the host */
-                while (!(Endpoint_IsOUTReceived()))
-                {
-                    if (USB_DeviceState == DEVICE_STATE_Unattached)
-                      return;
-                }
 
                 // Interface
                 switch (USB_ControlRequest.wIndex) {
                 case KEYBOARD_INTERFACE:
-                    // TODO: test/check
-                    /* Read in the LED report from the host */
+                    Endpoint_ClearSETUP();
+
+                    while (!(Endpoint_IsOUTReceived())) {
+                        if (USB_DeviceState == DEVICE_STATE_Unattached)
+                          return;
+                    }
                     keyboard_led_stats = Endpoint_Read_8();
-                    break;
-#ifdef MOUSE_ENABLE
-                case MOUSE_INTERFACE:
-                    break;
-#endif
-#ifdef EXTRAKEY_ENABLE
-                case EXTRA_INTERFACE:
-                    break;
-#endif
-                case CONSOLE_INTERFACE:
+
+                    Endpoint_ClearOUT();
+                    Endpoint_ClearStatusStage();
                     break;
                 }
 
-                Endpoint_ClearOUT();
+            }
+
+            break;
+
+        case HID_REQ_GetProtocol:
+            if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+            {
+                Endpoint_ClearSETUP();
+                while (!(Endpoint_IsINReady()));
+                Endpoint_Write_8(protocol_report);
+                Endpoint_ClearIN();
+                Endpoint_ClearStatusStage();
+            }
+
+            break;
+        case HID_REQ_SetProtocol:
+            if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+            {
+                Endpoint_ClearSETUP();
+                Endpoint_ClearStatusStage();
+
+                protocol_report = ((USB_ControlRequest.wValue & 0xFF) != 0x00);
+            }
+
+            break;
+        case HID_REQ_SetIdle:
+            if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+            {
+                Endpoint_ClearSETUP();
+                Endpoint_ClearStatusStage();
+
+                idle_duration = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
+            }
+
+            break;
+        case HID_REQ_GetIdle:
+            if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+            {
+                Endpoint_ClearSETUP();
+                while (!(Endpoint_IsINReady()));
+                Endpoint_Write_8(idle_duration);
+                Endpoint_ClearIN();
                 Endpoint_ClearStatusStage();
             }
 
@@ -329,23 +341,17 @@ static void send_mouse(report_mouse_t *report)
         /* Finalize the stream transfer to send the last packet */
         Endpoint_ClearIN();
     }
-    mouse_report_sent = *report;
 #endif
 }
 
-typedef struct {
-    uint8_t  report_id;
-    uint16_t usage;
-} __attribute__ ((packed)) report_extra_t;
-
 static void send_system(uint16_t data)
 {
+    report_extra_t r = {
+        .report_id = REPORT_ID_SYSTEM,
+        .usage = data
+    };
     Endpoint_SelectEndpoint(EXTRA_IN_EPNUM);
     if (Endpoint_IsReadWriteAllowed()) {
-        report_extra_t r = {
-            .report_id = REPORT_ID_SYSTEM,
-            .usage = data
-        };
         Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
         Endpoint_ClearIN();
     }
@@ -353,12 +359,12 @@ static void send_system(uint16_t data)
 
 static void send_consumer(uint16_t data)
 {
+    report_extra_t r = {
+        .report_id = REPORT_ID_CONSUMER,
+        .usage = data
+    };
     Endpoint_SelectEndpoint(EXTRA_IN_EPNUM);
     if (Endpoint_IsReadWriteAllowed()) {
-        report_extra_t r = {
-            .report_id = REPORT_ID_CONSUMER,
-            .usage = data
-        };
         Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
         Endpoint_ClearIN();
     }
diff --git a/protocol/lufa/lufa.h b/protocol/lufa/lufa.h
index efb8c38378..71c279b0dc 100644
--- a/protocol/lufa/lufa.h
+++ b/protocol/lufa/lufa.h
@@ -1,3 +1,10 @@
+/* 
+ * Copyright 2012 Jun Wako <wakojun@gmail.com>
+ * This file is based on:
+ *     LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse
+ *     LUFA-120219/Demos/Device/Lowlevel/GenericHID
+ */
+
 /*
              LUFA Library
      Copyright (C) Dean Camera, 2012.
@@ -32,7 +39,6 @@
 #ifndef _LUFA_H_
 #define _LUFA_H_
 
-	/* Includes: */
 #include <avr/io.h>
 #include <avr/wdt.h>
 #include <avr/power.h>
@@ -42,4 +48,11 @@
 #include <LUFA/Version.h>
 #include <LUFA/Drivers/USB/USB.h>
 
+
+/* extra report structure */
+typedef struct {
+    uint8_t  report_id;
+    uint16_t usage;
+} __attribute__ ((packed)) report_extra_t;
+
 #endif