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.
pull/1469/head
Dean Camera 15 years ago
parent eaa914a4e4
commit 7c6b2019a3

@ -99,6 +99,14 @@ int main(void)
break; 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"); printf("Mouse Enumerated.\r\n");
USB_HostState = HOST_STATE_Configured; USB_HostState = HOST_STATE_Configured;
break; break;

@ -137,7 +137,7 @@
* *
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state. * \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 * \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. * 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] 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 * \param[out] ReportSize Number of bytes in the generated input report, or zero if no report is to be sent

@ -145,6 +145,8 @@
* values of the interface have been changed to push the new settings to the USB device. * 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 * \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); 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. * 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 * \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); uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);

@ -169,23 +169,73 @@ bool HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo)
return ReportReceived; 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) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SetProtocol, .bRequest = REQ_SetProtocol,
.wValue = UseReportProtocol, .wValue = 1,
.wIndex = HIDInterfaceInfo->State.InterfaceNumber, .wIndex = HIDInterfaceInfo->State.InterfaceNumber,
.wLength = 0, .wLength = 0,
}; };
Pipe_SelectPipe(PIPE_CONTROLPIPE); Pipe_SelectPipe(PIPE_CONTROLPIPE);
if (UseReportProtocol && !(HIDInterfaceInfo->State.SupportsBootSubClass)) if (!(HIDInterfaceInfo->State.SupportsBootSubClass))
return MS_ERROR_UNSUPPORTED; return HID_ERROR_LOGICAL;
return USB_Host_SendControlRequest(NULL); 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 #endif

@ -34,6 +34,7 @@
* \section Sec_Dependencies Module Source Dependencies * \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module: * 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/HID.c
* - LUFA/Drivers/USB/Class/Host/HIDParser.c
* *
* \section Module Description * \section Module Description
* Host Mode USB Class driver framework interface, for the HID USB Class driver. * 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: */ /* Public Interface - May be used in end-application: */
/* Macros: */ /* Macros: */
/** Error code for some HID Host functions, indicating a logical (and not hardware) error */ /** 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: */ /* Type Defines: */
/** Class state structure. An instance of this structure should be made within the user application, /** 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 */ 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 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 */ 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 } 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; } USB_ClassInfo_HID_Host_t;
/* Enums: */ /* Enums: */
/** Enum for the possible error codes returned by the \ref HID_Host_ConfigurePipes() function. */
enum HIDHost_EnumerationFailure_ErrorCodes_t enum HIDHost_EnumerationFailure_ErrorCodes_t
{ {
HID_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */ HID_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */
@ -112,13 +114,64 @@
}; };
/* Function Prototypes: */ /* 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); 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 HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* HIDInterfaceInfo, uint16_t ConfigDescriptorLength,
uint8_t* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1, 3); 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); 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: */ /* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__) #if !defined(__DOXYGEN__)

@ -274,7 +274,9 @@ static uint8_t MS_Host_GetReturnedStatus(USB_ClassInfo_MS_Host_t* MSInterfaceInf
if ((ErrorCode = Pipe_Read_Stream_LE(SCSICommandStatus, sizeof(MS_CommandStatusWrapper_t), if ((ErrorCode = Pipe_Read_Stream_LE(SCSICommandStatus, sizeof(MS_CommandStatusWrapper_t),
NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError) NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
return ErrorCode; {
return ErrorCode;
}
Pipe_ClearIN(); Pipe_ClearIN();
Pipe_Freeze(); Pipe_Freeze();
@ -322,14 +324,10 @@ uint8_t MS_Host_GetMaxLUN(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, uint8_t* Max
Pipe_SelectPipe(PIPE_CONTROLPIPE); Pipe_SelectPipe(PIPE_CONTROLPIPE);
if ((ErrorCode = USB_Host_SendControlRequest(MaxLUNIndex)) == HOST_SENDCONTROL_SetupStalled) if ((ErrorCode = USB_Host_SendControlRequest(MaxLUNIndex)) != HOST_SENDCONTROL_Successful)
{ *MaxLUNIndex = 0;
Pipe_ClearStall();
*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) uint8_t MS_Host_GetInquiryData(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, uint8_t LUNIndex, SCSI_Inquiry_Response_t* InquiryData)

@ -56,7 +56,7 @@
/* Public Interface - May be used in end-application: */ /* Public Interface - May be used in end-application: */
/* Macros: */ /* Macros: */
/** Error code for some Mass Storage Host functions, indicating a logical (and not hardware) error */ /** 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: */ /* Type Defines: */
/** Class state structure. An instance of this structure should be made within the user application, /** Class state structure. An instance of this structure should be made within the user application,

@ -56,7 +56,7 @@
/* Public Interface - May be used in end-application: */ /* Public Interface - May be used in end-application: */
/* Macros: */ /* Macros: */
/** Error code for some Still Image Host functions, indicating a logical (and not hardware) error */ /** 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: */ /* Type Defines: */
typedef struct typedef struct

@ -155,6 +155,7 @@
uint8_t USB_GetNextDescriptorComp(uint16_t* BytesRem, uint8_t** CurrConfigLoc, ConfigComparatorPtr_t ComparatorRoutine); uint8_t USB_GetNextDescriptorComp(uint16_t* BytesRem, uint8_t** CurrConfigLoc, ConfigComparatorPtr_t ComparatorRoutine);
/* Enums: */ /* Enums: */
/** Enum for the possible return codes of the \ref USB_GetDeviceConfigDescriptor() function. */
enum USB_Host_GetConfigDescriptor_ErrorCodes_t enum USB_Host_GetConfigDescriptor_ErrorCodes_t
{ {
HOST_GETCONFIG_Successful = 0, /**< No error occurred while retrieving the configuration descriptor */ HOST_GETCONFIG_Successful = 0, /**< No error occurred while retrieving the configuration descriptor */

@ -65,7 +65,7 @@
* - Fix allowable F_CPU values comment in project makefiles to more accurately reflect the allowable values on the USB AVRs * - 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 * - 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 * 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) * - Fixed MIDI Device Class driver not sending/receiving MIDI packets of the correct size (thanks to Thomas Bleeker)
* *
* *

Loading…
Cancel
Save