Added new Pipe_IsFrozen() macro to determine if the currently selected pipe is frozen.
authorDean Camera <dean@fourwalledcubicle.com>
Sun, 20 Sep 2009 12:01:25 +0000 (12:01 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Sun, 20 Sep 2009 12:01:25 +0000 (12:01 +0000)
Added new USB_GetHIDReportSize() function to the HID report parser to retrieve the size of a given report by its ID.

More additions to the unfinished HID Host Class Driver.

18 files changed:
Bootloaders/CDC/BootloaderCDC.c
Demos/Device/ClassDriver/GenericHID/Descriptors.c
Demos/Device/ClassDriver/Joystick/Descriptors.c
Demos/Device/ClassDriver/Keyboard/Descriptors.c
Demos/Device/ClassDriver/KeyboardMouse/Descriptors.c
Demos/Device/ClassDriver/Mouse/Descriptors.c
Demos/Host/ClassDriver/MouseHost/MouseHost.c
Demos/Host/ClassDriver/MouseHost/makefile
LUFA/Drivers/USB/Class/Common/HID.h
LUFA/Drivers/USB/Class/Device/HID.h
LUFA/Drivers/USB/Class/Host/HID.c
LUFA/Drivers/USB/Class/Host/HID.h
LUFA/Drivers/USB/Class/Host/HIDParser.c
LUFA/Drivers/USB/Class/Host/HIDParser.h
LUFA/Drivers/USB/LowLevel/Pipe.c
LUFA/Drivers/USB/LowLevel/Pipe.h
LUFA/ManPages/ChangeLog.txt
LUFA/ManPages/DeviceSupport.txt

index d1f595c..f666023 100644 (file)
@@ -524,7 +524,7 @@ void CDC_Task(void)
                else if (Command == 'D')\r
                {\r
                        /* Read the byte from the endpoint and write it to the EEPROM */\r
-                       eeprom_write_byte((uint8_t*)(uint16_t)(CurrAddress >> 1), FetchNextCommandByte());\r
+                       eeprom_write_byte((uint8_t*)((uint16_t)(CurrAddress >> 1)), FetchNextCommandByte());\r
                        \r
                        /* Increment the address after use */                   \r
                        CurrAddress += 2;\r
@@ -535,7 +535,7 @@ void CDC_Task(void)
                else if (Command == 'd')\r
                {\r
                        /* Read the EEPROM byte and write it to the endpoint */\r
-                       WriteNextResponseByte(eeprom_read_byte((uint8_t*)(uint16_t)(CurrAddress >> 1)));\r
+                       WriteNextResponseByte(eeprom_read_byte((uint8_t*)((uint16_t)(CurrAddress >> 1))));\r
 \r
                        /* Increment the address after use */\r
                        CurrAddress += 2;\r
index a2bea6d..e937973 100644 (file)
@@ -123,7 +123,7 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
                                \r
                        .Class                  = 0x03,\r
                        .SubClass               = 0x00,\r
-                       .Protocol               = 0x00,\r
+                       .Protocol               = HID_NON_BOOT_PROTOCOL,\r
                                \r
                        .InterfaceStrIndex      = NO_DESCRIPTOR\r
                },\r
index 74ab7d9..8f4177e 100644 (file)
@@ -133,7 +133,7 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
                                \r
                        .Class                  = 0x03,\r
                        .SubClass               = 0x00,\r
-                       .Protocol               = 0x00,\r
+                       .Protocol               = HID_NON_BOOT_PROTOCOL,\r
                                \r
                        .InterfaceStrIndex      = NO_DESCRIPTOR\r
                },\r
index adc6210..12d8962 100644 (file)
@@ -140,7 +140,7 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
                                \r
                        .Class                  = 0x03,\r
                        .SubClass               = 0x01,\r
-                       .Protocol               = 0x01,\r
+                       .Protocol               = HID_BOOT_KEYBOARD_PROTOCOL,\r
                                \r
                        .InterfaceStrIndex      = NO_DESCRIPTOR\r
                },\r
index 114d863..520d57d 100644 (file)
@@ -173,7 +173,7 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
                                \r
                        .Class                  = 0x03,\r
                        .SubClass               = 0x01,\r
-                       .Protocol               = 0x01,\r
+                       .Protocol               = HID_BOOT_KEYBOARD_PROTOCOL,\r
                                \r
                        .InterfaceStrIndex      = NO_DESCRIPTOR\r
                },\r
@@ -210,7 +210,7 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
                                \r
                        .Class                  = 0x03,\r
                        .SubClass               = 0x01,\r
-                       .Protocol               = 0x02,\r
+                       .Protocol               = HID_BOOT_MOUSE_PROTOCOL,\r
                                \r
                        .InterfaceStrIndex      = NO_DESCRIPTOR\r
                },\r
index 7161da1..f6d6e89 100644 (file)
@@ -133,7 +133,7 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
                                \r
                        .Class                  = 0x03,\r
                        .SubClass               = 0x01,\r
-                       .Protocol               = 0x02,\r
+                       .Protocol               = HID_BOOT_MOUSE_PROTOCOL,\r
                                \r
                        .InterfaceStrIndex      = NO_DESCRIPTOR\r
                },\r
index b80a91c..ead2961 100644 (file)
@@ -47,7 +47,7 @@ USB_ClassInfo_HID_Host_t Mouse_HID_Interface =
                                .DataINPipeNumber       = 1,\r
                                .DataOUTPipeNumber      = 2,\r
                                \r
-                               .HIDInterfaceProtocol   = 0x02,\r
+                               .HIDInterfaceProtocol   = HID_BOOT_MOUSE_PROTOCOL,\r
                        },\r
        };\r
 \r
@@ -110,7 +110,38 @@ int main(void)
                                printf("Mouse Enumerated.\r\n");\r
                                USB_HostState = HOST_STATE_Configured;\r
                                break;\r
-                       case HOST_STATE_Configured:                     \r
+                       case HOST_STATE_Configured:\r
+                               if (HID_Host_IsReportReceived(&Mouse_HID_Interface))\r
+                               {\r
+                                       USB_MouseReport_Data_t MouseReport;\r
+                                       uint8_t ReportID = 0;\r
+                                       uint8_t LEDMask = LEDS_NO_LEDS;\r
+                               \r
+                                       HID_Host_ReceiveReport(&Mouse_HID_Interface, false, &ReportID, &MouseReport);\r
+                                       \r
+                                       /* Alter status LEDs according to mouse X movement */\r
+                                       if (MouseReport.X > 0)\r
+                                         LEDMask |= LEDS_LED1;\r
+                                       else if (MouseReport.X < 0)\r
+                                         LEDMask |= LEDS_LED2;\r
+                                               \r
+                                       /* Alter status LEDs according to mouse Y movement */\r
+                                       if (MouseReport.Y > 0)\r
+                                         LEDMask |= LEDS_LED3;\r
+                                       else if (MouseReport.Y < 0)\r
+                                         LEDMask |= LEDS_LED4;\r
+\r
+                                       /* Alter status LEDs according to mouse button position */\r
+                                       if (MouseReport.Button)\r
+                                         LEDMask  = LEDS_ALL_LEDS;\r
+                                       \r
+                                       LEDs_SetAllLEDs(LEDMask);\r
+                               }\r
+                               else\r
+                               {\r
+                                       LEDs_SetAllLEDs(LEDS_NO_LEDS);\r
+                               }\r
+                               \r
                                break;\r
                }\r
        \r
index 5d1d953..f0df3cc 100644 (file)
@@ -136,6 +136,7 @@ SRC = $(TARGET).c                                                 \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/HID.c            \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/Class/Host/HID.c              \\r
+         $(LUFA_PATH)/LUFA/Drivers/USB/Class/Host/HIDParser.c        \\r
          \r
 \r
 # List C++ source files here. (C dependencies are automatically generated.)\r
index b860f08..f6b49df 100644 (file)
 \r
        /* Macros: */\r
                /** HID Class Specific Request to get the current HID report from the device. */\r
-               #define REQ_GetReport      0x01\r
+               #define REQ_GetReport                0x01\r
 \r
                /** HID Class Specific Request to get the current device idle count. */\r
-               #define REQ_GetIdle        0x02\r
+               #define REQ_GetIdle                  0x02\r
 \r
                /** HID Class Specific Request to set the current HID report to the device. */\r
-               #define REQ_SetReport      0x09\r
+               #define REQ_SetReport                0x09\r
 \r
                /** HID Class Specific Request to set the device's idle count. */\r
-               #define REQ_SetIdle        0x0A\r
+               #define REQ_SetIdle                  0x0A\r
 \r
                /** HID Class Specific Request to get the current HID report protocol mode. */\r
-               #define REQ_GetProtocol    0x03\r
+               #define REQ_GetProtocol              0x03\r
 \r
                /** HID Class Specific Request to set the current HID report protocol mode. */\r
-               #define REQ_SetProtocol    0x0B\r
+               #define REQ_SetProtocol              0x0B\r
 \r
                /** Descriptor header type value, to indicate a HID class HID descriptor. */\r
-               #define DTYPE_HID          0x21\r
+               #define DTYPE_HID                    0x21\r
                \r
                /** Descriptor header type value, to indicate a HID class HID report descriptor. */\r
-               #define DTYPE_Report       0x22\r
+               #define DTYPE_Report                 0x22\r
                \r
+               /** Constant for the protocol value of a HID interface descriptor, indicating that the interface does not support\r
+                *  any HID class boot protocol (see HID Class Specification).\r
+                */\r
+               #define HID_NON_BOOT_PROTOCOL        0x00\r
+\r
+               /** Constant for the protocol value of a HID interface descriptor, indicating that the interface supports the\r
+                *  HID class Mouse boot protocol (see HID Class Specification).\r
+                */\r
+               #define HID_BOOT_MOUSE_PROTOCOL      0x02\r
+               \r
+               /** Constant for the protocol value of a HID interface descriptor, indicating that the interface supports the\r
+                *  HID class Keyboard boot protocol (see HID Class Specification).\r
+                */\r
+               #define HID_BOOT_KEYBOARD_PROTOCOL   0x01\r
+\r
        /* Type Defines: */\r
                /** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID\r
                 *  specification for details on the structure elements.\r
                        uint16_t                 HIDReportLength;\r
                } USB_HID_Descriptor_t;\r
 \r
+               /** Type define for a standard Boot Protocol Mouse report */\r
+               typedef struct\r
+               {\r
+                       uint8_t Button; /**< Button mask for currently pressed buttons in the mouse */\r
+                       int8_t  X; /**< Current delta X movement of the mouse */\r
+                       int8_t  Y; /**< Current delta Y movement on the mouse */\r
+               } USB_MouseReport_Data_t;\r
+               \r
+               /** Type define for a standard Boot Protocol Keyboard report */\r
+               typedef struct\r
+               {\r
+                       uint8_t Modifier; /**< Keyboard modifier byte, indicating pressed modifier keys (such as Shift, Control, etc.) */\r
+                       uint8_t Reserved; /**< Reserved for OEM use, always set to 0 */\r
+                       uint8_t KeyCode; /**< Key code of the currently pressed key */\r
+               } USB_KeyboardReport_Data_t;\r
+\r
                /** Type define for the data type used to store HID report descriptor elements. */\r
                typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;\r
 \r
index faf9d5f..a3e3b85 100644 (file)
                         */\r
                        void HID_Device_MillisecondElapsed(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);\r
                        \r
-                       /** HID class driver callback for the user creation of a HID input report. This callback may fire in response to either\r
+                       /** HID class driver callback for the user creation of a HID IN report. This callback may fire in response to either\r
                         *  HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback the\r
                         *  user is responsible for the creation of the next HID input report to be sent to the host.\r
                         *\r
                        bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,\r
                                                      void* ReportData, uint16_t* ReportSize) ATTR_NON_NULL_PTR_ARG(1, 2, 3, 4);\r
                        \r
-                       /** HID class driver callback for the user processing of a received HID input report. This callback may fire in response to\r
+                       /** HID class driver callback for the user processing of a received HID OUT report. This callback may fire in response to\r
                         *  either HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback\r
                         *  the user is responsible for the processing of the received HID output report from the host.\r
                         *\r
index 9b1ec16..22b2de1 100644 (file)
@@ -61,7 +61,7 @@ uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo, uint
                 (CurrentHIDInterface->Protocol != HIDInterfaceInfo->Config.HIDInterfaceProtocol));\r
 \r
        HIDInterfaceInfo->State.InterfaceNumber      = CurrentHIDInterface->InterfaceNumber;\r
-       HIDInterfaceInfo->State.SupportsBootSubClass = (CurrentHIDInterface->SubClass != 0);\r
+       HIDInterfaceInfo->State.SupportsBootProtocol = (CurrentHIDInterface->SubClass != HID_NON_BOOT_PROTOCOL);\r
 \r
        if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, DComp_NextHID) != DESCRIPTOR_SEARCH_COMP_Found)\r
        {\r
@@ -97,6 +97,8 @@ uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo, uint
                                                           EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);\r
                        HIDInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize;\r
                        \r
+                       HIDInterfaceInfo->State.DeviceUsesOUTPipe = true;\r
+                       \r
                        FoundEndpoints |= HID_FOUND_DATAPIPE_OUT;               \r
                }\r
        }\r
@@ -152,6 +154,97 @@ void HID_Host_USBTask(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo)
 \r
 }\r
 \r
+uint8_t HID_Host_ReceiveReport(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo, bool ControlRequest, uint8_t* ReportID, void* Buffer)\r
+{\r
+       if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive))\r
+         return false;\r
+\r
+       if (ControlRequest)\r
+       {\r
+               USB_ControlRequest = (USB_Request_Header_t)\r
+               {\r
+                       .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),\r
+                       .bRequest      = REQ_SetReport,\r
+                       .wValue        = *ReportID,\r
+                       .wIndex        = HIDInterfaceInfo->State.InterfaceNumber,\r
+                       .wLength       = USB_GetHIDReportSize(HIDInterfaceInfo->Config.HIDParserData, *ReportID, REPORT_ITEM_TYPE_In),\r
+               };\r
+\r
+               Pipe_SelectPipe(PIPE_CONTROLPIPE);\r
+               \r
+               return USB_Host_SendControlRequest(Buffer);\r
+       }\r
+       else\r
+       {\r
+               uint8_t ErrorCode;\r
+       \r
+               Pipe_SelectPipe(HIDInterfaceInfo->Config.DataINPipeNumber);\r
+               Pipe_Unfreeze();\r
+               \r
+               uint16_t ReportSize;\r
+\r
+               if (HIDInterfaceInfo->State.UsingBootProtocol)\r
+               {\r
+                       ReportSize = Pipe_BytesInPipe();\r
+               }\r
+               else\r
+               {\r
+                       if (HIDInterfaceInfo->Config.HIDParserData->UsingReportIDs)\r
+                               *ReportID = Pipe_Read_Byte();\r
+                       else\r
+                               *ReportID = 0;\r
+                       \r
+                       ReportSize = USB_GetHIDReportSize(HIDInterfaceInfo->Config.HIDParserData, *ReportID, REPORT_ITEM_TYPE_In);\r
+               }\r
+\r
+               if ((ErrorCode = Pipe_Read_Stream_LE(Buffer, ReportSize, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)\r
+                 return ErrorCode;\r
+               \r
+               Pipe_Freeze();\r
+               \r
+               return PIPE_RWSTREAM_NoError;           \r
+       }\r
+}\r
+\r
+uint8_t HID_Host_SendReport(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo, uint8_t ReportID, void* Buffer, uint16_t ReportSize)\r
+{\r
+       if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive))\r
+         return false;\r
+         \r
+       if (HIDInterfaceInfo->State.DeviceUsesOUTPipe)\r
+       {\r
+               USB_ControlRequest = (USB_Request_Header_t)\r
+               {\r
+                       .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),\r
+                       .bRequest      = REQ_SetReport,\r
+                       .wValue        = ReportID,\r
+                       .wIndex        = HIDInterfaceInfo->State.InterfaceNumber,\r
+                       .wLength       = ReportSize,\r
+               };\r
+\r
+               Pipe_SelectPipe(PIPE_CONTROLPIPE);\r
+               \r
+               return USB_Host_SendControlRequest(Buffer);\r
+       }\r
+       else\r
+       {\r
+               uint8_t ErrorCode;\r
+       \r
+               Pipe_SelectPipe(HIDInterfaceInfo->Config.DataOUTPipeNumber);\r
+               Pipe_Unfreeze();\r
+               \r
+               if (ReportID)\r
+                 Pipe_Write_Stream_LE(&ReportID, sizeof(ReportID), NO_STREAM_CALLBACK);\r
+               \r
+               if ((ErrorCode = Pipe_Write_Stream_LE(Buffer, ReportSize, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)\r
+                 return ErrorCode;\r
+               \r
+               Pipe_Freeze();\r
+               \r
+               return PIPE_RWSTREAM_NoError;\r
+       }\r
+}\r
+\r
 bool HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo)\r
 {\r
        if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive))\r
@@ -165,7 +258,7 @@ bool HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo)
        ReportReceived = Pipe_IsReadWriteAllowed();\r
        \r
        Pipe_Freeze();\r
-\r
+       \r
        return ReportReceived;\r
 }\r
 \r
@@ -174,6 +267,8 @@ uint8_t USB_HID_Host_SetBootProtocol(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo)
        if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive))\r
          return false;\r
 \r
+       uint8_t ErrorCode;\r
+\r
        USB_ControlRequest = (USB_Request_Header_t)\r
                {\r
                        .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),\r
@@ -188,7 +283,7 @@ uint8_t USB_HID_Host_SetBootProtocol(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo)
        if (!(HIDInterfaceInfo->State.SupportsBootProtocol))\r
          return HID_ERROR_LOGICAL;\r
 \r
-       if ((ErrorCode = USB_Host_SendControlRequest(HIDReportData)) != HOST_SENDCONTROL_Successful)\r
+       if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)\r
          return ErrorCode;\r
 \r
        HIDInterfaceInfo->State.UsingBootProtocol = true;\r
index 95c1334..230930a 100644 (file)
@@ -73,8 +73,9 @@
                                        uint8_t  DataOUTPipeNumber; /**< Pipe number of the HID interface's OUT data pipe */\r
 \r
                                        uint8_t  HIDInterfaceProtocol; /**< HID interface protocol value to match against if a specific\r
-                                                                       *   boot subclass protocol is required (e.g. keyboard, mouse), or\r
-                                                                       *   leave as 0 to match against the first HID interface found\r
+                                                                       *   boot subclass protocol is required, either \ref HID_BOOT_MOUSE_PROTOCOL,\r
+                                                                                                       *   \ref HID_BOOT_KEYBOARD_PROTOCOL or \ref HID_NON_BOOT_PROTOCOL if any\r
+                                                                                                       *   HID device should be enumerated by the interface\r
                                                                        */\r
                                        HID_ReportInfo_t* HIDParserData; /**< HID parser data to store the parsed HID report data, when boot protocol\r
                                                                          *   is not used */\r
@@ -95,6 +96,9 @@
                                        bool SupportsBootProtocol; /**< Indicates if the current interface instance supports the HID Boot\r
                                                                    *   Protocol when enabled via \ref USB_HID_Host_SetBootProtocol()\r
                                                                    */\r
+                                       bool DeviceUsesOUTPipe; /**< Indicates if the current interface instance uses a seperate OUT data pipe for\r
+                                                                *   OUT reports, or if OUT reports are sent via the control pipe instead.\r
+                                                                */\r
                                        bool UsingBootProtocol; /**< Indicates that the interface is currently initialised in Boot Protocol mode */\r
                                        uint16_t HIDReportSize; /**< Size in bytes of the HID report descriptor in the device */\r
                                } State; /**< State data for the USB class interface within the device. All elements in this section\r
                        uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo, uint16_t ConfigDescriptorLength,\r
                                                        uint8_t* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1, 3);\r
 \r
-                       /** Determines if a report has been received on the HID interface's IN report pipe, when the device is initialized\r
-                        *  into Report Protocol mode.\r
+\r
+                       /** Receives a HID IN report from the attached HID device, either the next report from the device's IN data pipe,\r
+                        *  or a given report (by Report ID) if a specific report is desired.\r
+                        *\r
+                        *  \param[in,out] HIDInterfaceInfo  Pointer to a structure containing a HID Class host configuration and state\r
+                        *  \param[in] ControlRequest  Set to true if the report should be requested by a control request, false otherwise\r
+                        *  \param[in,out] ReportID  Report ID of the received report if ControlRequest is false, set by the to the Report ID\r
+                        *                           to fetch if ControlRequest is true\r
+                        *  \param[in] Buffer  Buffer to store the received report into\r
+                        *\r
+                        *  \return An error code from the \ref USB_Host_SendControlErrorCodes_t enum if the ControlRequest flag is set,\r
+                        *          a value from the \ref Pipe_Stream_RW_ErrorCodes_t enum otherwise\r
+                        */\r
+                       uint8_t HID_Host_ReceiveReport(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo, bool ControlRequest, uint8_t* ReportID,\r
+                                                      void* Buffer) ATTR_NON_NULL_PTR_ARG(1, 3);\r
+\r
+                       /** Sends an OUT report to the currently attached HID device, using the device's OUT pipe if available or the device's\r
+                        *  Control pipe if not.\r
+                        *\r
+                        *  \param[in,out] HIDInterfaceInfo  Pointer to a structure containing a HID Class host configuration and state\r
+                        *  \param[in] ReportID  Report ID of the report to send to the device, or 0 if the device does not use report IDs\r
+                        *  \param[in] Buffer  Buffer containing the report to send to the attached device\r
+                        *  \param[in] ReportSize  Report size in bytes to send to the attached device\r
+                        *\r
+                        *  \return An error code from the \ref USB_Host_SendControlErrorCodes_t enum if the DeviceUsesOUTPipe flag is set in\r
+                        *          the interface's state structure, a value from the \ref Pipe_Stream_RW_ErrorCodes_t enum otherwise\r
+                        */\r
+                       uint8_t HID_Host_SendReport(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo, uint8_t ReportID,\r
+                                                   void* Buffer, uint16_t ReportSize) ATTR_NON_NULL_PTR_ARG(1, 3);\r
+\r
+                       /** Determines if a HID IN report has been received from the attached device on the data IN pipe.\r
                         *\r
                         *  \param[in,out] HIDInterfaceInfo  Pointer to a structure containing a HID Class host configuration and state\r
                         *\r
                         *  \return Boolean true if a report has been received, false otherwise\r
                         */\r
-                       bool    HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);\r
+                       bool HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);\r
                        \r
                        /** Switches the attached HID device's reporting protocol over to the Boot Report protocol mode, on supported devices.\r
                         *\r
index 4293a3d..008d173 100644 (file)
@@ -342,4 +342,25 @@ void USB_SetHIDReportItemInfo(uint8_t* ReportData, const HID_ReportItem_t* Repor
        }\r
 }\r
 \r
+uint16_t USB_GetHIDReportSize(HID_ReportInfo_t* const ParserData, uint8_t ReportID, uint8_t ReportType)\r
+{\r
+       for (uint8_t i = 0; i < HID_MAX_REPORT_IDS; i++)\r
+       {\r
+               if (ParserData->ReportIDSizes[i].ReportID == ReportID)\r
+               {\r
+                       switch (ReportType)\r
+                       {\r
+                               case REPORT_ITEM_TYPE_In:\r
+                                       return ParserData->ReportIDSizes[i].BitsIn;\r
+                               case REPORT_ITEM_TYPE_Out:\r
+                                       return ParserData->ReportIDSizes[i].BitsOut;\r
+                               case REPORT_ITEM_TYPE_Feature:\r
+                                       return ParserData->ReportIDSizes[i].BitsFeature;\r
+                       }\r
+               }\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
 #endif\r
index d9adae3..f598789 100644 (file)
                        void USB_SetHIDReportItemInfo(uint8_t* ReportData, const HID_ReportItem_t* ReportItem)\r
                                                      ATTR_NON_NULL_PTR_ARG(1, 2);\r
                                                                                  \r
+                       /** Retrieves the size of a given HID report in bytes from it's Report ID.\r
+                        *\r
+                        *  \param[in] ParserData  Pointer to a \ref HID_ReportInfo_t instance containing the parser output\r
+                        *  \param[in] ReportID  Report ID of the report whose size is to be retrieved\r
+                        *  \param[in] ReportType  Type of the report whose size is to be determined, a valued from the\r
+                        *                         \ref HID_ReportItemTypes_t enum\r
+                        *\r
+                        *  \return Size of the report in bytes, or 0 if the report does not exist\r
+                        */\r
+                       uint16_t USB_GetHIDReportSize(HID_ReportInfo_t* const ParserData, uint8_t ReportID,\r
+                                                     uint8_t ReportType) ATTR_NON_NULL_PTR_ARG(1);\r
+\r
                        /** Callback routine for the HID Report Parser. This callback <b>must</b> be implemented by the user code when\r
                         *  the parser is used, to determine what report IN, OUT and FEATURE item's information is stored into the user\r
                         *  HID_ReportInfo_t structure. This can be used to filter only those items the application will be using, so that\r
index 9c6a53e..58d7343 100644 (file)
@@ -93,7 +93,7 @@ uint8_t Pipe_WaitUntilReady(void)
        #else\r
        uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;\r
        #endif\r
-\r
+       \r
        for (;;)\r
        {\r
                if (Pipe_GetPipeToken() == PIPE_TOKEN_IN)\r
index 2945458..fd01b5c 100644 (file)
                                /** Freezes the selected pipe, preventing it from communicating with an attached device. */\r
                                static inline void Pipe_Freeze(void);\r
 \r
+                               /** Determines if the currently selected pipe is frozen, and not able to accept data.\r
+                                *\r
+                                *  \return Boolean true if the currently selected pipe is frozen, false otherwise\r
+                                */\r
+                               static inline bool Pipe_IsFrozen(void);\r
+                               \r
                                /** Clears the master pipe error flag. */\r
                                static inline void Pipe_ClearError(void);\r
                                \r
                                #define Pipe_Unfreeze()                MACROS{ UPCONX &= ~(1 << PFREEZE); }MACROE\r
 \r
                                #define Pipe_Freeze()                  MACROS{ UPCONX |= (1 << PFREEZE); }MACROE\r
+                               \r
+                               #define Pipe_IsFrozen()                ((UPCONX & (1 << PFREEZE)) ? true : false)\r
 \r
                                #define Pipe_ClearError()              MACROS{ UPINTX &= ~(1 << PERRI); }MACROE\r
 \r
index 4c36afc..bdb48d9 100644 (file)
@@ -20,7 +20,9 @@
   *  - Added extra masks to the SPI driver, changed SPI_Init() so that the clock polarity and sample modes can be set\r
   *  - Added new callback to the HID report parser, so that the user application can filter only the items it is interested\r
   *    in to be stored into the HIDReportInfo structure to save RAM\r
-  *  - Added support for the officially recommended layout of the external peripherals connected to the BUMBLEB board\r
+  *  - Added support for the officially recommended external peripheral layout for the BUMBLEB board (thanks to Dave Fletcher)\r
+  *  - Added new Pipe_IsFrozen() macro to determine if the currently selected pipe is frozen\r
+  *  - Added new USB_GetHIDReportSize() function to the HID report parser to retrieve the size of a given report by its ID\r
   *  \r
   *  <b>Changed:</b>\r
   *  - SetIdle requests to the HID device driver with a 0 idle period (send changes only) now only affect the requested\r
index 2eb963e..bd1b1c4 100644 (file)
@@ -29,7 +29,7 @@
  *   - ATAVRUSBRF01\r
  *\r
  *  Currently supported third-party boards:\r
- *   - BUMBLEB (using recommended peripheral layout)\r
+ *   - BUMBLEB (using officially recommended peripheral layout)\r
  *   - Any Other Custom User Boards (with Board Drivers, \see Page_WritingBoardDrivers)\r
  */\r
  
\ No newline at end of file