parent
944e0d2009
commit
81fd8d4004
@ -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 |
||||||
|
|
@ -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 |
||||||
|
|
||||||
|
/** @} */ |
||||||
|
|
Loading…
Reference in new issue