diff options
author | Dean Camera <dean@fourwalledcubicle.com> | 2009-09-17 13:12:21 +0000 |
---|---|---|
committer | Dean Camera <dean@fourwalledcubicle.com> | 2009-09-17 13:12:21 +0000 |
commit | 7c6b2019a302fb064665c1a69e559678c299e9bb (patch) | |
tree | f9348ddac5fe0b45fa687df5941d391e91715326 /LUFA/Drivers/USB | |
parent | eaa914a4e445c25ffdbee7be7caf85165540c98a (diff) | |
download | lufa-7c6b2019a302fb064665c1a69e559678c299e9bb.tar.gz lufa-7c6b2019a302fb064665c1a69e559678c299e9bb.tar.bz2 lufa-7c6b2019a302fb064665c1a69e559678c299e9bb.zip |
Fix Mass Storage Host Class driver GetMaxLUN command - incorrect function return codes used in comparison to check for success.
Add HID Host Class driver functions to set the report protocol, add more class driver documentation.
Diffstat (limited to 'LUFA/Drivers/USB')
-rw-r--r-- | LUFA/Drivers/USB/Class/Device/HID.h | 2 | ||||
-rw-r--r-- | LUFA/Drivers/USB/Class/Host/CDC.h | 4 | ||||
-rw-r--r-- | LUFA/Drivers/USB/Class/Host/HID.c | 58 | ||||
-rw-r--r-- | LUFA/Drivers/USB/Class/Host/HID.h | 59 | ||||
-rw-r--r-- | LUFA/Drivers/USB/Class/Host/MassStorage.c | 16 | ||||
-rw-r--r-- | LUFA/Drivers/USB/Class/Host/MassStorage.h | 2 | ||||
-rw-r--r-- | LUFA/Drivers/USB/Class/Host/StillImage.h | 2 | ||||
-rw-r--r-- | LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h | 1 |
8 files changed, 125 insertions, 19 deletions
diff --git a/LUFA/Drivers/USB/Class/Device/HID.h b/LUFA/Drivers/USB/Class/Device/HID.h index ccd7426e1..faf9d5f72 100644 --- a/LUFA/Drivers/USB/Class/Device/HID.h +++ b/LUFA/Drivers/USB/Class/Device/HID.h @@ -137,7 +137,7 @@ *
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
* \param[in,out] ReportID If preset to a non-zero value, this is the report ID being requested by the host. If zero, this should
- * be set to the report ID of the generated HID input report. If multiple reports are not sent via the
+ * be set to the report ID of the generated HID input report (if any). If multiple reports are not sent via the
* given HID interface, this parameter should be ignored.
* \param[out] ReportData Pointer to a buffer where the generated HID report should be stored.
* \param[out] ReportSize Number of bytes in the generated input report, or zero if no report is to be sent
diff --git a/LUFA/Drivers/USB/Class/Host/CDC.h b/LUFA/Drivers/USB/Class/Host/CDC.h index de4b6afd4..df5a41ff0 100644 --- a/LUFA/Drivers/USB/Class/Host/CDC.h +++ b/LUFA/Drivers/USB/Class/Host/CDC.h @@ -145,6 +145,8 @@ * values of the interface have been changed to push the new settings to the USB device.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state
+ *
+ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
*/
uint8_t CDC_Host_SetLineEncoding(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
@@ -154,6 +156,8 @@ * to push the new states to the USB device.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state
+ *
+ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum
*/
uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
diff --git a/LUFA/Drivers/USB/Class/Host/HID.c b/LUFA/Drivers/USB/Class/Host/HID.c index 11dfb67ad..5a5ec484d 100644 --- a/LUFA/Drivers/USB/Class/Host/HID.c +++ b/LUFA/Drivers/USB/Class/Host/HID.c @@ -169,23 +169,73 @@ bool HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo) return ReportReceived;
}
-uint8_t USB_HID_Host_SetProtocol(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo, bool UseReportProtocol)
+uint8_t USB_HID_Host_SetBootProtocol(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo)
{
+ if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive))
+ return false;
+
USB_ControlRequest = (USB_Request_Header_t)
{
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SetProtocol,
- .wValue = UseReportProtocol,
+ .wValue = 1,
.wIndex = HIDInterfaceInfo->State.InterfaceNumber,
.wLength = 0,
};
Pipe_SelectPipe(PIPE_CONTROLPIPE);
- if (UseReportProtocol && !(HIDInterfaceInfo->State.SupportsBootSubClass))
- return MS_ERROR_UNSUPPORTED;
+ if (!(HIDInterfaceInfo->State.SupportsBootSubClass))
+ return HID_ERROR_LOGICAL;
return USB_Host_SendControlRequest(NULL);
}
+uint8_t USB_HID_Host_SetReportProtocol(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive))
+ return false;
+
+ uint8_t ErrorCode;
+
+ uint8_t HIDReportData[HIDInterfaceInfo->State.HIDReportSize];
+
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE),
+ .bRequest = REQ_GetDescriptor,
+ .wValue = (DTYPE_Report << 8),
+ .wIndex = HIDInterfaceInfo->State.InterfaceNumber,
+ .wLength = HIDInterfaceInfo->State.HIDReportSize,
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+ if ((ErrorCode = USB_Host_SendControlRequest(HIDReportData)) != HOST_SENDCONTROL_Successful)
+ return ErrorCode;
+
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = REQ_SetProtocol,
+ .wValue = 0,
+ .wIndex = HIDInterfaceInfo->State.InterfaceNumber,
+ .wLength = 0,
+ };
+
+ if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
+ return ErrorCode;
+
+ if (HIDInterfaceInfo->Config.HIDParserData == NULL)
+ return HID_ERROR_LOGICAL;
+
+ if ((ErrorCode = USB_ProcessHIDReport(HIDReportData, HIDInterfaceInfo->State.HIDReportSize,
+ HIDInterfaceInfo->Config.HIDParserData)) != HID_PARSE_Successful)
+ {
+ return HID_ERROR_LOGICAL | ErrorCode;
+ }
+
+ return 0;
+}
+
#endif
diff --git a/LUFA/Drivers/USB/Class/Host/HID.h b/LUFA/Drivers/USB/Class/Host/HID.h index c1a68f819..c0f67e752 100644 --- a/LUFA/Drivers/USB/Class/Host/HID.h +++ b/LUFA/Drivers/USB/Class/Host/HID.h @@ -34,6 +34,7 @@ * \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Drivers/USB/Class/Host/HID.c
+ * - LUFA/Drivers/USB/Class/Host/HIDParser.c
*
* \section Module Description
* Host Mode USB Class driver framework interface, for the HID USB Class driver.
@@ -57,7 +58,7 @@ /* Public Interface - May be used in end-application: */
/* Macros: */
/** Error code for some HID Host functions, indicating a logical (and not hardware) error */
- #define MS_ERROR_UNSUPPORTED 0xC0
+ #define HID_ERROR_LOGICAL 0x80
/* Type Defines: */
/** Class state structure. An instance of this structure should be made within the user application,
@@ -92,7 +93,7 @@ uint16_t DataOUTPipeSize; /**< Size in bytes of the HID interface's OUT data pipe */
bool SupportsBootSubClass; /**< Indicates if the current interface instance supports the HID Boot
- * Protocol when enabled via \ref USB_HID_Host_SetProtocol()
+ * Protocol when enabled via \ref USB_HID_Host_SetBootProtocol()
*/
uint16_t HIDReportSize; /**< Size in bytes of the HID report descriptor in the device */
} State; /**< State data for the USB class interface within the device. All elements in this section
@@ -102,6 +103,7 @@ } USB_ClassInfo_HID_Host_t;
/* Enums: */
+ /** Enum for the possible error codes returned by the \ref HID_Host_ConfigurePipes() function. */
enum HIDHost_EnumerationFailure_ErrorCodes_t
{
HID_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */
@@ -112,13 +114,64 @@ };
/* Function Prototypes: */
+ /** General management task for a given Human Interface Class host class interface, required for the correct operation of
+ * the interface. This should be called frequently in the main program loop, before the master USB management task
+ * \ref USB_USBTask().
+ *
+ * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
+ */
void HID_Host_USBTask(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Host interface configuration routine, to configure a given HID host interface instance using the Configuration
+ * Descriptor read from an attached USB device. This function automatically updates the given HID Host instance's
+ * state values and configures the pipes required to communicate with the interface if it is found within the
+ * device. This should be called once after the stack has enumerated the attached device, while the host state
+ * machine is in the Addressed state.
+ *
+ * \note Once the device pipes are configured, the HID device's reporting protocol <b>must</b> be set via a call
+ * to either the \ref USB_HID_Host_SetBootProtocol() or \ref USB_HID_Host_SetReportProtocol() function.
+ *
+ * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
+ * \param[in] ConfigDescriptorLength Length of the attached device's Configuration Descriptor
+ * \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor
+ *
+ * \return A value from the \ref HIDHost_EnumerationFailure_ErrorCodes_t enum
+ */
uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo, uint16_t ConfigDescriptorLength,
uint8_t* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1, 3);
+ /** Determines if a report has been received on the HID interface's IN report pipe, when the device is initialized
+ * into Report Protocol mode.
+ *
+ * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
+ *
+ * \return Boolean true if a report has been received, false otherwise
+ */
bool HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
- uint8_t USB_HID_Host_SetProtocol(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo, bool UseReportProtocol) ATTR_NON_NULL_PTR_ARG(1);
+ /** Switches the attached HID device's reporting protocol over to the Boot Report protocol mode, on supported devices.
+ *
+ * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
+ *
+ * \return \ref HID_ERROR_LOGICAL if the device does not support Boot Protocol mode, a value from the
+ * \ref USB_Host_SendControlErrorCodes_t enum otherwise
+ */
+ uint8_t USB_HID_Host_SetBootProtocol(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Switches the attached HID device's reporting protocol over to the standard Report protocol mode. This also retrieves
+ * and parses the device's HID report descriptor, so that the size of each report can be determined in advance.
+ *
+ * \note Whether this function is used or not, the \ref CALLBACK_HIDParser_FilterHIDReportItem() callback from the HID
+ * Report Parser this function references <b>must</b> be implemented in the user code.
+ *
+ * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state
+ *
+ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum if an error occurs while retrieving the HID
+ * Report descriptor or the setting of the Report protocol, \ref HID_ERROR_LOGICAL if the HID interface does
+ * not have a valid \ref HID_ReportInfo_t structure set in its configuration, a mask of \ref HID_ERROR_LOGICAL
+ * and a value from the \ref HID_Parse_ErrorCodes_t otherwise
+ */
+ uint8_t USB_HID_Host_SetReportProtocol(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
diff --git a/LUFA/Drivers/USB/Class/Host/MassStorage.c b/LUFA/Drivers/USB/Class/Host/MassStorage.c index 2d2f042b7..ead7768d6 100644 --- a/LUFA/Drivers/USB/Class/Host/MassStorage.c +++ b/LUFA/Drivers/USB/Class/Host/MassStorage.c @@ -274,8 +274,10 @@ static uint8_t MS_Host_GetReturnedStatus(USB_ClassInfo_MS_Host_t* MSInterfaceInf if ((ErrorCode = Pipe_Read_Stream_LE(SCSICommandStatus, sizeof(MS_CommandStatusWrapper_t),
NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
- return ErrorCode;
-
+ {
+ return ErrorCode;
+ }
+
Pipe_ClearIN();
Pipe_Freeze();
@@ -322,14 +324,10 @@ uint8_t MS_Host_GetMaxLUN(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, uint8_t* Max Pipe_SelectPipe(PIPE_CONTROLPIPE);
- if ((ErrorCode = USB_Host_SendControlRequest(MaxLUNIndex)) == HOST_SENDCONTROL_SetupStalled)
- {
- Pipe_ClearStall();
-
- *MaxLUNIndex = 0;
- }
+ if ((ErrorCode = USB_Host_SendControlRequest(MaxLUNIndex)) != HOST_SENDCONTROL_Successful)
+ *MaxLUNIndex = 0;
- return HOST_SENDCONTROL_SetupStalled;
+ return ErrorCode;
}
uint8_t MS_Host_GetInquiryData(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, uint8_t LUNIndex, SCSI_Inquiry_Response_t* InquiryData)
diff --git a/LUFA/Drivers/USB/Class/Host/MassStorage.h b/LUFA/Drivers/USB/Class/Host/MassStorage.h index f6a1b61c2..2395fcf1f 100644 --- a/LUFA/Drivers/USB/Class/Host/MassStorage.h +++ b/LUFA/Drivers/USB/Class/Host/MassStorage.h @@ -56,7 +56,7 @@ /* Public Interface - May be used in end-application: */
/* Macros: */
/** Error code for some Mass Storage Host functions, indicating a logical (and not hardware) error */
- #define MS_ERROR_LOGICAL_CMD_FAILED 0xC0
+ #define MS_ERROR_LOGICAL_CMD_FAILED 0x80
/* Type Defines: */
/** Class state structure. An instance of this structure should be made within the user application,
diff --git a/LUFA/Drivers/USB/Class/Host/StillImage.h b/LUFA/Drivers/USB/Class/Host/StillImage.h index fd67134c1..037ae6c01 100644 --- a/LUFA/Drivers/USB/Class/Host/StillImage.h +++ b/LUFA/Drivers/USB/Class/Host/StillImage.h @@ -56,7 +56,7 @@ /* Public Interface - May be used in end-application: */
/* Macros: */
/** Error code for some Still Image Host functions, indicating a logical (and not hardware) error */
- #define SI_ERROR_LOGICAL_CMD_FAILED 0xC0
+ #define SI_ERROR_LOGICAL_CMD_FAILED 0x80
/* Type Defines: */
typedef struct
diff --git a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h index be24debba..c0ebe0956 100644 --- a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h +++ b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h @@ -155,6 +155,7 @@ uint8_t USB_GetNextDescriptorComp(uint16_t* BytesRem, uint8_t** CurrConfigLoc, ConfigComparatorPtr_t ComparatorRoutine);
/* Enums: */
+ /** Enum for the possible return codes of the \ref USB_GetDeviceConfigDescriptor() function. */
enum USB_Host_GetConfigDescriptor_ErrorCodes_t
{
HOST_GETCONFIG_Successful = 0, /**< No error occurred while retrieving the configuration descriptor */
|