Fix HID class device driver -- if a SetIDle request is issued with the LSB of wValue...
authorDean Camera <dean@fourwalledcubicle.com>
Wed, 15 Jul 2009 05:49:19 +0000 (05:49 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Wed, 15 Jul 2009 05:49:19 +0000 (05:49 +0000)
Fix Keyboard and Mouse demos, Idle period is now multiplied by 4 as the period is read into and sent out of the device to ensure it is always stored as a multiple of 1ms. Fixes Keyboard demo using an initial Idle period of 2s rather than 500ms (thanks to Brian Dickman).

Move out the internal device serial descriptor reading routine into a seperate static function, rather than being part of USB_Device_GetDescriptor.

Demos/Device/LowLevel/Keyboard/Keyboard.c
Demos/Device/LowLevel/Mouse/Mouse.c
LUFA/Drivers/USB/Class/Device/HID.c
LUFA/Drivers/USB/LowLevel/DevChapter9.c
LUFA/Drivers/USB/LowLevel/DevChapter9.h
LUFA/ManPages/ChangeLog.txt

index 185d968..2527148 100644 (file)
@@ -225,8 +225,8 @@ void EVENT_USB_UnhandledControlPacket(void)
                        {\r
                                Endpoint_ClearSETUP();\r
                                \r
                        {\r
                                Endpoint_ClearSETUP();\r
                                \r
-                               /* Get idle period in MSB */\r
-                               IdleCount = (USB_ControlRequest.wValue >> 8);\r
+                               /* Get idle period in MSB, IdleCount must be multiplied by 4 to get number of milliseconds */\r
+                               IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6);\r
                                \r
                                /* Acknowledge status stage */\r
                                while (!(Endpoint_IsINReady()));\r
                                \r
                                /* Acknowledge status stage */\r
                                while (!(Endpoint_IsINReady()));\r
@@ -239,8 +239,8 @@ void EVENT_USB_UnhandledControlPacket(void)
                        {               \r
                                Endpoint_ClearSETUP();\r
                                \r
                        {               \r
                                Endpoint_ClearSETUP();\r
                                \r
-                               /* Write the current idle duration to the host */\r
-                               Endpoint_Write_Byte(IdleCount);\r
+                               /* Write the current idle duration to the host, must be divided by 4 before sent to host */\r
+                               Endpoint_Write_Byte(IdleCount >> 2);\r
                                \r
                                /* Send the flag to the host */\r
                                Endpoint_ClearIN();\r
                                \r
                                /* Send the flag to the host */\r
                                Endpoint_ClearIN();\r
@@ -329,8 +329,8 @@ void SendNextReport(void)
        /* Check if the idle period is set and has elapsed */\r
        if ((IdleCount != HID_IDLE_CHANGESONLY) && (!(IdleMSRemaining)))\r
        {\r
        /* Check if the idle period is set and has elapsed */\r
        if ((IdleCount != HID_IDLE_CHANGESONLY) && (!(IdleMSRemaining)))\r
        {\r
-               /* Reset the idle time remaining counter, must multiply by 4 to get the duration in milliseconds */\r
-               IdleMSRemaining = (IdleCount << 2);\r
+               /* Reset the idle time remaining counter */\r
+               IdleMSRemaining = IdleCount;\r
                \r
                /* Idle period is set and has elapsed, must send a report to the host */\r
                SendReport = true;\r
                \r
                /* Idle period is set and has elapsed, must send a report to the host */\r
                SendReport = true;\r
index c0989c5..60eb7fa 100644 (file)
@@ -197,8 +197,8 @@ void EVENT_USB_UnhandledControlPacket(void)
                        {\r
                                Endpoint_ClearSETUP();\r
                                \r
                        {\r
                                Endpoint_ClearSETUP();\r
                                \r
-                               /* Get idle period in MSB */\r
-                               IdleCount = (USB_ControlRequest.wValue >> 8);\r
+                               /* Get idle period in MSB, must multiply by 4 to get the duration in milliseconds */\r
+                               IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6);\r
                                \r
                                /* Acknowledge status stage */\r
                                while (!(Endpoint_IsINReady()));\r
                                \r
                                /* Acknowledge status stage */\r
                                while (!(Endpoint_IsINReady()));\r
@@ -211,8 +211,8 @@ void EVENT_USB_UnhandledControlPacket(void)
                        {               \r
                                Endpoint_ClearSETUP();\r
                                \r
                        {               \r
                                Endpoint_ClearSETUP();\r
                                \r
-                               /* Write the current idle duration to the host */\r
-                               Endpoint_Write_Byte(IdleCount);\r
+                               /* Write the current idle duration to the host, must be divided by 4 before sent to host */\r
+                               Endpoint_Write_Byte(IdleCount >> 2);\r
                                \r
                                /* Send the flag to the host */\r
                                Endpoint_ClearIN();\r
                                \r
                                /* Send the flag to the host */\r
                                Endpoint_ClearIN();\r
@@ -289,8 +289,8 @@ void SendNextReport(void)
        /* Check if the idle period is set and has elapsed */\r
        if ((IdleCount != HID_IDLE_CHANGESONLY) && (!(IdleMSRemaining)))\r
        {\r
        /* Check if the idle period is set and has elapsed */\r
        if ((IdleCount != HID_IDLE_CHANGESONLY) && (!(IdleMSRemaining)))\r
        {\r
-               /* Reset the idle time remaining counter, must multiply by 4 to get the duration in milliseconds */\r
-               IdleMSRemaining = (IdleCount << 2);\r
+               /* Reset the idle time remaining counter */\r
+               IdleMSRemaining = IdleCount;\r
                \r
                /* Idle period is set and has elapsed, must send a report to the host */\r
                SendReport = true;\r
                \r
                /* Idle period is set and has elapsed, must send a report to the host */\r
                SendReport = true;\r
index d032086..bad934a 100644 (file)
@@ -38,8 +38,11 @@ void HID_Device_ProcessControlPacket(USB_ClassInfo_HID_Device_t* const HIDInterf
        if (!(Endpoint_IsSETUPReceived()))\r
          return;\r
          \r
        if (!(Endpoint_IsSETUPReceived()))\r
          return;\r
          \r
-       if (USB_ControlRequest.wIndex != HIDInterfaceInfo->Config.InterfaceNumber)\r
-         return;\r
+       if ((USB_ControlRequest.wIndex   != HIDInterfaceInfo->Config.InterfaceNumber) &&\r
+           (USB_ControlRequest.bRequest != SetIdle))\r
+       {\r
+               return;\r
+       }\r
 \r
        switch (USB_ControlRequest.bRequest)\r
        {\r
 \r
        switch (USB_ControlRequest.bRequest)\r
        {\r
@@ -105,12 +108,16 @@ void HID_Device_ProcessControlPacket(USB_ClassInfo_HID_Device_t* const HIDInterf
                case REQ_SetIdle:\r
                        if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
                        {\r
                case REQ_SetIdle:\r
                        if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
                        {\r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               HIDInterfaceInfo->State.IdleCount = ((USB_ControlRequest.wValue >> 8) << 2);\r
-                               \r
-                               while (!(Endpoint_IsINReady()));\r
-                               Endpoint_ClearIN();\r
+                               if ((USB_ControlRequest.wIndex         == HIDInterfaceInfo->Config.InterfaceNumber) ||\r
+                                   (USB_ControlRequest.wValue & 0xFF) == 0)\r
+                               {\r
+                                       Endpoint_ClearSETUP();\r
+                                       \r
+                                       HIDInterfaceInfo->State.IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6);\r
+                                       \r
+                                       while (!(Endpoint_IsINReady()));\r
+                                       Endpoint_ClearIN();\r
+                               }\r
                        }\r
                        \r
                        break;\r
                        }\r
                        \r
                        break;\r
index f49f5b3..2318216 100644 (file)
@@ -174,59 +174,65 @@ void USB_Device_GetConfiguration(void)
        Endpoint_ClearOUT();\r
 }\r
 \r
        Endpoint_ClearOUT();\r
 }\r
 \r
-static void USB_Device_GetDescriptor(void)\r
+#if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))\r
+static void USB_Device_GetInternalSerialDescriptor(void)\r
 {\r
 {\r
-       void*    DescriptorPointer;\r
-       uint16_t DescriptorSize;\r
+       struct\r
+       {\r
+               USB_Descriptor_Header_t Header;\r
+               int16_t                 UnicodeString[12];\r
+       } SignatureDescriptor;\r
        \r
        \r
-       #if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))\r
-       if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))\r
+       uint8_t SigReadAddress  = 0x0E;         \r
+       bool    OddNibbleRead   = false;\r
+\r
+       #if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES)\r
+               SignatureDescriptor.Header.Size            = sizeof(SignatureDescriptor);\r
+               SignatureDescriptor.Header.Type            = DTYPE_String;\r
+       #else\r
+               SignatureDescriptor.Header.bLength         = sizeof(SignatureDescriptor);\r
+               SignatureDescriptor.Header.bDescriptorType = DTYPE_String;\r
+       #endif\r
+\r
+       for (uint8_t SerialCharNum = 0; SerialCharNum < 12; SerialCharNum++)\r
        {\r
        {\r
-               struct\r
-               {\r
-                       USB_Descriptor_Header_t Header;\r
-                       int16_t                 UnicodeString[12];\r
-               } SignatureDescriptor;\r
-\r
-               #if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES)\r
-                       SignatureDescriptor.Header.Size            = sizeof(SignatureDescriptor);\r
-                       SignatureDescriptor.Header.Type            = DTYPE_String;\r
-               #else\r
-                       SignatureDescriptor.Header.bLength         = sizeof(SignatureDescriptor);\r
-                       SignatureDescriptor.Header.bDescriptorType = DTYPE_String;\r
-               #endif\r
+               uint8_t SerialByte = boot_signature_byte_get(SigReadAddress);\r
                \r
                \r
-               uint8_t  SigReadAddress  = 0x0E;                \r
-               bool     OddRead         = false;\r
-\r
-               for (uint8_t SerialCharNum = 0; SerialCharNum < 12; SerialCharNum++)\r
+               if (OddNibbleRead)\r
                {\r
                {\r
-                       uint8_t SerialByte = boot_signature_byte_get(SigReadAddress);\r
-                       \r
-                       if (OddRead)\r
-                       {\r
-                               SerialByte >>= 4;\r
-                               SigReadAddress++;\r
-                       }\r
-                       else\r
-                       {\r
-                               SerialByte &= 0x0F;\r
-                       }\r
-                       \r
-                       OddRead = !(OddRead);\r
-\r
-                       if (SerialByte < 0x0A)\r
-                         SerialByte += '0';\r
-                       else\r
-                         SerialByte += ('A' - 0x0A);\r
-\r
-                       SignatureDescriptor.UnicodeString[SerialCharNum] = SerialByte;\r
+                       SerialByte >>= 4;\r
+                       SigReadAddress++;\r
+               }\r
+               else\r
+               {\r
+                       SerialByte &= 0x0F;\r
                }\r
                \r
                }\r
                \r
-               Endpoint_ClearSETUP();\r
-               Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor));\r
-               Endpoint_ClearOUT();\r
+               OddNibbleRead = !(OddNibbleRead);\r
+\r
+               if (SerialByte < 0x0A)\r
+                 SerialByte += '0';\r
+               else\r
+                 SerialByte += ('A' - 0x0A);\r
+\r
+               SignatureDescriptor.UnicodeString[SerialCharNum] = SerialByte;\r
+       }\r
+       \r
+       Endpoint_ClearSETUP();\r
+       Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor));\r
+       Endpoint_ClearOUT();\r
+}\r
+#endif\r
 \r
 \r
+static void USB_Device_GetDescriptor(void)\r
+{\r
+       void*    DescriptorPointer;\r
+       uint16_t DescriptorSize;\r
+       \r
+       #if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))\r
+       if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))\r
+       {\r
+               USB_Device_GetInternalSerialDescriptor();\r
                return;\r
        }\r
        #endif\r
                return;\r
        }\r
        #endif\r
index fdef727..2640cbb 100644 (file)
                                static void USB_Device_GetDescriptor(void);\r
                                static void USB_Device_GetStatus(void);\r
                                static void USB_Device_ClearSetFeature(void);\r
                                static void USB_Device_GetDescriptor(void);\r
                                static void USB_Device_GetStatus(void);\r
                                static void USB_Device_ClearSetFeature(void);\r
+                               \r
+                               #if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))\r
+                                       static void USB_Device_GetInternalSerialDescriptor(void);\r
+                               #endif                          \r
                        #endif\r
        #endif\r
 \r
                        #endif\r
        #endif\r
 \r
index 1610059..2281ca5 100644 (file)
@@ -55,6 +55,7 @@
   *  - Fixed USB_Host_SendControlRequest() not re-suspending the USB bus when initial device ready-wait fails\r
   *  - Fixed USB Pad regulator not being disabled on some AVR models when the USB_OPT_REG_DISABLED option is used\r
   *  - Fixed Host mode to Device mode UID change not causing a USB Disconnect event when a device was connected\r
   *  - Fixed USB_Host_SendControlRequest() not re-suspending the USB bus when initial device ready-wait fails\r
   *  - Fixed USB Pad regulator not being disabled on some AVR models when the USB_OPT_REG_DISABLED option is used\r
   *  - Fixed Host mode to Device mode UID change not causing a USB Disconnect event when a device was connected\r
+  *  - Fixed Mouse/Keyboard demos not performing the correct arithmetic on the Idle period at the right times (thanks to Brian Dickman)\r
   *\r
   *\r
   *  \section Sec_ChangeLog090605 Version 090605\r
   *\r
   *\r
   *  \section Sec_ChangeLog090605 Version 090605\r