Renamed USB_Host_ClearPipeStall() to USB_Host_ClearEndpointStall() as the function works on an endpoint address within the attached device, and not a Pipe within the host.

Updated MS_Host_ResetMSInterface() to now perform a full Mass Storage reset sequence to prevent data corruption in the event of a device lock up or timeout (thanks to David Lyons).

Add parenthesis around the library Endianness macros that do nothing on a particular architecture to prevent operator precedence issues depending on usage.

Minor documentation corrections.
pull/1469/head
Dean Camera 13 years ago
parent cff190b8f4
commit a233109909

@ -145,7 +145,7 @@ static uint8_t MassStore_WaitForDataReceived(void)
if (Pipe_IsStalled()) if (Pipe_IsStalled())
{ {
/* Clear the stall condition on the OUT pipe */ /* Clear the stall condition on the OUT pipe */
USB_Host_ClearPipeStall(MASS_STORE_DATA_OUT_PIPE); USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress());
return PIPE_RWSTREAM_PipeStalled; return PIPE_RWSTREAM_PipeStalled;
} }
@ -158,7 +158,7 @@ static uint8_t MassStore_WaitForDataReceived(void)
if (Pipe_IsStalled()) if (Pipe_IsStalled())
{ {
/* Clear the stall condition on the IN pipe */ /* Clear the stall condition on the IN pipe */
USB_Host_ClearPipeStall(MASS_STORE_DATA_IN_PIPE); USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress());
return PIPE_RWSTREAM_PipeStalled; return PIPE_RWSTREAM_PipeStalled;
} }
@ -274,12 +274,15 @@ static uint8_t MassStore_GetReturnedStatus(MS_CommandStatusWrapper_t* const SCSI
} }
/** Issues a Mass Storage class specific request to reset the attached device's Mass Storage interface, /** Issues a Mass Storage class specific request to reset the attached device's Mass Storage interface,
* readying the device for the next CBW. * readying the device for the next CBW. The Data endpoints are cleared of any STALL condition once this
* command completes sucessfuly.
* *
* \return A value from the USB_Host_SendControlErrorCodes_t enum, or MASS_STORE_SCSI_COMMAND_FAILED if the SCSI command fails * \return A value from the USB_Host_SendControlErrorCodes_t enum, or MASS_STORE_SCSI_COMMAND_FAILED if the SCSI command fails
*/ */
uint8_t MassStore_MassStorageReset(void) uint8_t MassStore_MassStorageReset(void)
{ {
uint8_t ErrorCode;
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),
@ -292,7 +295,22 @@ uint8_t MassStore_MassStorageReset(void)
/* Select the control pipe for the request transfer */ /* Select the control pipe for the request transfer */
Pipe_SelectPipe(PIPE_CONTROLPIPE); Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(NULL); if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
return ErrorCode;
/* Select first data pipe to clear STALL condition if one exists */
Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE);
if ((ErrorCode = USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress())) != HOST_SENDCONTROL_Successful)
return ErrorCode;
/* Select second data pipe to clear STALL condition if one exists */
Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE);
if ((ErrorCode = USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress())) != HOST_SENDCONTROL_Successful)
return ErrorCode;
return HOST_SENDCONTROL_Successful;
} }
/** Issues a Mass Storage class specific request to determine the index of the highest numbered Logical /** Issues a Mass Storage class specific request to determine the index of the highest numbered Logical

@ -140,7 +140,7 @@ uint8_t SImage_ReceiveBlockHeader(void)
if (Pipe_IsStalled()) if (Pipe_IsStalled())
{ {
/* Clear the stall condition on the OUT pipe */ /* Clear the stall condition on the OUT pipe */
USB_Host_ClearPipeStall(SIMAGE_DATA_OUT_PIPE); USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress());
/* Return error code and break out of the loop */ /* Return error code and break out of the loop */
return PIPE_RWSTREAM_PipeStalled; return PIPE_RWSTREAM_PipeStalled;
@ -154,7 +154,7 @@ uint8_t SImage_ReceiveBlockHeader(void)
if (Pipe_IsStalled()) if (Pipe_IsStalled())
{ {
/* Clear the stall condition on the IN pipe */ /* Clear the stall condition on the IN pipe */
USB_Host_ClearPipeStall(SIMAGE_DATA_IN_PIPE); USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress());
/* Return error code */ /* Return error code */
return PIPE_RWSTREAM_PipeStalled; return PIPE_RWSTREAM_PipeStalled;

@ -102,20 +102,20 @@
#if defined(ARCH_BIG_ENDIAN) && !defined(le16_to_cpu) #if defined(ARCH_BIG_ENDIAN) && !defined(le16_to_cpu)
#define le16_to_cpu(x) SwapEndian_16(x) #define le16_to_cpu(x) SwapEndian_16(x)
#define le32_to_cpu(x) SwapEndian_32(x) #define le32_to_cpu(x) SwapEndian_32(x)
#define be16_to_cpu(x) x #define be16_to_cpu(x) (x)
#define be32_to_cpu(x) x #define be32_to_cpu(x) (x)
#define cpu_to_le16(x) SwapEndian_16(x) #define cpu_to_le16(x) SwapEndian_16(x)
#define cpu_to_le32(x) SwapEndian_32(x) #define cpu_to_le32(x) SwapEndian_32(x)
#define cpu_to_be16(x) x #define cpu_to_be16(x) (x)
#define cpu_to_be32(x) x #define cpu_to_be32(x) (x)
#define LE16_TO_CPU(x) SWAPENDIAN_16(x) #define LE16_TO_CPU(x) SWAPENDIAN_16(x)
#define LE32_TO_CPU(x) SWAPENDIAN_32(x) #define LE32_TO_CPU(x) SWAPENDIAN_32(x)
#define BE16_TO_CPU(x) x #define BE16_TO_CPU(x) (x)
#define BE32_TO_CPU(x) x #define BE32_TO_CPU(x) (x)
#define CPU_TO_LE16(x) SWAPENDIAN_16(x) #define CPU_TO_LE16(x) SWAPENDIAN_16(x)
#define CPU_TO_LE32(x) SWAPENDIAN_32(x) #define CPU_TO_LE32(x) SWAPENDIAN_32(x)
#define CPU_TO_BE16(x) x #define CPU_TO_BE16(x) (x)
#define CPU_TO_BE32(x) x #define CPU_TO_BE32(x) (x)
#elif !defined(le16_to_cpu) #elif !defined(le16_to_cpu)
/** \name Run-time endianness conversion */ /** \name Run-time endianness conversion */
//@{ //@{
@ -134,7 +134,7 @@
* *
* \return Endian corrected version of the input value. * \return Endian corrected version of the input value.
*/ */
#define le16_to_cpu(x) x #define le16_to_cpu(x) (x)
/** Performs a conversion between a Little Endian encoded 32-bit piece of data and the /** Performs a conversion between a Little Endian encoded 32-bit piece of data and the
* Endianness of the currently selected CPU architecture. * Endianness of the currently selected CPU architecture.
@ -150,7 +150,7 @@
* *
* \return Endian corrected version of the input value. * \return Endian corrected version of the input value.
*/ */
#define le32_to_cpu(x) x #define le32_to_cpu(x) (x)
/** Performs a conversion between a Big Endian encoded 16-bit piece of data and the /** Performs a conversion between a Big Endian encoded 16-bit piece of data and the
* Endianness of the currently selected CPU architecture. * Endianness of the currently selected CPU architecture.
@ -198,7 +198,7 @@
* *
* \return Endian corrected version of the input value. * \return Endian corrected version of the input value.
*/ */
#define cpu_to_le16(x) x #define cpu_to_le16(x) (x)
/** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it /** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it
* is in Little Endian format regardless of the currently selected CPU architecture. * is in Little Endian format regardless of the currently selected CPU architecture.
@ -214,7 +214,7 @@
* *
* \return Endian corrected version of the input value. * \return Endian corrected version of the input value.
*/ */
#define cpu_to_le32(x) x #define cpu_to_le32(x) (x)
/** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it /** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it
* is in Big Endian format regardless of the currently selected CPU architecture. * is in Big Endian format regardless of the currently selected CPU architecture.
@ -267,7 +267,7 @@
* *
* \return Endian corrected version of the input value. * \return Endian corrected version of the input value.
*/ */
#define LE16_TO_CPU(x) x #define LE16_TO_CPU(x) (x)
/** Performs a conversion between a Little Endian encoded 32-bit piece of data and the /** Performs a conversion between a Little Endian encoded 32-bit piece of data and the
* Endianness of the currently selected CPU architecture. * Endianness of the currently selected CPU architecture.
@ -283,7 +283,7 @@
* *
* \return Endian corrected version of the input value. * \return Endian corrected version of the input value.
*/ */
#define LE32_TO_CPU(x) x #define LE32_TO_CPU(x) (x)
/** Performs a conversion between a Big Endian encoded 16-bit piece of data and the /** Performs a conversion between a Big Endian encoded 16-bit piece of data and the
* Endianness of the currently selected CPU architecture. * Endianness of the currently selected CPU architecture.
@ -331,7 +331,7 @@
* *
* \return Endian corrected version of the input value. * \return Endian corrected version of the input value.
*/ */
#define CPU_TO_LE16(x) x #define CPU_TO_LE16(x) (x)
/** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it /** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it
* is in Little Endian format regardless of the currently selected CPU architecture. * is in Little Endian format regardless of the currently selected CPU architecture.
@ -347,7 +347,7 @@
* *
* \return Endian corrected version of the input value. * \return Endian corrected version of the input value.
*/ */
#define CPU_TO_LE32(x) x #define CPU_TO_LE32(x) (x)
/** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it /** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it
* is in Big Endian format regardless of the currently selected CPU architecture. * is in Big Endian format regardless of the currently selected CPU architecture.

@ -226,8 +226,7 @@ static uint8_t MS_Host_WaitForDataReceived(USB_ClassInfo_MS_Host_t* const MSInte
if (Pipe_IsStalled()) if (Pipe_IsStalled())
{ {
USB_Host_ClearPipeStall(MSInterfaceInfo->Config.DataOUTPipeNumber); USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress());
return PIPE_RWSTREAM_PipeStalled; return PIPE_RWSTREAM_PipeStalled;
} }
@ -237,8 +236,7 @@ static uint8_t MS_Host_WaitForDataReceived(USB_ClassInfo_MS_Host_t* const MSInte
if (Pipe_IsStalled()) if (Pipe_IsStalled())
{ {
USB_Host_ClearPipeStall(MSInterfaceInfo->Config.DataINPipeNumber); USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress());
return PIPE_RWSTREAM_PipeStalled; return PIPE_RWSTREAM_PipeStalled;
} }
@ -328,6 +326,8 @@ static uint8_t MS_Host_GetReturnedStatus(USB_ClassInfo_MS_Host_t* const MSInterf
uint8_t MS_Host_ResetMSInterface(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) uint8_t MS_Host_ResetMSInterface(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo)
{ {
uint8_t ErrorCode;
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),
@ -339,7 +339,20 @@ uint8_t MS_Host_ResetMSInterface(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo)
Pipe_SelectPipe(PIPE_CONTROLPIPE); Pipe_SelectPipe(PIPE_CONTROLPIPE);
return USB_Host_SendControlRequest(NULL); if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
return ErrorCode;
Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber);
if ((ErrorCode = USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress())) != HOST_SENDCONTROL_Successful)
return ErrorCode;
Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipeNumber);
if ((ErrorCode = USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress())) != HOST_SENDCONTROL_Successful)
return ErrorCode;
return HOST_SENDCONTROL_Successful;
} }
uint8_t MS_Host_GetMaxLUN(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, uint8_t MS_Host_GetMaxLUN(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,

@ -254,7 +254,7 @@ uint8_t SI_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInf
if (Pipe_IsStalled()) if (Pipe_IsStalled())
{ {
USB_Host_ClearPipeStall(SIInterfaceInfo->Config.DataOUTPipeNumber); USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress());
return PIPE_RWSTREAM_PipeStalled; return PIPE_RWSTREAM_PipeStalled;
} }
@ -264,7 +264,7 @@ uint8_t SI_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInf
if (Pipe_IsStalled()) if (Pipe_IsStalled())
{ {
USB_Host_ClearPipeStall(SIInterfaceInfo->Config.DataINPipeNumber); USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress());
return PIPE_RWSTREAM_PipeStalled; return PIPE_RWSTREAM_PipeStalled;
} }

@ -860,7 +860,7 @@
const uint16_t Size, const uint16_t Size,
const uint8_t Banks); const uint8_t Banks);
/** Spin-loops until the currently selected non-control pipe is ready for the next packed of data to be read /** Spin-loops until the currently selected non-control pipe is ready for the next packet of data to be read
* or written to it, aborting in the case of an error condition (such as a timeout or device disconnect). * or written to it, aborting in the case of an error condition (such as a timeout or device disconnect).
* *
* \ingroup Group_PipeRW_AVR8 * \ingroup Group_PipeRW_AVR8

@ -254,7 +254,7 @@ uint8_t USB_Host_GetDeviceStatus(uint8_t* const FeatureStatus)
return USB_Host_SendControlRequest(FeatureStatus); return USB_Host_SendControlRequest(FeatureStatus);
} }
uint8_t USB_Host_ClearPipeStall(const uint8_t EndpointAddress) uint8_t USB_Host_ClearEndpointStall(const uint8_t EndpointAddress)
{ {
USB_ControlRequest = (USB_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {

@ -177,7 +177,7 @@
* *
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
*/ */
uint8_t USB_Host_ClearPipeStall(const uint8_t EndpointAddress); uint8_t USB_Host_ClearEndpointStall(const uint8_t EndpointAddress);
/** Selects a given alternative setting for the specified interface, via a SET INTERFACE standard request to /** Selects a given alternative setting for the specified interface, via a SET INTERFACE standard request to
* the attached device. * the attached device.

@ -681,7 +681,8 @@
* Under GCC, strings prefixed with the "L" character (before * Under GCC, strings prefixed with the "L" character (before
* the opening string quotation mark) are considered to be * the opening string quotation mark) are considered to be
* Unicode strings, and may be used instead of an explicit * Unicode strings, and may be used instead of an explicit
* array of ASCII characters. * array of ASCII characters on little endian devices with
* UTF-16-LE \c wchar_t encoding.
*/ */
#endif #endif
} ATTR_PACKED USB_Descriptor_String_t; } ATTR_PACKED USB_Descriptor_String_t;

@ -871,7 +871,7 @@
const uint16_t Size, const uint16_t Size,
const uint8_t Banks); const uint8_t Banks);
/** Spin-loops until the currently selected non-control pipe is ready for the next packed of data to be read /** Spin-loops until the currently selected non-control pipe is ready for the next packet of data to be read
* or written to it, aborting in the case of an error condition (such as a timeout or device disconnect). * or written to it, aborting in the case of an error condition (such as a timeout or device disconnect).
* *
* \ingroup Group_PipeRW_UC3 * \ingroup Group_PipeRW_UC3

@ -58,6 +58,10 @@
* - Removed the ENDPOINT_DESCRIPTOR_DIR_* macros, replaced by ENDPOINT_DIR_* instead * - Removed the ENDPOINT_DESCRIPTOR_DIR_* macros, replaced by ENDPOINT_DIR_* instead
* - Renamed the JTAG_DEBUG_ASSERT() macro to JTAG_ASSERT() * - Renamed the JTAG_DEBUG_ASSERT() macro to JTAG_ASSERT()
* - Added variable number of axis to HID_DESCRIPTOR_JOYSTICK() for multi-axis joysticks above just X and Y * - Added variable number of axis to HID_DESCRIPTOR_JOYSTICK() for multi-axis joysticks above just X and Y
* - Renamed USB_Host_ClearPipeStall() to USB_Host_ClearEndpointStall() as the function works on an endpoint address within the attached device,
* and not a Pipe within the host
* - The MS_Host_ResetMSInterface() now performs a full Mass Storage reset sequence to prevent data corruption in the event of a device
* lock up or timeout (thanks to David Lyons)
* - Library Applications: * - Library Applications:
* - Modified the Low Level and Class Driver AudioInput and AudioOutput demos to support multiple audio sample rates * - Modified the Low Level and Class Driver AudioInput and AudioOutput demos to support multiple audio sample rates
* - Updated all host mode demos and projects to use the EVENT_USB_Host_DeviceEnumerationComplete() event callback for device configuration * - Updated all host mode demos and projects to use the EVENT_USB_Host_DeviceEnumerationComplete() event callback for device configuration

Loading…
Cancel
Save