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 | |
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.
-rw-r--r-- | Demos/Host/ClassDriver/MouseHost/MouseHost.c | 8 | ||||
-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 | ||||
-rw-r--r-- | LUFA/ManPages/ChangeLog.txt | 2 |
10 files changed, 134 insertions, 20 deletions
diff --git a/Demos/Host/ClassDriver/MouseHost/MouseHost.c b/Demos/Host/ClassDriver/MouseHost/MouseHost.c index 844fa334c..5b9b4431e 100644 --- a/Demos/Host/ClassDriver/MouseHost/MouseHost.c +++ b/Demos/Host/ClassDriver/MouseHost/MouseHost.c @@ -98,6 +98,14 @@ int main(void) USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
}
+
+ if (USB_HID_Host_SetBootProtocol(&Mouse_HID_Interface) != 0)
+ {
+ printf("Could not Set Boot Protocol Mode.\r\n");
+ LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+ USB_HostState = HOST_STATE_WaitForDeviceRemoval;
+ break;
+ }
printf("Mouse Enumerated.\r\n");
USB_HostState = HOST_STATE_Configured;
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 */
diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index be5251fa5..b2e80da7a 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -65,7 +65,7 @@ * - Fix allowable F_CPU values comment in project makefiles to more accurately reflect the allowable values on the USB AVRs
* - Fixed DFU and CDC class bootloaders on the series 2 USB AVRs, corrected invalid signatures, added support for the new
* ATMEGAxxx2 series 2 variant AVRs to the DFU bootloader
- * - Fixed Low Level USBtoSerial demo not storing received characters (thanks to Michael from DirectAid.ca)
+ * - Fixed Low Level USBtoSerial demo not storing received characters (thanks to Michael Cooper)
* - Fixed MIDI Device Class driver not sending/receiving MIDI packets of the correct size (thanks to Thomas Bleeker)
*
*
|