Commit 7c6b2019 authored by Dean Camera's avatar Dean Camera
Browse files

Fix Mass Storage Host Class driver GetMaxLUN command - incorrect function...

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.
parent eaa914a4
......@@ -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;
......
......@@ -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
......
......@@ -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);
......
......@@ -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
......@@ -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__)
......
......@@ -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)
......
......@@ -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,
......
......@@ -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
......
......@@ -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 */
......
......@@ -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)
*
*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment