From 81fd8d4004247f169987acb2b5b4225bae651baf Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Sun, 13 Mar 2011 22:02:07 +0000 Subject: Re-add accidentally deleted Host_UC3.c and Host_UC3.h files. --- LUFA/Drivers/USB/Core/UC3/Host_UC3.c | 355 +++++++++++++++++++++++++++++ LUFA/Drivers/USB/Core/UC3/Host_UC3.h | 422 +++++++++++++++++++++++++++++++++++ 2 files changed, 777 insertions(+) create mode 100644 LUFA/Drivers/USB/Core/UC3/Host_UC3.c create mode 100644 LUFA/Drivers/USB/Core/UC3/Host_UC3.h (limited to 'LUFA/Drivers') diff --git a/LUFA/Drivers/USB/Core/UC3/Host_UC3.c b/LUFA/Drivers/USB/Core/UC3/Host_UC3.c new file mode 100644 index 000000000..6d49abbb2 --- /dev/null +++ b/LUFA/Drivers/USB/Core/UC3/Host_UC3.c @@ -0,0 +1,355 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2011. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#define __INCLUDE_FROM_HOST_C +#include "../Host.h" + +void USB_Host_ProcessNextHostState(void) +{ + uint8_t ErrorCode = HOST_ENUMERROR_NoError; + uint8_t SubErrorCode = HOST_ENUMERROR_NoError; + + static uint16_t WaitMSRemaining; + static uint8_t PostWaitState; + + switch (USB_HostState) + { + case HOST_STATE_WaitForDevice: + if (WaitMSRemaining) + { + if ((SubErrorCode = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful) + { + USB_HostState = PostWaitState; + ErrorCode = HOST_ENUMERROR_WaitStage; + break; + } + + if (!(--WaitMSRemaining)) + USB_HostState = PostWaitState; + } + + break; + case HOST_STATE_Powered: + WaitMSRemaining = HOST_DEVICE_SETTLE_DELAY_MS; + + USB_HostState = HOST_STATE_Powered_WaitForDeviceSettle; + break; + case HOST_STATE_Powered_WaitForDeviceSettle: + if (WaitMSRemaining--) + { + _delay_ms(1); + break; + } + else + { + USB_Host_VBUS_Manual_Off(); + + USB_OTGPAD_On(); + USB_Host_VBUS_Auto_Enable(); + USB_Host_VBUS_Auto_On(); + + USB_HostState = HOST_STATE_Powered_WaitForConnect; + } + + break; + case HOST_STATE_Powered_WaitForConnect: + if (USB_INT_HasOccurred(USB_INT_DCONNI)) + { + USB_INT_Clear(USB_INT_DCONNI); + USB_INT_Clear(USB_INT_DDISCI); + + USB_INT_Clear(USB_INT_VBERRI); + USB_INT_Enable(USB_INT_VBERRI); + + USB_Host_ResumeBus(); + Pipe_ClearPipes(); + + HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Powered_DoReset); + } + + break; + case HOST_STATE_Powered_DoReset: + USB_Host_ResetDevice(); + + HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Powered_ConfigPipe); + break; + case HOST_STATE_Powered_ConfigPipe: + Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL, + PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP, + PIPE_CONTROLPIPE_DEFAULT_SIZE, PIPE_BANK_SINGLE); + + if (!(Pipe_IsConfigured())) + { + ErrorCode = HOST_ENUMERROR_PipeConfigError; + SubErrorCode = 0; + break; + } + + USB_HostState = HOST_STATE_Default; + break; + case HOST_STATE_Default: + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE), + .bRequest = REQ_GetDescriptor, + .wValue = (DTYPE_Device << 8), + .wIndex = 0, + .wLength = 8, + }; + + uint8_t DataBuffer[8]; + + if ((SubErrorCode = USB_Host_SendControlRequest(DataBuffer)) != HOST_SENDCONTROL_Successful) + { + ErrorCode = HOST_ENUMERROR_ControlError; + break; + } + + USB_ControlPipeSize = DataBuffer[offsetof(USB_Descriptor_Device_t, Endpoint0Size)]; + + USB_Host_ResetDevice(); + + HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Default_PostReset); + break; + case HOST_STATE_Default_PostReset: + Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL, + PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP, + USB_ControlPipeSize, PIPE_BANK_SINGLE); + + if (!(Pipe_IsConfigured())) + { + ErrorCode = HOST_ENUMERROR_PipeConfigError; + SubErrorCode = 0; + break; + } + + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE), + .bRequest = REQ_SetAddress, + .wValue = USB_HOST_DEVICEADDRESS, + .wIndex = 0, + .wLength = 0, + }; + + if ((SubErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful) + { + ErrorCode = HOST_ENUMERROR_ControlError; + break; + } + + HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Default_PostAddressSet); + break; + case HOST_STATE_Default_PostAddressSet: + USB_Host_SetDeviceAddress(USB_HOST_DEVICEADDRESS); + + EVENT_USB_Host_DeviceEnumerationComplete(); + USB_HostState = HOST_STATE_Addressed; + break; + } + + if ((ErrorCode != HOST_ENUMERROR_NoError) && (USB_HostState != HOST_STATE_Unattached)) + { + EVENT_USB_Host_DeviceEnumerationFailed(ErrorCode, SubErrorCode); + + USB_Host_VBUS_Auto_Off(); + + EVENT_USB_Host_DeviceUnattached(); + + USB_ResetInterface(); + } +} + +uint8_t USB_Host_WaitMS(uint8_t MS) +{ + bool BusSuspended = USB_Host_IsBusSuspended(); + uint8_t ErrorCode = HOST_WAITERROR_Successful; + bool HSOFIEnabled = USB_INT_IsEnabled(USB_INT_HSOFI); + + USB_INT_Disable(USB_INT_HSOFI); + USB_INT_Clear(USB_INT_HSOFI); + + USB_Host_ResumeBus(); + + while (MS) + { + if (USB_INT_HasOccurred(USB_INT_HSOFI)) + { + USB_INT_Clear(USB_INT_HSOFI); + MS--; + } + + if ((USB_HostState == HOST_STATE_Unattached) || (USB_CurrentMode != USB_MODE_Host)) + { + ErrorCode = HOST_WAITERROR_DeviceDisconnect; + + break; + } + + if (Pipe_IsError() == true) + { + Pipe_ClearError(); + ErrorCode = HOST_WAITERROR_PipeError; + + break; + } + + if (Pipe_IsStalled() == true) + { + Pipe_ClearStall(); + ErrorCode = HOST_WAITERROR_SetupStalled; + + break; + } + } + + if (BusSuspended) + USB_Host_SuspendBus(); + + if (HSOFIEnabled) + USB_INT_Enable(USB_INT_HSOFI); + + return ErrorCode; +} + +static void USB_Host_ResetDevice(void) +{ + bool BusSuspended = USB_Host_IsBusSuspended(); + + USB_INT_Disable(USB_INT_DDISCI); + + USB_Host_ResetBus(); + while (!(USB_Host_IsBusResetComplete())); + USB_Host_ResumeBus(); + + bool HSOFIEnabled = USB_INT_IsEnabled(USB_INT_HSOFI); + + USB_INT_Disable(USB_INT_HSOFI); + USB_INT_Clear(USB_INT_HSOFI); + + for (uint8_t MSRem = 10; MSRem != 0; MSRem--) + { + /* Workaround for powerless-pull-up devices. After a USB bus reset, + all disconnection interrupts are suppressed while a USB frame is + looked for - if it is found within 10ms, the device is still + present. */ + + if (USB_INT_HasOccurred(USB_INT_HSOFI)) + { + USB_INT_Clear(USB_INT_HSOFI); + USB_INT_Clear(USB_INT_DDISCI); + break; + } + + _delay_ms(1); + } + + if (HSOFIEnabled) + USB_INT_Enable(USB_INT_HSOFI); + + if (BusSuspended) + USB_Host_SuspendBus(); + + USB_INT_Enable(USB_INT_DDISCI); +} + +uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE), + .bRequest = REQ_SetConfiguration, + .wValue = ConfigNumber, + .wIndex = 0, + .wLength = 0, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + return USB_Host_SendControlRequest(NULL); +} + +uint8_t USB_Host_GetDeviceDescriptor(void* const 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_GetDeviceStringDescriptor(const uint8_t Index, + void* const Buffer, + const uint8_t BufferLength) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE), + .bRequest = REQ_GetDescriptor, + .wValue = (DTYPE_String << 8) | Index, + .wIndex = 0, + .wLength = BufferLength, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + return USB_Host_SendControlRequest(Buffer); +} + +uint8_t USB_Host_ClearPipeStall(const uint8_t EndpointNum) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT), + .bRequest = REQ_ClearFeature, + .wValue = FEATURE_SEL_EndpointHalt, + .wIndex = EndpointNum, + .wLength = 0, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + return USB_Host_SendControlRequest(NULL); +} + +#endif + diff --git a/LUFA/Drivers/USB/Core/UC3/Host_UC3.h b/LUFA/Drivers/USB/Core/UC3/Host_UC3.h new file mode 100644 index 000000000..4d08a4c98 --- /dev/null +++ b/LUFA/Drivers/USB/Core/UC3/Host_UC3.h @@ -0,0 +1,422 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2011. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Host definitions for the AVR32 UC3B microcontrollers. + * \copydetails Group_Host_UC3B + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_Host + * \defgroup Group_Host_UC3B Host Management (UC3B) + * \brief USB Host definitions for the AVR32 UC3B microcontrollers. + * + * Architecture specific USB Host definitions for the Atmel 32-bit AVR UC3B microcontrollers. + * + * @{ + */ + +#ifndef __USBHOST_UC3B_H__ +#define __USBHOST_UC3B_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../StdDescriptors.h" + #include "../Pipe.h" + #include "../USBInterrupt.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Indicates the fixed USB device address which any attached device is enumerated to when in + * host mode. As only one USB device may be attached to the AVR in host mode at any one time + * and that the address used is not important (other than the fact that it is non-zero), a + * fixed value is specified by the library. + */ + #define USB_HOST_DEVICEADDRESS 1 + + #if !defined(USB_HOST_TIMEOUT_MS) || defined(__DOXYGEN__) + /** Constant for the maximum software timeout period of sent USB control transactions to an attached + * device. If a device fails to respond to a sent control request within this period, the + * library will return a timeout error code. + * + * This value may be overridden in the user project makefile as the value of the + * \ref USB_HOST_TIMEOUT_MS token, and passed to the compiler using the -D switch. + */ + #define USB_HOST_TIMEOUT_MS 1000 + #endif + + #if !defined(HOST_DEVICE_SETTLE_DELAY_MS) || defined(__DOXYGEN__) + /** Constant for the delay in milliseconds after a device is connected before the library + * will start the enumeration process. Some devices require a delay of up to 5 seconds + * after connection before the enumeration process can start or incorrect operation will + * occur. + * + * The default delay value may be overridden in the user project makefile by defining the + * \c HOST_DEVICE_SETTLE_DELAY_MS token to the required delay in milliseconds, and passed to the + * compiler using the -D switch. + */ + #define HOST_DEVICE_SETTLE_DELAY_MS 1000 + #endif + + /* Enums: */ + /** Enum for the error codes for the \ref EVENT_USB_Host_HostError() event. + * + * \see \ref Group_Events for more information on this event. + */ + enum USB_Host_ErrorCodes_t + { + HOST_ERROR_VBusVoltageDip = 0, /**< VBUS voltage dipped to an unacceptable level. This + * error may be the result of an attached device drawing + * too much current from the VBUS line, or due to the + * AVR's power source being unable to supply sufficient + * current. + */ + }; + + /** Enum for the error codes for the \ref EVENT_USB_Host_DeviceEnumerationFailed() event. + * + * \see \ref Group_Events for more information on this event. + */ + enum USB_Host_EnumerationErrorCodes_t + { + HOST_ENUMERROR_NoError = 0, /**< No error occurred. Used internally, this is not a valid + * ErrorCode parameter value for the \ref EVENT_USB_Host_DeviceEnumerationFailed() + * event. + */ + HOST_ENUMERROR_WaitStage = 1, /**< One of the delays between enumeration steps failed + * to complete successfully, due to a timeout or other + * error. + */ + HOST_ENUMERROR_NoDeviceDetected = 2, /**< No device was detected, despite the USB data lines + * indicating the attachment of a device. + */ + HOST_ENUMERROR_ControlError = 3, /**< One of the enumeration control requests failed to + * complete successfully. + */ + HOST_ENUMERROR_PipeConfigError = 4, /**< The default control pipe (address 0) failed to + * configure correctly. + */ + }; + + /* Inline Functions: */ + /** Returns the current USB frame number, when in host mode. Every millisecond the USB bus is active (i.e. not suspended) + * the frame number is incremented by one. + */ + static inline uint16_t USB_Host_GetFrameNumber(void) + { + return AVR32_USBB_UHFNUM; + } + + #if !defined(NO_SOF_EVENTS) + /** Enables the host mode Start Of Frame events. When enabled, this causes the + * \ref EVENT_USB_Host_StartOfFrame() event to fire once per millisecond, synchronized to the USB bus, + * at the start of each USB frame when a device is enumerated while in host mode. + * + * \note Not available when the \c NO_SOF_EVENTS compile time token is defined. + */ + static inline void USB_Host_EnableSOFEvents(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_EnableSOFEvents(void) + { + USB_INT_Enable(USB_INT_HSOFI); + } + + /** Disables the host mode Start Of Frame events. When disabled, this stops the firing of the + * \ref EVENT_USB_Host_StartOfFrame() event when enumerated in host mode. + * + * \note Not available when the NO_SOF_EVENTS compile time token is defined. + */ + static inline void USB_Host_DisableSOFEvents(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_DisableSOFEvents(void) + { + USB_INT_Disable(USB_INT_HSOFI); + } + #endif + + /** Resets the USB bus, including the endpoints in any attached device and pipes on the AVR host. + * USB bus resets leave the default control pipe configured (if already configured). + * + * If the USB bus has been suspended prior to issuing a bus reset, the attached device will be + * woken up automatically and the bus resumed after the reset has been correctly issued. + */ + static inline void USB_Host_ResetBus(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_ResetBus(void) + { + AVR32_USBB.UHCON.reset = true; + } + + /** Determines if a previously issued bus reset (via the \ref USB_Host_ResetBus() macro) has + * completed. + * + * \return Boolean \c true if no bus reset is currently being sent, \c false otherwise. + */ + static inline bool USB_Host_IsBusResetComplete(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool USB_Host_IsBusResetComplete(void) + { + return AVR32_USBB.UHCON.reset; + } + + /** Resumes USB communications with an attached and enumerated device, by resuming the transmission + * of the 1MS Start Of Frame messages to the device. When resumed, USB communications between the + * host and attached device may occur. + */ + static inline void USB_Host_ResumeBus(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_ResumeBus(void) + { + AVR32_USBB.UHCON.sofe = true; + } + + /** Suspends the USB bus, preventing any communications from occurring between the host and attached + * device until the bus has been resumed. This stops the transmission of the 1MS Start Of Frame + * messages to the device. + */ + static inline void USB_Host_SuspendBus(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_SuspendBus(void) + { + AVR32_USBB.UHCON.sofe = false; + } + + /** Determines if the USB bus has been suspended via the use of the \ref USB_Host_SuspendBus() macro, + * false otherwise. While suspended, no USB communications can occur until the bus is resumed, + * except for the Remote Wakeup event from the device if supported. + * + * \return Boolean \c true if the bus is currently suspended, \c false otherwise. + */ + static inline bool USB_Host_IsBusSuspended(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool USB_Host_IsBusSuspended(void) + { + return AVR32_USBB.UHCON.sofe; + } + + /** Determines if the attached device is currently enumerated in Full Speed mode (12Mb/s), or + * false if the attached device is enumerated in Low Speed mode (1.5Mb/s). + * + * \return Boolean \c true if the attached device is enumerated in Full Speed mode, \c false otherwise. + */ + static inline bool USB_Host_IsDeviceFullSpeed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool USB_Host_IsDeviceFullSpeed(void) + { + return (AVR32_USBB.USBSTA.speed == AVR32_USBB_SPEED_FULL); + } + + /** Determines if the attached device is currently issuing a Remote Wakeup request, requesting + * that the host resume the USB bus and wake up the device, false otherwise. + * + * \return Boolean \c true if the attached device has sent a Remote Wakeup request, \c false otherwise. + */ + static inline bool USB_Host_IsRemoteWakeupSent(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool USB_Host_IsRemoteWakeupSent(void) + { + return AVR32_USBB.UHINT.rxrsmi; + } + + /** Clears the flag indicating that a Remote Wakeup request has been issued by an attached device. */ + static inline void USB_Host_ClearRemoteWakeupSent(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_ClearRemoteWakeupSent(void) + { + AVR32_USBB.UHINTCLR.rxrsmic = true; + } + + /** Accepts a Remote Wakeup request from an attached device. This must be issued in response to + * a device's Remote Wakeup request within 2ms for the request to be accepted and the bus to + * be resumed. + */ + static inline void USB_Host_ResumeFromWakeupRequest(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_ResumeFromWakeupRequest(void) + { + AVR32_USBB.UHCON.resume = true; + } + + /** Determines if a resume from Remote Wakeup request is currently being sent to an attached + * device. + * + * \return Boolean \c true if no resume request is currently being sent, \c false otherwise. + */ + static inline bool USB_Host_IsResumeFromWakeupRequestSent(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool USB_Host_IsResumeFromWakeupRequestSent(void) + { + return AVR32_USBB.UHCON.resume; + } + + /* Function Prototypes: */ + /** Convenience function. This routine sends a SET CONFIGURATION standard request to the attached + * device, with the given configuration index. This can be used to easily set the device + * configuration without creating and sending the request manually. + * + * \note After this routine returns, the control pipe will be selected. + * + * \param[in] ConfigNumber Configuration index to send to the device. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. + */ + uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber); + + /** Convenience function. This routine sends a GET DESCRIPTOR 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[out] 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(void* const DeviceDescriptorPtr); + + /** Convenience function. This routine sends a GET DESCRIPTOR standard request to the attached + * device, requesting the string descriptor of the specified index. This can be used to easily + * retrieve string descriptors from the device by index, after the index is obtained from the + * Device or Configuration descriptors. + * + * \note After this routine returns, the control pipe will be selected. + * + * \param[in] Index Index of the string index to retrieve. + * \param[out] Buffer Pointer to the destination buffer where the retrieved string descriptor is + * to be stored. + * \param[in] BufferLength Maximum size of the string descriptor which can be stored into the buffer. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. + */ + uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t Index, + void* const Buffer, + const uint8_t BufferLength); + + /** Clears a stall condition on the given pipe, via a CLEAR FEATURE standard request to the attached device. + * + * \note After this routine returns, the control pipe will be selected. + * + * \param[in] EndpointIndex Index of the endpoint to clear, including the endpoint's direction. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. + */ + uint8_t USB_Host_ClearPipeStall(const uint8_t EndpointIndex); + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + static inline void USB_Host_HostMode_On(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_HostMode_On(void) + { + // Not required for UC3B + } + + static inline void USB_Host_HostMode_Off(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_HostMode_Off(void) + { + // Not required for UC3B + } + + static inline void USB_Host_VBUS_Auto_Enable(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_VBUS_Auto_Enable(void) + { + AVR32_USBB.USBCON.vbushwc = false; + } + + static inline void USB_Host_VBUS_Manual_Enable(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_VBUS_Manual_Enable(void) + { + AVR32_USBB.USBCON.vbushwc = true; + } + + static inline void USB_Host_VBUS_Auto_On(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_VBUS_Auto_On(void) + { + AVR32_USBB.USBSTASET.vbusrqs = true; + } + + static inline void USB_Host_VBUS_Manual_On(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_VBUS_Manual_On(void) + { + AVR32_USBB.USBSTASET.vbusrqs = true; + } + + static inline void USB_Host_VBUS_Auto_Off(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_VBUS_Auto_Off(void) + { + AVR32_USBB.USBSTACLR.vbusrqc = true; + } + + static inline void USB_Host_VBUS_Manual_Off(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_VBUS_Manual_Off(void) + { + AVR32_USBB.USBSTACLR.vbusrqc = true; + } + + static inline void USB_Host_SetDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE; + static inline void USB_Host_SetDeviceAddress(const uint8_t Address) + { + AVR32_USBB.UHADDR1.uhaddr_p0 = Address; + AVR32_USBB.UHADDR1.uhaddr_p1 = Address; + AVR32_USBB.UHADDR1.uhaddr_p2 = Address; + AVR32_USBB.UHADDR1.uhaddr_p3 = Address; + AVR32_USBB.UHADDR2.uhaddr_p4 = Address; + AVR32_USBB.UHADDR2.uhaddr_p5 = Address; + AVR32_USBB.UHADDR2.uhaddr_p6 = Address; + } + + /* Enums: */ + enum USB_Host_WaitMSErrorCodes_t + { + HOST_WAITERROR_Successful = 0, + HOST_WAITERROR_DeviceDisconnect = 1, + HOST_WAITERROR_PipeError = 2, + HOST_WAITERROR_SetupStalled = 3, + }; + + /* Function Prototypes: */ + void USB_Host_ProcessNextHostState(void); + uint8_t USB_Host_WaitMS(uint8_t MS); + + #if defined(__INCLUDE_FROM_HOST_C) + static void USB_Host_ResetDevice(void); + #endif + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + -- cgit v1.2.3