From e338cb6f329d6bf948abad88637f81436ee90daf Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Thu, 18 Jun 2009 07:53:51 +0000 Subject: [PATCH] Added new USB_Host_ClearPipeStall() convenience function to clear a stall condition on an attached device's endpoint. Added new USB_Host_GetDeviceDescriptor() convenience function to retrieve the attached device's Device descriptor. Make Pipe_ConfigurePipe() mask the given endpoint number against PIPE_EPNUM_MASK to ensure the endpoint IN direction bit is cleared to prevent endpoint type corruption. Fix documentation mentioning Pipe_GetCurrentToken() function when real name is Pipe_GetPipeToken(). --- Bootloaders/CDC/makefile | 4 --- Bootloaders/DFU/makefile | 4 --- Bootloaders/TeensyHID/makefile | 4 --- .../MassStorageHost/Lib/MassStoreCommands.c | 4 +-- .../MassStorageHost/Lib/MassStoreCommands.h | 1 - .../Incomplete/BluetoothHost/BluetoothHost.c | 14 ++------ .../MassStorageHost/Lib/MassStoreCommands.c | 27 ++------------ .../MassStorageHost/Lib/MassStoreCommands.h | 1 - LUFA/Drivers/USB/HighLevel/USBTask.h | 2 ++ LUFA/Drivers/USB/LowLevel/Host.c | 35 +++++++++++++++++++ LUFA/Drivers/USB/LowLevel/Host.h | 25 +++++++++++++ LUFA/Drivers/USB/LowLevel/Pipe.c | 2 +- LUFA/Drivers/USB/LowLevel/Pipe.h | 2 +- LUFA/ManPages/ChangeLog.txt | 5 +++ LUFA/ManPages/FutureChanges.txt | 3 ++ 15 files changed, 78 insertions(+), 55 deletions(-) diff --git a/Bootloaders/CDC/makefile b/Bootloaders/CDC/makefile index cf7030d456..8425e9b312 100644 --- a/Bootloaders/CDC/makefile +++ b/Bootloaders/CDC/makefile @@ -206,10 +206,6 @@ CFLAGS += -ffunction-sections CFLAGS += -fpack-struct CFLAGS += -fshort-enums CFLAGS += -fno-inline-small-functions -CFLAGS += -fno-reorder-blocks -CFLAGS += -fno-reorder-blocks-and-partition -CFLAGS += -fno-reorder-functions -CFLAGS += -fno-toplevel-reorder CFLAGS += -Wall CFLAGS += -Wstrict-prototypes CFLAGS += -Wundef diff --git a/Bootloaders/DFU/makefile b/Bootloaders/DFU/makefile index f9f8f65633..871a92da2c 100644 --- a/Bootloaders/DFU/makefile +++ b/Bootloaders/DFU/makefile @@ -207,10 +207,6 @@ CFLAGS += -fdata-sections CFLAGS += -fpack-struct CFLAGS += -fshort-enums CFLAGS += -fno-inline-small-functions -CFLAGS += -fno-reorder-blocks -CFLAGS += -fno-reorder-blocks-and-partition -CFLAGS += -fno-reorder-functions -CFLAGS += -fno-toplevel-reorder CFLAGS += -Wall CFLAGS += -Wstrict-prototypes CFLAGS += -Wundef diff --git a/Bootloaders/TeensyHID/makefile b/Bootloaders/TeensyHID/makefile index 91d3ada0aa..fb3f1eb28c 100644 --- a/Bootloaders/TeensyHID/makefile +++ b/Bootloaders/TeensyHID/makefile @@ -206,10 +206,6 @@ CFLAGS += -ffunction-sections CFLAGS += -fpack-struct CFLAGS += -fshort-enums CFLAGS += -fno-inline-small-functions -CFLAGS += -fno-reorder-blocks -CFLAGS += -fno-reorder-blocks-and-partition -CFLAGS += -fno-reorder-functions -CFLAGS += -fno-toplevel-reorder CFLAGS += -Wall CFLAGS += -Wstrict-prototypes CFLAGS += -Wundef diff --git a/Demos/Host/ClassDriver/MassStorageHost/Lib/MassStoreCommands.c b/Demos/Host/ClassDriver/MassStorageHost/Lib/MassStoreCommands.c index afeace02f5..75974732cb 100644 --- a/Demos/Host/ClassDriver/MassStorageHost/Lib/MassStoreCommands.c +++ b/Demos/Host/ClassDriver/MassStorageHost/Lib/MassStoreCommands.c @@ -134,7 +134,7 @@ static uint8_t MassStore_WaitForDataReceived(void) if (Pipe_IsStalled()) { /* Clear the stall condition on the OUT pipe */ - MassStore_ClearPipeStall(MASS_STORE_DATA_OUT_PIPE); + USB_Host_ClearPipeStall(MASS_STORE_DATA_OUT_PIPE); return PIPE_RWSTREAM_PipeStalled; } @@ -147,7 +147,7 @@ static uint8_t MassStore_WaitForDataReceived(void) if (Pipe_IsStalled()) { /* Clear the stall condition on the IN pipe */ - MassStore_ClearPipeStall(MASS_STORE_DATA_IN_PIPE); + USB_Host_ClearPipeStall(MASS_STORE_DATA_IN_PIPE); return PIPE_RWSTREAM_PipeStalled; } diff --git a/Demos/Host/ClassDriver/MassStorageHost/Lib/MassStoreCommands.h b/Demos/Host/ClassDriver/MassStorageHost/Lib/MassStoreCommands.h index e939f1c869..78700de841 100644 --- a/Demos/Host/ClassDriver/MassStorageHost/Lib/MassStoreCommands.h +++ b/Demos/Host/ClassDriver/MassStorageHost/Lib/MassStoreCommands.h @@ -158,7 +158,6 @@ static uint8_t MassStore_GetReturnedStatus(void); #endif - uint8_t MassStore_ClearPipeStall(const uint8_t EndpointNum); uint8_t MassStore_MassStorageReset(void); uint8_t MassStore_GetMaxLUN(uint8_t* const MaxLUNIndex); uint8_t MassStore_RequestSense(const uint8_t LUNIndex, const SCSI_Request_Sense_Response_t* const SensePtr) diff --git a/Demos/Host/Incomplete/BluetoothHost/BluetoothHost.c b/Demos/Host/Incomplete/BluetoothHost/BluetoothHost.c index b7d49f609f..1aaa8141ef 100644 --- a/Demos/Host/Incomplete/BluetoothHost/BluetoothHost.c +++ b/Demos/Host/Incomplete/BluetoothHost/BluetoothHost.c @@ -144,22 +144,12 @@ void Bluetooth_Management_Task(void) } puts_P(PSTR("Bluetooth Dongle Detected.\r\n")); - - /* Standard request to set the device configuration to configuration 1 */ - USB_ControlRequest = (USB_Request_Header_t) - { - bmRequestType: (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE), - bRequest: REQ_SetConfiguration, - wValue: 1, - wIndex: 0, - wLength: 0, - }; /* Select the control pipe for the request transfer */ Pipe_SelectPipe(PIPE_CONTROLPIPE); - /* Send the request, display error and wait for device detatch if request fails */ - if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful) + /* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */ + if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Control Error (Set Configuration).\r\n")); printf_P(PSTR(" -- Error Code: %d\r\n"), ErrorCode); diff --git a/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c b/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c index afeace02f5..c524b5387e 100644 --- a/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c +++ b/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c @@ -134,7 +134,7 @@ static uint8_t MassStore_WaitForDataReceived(void) if (Pipe_IsStalled()) { /* Clear the stall condition on the OUT pipe */ - MassStore_ClearPipeStall(MASS_STORE_DATA_OUT_PIPE); + USB_Host_ClearPipeStall(MASS_STORE_DATA_OUT_PIPE); return PIPE_RWSTREAM_PipeStalled; } @@ -147,7 +147,7 @@ static uint8_t MassStore_WaitForDataReceived(void) if (Pipe_IsStalled()) { /* Clear the stall condition on the IN pipe */ - MassStore_ClearPipeStall(MASS_STORE_DATA_IN_PIPE); + USB_Host_ClearPipeStall(MASS_STORE_DATA_IN_PIPE); return PIPE_RWSTREAM_PipeStalled; } @@ -243,29 +243,6 @@ static uint8_t MassStore_GetReturnedStatus(void) return PIPE_RWSTREAM_NoError; } -/** Clears the stall condition in the attached device on the nominated endpoint number. - * - * \param EndpointNum Endpoint number in the attached device whose stall condition is to be cleared - * - * \return A value from the USB_Host_SendControlErrorCodes_t enum - */ -uint8_t MassStore_ClearPipeStall(const uint8_t EndpointNum) -{ - USB_ControlRequest = (USB_Request_Header_t) - { - .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT), - .bRequest = REQ_ClearFeature, - .wValue = FEATURE_ENDPOINT_HALT, - .wIndex = EndpointNum, - .wLength = 0, - }; - - /* Select the control pipe for the request transfer */ - Pipe_SelectPipe(PIPE_CONTROLPIPE); - - return USB_Host_SendControlRequest(NULL); -} - /** Issues a Mass Storage class specific request to reset the attached device's Mass Storage interface, * readying the device for the next CBW. * diff --git a/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.h b/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.h index e939f1c869..78700de841 100644 --- a/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.h +++ b/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.h @@ -158,7 +158,6 @@ static uint8_t MassStore_GetReturnedStatus(void); #endif - uint8_t MassStore_ClearPipeStall(const uint8_t EndpointNum); uint8_t MassStore_MassStorageReset(void); uint8_t MassStore_GetMaxLUN(uint8_t* const MaxLUNIndex); uint8_t MassStore_RequestSense(const uint8_t LUNIndex, const SCSI_Request_Sense_Response_t* const SensePtr) diff --git a/LUFA/Drivers/USB/HighLevel/USBTask.h b/LUFA/Drivers/USB/HighLevel/USBTask.h index e4c8a02ae5..2a9bf19535 100644 --- a/LUFA/Drivers/USB/HighLevel/USBTask.h +++ b/LUFA/Drivers/USB/HighLevel/USBTask.h @@ -116,6 +116,8 @@ * * \note This global is only present if the user application can be a USB host. * + * \see \ref USB_Host_States_t for a list of possible host states + * * \ingroup Group_Host */ extern volatile uint8_t USB_HostState; diff --git a/LUFA/Drivers/USB/LowLevel/Host.c b/LUFA/Drivers/USB/LowLevel/Host.c index c059b43acf..421719bf84 100644 --- a/LUFA/Drivers/USB/LowLevel/Host.c +++ b/LUFA/Drivers/USB/LowLevel/Host.c @@ -302,4 +302,39 @@ uint8_t USB_Host_SetDeviceConfiguration(uint8_t ConfigNumber) return USB_Host_SendControlRequest(NULL); } +uint8_t USB_Host_GetDeviceDescriptor(USB_Descriptor_Device_t* DeviceDescriptorPtr) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + bmRequestType: (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE), + bRequest: REQ_GetDescriptor, + wValue: (DTYPE_Device << 8), + wIndex: 0, + wLength: sizeof(USB_Descriptor_Device_t), + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + return USB_Host_SendControlRequest(DeviceDescriptorPtr); +} + +uint8_t USB_Host_ClearPipeStall(uint8_t EndpointNum) +{ + if (Pipe_GetPipeToken() == PIPE_TOKEN_IN) + EndpointNum |= (1 << 7); + + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT), + .bRequest = REQ_ClearFeature, + .wValue = FEATURE_ENDPOINT_HALT, + .wIndex = EndpointNum, + .wLength = 0, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + return USB_Host_SendControlRequest(NULL); +} + #endif diff --git a/LUFA/Drivers/USB/LowLevel/Host.h b/LUFA/Drivers/USB/LowLevel/Host.h index 7130c7579c..2a40a1dbc6 100644 --- a/LUFA/Drivers/USB/LowLevel/Host.h +++ b/LUFA/Drivers/USB/LowLevel/Host.h @@ -47,6 +47,8 @@ #include "../../../Common/Common.h" #include "../HighLevel/USBInterrupt.h" + #include "../HighLevel/StdDescriptors.h" + #include "Pipe.h" /* Enable C linkage for C++ Compilers: */ #if defined(__cplusplus) @@ -185,6 +187,29 @@ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. */ uint8_t USB_Host_SetDeviceConfiguration(uint8_t ConfigNumber); + + /** Convenience function. This routine sends a GetDescriptor standard request to the attached + * device, requesting the device descriptor. This can be used to easily retrieve information + * about the device such as its VID, PID and power requirements. + * + * \note After this routine returns, the control pipe will be selected. + * + * \param DeviceDescriptorPtr Pointer to the destination device descriptor structure where + * the read data is to be stored + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. + */ + uint8_t USB_Host_GetDeviceDescriptor(USB_Descriptor_Device_t* DeviceDescriptorPtr); + + /** Clears a stall condition on the given pipe, via a ClearFeature request to the attached device. + * + * \note After this routine returns, the control pipe will be selected. + * + * \param EndpointIndex Index of the endpoint to clear + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. + */ + uint8_t USB_Host_ClearPipeStall(uint8_t EndpointIndex); /* Enums: */ /** Enum for the various states of the USB Host state machine. Only some states are diff --git a/LUFA/Drivers/USB/LowLevel/Pipe.c b/LUFA/Drivers/USB/LowLevel/Pipe.c index 3c493fe5a0..189aaa63b0 100644 --- a/LUFA/Drivers/USB/LowLevel/Pipe.c +++ b/LUFA/Drivers/USB/LowLevel/Pipe.c @@ -45,7 +45,7 @@ bool Pipe_ConfigurePipe(const uint8_t Number, const uint8_t Type, const uint8_t UPCFG1X = 0; - UPCFG0X = ((Type << EPTYPE0) | Token | (EndpointNumber << PEPNUM0)); + UPCFG0X = ((Type << EPTYPE0) | Token | ((EndpointNumber & PIPE_EPNUM_MASK) << PEPNUM0)); UPCFG1X = ((1 << ALLOC) | Banks | Pipe_BytesToEPSizeMask(Size)); return Pipe_IsConfigured(); diff --git a/LUFA/Drivers/USB/LowLevel/Pipe.h b/LUFA/Drivers/USB/LowLevel/Pipe.h index 62cbe65a22..82d9b69d42 100644 --- a/LUFA/Drivers/USB/LowLevel/Pipe.h +++ b/LUFA/Drivers/USB/LowLevel/Pipe.h @@ -219,7 +219,7 @@ * * \return The current pipe token, as a PIPE_TOKEN_* mask */ - static inline uint8_t Pipe_GetCurrentToken(void); + static inline uint8_t Pipe_GetPipeToken(void); /** Sets the token for the currently selected pipe to one of the tokens specified by the PIPE_TOKEN_* * masks. This can be used on CONTROL type pipes, to allow for bidirectional transfer of data during diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index b3d533d725..3ef3a6e83f 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -20,8 +20,13 @@ * internal control * - Added new USB_Host_SetDeviceConfiguration() convenience function for easy configuration selection of devices while in USB * host mode + * - Added new USB_Host_ClearPipeStall() convenience function to clear a stall condition on an attached device's endpoint + * - Added new USB_Host_GetDeviceDescriptor() convenience function to retrieve the attached device's Device descriptor * - Added USB Missle Launcher project, submitted by Dave Fletcher * - Pipe_GetErrorFlags() now returns additional error flags for overflow and underflow errors + * - Make Pipe_ConfigurePipe() mask the given endpoint number against PIPE_EPNUM_MASK to ensure the endpoint IN direction bit is + * cleared to prevent endpoint type corruption + * - Fix documentation mentioning Pipe_GetCurrentToken() function when real name is Pipe_GetPipeToken() * * * \section Sec_ChangeLog090605 Version 090605 diff --git a/LUFA/ManPages/FutureChanges.txt b/LUFA/ManPages/FutureChanges.txt index e8ae78588e..2a714f7205 100644 --- a/LUFA/ManPages/FutureChanges.txt +++ b/LUFA/ManPages/FutureChanges.txt @@ -21,4 +21,7 @@ * - Port LUFA to the Atmel ARM7 series microcontrollers * - Remake AVRStudio project files * - Master LUFA include file + * - Debug mode for pipe/endpoint calls + * - Device descriptor get routines + * - Add ClearPipeStall host function */