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