Moved all source to the trunk directory.
This commit is contained in:
parent
9991321321
commit
6a10d6b465
88 changed files with 15575 additions and 0 deletions
39
LUFA/Drivers/USB/HighLevel/Events.c
Normal file
39
LUFA/Drivers/USB/HighLevel/Events.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, 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.
|
||||
*/
|
||||
|
||||
#include "../LowLevel/USBMode.h"
|
||||
|
||||
#define INCLUDE_FROM_EVENTS_C
|
||||
#include "Events.h"
|
||||
|
||||
void USB_Event_Stub(void)
|
||||
{
|
||||
|
||||
}
|
440
LUFA/Drivers/USB/HighLevel/Events.h
Normal file
440
LUFA/Drivers/USB/HighLevel/Events.h
Normal file
|
@ -0,0 +1,440 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, 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.
|
||||
*/
|
||||
|
||||
/** Library events module. This module contains macros and functions relating to the management of library
|
||||
* events, which are small pieces of code similar to ISRs which are run when a given condition is met. Each
|
||||
* event can be fired from multiple places in the user or library code, which may or may not be inside an ISR,
|
||||
* thus each handler should be written to be as small and fast as possible to prevent possible problems.
|
||||
*
|
||||
* Events can be hooked by the user application using the EVENT_HANDLER() and HANDLES_EVENT() macros. If an
|
||||
* event with no associated handler is fired within the library, it by default fires an internal empty stub
|
||||
* function. This is achieved through the use of the GCC compiler's "alias" attribute.
|
||||
*
|
||||
* Each event must only have one associated event handler, but can be raised by multiple sources.
|
||||
*/
|
||||
|
||||
#ifndef __USBEVENTS_H__
|
||||
#define __USBEVENTS_H__
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "../../../Common/Common.h"
|
||||
#include "../LowLevel/USBMode.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Raises a given event name, with the specified parameters. For events with no parameters the
|
||||
* only argument to the macro is the event name, events with parameters list the parameter values
|
||||
* after the name as a comma seperated list.
|
||||
*
|
||||
* When a given event is fired, its corresponding event handler code is executed.
|
||||
*
|
||||
* Usage Examples:
|
||||
* \code
|
||||
* // Raise the USB_VBUSChange event, which takes no parameters
|
||||
* RAISE_EVENT(USB_VBUSChange);
|
||||
*
|
||||
* // Raise the USB_UnhandledControlPacket event which takes two parameters
|
||||
* RAISE_EVENT(USB_UnhandledControlPacket, 0, 1);
|
||||
* \endcode
|
||||
*
|
||||
* \see RAISES_EVENT()
|
||||
*/
|
||||
#define RAISE_EVENT(e, ...) Event_ ## e (__VA_ARGS__)
|
||||
|
||||
/** Indicates that a given module can raise a given event. This is the equivelent of putting the
|
||||
* event function's prototype into the module, but in a cleaner way. Each event which may be
|
||||
* fired via the RAISE_EVENT macro in the module should have an accompanying RAISES_EVENT
|
||||
* prototype in the module's header file.
|
||||
*
|
||||
* Usage Examples:
|
||||
* \code
|
||||
* // Module can raise the USB_VBUSChange event
|
||||
* RAISES_EVENT(USB_VBUSChange);
|
||||
*
|
||||
* // ...
|
||||
* // Inside a block of code in a function of the module, raise the USB_VBUSChange event
|
||||
* RAISE_EVENT(USB_VBUSChange);
|
||||
* \endcode
|
||||
*
|
||||
* \see RAISE_EVENT()
|
||||
*/
|
||||
#define RAISES_EVENT(e) HANDLES_EVENT(e)
|
||||
|
||||
/** Defines an event handler for the given event. Event handlers should be short in length, as they
|
||||
* may be raised from inside an ISR. The user application can react to each event as it sees fit,
|
||||
* such as logging the event, indicating the change to the user or performing some other action.
|
||||
*
|
||||
* Only one event handler may be defined in any user project for each individual event. Events may
|
||||
* or may not have parameters - for each event, refer to its documentation elsewhere in this module
|
||||
* to determine the presense and purpose of any event parameters.
|
||||
*
|
||||
* Usage Example:
|
||||
* \code
|
||||
* // Create an event handler for the USB_VBUSChange event
|
||||
* EVENT_HANDLER(USB_VBUSChange)
|
||||
* {
|
||||
* // Code to execute when the VBUS level changes
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \see HANDLES_EVENT()
|
||||
*/
|
||||
#define EVENT_HANDLER(e) void Event_ ## e e ## _P
|
||||
|
||||
/** Indicates that a given module handles an event. This is the equivelent of putting the
|
||||
* event function's prototype into the module, but in a cleaner way. Each event which may be
|
||||
* handled via the EVENT_HANDLER macro in the module should have an accompanying HANDLES_EVENT
|
||||
* prototype in the module's header file.
|
||||
*
|
||||
* Usage Examples:
|
||||
* \code
|
||||
* // Module handles the USB_VBUSChange event
|
||||
* HANDLES_EVENT(USB_VBUSChange);
|
||||
*
|
||||
* // Create the USB_VBUSChange event handler
|
||||
* EVENT_HANDLER(USB_VBUSChange)
|
||||
* {
|
||||
* // Event handler code here
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* \see EVENT_HANDLER()
|
||||
*/
|
||||
#define HANDLES_EVENT(e) EVENT_HANDLER(e)
|
||||
|
||||
/* Psudo-Functions for Doxygen: */
|
||||
#if defined(__DOXYGEN__)
|
||||
/** Event for VBUS level change. This event fires when the VBUS line of the USB AVR changes from
|
||||
* high to low or vice-versa.
|
||||
*
|
||||
* \note This event is only available on USB AVR models which support VBUS notification interrupts.
|
||||
*/
|
||||
void USB_VBUSChange(void);
|
||||
|
||||
/** Event for VBUS attachment. This event fires when the VBUS line of the USB AVR changes from
|
||||
* low to high, signalling the attachment of the USB device to a host, before the enumeration
|
||||
* process has begun.
|
||||
*
|
||||
* \note This event is only available on USB AVR models which support VBUS notification interrupts.
|
||||
*/
|
||||
void USB_VBUSConnect(void);
|
||||
|
||||
/** Event for VBUS detachment. This event fires when the VBUS line of the USB AVR changes from
|
||||
* high to low, signalling the USB device has been removed from a host whether it has been enumerated
|
||||
* or not.
|
||||
*
|
||||
* \note This event is only available on USB AVR models which support VBUS notification interrupts.
|
||||
*/
|
||||
void USB_VBUSDisconnect(void);
|
||||
|
||||
/** Event for USB device connection. This event fires when the AVR is in USB host mode and a device
|
||||
* has been attached (but not yet fully enumerated), or when in device mode and the device is connected
|
||||
* to a host, beginning the enumeration process.
|
||||
*
|
||||
* When in device mode, this can be used to progmatically start the USB management task to reduce
|
||||
* CPU usage.
|
||||
*
|
||||
* \note For the smaller USB AVRs (AT90USBXX2) with limited USB controllers, VBUS is not available to the USB controller.
|
||||
* this means that the current connection state is derived from the bus suspension and wake up events by default,
|
||||
* which is not always accurate (host may suspend the bus while still connected). If the actual connection state
|
||||
* needs to be determined, VBUS should be routed to an external pin, and the auto-detect behaviour turned off by
|
||||
* passing the NO_LIMITED_CONTROLLER_CONNECT token to the compiler via the -D switch at compile time. The connection
|
||||
* and disconnection events may be manually fired by RAISE_EVENT(), and the USB_IsConnected global changed manually.
|
||||
*
|
||||
* \see USBTask.h for more information on the USB management task and reducing CPU usage.
|
||||
*/
|
||||
void USB_Connect(void);
|
||||
|
||||
/** Event for USB device disconnection. This event fires when the AVR is in USB host mode and an
|
||||
* attached and enumerated device has been disconnected, or when in device mode and the device is
|
||||
* disconnected from the host.
|
||||
*
|
||||
* When in device mode, this can be used to progmatically stop the USB management task to reduce
|
||||
* CPU usage.
|
||||
*
|
||||
* \note For the smaller USB AVRs (AT90USBXX2) with limited USB controllers, VBUS is not available to the USB controller.
|
||||
* this means that the current connection state is derived from the bus suspension and wake up events by default,
|
||||
* which is not always accurate (host may suspend the bus while still connected). If the actual connection state
|
||||
* needs to be determined, VBUS should be routed to an external pin, and the auto-detect behaviour turned off by
|
||||
* passing the NO_LIMITED_CONTROLLER_CONNECT token to the compiler via the -D switch at compile time. The connection
|
||||
* and disconnection events may be manually fired by RAISE_EVENT(), and the USB_IsConnected global changed manually.
|
||||
*
|
||||
* \see USBTask.h for more information on the USB management task and reducing CPU usage.
|
||||
*/
|
||||
void USB_Disconnect(void);
|
||||
|
||||
/** Event for USB device power on failure. This event fires when the USB interface fails to
|
||||
* initialize correctly due to a hardware or software fault.
|
||||
*
|
||||
* \param ErrorCode Error code indicating the failure reason, a value in USB_PowerOnErrorCodes_t
|
||||
* located in LowLevel.h.
|
||||
*/
|
||||
void USB_PowerOnFail(const uint8_t ErrorCode);
|
||||
|
||||
/** Event for USB mode pin level change. This event fires when the USB interface is set to dual role
|
||||
* mode, and the UID pin level has changed to indicate a new mode (device or host). This event fires
|
||||
* before the mode is switched to the newly indicated mode.
|
||||
*
|
||||
* \note This event only exists on USB AVR models which support dual role modes.
|
||||
*
|
||||
* \note This event does not exist if the USB_DEVICE_ONLY or USB_HOST_ONLY tokens have been supplied
|
||||
* to the compiler (see LowLevel.h documentation).
|
||||
*/
|
||||
void USB_UIDChange(void);
|
||||
|
||||
/** Event for USB host error. This event fires when a hardware fault has occurred whilst the USB
|
||||
* interface is in host mode.
|
||||
*
|
||||
* \param ErrorCode Error code indicating the failure reason, a value in USB_Host_ErrorCodes_t
|
||||
* located in Host.h.
|
||||
*
|
||||
* \note This event only exists on USB AVR models which supports host mode.
|
||||
*
|
||||
* \note This event does not exist if the USB_DEVICE_ONLY token is supplied to the compiler (see
|
||||
* LowLevel.h documentation).
|
||||
*/
|
||||
void USB_HostError(const uint8_t ErrorCode);
|
||||
|
||||
/** Event for USB device attachment. This event fires when a the USB interface is in host mode, and
|
||||
* a USB device has been connected to the USB interface. This is interrupt driven, thus fires before
|
||||
* the standard USB_DeviceConnect event and so can be used to programatically start the USB management
|
||||
* task to reduce CPU consumption.
|
||||
*
|
||||
* \note This event only exists on USB AVR models which supports host mode.
|
||||
*
|
||||
* \note This event does not exist if the USB_DEVICE_ONLY token is supplied to the compiler (see
|
||||
* LowLevel.h documentation).
|
||||
*
|
||||
* \see USBTask.h for more information on the USB management task and reducing CPU usage.
|
||||
*/
|
||||
void USB_DeviceAttached(void);
|
||||
|
||||
/** Event for USB device removal. This event fires when a the USB interface is in host mode, and
|
||||
* a USB device has been removed the USB interface whether or not it has been enumerated. This
|
||||
* can be used to programatically stop the USB management task to reduce CPU consumption.
|
||||
*
|
||||
* \note This event only exists on USB AVR models which supports host mode.
|
||||
*
|
||||
* \note This event does not exist if the USB_DEVICE_ONLY token is supplied to the compiler (see
|
||||
* LowLevel.h documentation).
|
||||
*
|
||||
* \see USBTask.h for more information on the USB management task and reducing CPU usage.
|
||||
*/
|
||||
void USB_DeviceUnattached(void);
|
||||
|
||||
/** Event for USB device enumeration failure. This event fires when a the USB interface is
|
||||
* in host mode, and an attached USB device has failed to enumerate completely.
|
||||
*
|
||||
* \param ErrorCode Error code indicating the failure reason, a value in
|
||||
* USB_Host_EnumerationErrorCodes_t located in Host.h.
|
||||
*
|
||||
* \param SubErrorCode Sub error code indicating the reason for failure - for example, if the
|
||||
* ErrorCode parameter indicates a control error, this will give the error
|
||||
* code returned by the USB_Host_SendControlRequest() function.
|
||||
*
|
||||
* \note This event only exists on USB AVR models which supports host mode.
|
||||
*
|
||||
* \note This event does not exist if the USB_DEVICE_ONLY token is supplied to the compiler (see
|
||||
* LowLevel.h documentation).
|
||||
*/
|
||||
void USB_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8_t SubErrorCode);
|
||||
|
||||
/** Event for USB device enumeration completion. This event fires when a the USB interface is
|
||||
* in host mode and an attached USB device has been completely enumerated and is ready to be
|
||||
* controlled by the user application, or when the library is in device mode, and the Host
|
||||
* has finished enumerating the device.
|
||||
*/
|
||||
void USB_DeviceEnumerationComplete(void);
|
||||
|
||||
/** Event for unhandled control requests. This event fires when a the USB host issues a control
|
||||
* request to the control endpoint (address 0) that the library does not handle. This may either
|
||||
* be a standard request that the library has no handler code for, or a class specific request
|
||||
* issued to the device which must be handled appropriately. Due to the strict timing requirements
|
||||
* on control transfers, interrupts are disabled during control request processing.
|
||||
*
|
||||
* \param bRequest Request value, indicating what command the host has issued.
|
||||
* \param bmRequestType Mask indicating the request data direction (if any), type and recipient.
|
||||
*
|
||||
* \note This event does not exist if the USB_HOST_ONLY token is supplied to the compiler (see
|
||||
* LowLevel.h documentation).
|
||||
*
|
||||
* \note Requests should be handled in the same manner as described in the USB 2.0 Specification,
|
||||
* or appropriate class' specification. In all instances, the library has already read the
|
||||
* request bmRequestType and bRequest values out (into the Request and RequestType parameters
|
||||
* respectively) so that it can correctly determine if it is able to handle the request
|
||||
* internally, or hand off the request to the user application via this event. Other request
|
||||
* parameters (wValue, wIndex, wLength, and Data) remain in the control endpoint bank until
|
||||
* read out by the user application for processing.
|
||||
*/
|
||||
void USB_UnhandledControlPacket(const uint8_t bRequest, const uint8_t bmRequestType);
|
||||
|
||||
/** Event for USB configuration number changed. This event fires when a the USB host changes the
|
||||
* selected configuration number while in device mode. This event should be hooked in device
|
||||
* applications to create the endpoints and configure the device for the selected configuration.
|
||||
*
|
||||
* This event fires after the value of USB_ConfigurationNumber has been changed.
|
||||
*
|
||||
* \note This event does not exist if the USB_HOST_ONLY token is supplied to the compiler (see
|
||||
* LowLevel.h documentation).
|
||||
*/
|
||||
void USB_ConfigurationChanged(void);
|
||||
|
||||
/** Event for USB suspend. This event fires when a the USB host suspends the device by halting its
|
||||
* transmission of Start Of Frame pulses to the device. This is generally hooked in order to move
|
||||
* the device over to a low power state until the host wakes up the device.
|
||||
*
|
||||
* \note This event does not exist if the USB_HOST_ONLY token is supplied to the compiler (see
|
||||
* LowLevel.h documentation).
|
||||
*
|
||||
* \see USB_WakeUp() event for accompanying Wake Up event.
|
||||
*/
|
||||
void USB_Suspend(void);
|
||||
|
||||
/** Event for USB wake up. This event fires when a the USB interface is suspended while in device
|
||||
* mode, and the host wakes up the device by supplying Start Of Frame pulses. This is generally
|
||||
* hooked to pull the user application out of a lowe power state and back into normal operating
|
||||
* mode.
|
||||
*
|
||||
* \note This event does not exist if the USB_HOST_ONLY token is supplied to the compiler (see
|
||||
* LowLevel.h documentation).
|
||||
*
|
||||
* \see USB_Suspend() event for accompanying Suspend event.
|
||||
*/
|
||||
void USB_WakeUp(void);
|
||||
|
||||
/** Event for USB interface reset. This event fires when a the USB interface is in device mode, and
|
||||
* a the USB host requests that the device reset its interface. This is generally hooked so that
|
||||
* the USB control endpoint can be switched to interrupt driven mode, by selecting it and calling
|
||||
* USB_INT_Enable(ENDPOINT_INT_SETUP). Before this event fires, all device endpoints are reset and
|
||||
* disabled.
|
||||
*
|
||||
* \note This event does not exist if the USB_HOST_ONLY token is supplied to the compiler (see
|
||||
* LowLevel.h documentation).
|
||||
*/
|
||||
void USB_Reset(void);
|
||||
|
||||
/** Event for USB device mode error. This event fires when the USB interface is in device mode,
|
||||
* and an error occurs which prevents it from operating normally.
|
||||
*
|
||||
* \param ErrorCode Error code indicating the source of the error. One of the values in the
|
||||
* USB_Device_ErrorCodes_t enum located in Device.h.
|
||||
*
|
||||
* \note This event does not exist if the USB_HOST_ONLY token is supplied to the compiler (see
|
||||
* LowLevel.h documentation).
|
||||
*/
|
||||
void USB_DeviceError(const uint8_t ErrorCode);
|
||||
#endif
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
#define ALIAS_STUB(e) EVENT_HANDLER(e) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub)
|
||||
|
||||
#if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER)
|
||||
#define USB_VBUSChange_P (void)
|
||||
#define USB_VBUSConnect_P (void)
|
||||
#define USB_VBUSDisconnect_P (void)
|
||||
#endif
|
||||
|
||||
#define USB_Connect_P (void)
|
||||
#define USB_Disconnect_P (void)
|
||||
#define USB_DeviceEnumerationComplete_P (void)
|
||||
|
||||
#if defined(USB_CAN_BE_BOTH)
|
||||
#define USB_PowerOnFail_P (const uint8_t ErrorCode)
|
||||
#define USB_UIDChange_P (void)
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
#define USB_HostError_P (const uint8_t ErrorCode)
|
||||
#define USB_DeviceAttached_P (void)
|
||||
#define USB_DeviceUnattached_P (void)
|
||||
#define USB_DeviceEnumerationFailed_P (const uint8_t ErrorCode, const uint8_t SubErrorCode)
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
#define USB_UnhandledControlPacket_P (const uint8_t bRequest, const uint8_t bmRequestType)
|
||||
#define USB_ConfigurationChanged_P (void)
|
||||
#define USB_Suspend_P (void)
|
||||
#define USB_WakeUp_P (void)
|
||||
#define USB_Reset_P (void)
|
||||
#define USB_DeviceError_P (const uint8_t ErrorCode)
|
||||
#endif
|
||||
|
||||
/* Function Prototypes: */
|
||||
#if defined(INCLUDE_FROM_EVENTS_C)
|
||||
void USB_Event_Stub (void) ATTR_CONST;
|
||||
|
||||
#if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER)
|
||||
ALIAS_STUB(USB_VBUSChange);
|
||||
ALIAS_STUB(USB_VBUSConnect);
|
||||
ALIAS_STUB(USB_VBUSDisconnect);
|
||||
#endif
|
||||
|
||||
ALIAS_STUB(USB_Connect);
|
||||
ALIAS_STUB(USB_Disconnect);
|
||||
ALIAS_STUB(USB_DeviceEnumerationComplete);
|
||||
|
||||
#if defined(USB_CAN_BE_BOTH)
|
||||
ALIAS_STUB(USB_PowerOnFail);
|
||||
ALIAS_STUB(USB_UIDChange);
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
ALIAS_STUB(USB_HostError);
|
||||
ALIAS_STUB(USB_DeviceAttached);
|
||||
ALIAS_STUB(USB_DeviceUnattached);
|
||||
ALIAS_STUB(USB_DeviceEnumerationFailed);
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
ALIAS_STUB(USB_UnhandledControlPacket);
|
||||
ALIAS_STUB(USB_ConfigurationChanged);
|
||||
ALIAS_STUB(USB_Suspend);
|
||||
ALIAS_STUB(USB_WakeUp);
|
||||
ALIAS_STUB(USB_Reset);
|
||||
ALIAS_STUB(USB_DeviceError);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
43
LUFA/Drivers/USB/HighLevel/StdDescriptors.c
Normal file
43
LUFA/Drivers/USB/HighLevel/StdDescriptors.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, 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.
|
||||
*/
|
||||
|
||||
#include "../LowLevel/USBMode.h"
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
|
||||
#include "StdDescriptors.h"
|
||||
|
||||
uint16_t USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
|
||||
{
|
||||
RAISE_EVENT(USB_DeviceError, DEVICE_ERROR_GetDescriptorNotHooked);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
#endif
|
523
LUFA/Drivers/USB/HighLevel/StdDescriptors.h
Normal file
523
LUFA/Drivers/USB/HighLevel/StdDescriptors.h
Normal file
|
@ -0,0 +1,523 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, 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
|
||||
*
|
||||
* Standard USB device descriptor defines and retrieval routines, for USB devices. This module contains
|
||||
* strucutures and macros for the easy creation of standard USB descriptors in USB device projects.
|
||||
*
|
||||
* All standard descriptors have their elements named in an identical manner to the official USB specification,
|
||||
* however slightly more verbose alternate (non-standard) names are also supplied if the macro
|
||||
* USE_NONSTANDARD_DESCRIPTOR_NAMES is defined in the user project makefile and passed to the compiler at
|
||||
* compilation time using the -D option.
|
||||
*
|
||||
* The non-standard names are documented here - if USE_NONSTANDARD_DESCRIPTOR_NAMES is not defined, then all
|
||||
* descriptors will contain elements named identically to the official USB specification. The alternately
|
||||
* named descriptor elements are placed in the same order inside the descriptor structures as their officially
|
||||
* named counterparts, thus they can be correlated easily with the official USB specification.
|
||||
*/
|
||||
|
||||
#ifndef __USBDESCRIPTORS_H__
|
||||
#define __USBDESCRIPTORS_H__
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/pgmspace.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "../../../Common/Common.h"
|
||||
#include "../LowLevel/USBMode.h"
|
||||
#include "Events.h"
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
#include "../LowLevel/Device.h"
|
||||
#endif
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Indicates that a given descriptor does not exist in the device. This can be used inside descriptors
|
||||
* for string descriptor indexes, or may be use as a return value for GetDescriptor when the specified
|
||||
* descriptor does not exist.
|
||||
*/
|
||||
#define NO_DESCRIPTOR 0
|
||||
|
||||
/** Macro to calculate the power value for the device descriptor, from a given number of milliamps. */
|
||||
#define USB_CONFIG_POWER_MA(x) (x >> 1)
|
||||
|
||||
/** Macro to calculate the Unicode length of a string with a given number of Unicode characters.
|
||||
* Should be used in string descriptor's headers for giving the string descriptor's byte length.
|
||||
*/
|
||||
#define USB_STRING_LEN(x) (sizeof(USB_Descriptor_Header_t) + (x << 1))
|
||||
|
||||
/** Macro to encode a given four digit floating point version number (e.g. 01.23) into Binary Coded
|
||||
* Decimal format for descriptor fields requiring BCD encoding, such as the USB version number in the
|
||||
* standard device descriptor.
|
||||
*/
|
||||
#define VERSION_BCD(x) ((((VERSION_TENS(x) << 4) | VERSION_ONES(x)) << 8) | \
|
||||
((VERSION_TENTHS(x) << 4) | VERSION_HUNDREDTHS(x)))
|
||||
|
||||
/** String language ID for the English language. Should be used in USB_Descriptor_Language_t descriptors
|
||||
* to indicate that the English language is supported by the device in its string descriptors.
|
||||
*/
|
||||
#define LANGUAGE_ID_ENG 0x0409
|
||||
|
||||
/** Can be masked with an endpoint address for a USB_Descriptor_Endpoint_t endpoint descriptor's
|
||||
* EndpointAddress value to indicate to the host that the endpoint is of the IN direction (i.e, from
|
||||
* device to host).
|
||||
*/
|
||||
#define ENDPOINT_DESCRIPTOR_DIR_IN 0x80
|
||||
|
||||
/** Can be masked with an endpoint address for a USB_Descriptor_Endpoint_t endpoint descriptor's
|
||||
* EndpointAddress value to indicate to the host that the endpoint is of the OUT direction (i.e, from
|
||||
* host to device).
|
||||
*/
|
||||
#define ENDPOINT_DESCRIPTOR_DIR_OUT 0x00
|
||||
|
||||
/** Can be masked with other configuration descriptor attributes for a USB_Descriptor_Configuration_Header_t
|
||||
* descriptor's ConfigAttributes value to indicate that the specified configuration can draw its power
|
||||
* from the host's VBUS line.
|
||||
*/
|
||||
#define USB_CONFIG_ATTR_BUSPOWERED 0b10000000
|
||||
|
||||
/** Can be masked with other configuration descriptor attributes for a USB_Descriptor_Configuration_Header_t
|
||||
* descriptor's ConfigAttributes value to indicate that the specified configuration can draw its power
|
||||
* from the device's own power source.
|
||||
*/
|
||||
#define USB_CONFIG_ATTR_SELFPOWERED 0b11000000
|
||||
|
||||
/** Can be masked with other configuration descriptor attributes for a USB_Descriptor_Configuration_Header_t
|
||||
* descriptor's ConfigAttributes value to indicate that the specified configuration supports the
|
||||
* remote wakeup feature of the USB standard, allowing a suspended USB device to wake up the host upon
|
||||
* request.
|
||||
*/
|
||||
#define USB_CONFIG_ATTR_REMOTEWAKEUP 0b10100000
|
||||
|
||||
/** Can be masked with other endpoint descriptor attributes for a USB_Descriptor_Endpoint_t descriptor's
|
||||
* Attributes value to indicate that the specified endpoint is not synchronized.
|
||||
*
|
||||
* \see The USB specification for more details on the possible Endpoint attributes.
|
||||
*/
|
||||
#define ENDPOINT_ATTR_NO_SYNC (0b00 << 2)
|
||||
|
||||
/** Can be masked with other endpoint descriptor attributes for a USB_Descriptor_Endpoint_t descriptor's
|
||||
* Attributes value to indicate that the specified endpoint is asynchronous.
|
||||
*
|
||||
* \see The USB specification for more details on the possible Endpoint attributes.
|
||||
*/
|
||||
#define ENDPOINT_ATTR_ASYNC (0b01 << 2)
|
||||
|
||||
/** Can be masked with other endpoint descriptor attributes for a USB_Descriptor_Endpoint_t descriptor's
|
||||
* Attributes value to indicate that the specified endpoint is adaptive.
|
||||
*
|
||||
* \see The USB specification for more details on the possible Endpoint attributes.
|
||||
*/
|
||||
#define ENDPOINT_ATTR_ADAPTIVE (0b10 << 2)
|
||||
|
||||
/** Can be masked with other endpoint descriptor attributes for a USB_Descriptor_Endpoint_t descriptor's
|
||||
* Attributes value to indicate that the specified endpoint is synchronized.
|
||||
*
|
||||
* \see The USB specification for more details on the possible Endpoint attributes.
|
||||
*/
|
||||
#define ENDPOINT_ATTR_SYNC (0b11 << 2)
|
||||
|
||||
/** Can be masked with other endpoint descriptor attributes for a USB_Descriptor_Endpoint_t descriptor's
|
||||
* Attributes value to indicate that the specified endpoint is used for data transfers.
|
||||
*
|
||||
* \see The USB specification for more details on the possible Endpoint usage attributes.
|
||||
*/
|
||||
#define ENDPOINT_USAGE_DATA (0b00 << 4)
|
||||
|
||||
/** Can be masked with other endpoint descriptor attributes for a USB_Descriptor_Endpoint_t descriptor's
|
||||
* Attributes value to indicate that the specified endpoint is used for feedback.
|
||||
*
|
||||
* \see The USB specification for more details on the possible Endpoint usage attributes.
|
||||
*/
|
||||
#define ENDPOINT_USAGE_FEEDBACK (0b01 << 4)
|
||||
|
||||
/** Can be masked with other endpoint descriptor attributes for a USB_Descriptor_Endpoint_t descriptor's
|
||||
* Attributes value to indicate that the specified endpoint is used for implicit feedback.
|
||||
*
|
||||
* \see The USB specification for more details on the possible Endpoint usage attributes.
|
||||
*/
|
||||
#define ENDPOINT_USAGE_IMPLICIT_FEEDBACK (0b10 << 4)
|
||||
|
||||
/** Gives a void pointer to the specified descriptor (of any type). */
|
||||
#define DESCRIPTOR_ADDRESS(Descriptor) ((void*)&Descriptor)
|
||||
|
||||
/* Events: */
|
||||
#if defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__)
|
||||
/** This module raises the Device Error event while in device mode, if the USB_GetDescriptor()
|
||||
* routine is not hooked in the user application to properly return descriptors to the library.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_DeviceError);
|
||||
#endif
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the possible standard descriptor types, as given in each descriptor's header. */
|
||||
enum USB_DescriptorTypes_t
|
||||
{
|
||||
DTYPE_Device = 0x01, /**< Indicates that the descriptor is a device descriptor. */
|
||||
DTYPE_Configuration = 0x02, /**< Indicates that the descriptor is a configuration descriptor. */
|
||||
DTYPE_String = 0x03, /**< Indicates that the descriptor is a string descriptor. */
|
||||
DTYPE_Interface = 0x04, /**< Indicates that the descriptor is an interface descriptor. */
|
||||
DTYPE_Endpoint = 0x05, /**< Indicates that the descriptor is an endpoint descriptor. */
|
||||
DTYPE_DeviceQualifier = 0x06, /**< Indicates that the descriptor is a device qualifier descriptor. */
|
||||
DTYPE_Other = 0x07, /**< Indicates that the descriptor is of other type. */
|
||||
DTYPE_InterfacePower = 0x08, /**< Indicates that the descriptor is an interface power descriptor. */
|
||||
DTYPE_InterfaceAssociation = 0x0B, /**< Indicates that the descriptor is an interface association descriptor. */
|
||||
};
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for all descriptor's header, indicating the descriptor's length and type.
|
||||
*
|
||||
* \note The non-standard structure element names are documented here - see the StdDescriptors.h file
|
||||
* documentation for more information on the two descriptor naming schemes. If the
|
||||
* USE_NONSTANDARD_DESCRIPTOR_NAMES token is not set, this structure contains elements with names
|
||||
* identical to those listed in the USB standard.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
#if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES) || defined(__DOXYGEN__)
|
||||
uint8_t Size; /**< Size of the descriptor, in bytes. */
|
||||
uint8_t Type; /**< Type of the descriptor, either a value in DescriptorTypes_t or a value
|
||||
* given by the specific class.
|
||||
*/
|
||||
#else
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
#endif
|
||||
} USB_Descriptor_Header_t;
|
||||
|
||||
/** Type define for a standard device descriptor.
|
||||
*
|
||||
* \note The non-standard structure element names are documented here - see the StdDescriptors.h file
|
||||
* documentation for more information on the two descriptor naming schemes. If the
|
||||
* USE_NONSTANDARD_DESCRIPTOR_NAMES token is not set, this structure contains elements with names
|
||||
* identical to those listed in the USB standard.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
#if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES) || defined(__DOXYGEN__)
|
||||
USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */
|
||||
|
||||
uint16_t USBSpecification; /**< BCD of the supported USB specification. */
|
||||
uint8_t Class; /**< USB device class. */
|
||||
uint8_t SubClass; /**< USB device subclass. */
|
||||
uint8_t Protocol; /**< USB device protocol. */
|
||||
|
||||
uint8_t Endpoint0Size; /**< Size of the control (address 0) endpoint's bank in bytes. */
|
||||
|
||||
uint16_t VendorID; /**< Vendor ID for the USB product. */
|
||||
uint16_t ProductID; /**< Unique product ID for the USB product. */
|
||||
uint16_t ReleaseNumber; /**< Product release (version) number. */
|
||||
|
||||
uint8_t ManufacturerStrIndex; /**< String index for the manufacturer's name. The
|
||||
* host will request this string via a seperate
|
||||
* control request for the string descriptor.
|
||||
*
|
||||
* \note If no string supplied, use NO_DESCRIPTOR.
|
||||
*/
|
||||
uint8_t ProductStrIndex; /**< String index for the product name/details.
|
||||
*
|
||||
* \see ManufacturerStrIndex structure entry.
|
||||
*/
|
||||
uint8_t SerialNumStrIndex; /**< String index for the product's globally unique hexadecimal
|
||||
* serial number, in uppercase Unicoded ASCII.
|
||||
*
|
||||
* \see ManufacturerStrIndex structure entry.
|
||||
*/
|
||||
|
||||
uint8_t NumberOfConfigurations; /**< Total number of configurations supported by
|
||||
* the device.
|
||||
*/
|
||||
#else
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdUSB;
|
||||
uint8_t bDeviceClass;
|
||||
uint8_t bDeviceSubClass;
|
||||
uint8_t bDeviceProtocol;
|
||||
uint8_t bMaxPacketSize0;
|
||||
uint16_t idVendor;
|
||||
uint16_t idProduct;
|
||||
uint16_t bcdDevice;
|
||||
uint8_t iManufacturer;
|
||||
uint8_t iProduct;
|
||||
uint8_t iSerialNumber;
|
||||
uint8_t bNumConfigurations;
|
||||
#endif
|
||||
} USB_Descriptor_Device_t;
|
||||
|
||||
/** Type define for a standard configuration descriptor.
|
||||
*
|
||||
* \note The non-standard structure element names are documented here - see the StdDescriptors.h file
|
||||
* documentation for more information on the two descriptor naming schemes. If the
|
||||
* USE_NONSTANDARD_DESCRIPTOR_NAMES token is not set, this structure contains elements with names
|
||||
* identical to those listed in the USB standard.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
#if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES) || defined(__DOXYGEN__)
|
||||
USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */
|
||||
|
||||
uint16_t TotalConfigurationSize; /**< Size of the configuration descriptor header,
|
||||
* and all sub descriptors inside the configuration.
|
||||
*/
|
||||
uint8_t TotalInterfaces; /**< Total number of interfaces in the configuration. */
|
||||
|
||||
uint8_t ConfigurationNumber; /**< Configuration index of the current configuration. */
|
||||
uint8_t ConfigurationStrIndex; /**< Index of a string descriptor describing the configuration. */
|
||||
|
||||
uint8_t ConfigAttributes; /**< Configuration attributes, comprised of a mask of zero or
|
||||
* more USB_CONFIG_ATTR_* masks.
|
||||
*/
|
||||
|
||||
uint8_t MaxPowerConsumption; /**< Maximum power consumption of the device while in the
|
||||
* current configuration, calculated by the USB_CONFIG_POWER_MA()
|
||||
* macro.
|
||||
*/
|
||||
#else
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t wTotalLength;
|
||||
uint8_t bNumInterfaces;
|
||||
uint8_t bConfigurationValue;
|
||||
uint8_t iConfiguration;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t bMaxPower;
|
||||
#endif
|
||||
} USB_Descriptor_Configuration_Header_t;
|
||||
|
||||
/** Type define for a standard interface descriptor.
|
||||
*
|
||||
* \note The non-standard structure element names are documented here - see the StdDescriptors.h file
|
||||
* documentation for more information on the two descriptor naming schemes. If the
|
||||
* USE_NONSTANDARD_DESCRIPTOR_NAMES token is not set, this structure contains elements with names
|
||||
* identical to those listed in the USB standard.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
#if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES) || defined(__DOXYGEN__)
|
||||
USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */
|
||||
|
||||
uint8_t InterfaceNumber; /**< Index of the interface in the current configuration. */
|
||||
uint8_t AlternateSetting; /**< Alternate setting for the interface number. The same
|
||||
* interface number can have multiple alternate settings
|
||||
* with different endpoint configurations, which can be
|
||||
* selected by the host.
|
||||
*/
|
||||
uint8_t TotalEndpoints; /**< Total number of endpoints in the interface. */
|
||||
|
||||
uint8_t Class; /**< Interface class ID. */
|
||||
uint8_t SubClass; /**< Interface subclass ID. */
|
||||
uint8_t Protocol; /**< Interface protocol ID. */
|
||||
|
||||
uint8_t InterfaceStrIndex; /**< Index of the string descriptor describing the
|
||||
* interface.
|
||||
*/
|
||||
#else
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bInterfaceNumber;
|
||||
uint8_t bAlternateSetting;
|
||||
uint8_t bNumEndpoints;
|
||||
uint8_t bInterfaceClass;
|
||||
uint8_t bInterfaceSubClass;
|
||||
uint8_t bInterfaceProtocol;
|
||||
uint8_t iInterface;
|
||||
#endif
|
||||
} USB_Descriptor_Interface_t;
|
||||
|
||||
/** Type define for a standard interface association descriptor.
|
||||
*
|
||||
* This descriptor has been added as a suppliment to the USB2.0 standard, in the ECN located at
|
||||
* <a>http://www.usb.org/developers/docs/InterfaceAssociationDescriptor_ecn.pdf</a>. It allows compound
|
||||
* devices with multiple interfaces related to the same function to have the multiple interfaces bound
|
||||
* together at the point of enumeration, loading one generic driver for all the interfaces in the single
|
||||
* function. Read the ECN for more information.
|
||||
*
|
||||
* \note The non-standard structure element names are documented here - see the StdDescriptors.h file
|
||||
* documentation for more information on the two descriptor naming schemes. If the
|
||||
* USE_NONSTANDARD_DESCRIPTOR_NAMES token is not set, this structure contains elements with names
|
||||
* identical to those listed in the USB standard.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
#if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES) || defined(__DOXYGEN__)
|
||||
USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */
|
||||
|
||||
uint8_t FirstInterfaceIndex; /**< Index of the first associated interface. */
|
||||
uint8_t TotalInterfaces; /** Total number of associated interfaces. */
|
||||
|
||||
uint8_t Class; /**< Interface class ID. */
|
||||
uint8_t SubClass; /**< Interface subclass ID. */
|
||||
uint8_t Protocol; /**< Interface protocol ID. */
|
||||
|
||||
uint8_t IADStrIndex; /**< Index of the string descriptor describing the
|
||||
* interface association.
|
||||
*/
|
||||
#else
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bFirstInterface;
|
||||
uint8_t bInterfaceCount;
|
||||
uint8_t bFunctionClass;
|
||||
uint8_t bFunctionSubClass;
|
||||
uint8_t bFunctionProtocol;
|
||||
uint8_t iFunction;
|
||||
#endif
|
||||
} USB_Descriptor_Interface_Association_t;
|
||||
|
||||
/** Type define for a standard endpoint descriptor.
|
||||
*
|
||||
* \note The non-standard structure element names are documented here - see the StdDescriptors.h file
|
||||
* documentation for more information on the two descriptor naming schemes. If the
|
||||
* USE_NONSTANDARD_DESCRIPTOR_NAMES token is not set, this structure contains elements with names
|
||||
* identical to those listed in the USB standard.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
#if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES) || defined(__DOXYGEN__)
|
||||
USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */
|
||||
|
||||
uint8_t EndpointAddress; /**< Logical address of the endpoint within the device
|
||||
* for the current configuration, including direction
|
||||
* mask.
|
||||
*/
|
||||
uint8_t Attributes; /**< Endpoint attributes, comprised of a mask of the
|
||||
* endpoint type (EP_TYPE_*) and attributes (ENDPOINT_ATTR_*)
|
||||
* masks.
|
||||
*/
|
||||
uint16_t EndpointSize; /**< Size of the endpoint bank, in bytes. This indicates the
|
||||
* maximum packet size that the endpoint can receive at a time.
|
||||
*/
|
||||
|
||||
uint8_t PollingIntervalMS; /**< Polling interval in milliseconds for the endpont
|
||||
* if it is an INTERRUPT or ISOCHRONOUS type.
|
||||
*/
|
||||
#else
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bEndpointAddress;
|
||||
uint8_t bmAttributes;
|
||||
uint16_t wMaxPacketSize;
|
||||
uint8_t bInterval;
|
||||
#endif
|
||||
} USB_Descriptor_Endpoint_t;
|
||||
|
||||
/** Type define for a standard string descriptor. Unlike other standard descriptors, the length
|
||||
* of the descriptor for placement in the descriptor header must be determined by the USB_STRING_LEN()
|
||||
* macro rather than by the size of the descriptor structure, as the length is not fixed.
|
||||
*
|
||||
* This structure should also be used for string index 0, which contains the supported language IDs for
|
||||
* the device as an array.
|
||||
*
|
||||
* \note The non-standard structure element names are documented here - see the StdDescriptors.h file
|
||||
* documentation for more information on the two descriptor naming schemes. If the
|
||||
* USE_NONSTANDARD_DESCRIPTOR_NAMES token is not set, this structure contains elements with names
|
||||
* identical to those listed in the USB standard.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
#if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES) || defined(__DOXYGEN__)
|
||||
USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */
|
||||
|
||||
int16_t UnicodeString[]; /**< String data, as unicode characters (alternatively,
|
||||
* string language IDs). If normal ASCII characters are
|
||||
* to be used, they must be added as an array of characters
|
||||
* rather than a normal C string so that they are widened to
|
||||
* Unicode size.
|
||||
*
|
||||
* Under GCC, strings prefixed with the "L" character (before
|
||||
* the opening string quotation mark) are considered to be
|
||||
* Unicode strings, and may be used instead of an explicit
|
||||
* array of ASCII characters.
|
||||
*/
|
||||
#else
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
int16_t bString[];
|
||||
#endif
|
||||
} USB_Descriptor_String_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t Size;
|
||||
void* Address;
|
||||
} USB_Descriptor_Details_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Function to retrieve a given descriptor's size and memory location from the given descriptor type value,
|
||||
* index and language ID. This function MUST be overridden in the user application (added with full, identical
|
||||
* prototype and name except for the ATTR_WEAK attribute) so that the library can call it to retrieve descriptor
|
||||
* data.
|
||||
*
|
||||
* \param wValue The type of the descriptor to retrieve in the upper byte, and the index in the
|
||||
* lower byte (when more than one descriptor of the given type exists, such as the
|
||||
* case of string descriptors). The type may be one of the standard types defined
|
||||
* in the DescriptorTypes_t enum, or may be a class-specific descriptor type value.
|
||||
* \param wIndex The language ID of the string to return if the wValue type indicates DTYPE_String,
|
||||
* otherwise zero for standard descriptors, or as defined in a class-specific
|
||||
* standards.
|
||||
* \param DescriptorAddress Pointer to the descriptor in memory. This should be set by the routine to
|
||||
* the location of the descriptor, found by the DESCRIPTOR_ADDRESS macro.
|
||||
*
|
||||
* \note By default, the library expects all descriptors to be located in flash memory via the PROGMEM attribute.
|
||||
* If descriptors should be located in RAM or EEPROM instead (to speed up access in the case of RAM, or to
|
||||
* allow the descriptors to be changed dynamically at runtime) either the USE_SRAM_DESCRIPTORS or the
|
||||
* USE_EEPROM_DESCRIPTORS tokens may be defined in the project makefile and passed to the compiler by the -D
|
||||
* switch.
|
||||
*
|
||||
* \return Size in bytes of the descriptor if it exists, zero or NO_DESCRIPTOR otherwise
|
||||
*/
|
||||
uint16_t USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_WEAK ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
#define VERSION_TENS(x) (int)(x / 10)
|
||||
#define VERSION_ONES(x) (int)(x - (10 * VERSION_TENS(x)))
|
||||
#define VERSION_TENTHS(x) (int)((x - (int)x) * 10)
|
||||
#define VERSION_HUNDREDTHS(x) (int)(((x - (int)x) * 100) - (10 * VERSION_TENTHS(x)))
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
252
LUFA/Drivers/USB/HighLevel/USBInterrupt.c
Normal file
252
LUFA/Drivers/USB/HighLevel/USBInterrupt.c
Normal file
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, 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.
|
||||
*/
|
||||
|
||||
#include "../LowLevel/USBMode.h"
|
||||
#include "USBInterrupt.h"
|
||||
|
||||
void USB_INT_DisableAllInterrupts(void)
|
||||
{
|
||||
#if defined(USB_FULL_CONTROLLER)
|
||||
USBCON &= ~((1 << VBUSTE) | (1 << IDTE));
|
||||
#elif defined(USB_MODIFIED_FULL_CONTROLLER)
|
||||
USBCON &= ~(1 << VBUSTE);
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
UHIEN = 0;
|
||||
OTGIEN = 0;
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
UDIEN = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void USB_INT_ClearAllInterrupts(void)
|
||||
{
|
||||
#if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER)
|
||||
USBINT = 0;
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
UHINT = 0;
|
||||
OTGINT = 0;
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
UDINT = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
ISR(USB_GEN_vect, ISR_BLOCK)
|
||||
{
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
#if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER)
|
||||
if (USB_INT_HasOccurred(USB_INT_VBUS) && USB_INT_IsEnabled(USB_INT_VBUS))
|
||||
{
|
||||
USB_INT_Clear(USB_INT_VBUS);
|
||||
|
||||
RAISE_EVENT(USB_VBUSChange);
|
||||
|
||||
if (USB_VBUS_GetStatus())
|
||||
{
|
||||
RAISE_EVENT(USB_VBUSConnect);
|
||||
|
||||
if (USB_IsConnected)
|
||||
RAISE_EVENT(USB_Disconnect);
|
||||
|
||||
USB_ResetInterface();
|
||||
|
||||
USB_IsConnected = true;
|
||||
|
||||
RAISE_EVENT(USB_Connect);
|
||||
}
|
||||
else
|
||||
{
|
||||
RAISE_EVENT(USB_Disconnect);
|
||||
|
||||
USB_Detach();
|
||||
USB_CLK_Freeze();
|
||||
USB_PLL_Off();
|
||||
USB_REG_Off();
|
||||
|
||||
USB_IsConnected = false;
|
||||
|
||||
RAISE_EVENT(USB_VBUSDisconnect);
|
||||
|
||||
USB_INT_Clear(USB_INT_VBUS);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (USB_INT_HasOccurred(USB_INT_SUSPEND) && USB_INT_IsEnabled(USB_INT_SUSPEND))
|
||||
{
|
||||
USB_INT_Clear(USB_INT_SUSPEND);
|
||||
|
||||
USB_INT_Disable(USB_INT_SUSPEND);
|
||||
USB_INT_Enable(USB_INT_WAKEUP);
|
||||
|
||||
USB_CLK_Freeze();
|
||||
|
||||
if (!(USB_Options & USB_OPT_MANUAL_PLL))
|
||||
USB_PLL_Off();
|
||||
|
||||
USB_IsSuspended = true;
|
||||
|
||||
RAISE_EVENT(USB_Suspend);
|
||||
|
||||
#if defined(USB_LIMITED_CONTROLLER) && !defined(NO_LIMITED_CONTROLLER_CONNECT)
|
||||
if (USB_IsConnected)
|
||||
{
|
||||
USB_IsConnected = false;
|
||||
RAISE_EVENT(USB_Disconnect);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (USB_INT_HasOccurred(USB_INT_WAKEUP) && USB_INT_IsEnabled(USB_INT_WAKEUP))
|
||||
{
|
||||
if (!(USB_Options & USB_OPT_MANUAL_PLL))
|
||||
{
|
||||
USB_PLL_On();
|
||||
while (!(USB_PLL_IsReady()));
|
||||
}
|
||||
|
||||
USB_CLK_Unfreeze();
|
||||
|
||||
USB_INT_Clear(USB_INT_WAKEUP);
|
||||
|
||||
USB_INT_Disable(USB_INT_WAKEUP);
|
||||
USB_INT_Enable(USB_INT_SUSPEND);
|
||||
|
||||
#if defined(USB_LIMITED_CONTROLLER) && !defined(NO_LIMITED_CONTROLLER_CONNECT)
|
||||
if (!(USB_IsConnected))
|
||||
{
|
||||
USB_IsConnected = true;
|
||||
RAISE_EVENT(USB_Connect);
|
||||
}
|
||||
#endif
|
||||
|
||||
USB_IsSuspended = false;
|
||||
|
||||
RAISE_EVENT(USB_WakeUp);
|
||||
}
|
||||
|
||||
if (USB_INT_HasOccurred(USB_INT_EORSTI) && USB_INT_IsEnabled(USB_INT_EORSTI))
|
||||
{
|
||||
USB_INT_Clear(USB_INT_EORSTI);
|
||||
|
||||
USB_ConfigurationNumber = 0;
|
||||
|
||||
USB_INT_Clear(USB_INT_SUSPEND);
|
||||
USB_INT_Disable(USB_INT_SUSPEND);
|
||||
USB_INT_Enable(USB_INT_WAKEUP);
|
||||
|
||||
Endpoint_ClearEndpoints();
|
||||
|
||||
Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL,
|
||||
ENDPOINT_DIR_OUT, USB_ControlEndpointSize,
|
||||
ENDPOINT_BANK_SINGLE);
|
||||
|
||||
RAISE_EVENT(USB_Reset);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
if (USB_INT_HasOccurred(USB_INT_DDISCI) && USB_INT_IsEnabled(USB_INT_DDISCI))
|
||||
{
|
||||
USB_INT_Clear(USB_INT_DDISCI);
|
||||
USB_INT_Clear(USB_INT_DCONNI);
|
||||
USB_INT_Disable(USB_INT_DDISCI);
|
||||
|
||||
RAISE_EVENT(USB_DeviceUnattached);
|
||||
RAISE_EVENT(USB_Disconnect);
|
||||
|
||||
USB_ResetInterface();
|
||||
}
|
||||
|
||||
if (USB_INT_HasOccurred(USB_INT_VBERRI) && USB_INT_IsEnabled(USB_INT_VBERRI))
|
||||
{
|
||||
USB_INT_Clear(USB_INT_VBERRI);
|
||||
|
||||
USB_Host_VBUS_Manual_Off();
|
||||
USB_Host_VBUS_Auto_Off();
|
||||
|
||||
RAISE_EVENT(USB_HostError, HOST_ERROR_VBusVoltageDip);
|
||||
RAISE_EVENT(USB_DeviceUnattached);
|
||||
|
||||
USB_HostState = HOST_STATE_Unattached;
|
||||
}
|
||||
|
||||
if (USB_INT_HasOccurred(USB_INT_SRPI) && USB_INT_IsEnabled(USB_INT_SRPI))
|
||||
{
|
||||
USB_INT_Clear(USB_INT_SRPI);
|
||||
USB_INT_Disable(USB_INT_SRPI);
|
||||
|
||||
RAISE_EVENT(USB_DeviceAttached);
|
||||
|
||||
USB_INT_Enable(USB_INT_DDISCI);
|
||||
|
||||
USB_HostState = HOST_STATE_Attached;
|
||||
}
|
||||
|
||||
if (USB_INT_HasOccurred(USB_INT_BCERRI) && USB_INT_IsEnabled(USB_INT_BCERRI))
|
||||
{
|
||||
USB_INT_Clear(USB_INT_BCERRI);
|
||||
|
||||
RAISE_EVENT(USB_DeviceEnumerationFailed, HOST_ENUMERROR_NoDeviceDetected, 0);
|
||||
RAISE_EVENT(USB_DeviceUnattached);
|
||||
|
||||
if (USB_IsConnected)
|
||||
RAISE_EVENT(USB_Disconnect);
|
||||
|
||||
USB_ResetInterface();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_BOTH)
|
||||
if (USB_INT_HasOccurred(USB_INT_IDTI) && USB_INT_IsEnabled(USB_INT_IDTI))
|
||||
{
|
||||
USB_INT_Clear(USB_INT_IDTI);
|
||||
|
||||
if (USB_IsConnected)
|
||||
{
|
||||
if (USB_CurrentMode == USB_MODE_HOST)
|
||||
RAISE_EVENT(USB_DeviceUnattached);
|
||||
else
|
||||
RAISE_EVENT(USB_Disconnect);
|
||||
}
|
||||
|
||||
RAISE_EVENT(USB_UIDChange);
|
||||
|
||||
USB_ResetInterface();
|
||||
}
|
||||
#endif
|
||||
}
|
224
LUFA/Drivers/USB/HighLevel/USBInterrupt.h
Normal file
224
LUFA/Drivers/USB/HighLevel/USBInterrupt.h
Normal file
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, 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
|
||||
*
|
||||
* Main USB interrupt vector handler. This file manages the main USB interrupt vector, for handling such
|
||||
* events as VBUS interrupts (on supported USB AVR models), device connections and disconnections, etc.
|
||||
*/
|
||||
|
||||
#ifndef __USBINTERRUPT_H__
|
||||
#define __USBINTERRUPT_H__
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "../../../Common/Common.h"
|
||||
#include "../LowLevel/LowLevel.h"
|
||||
#include "../LowLevel/USBMode.h"
|
||||
#include "Events.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Vector name for the common endpoint and pipe vector. This can be used to write an ISR handler
|
||||
* for the endpoint and pipe events, to make certain USB functions interrupt rather than poll
|
||||
* driven.
|
||||
*/
|
||||
#define ENDPOINT_PIPE_vect USB_COM_vect
|
||||
|
||||
/** Enables the given USB interrupt vector (such as the ENDPOINT_INT_* and PIPE_INT_* vectors in
|
||||
* Endpoint.h and Pipe.h).
|
||||
*/
|
||||
#define USB_INT_Enable(int) MACROS{ USB_INT_GET_EN_REG(int) |= USB_INT_GET_EN_MASK(int); }MACROE
|
||||
|
||||
/** Disables the given USB interrupt vector.
|
||||
*
|
||||
* \see USB_INT_Enable()
|
||||
*/
|
||||
#define USB_INT_Disable(int) MACROS{ USB_INT_GET_EN_REG(int) &= ~(USB_INT_GET_EN_MASK(int)); }MACROE
|
||||
|
||||
/** Resets the given USB interrupt flag, so that the interrupt is re-primed for the next firing. */
|
||||
#define USB_INT_Clear(int) MACROS{ USB_INT_GET_INT_REG(int) &= ~(USB_INT_GET_INT_MASK(int)); }MACROE
|
||||
|
||||
/** Returns boolean false if the given USB interrupt is disabled, or true if the interrupt is currently
|
||||
* enabled.
|
||||
*/
|
||||
#define USB_INT_IsEnabled(int) ((USB_INT_GET_EN_REG(int) & USB_INT_GET_EN_MASK(int)) ? true : false)
|
||||
|
||||
/** Returns boolean true if the given interrupt flag is set (i.e. the condition for the interrupt has occurred,
|
||||
* but the interrupt vector is not neccesarily enabled), otherwise returns false.
|
||||
*/
|
||||
#define USB_INT_HasOccurred(int) ((USB_INT_GET_INT_REG(int) & USB_INT_GET_INT_MASK(int)) ? true : false)
|
||||
|
||||
/* Throwable Events: */
|
||||
/** This module raises the USB Connected interrupt when the AVR is attached to a host while in device
|
||||
* USB mode.
|
||||
*
|
||||
* \note For the smaller USB AVRs (AT90USBXX2) with limited USB controllers, VBUS is not available to the USB controller.
|
||||
* this means that the current connection state is derived from the bus suspension and wake up events by default,
|
||||
* which is not always accurate (host may suspend the bus while still connected). If the actual connection state
|
||||
* needs to be determined, VBUS should be routed to an external pin, and the auto-detect behaviour turned off by
|
||||
* passing the NO_LIMITED_CONTROLLER_CONNECT token to the compiler via the -D switch at compile time. The connection
|
||||
* and disconnection events may be manually fired by RAISE_EVENT(), and the USB_IsConnected global changed manually.
|
||||
*/
|
||||
RAISES_EVENT(USB_Connect);
|
||||
|
||||
/** This module raises the USB Disconnected interrupt when the AVR is removed from a host while in
|
||||
* device USB mode.
|
||||
*
|
||||
* \note For the smaller USB AVRs (AT90USBXX2) with limited USB controllers, VBUS is not available to the USB controller.
|
||||
* this means that the current connection state is derived from the bus suspension and wake up events by default,
|
||||
* which is not always accurate (host may suspend the bus while still connected). If the actual connection state
|
||||
* needs to be determined, VBUS should be routed to an external pin, and the auto-detect behaviour turned off by
|
||||
* passing the NO_LIMITED_CONTROLLER_CONNECT token to the compiler via the -D switch at compile time. The connection
|
||||
* and disconnection events may be manually fired by RAISE_EVENT(), and the USB_IsConnected global changed manually.
|
||||
*/
|
||||
RAISES_EVENT(USB_Disconnect);
|
||||
|
||||
#if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER) || defined(__DOXYGEN__)
|
||||
/** This module raises the VBUS Change event when the current VBUS status (present or not present) has
|
||||
* changed.
|
||||
*
|
||||
* \note Not all USB AVR models support VBUS interrupts; this event only exists on supported AVRs.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_VBUSChange);
|
||||
|
||||
/** This module raises the VBUS Connect event when the VBUS line is powered.
|
||||
*
|
||||
* \note Not all USB AVR models support VBUS interrupts; this event only exists on supported AVRs.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_VBUSConnect);
|
||||
|
||||
/** This module raises the VBUS Disconnect event when power is removed from the VBUS line.
|
||||
*
|
||||
* \note Not all USB AVR models support VBUS interrupts; this event only exists on supported AVRs.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_VBUSDisconnect);
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__)
|
||||
/** This module raises the Suspended event when the host suspends the USB interface of the AVR
|
||||
* whilst running in device mode.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_Suspend);
|
||||
|
||||
/** This module raises the Wake Up event when the host resumes the USB interface of the AVR
|
||||
* whilst running in device mode.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_WakeUp);
|
||||
|
||||
/** This module raises the USB Reset event when the host resets the USB interface of the AVR
|
||||
* whilst running in device mode.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_Reset);
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_HOST) || defined(__DOXYGEN__)
|
||||
/** This module raises the Host Error event when the VBUS line voltage dips below the minimum threshold
|
||||
* while running in host mode.
|
||||
*
|
||||
* \note Not all USB AVR models support host mode; this event only exists on supported AVRs.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_HostError);
|
||||
|
||||
/** This module raises the Device Unattached event when an attached device is removed from the AVR whilst
|
||||
* running in host mode.
|
||||
*
|
||||
* \note Not all USB AVR models support host mode; this event only exists on supported AVRs.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_DeviceUnattached);
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_BOTH) || defined(__DOXYGEN__)
|
||||
/** This module raises the UID Change event when the UID line changes in value on dual-role devices.
|
||||
*
|
||||
* \note Not all USB AVR models support host mode and thus the UID pin; this event only exists on
|
||||
* supported AVRs.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_UIDChange);
|
||||
#endif
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
#define USB_INT_GET_EN_REG(a, b, c, d) a
|
||||
#define USB_INT_GET_EN_MASK(a, b, c, d) b
|
||||
#define USB_INT_GET_INT_REG(a, b, c, d) c
|
||||
#define USB_INT_GET_INT_MASK(a, b, c, d) d
|
||||
|
||||
#define USB_INT_VBUS USBCON, (1 << VBUSTE) , USBINT, (1 << VBUSTI)
|
||||
#define USB_INT_IDTI USBCON, (1 << IDTE) , USBINT, (1 << IDTI)
|
||||
#define USB_INT_WAKEUP UDIEN , (1 << WAKEUPE), UDINT , (1 << WAKEUPI)
|
||||
#define USB_INT_SUSPEND UDIEN , (1 << SUSPE) , UDINT , (1 << SUSPI)
|
||||
#define USB_INT_EORSTI UDIEN , (1 << EORSTE) , UDINT , (1 << EORSTI)
|
||||
#define USB_INT_DCONNI UHIEN , (1 << DCONNE) , UHINT , (1 << DCONNI)
|
||||
#define USB_INT_DDISCI UHIEN , (1 << DDISCE) , UHINT , (1 << DDISCI)
|
||||
#define USB_INT_BCERRI OTGIEN, (1 << BCERRE) , OTGINT, (1 << BCERRI)
|
||||
#define USB_INT_VBERRI OTGIEN, (1 << VBERRE) , OTGINT, (1 << VBERRI)
|
||||
#define USB_INT_SOFI UDIEN, (1 << SOFE) , UDINT , (1 << SOFI)
|
||||
#define USB_INT_HSOFI UHIEN, (1 << HSOFE) , UHINT , (1 << HSOFI)
|
||||
#define USB_INT_RSTI UHIEN , (1 << RSTE) , UHINT , (1 << RSTI)
|
||||
#define USB_INT_SRPI OTGIEN, (1 << SRPE) , OTGINT, (1 << SRPI)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void USB_INT_ClearAllInterrupts(void);
|
||||
void USB_INT_DisableAllInterrupts(void);
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
253
LUFA/Drivers/USB/HighLevel/USBTask.c
Normal file
253
LUFA/Drivers/USB/HighLevel/USBTask.c
Normal file
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, 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.
|
||||
*/
|
||||
|
||||
#include "../LowLevel/USBMode.h"
|
||||
|
||||
#define INCLUDE_FROM_USBTASK_C
|
||||
#include "USBTask.h"
|
||||
|
||||
volatile bool USB_IsSuspended;
|
||||
volatile bool USB_IsConnected;
|
||||
volatile bool USB_IsInitialized;
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
volatile uint8_t USB_HostState;
|
||||
#endif
|
||||
|
||||
TASK(USB_USBTask)
|
||||
{
|
||||
#if defined(USB_HOST_ONLY)
|
||||
USB_HostTask();
|
||||
#elif defined(USB_DEVICE_ONLY)
|
||||
USB_DeviceTask();
|
||||
#else
|
||||
if (USB_CurrentMode == USB_MODE_DEVICE)
|
||||
USB_DeviceTask();
|
||||
else if (USB_CurrentMode == USB_MODE_HOST)
|
||||
USB_HostTask();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
static void USB_DeviceTask(void)
|
||||
{
|
||||
if (USB_IsConnected)
|
||||
{
|
||||
uint8_t PrevEndpoint = Endpoint_GetCurrentEndpoint();
|
||||
|
||||
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
|
||||
|
||||
if (Endpoint_IsSetupReceived())
|
||||
{
|
||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
|
||||
{
|
||||
USB_Device_ProcessControlPacket();
|
||||
}
|
||||
}
|
||||
|
||||
Endpoint_SelectEndpoint(PrevEndpoint);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
static void USB_HostTask(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;
|
||||
}
|
||||
|
||||
WaitMSRemaining--;
|
||||
}
|
||||
else
|
||||
{
|
||||
USB_HostState = PostWaitState;
|
||||
}
|
||||
|
||||
break;
|
||||
case HOST_STATE_Attached:
|
||||
WaitMSRemaining = HOST_DEVICE_SETTLE_DELAY_MS;
|
||||
|
||||
USB_HostState = HOST_STATE_Attached_WaitForDeviceSettle;
|
||||
break;
|
||||
case HOST_STATE_Attached_WaitForDeviceSettle:
|
||||
_delay_ms(1);
|
||||
|
||||
if (!(WaitMSRemaining--))
|
||||
{
|
||||
USB_Host_VBUS_Manual_Off();
|
||||
|
||||
USB_OTGPAD_On();
|
||||
USB_Host_VBUS_Auto_Enable();
|
||||
USB_Host_VBUS_Auto_On();
|
||||
|
||||
USB_HostState = HOST_STATE_Attached_WaitForConnect;
|
||||
}
|
||||
|
||||
break;
|
||||
case HOST_STATE_Attached_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_IsConnected = true;
|
||||
RAISE_EVENT(USB_Connect);
|
||||
|
||||
USB_Host_ResumeBus();
|
||||
Pipe_ClearPipes();
|
||||
|
||||
HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Attached_DoReset);
|
||||
}
|
||||
|
||||
break;
|
||||
case HOST_STATE_Attached_DoReset:
|
||||
USB_Host_ResetDevice();
|
||||
|
||||
HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Powered);
|
||||
break;
|
||||
case HOST_STATE_Powered:
|
||||
Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL,
|
||||
PIPE_TOKEN_SETUP, PIPE_CONTROLPIPE,
|
||||
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_HostRequest = (USB_Host_Request_Header_t)
|
||||
{
|
||||
bmRequestType: (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
|
||||
bRequest: REQ_GetDescriptor,
|
||||
wValue: (DTYPE_Device << 8),
|
||||
wIndex: 0,
|
||||
wLength: PIPE_CONTROLPIPE_DEFAULT_SIZE,
|
||||
};
|
||||
|
||||
uint8_t DataBuffer[PIPE_CONTROLPIPE_DEFAULT_SIZE];
|
||||
|
||||
if ((SubErrorCode = USB_Host_SendControlRequest(DataBuffer)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
ErrorCode = HOST_ENUMERROR_ControlError;
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES)
|
||||
USB_ControlPipeSize = DataBuffer[offsetof(USB_Descriptor_Device_t, Endpoint0Size)];
|
||||
#else
|
||||
USB_ControlPipeSize = DataBuffer[offsetof(USB_Descriptor_Device_t, bMaxPacketSize0)];
|
||||
#endif
|
||||
|
||||
USB_Host_ResetDevice();
|
||||
|
||||
HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Default_PostReset);
|
||||
break;
|
||||
case HOST_STATE_Default_PostReset:
|
||||
Pipe_DisablePipe();
|
||||
Pipe_DeallocateMemory();
|
||||
Pipe_ResetPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL,
|
||||
PIPE_TOKEN_SETUP, PIPE_CONTROLPIPE,
|
||||
USB_ControlPipeSize, PIPE_BANK_SINGLE);
|
||||
|
||||
if (!(Pipe_IsConfigured()))
|
||||
{
|
||||
ErrorCode = HOST_ENUMERROR_PipeConfigError;
|
||||
SubErrorCode = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
Pipe_SetInfiniteINRequests();
|
||||
|
||||
USB_HostRequest = (USB_Host_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);
|
||||
|
||||
RAISE_EVENT(USB_DeviceEnumerationComplete);
|
||||
USB_HostState = HOST_STATE_Addressed;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ErrorCode != HOST_ENUMERROR_NoError) && (USB_HostState != HOST_STATE_Unattached))
|
||||
{
|
||||
RAISE_EVENT(USB_DeviceEnumerationFailed, ErrorCode, SubErrorCode);
|
||||
|
||||
USB_Host_VBUS_Auto_Off();
|
||||
|
||||
RAISE_EVENT(USB_DeviceUnattached);
|
||||
|
||||
if (USB_IsConnected)
|
||||
RAISE_EVENT(USB_Disconnect);
|
||||
|
||||
USB_ResetInterface();
|
||||
}
|
||||
}
|
||||
#endif
|
198
LUFA/Drivers/USB/HighLevel/USBTask.h
Normal file
198
LUFA/Drivers/USB/HighLevel/USBTask.h
Normal file
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2009.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.fourwalledcubicle.com
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is hereby
|
||||
granted, 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
|
||||
*
|
||||
* Main library USB management task for both Host and Device mode operations. This contains the master
|
||||
* USB_USBTask task which should be periodically run to service both host and device USB projects.
|
||||
*/
|
||||
|
||||
#ifndef __USBTASK_H__
|
||||
#define __USBTASK_H__
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/atomic.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../../../Scheduler/Scheduler.h"
|
||||
#include "../LowLevel/LowLevel.h"
|
||||
#include "../LowLevel/HostChapter9.h"
|
||||
#include "../LowLevel/USBMode.h"
|
||||
#include "Events.h"
|
||||
#include "StdDescriptors.h"
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Global Variables: */
|
||||
/** Indicates if the USB interface is currently connected to a host if in device mode, or to a
|
||||
* device while running in host mode.
|
||||
*
|
||||
* \note This variable should be treated as read-only in the user application, and never manually
|
||||
* changed in value.
|
||||
*
|
||||
* \note For the smaller USB AVRs (AT90USBXX2) with limited USB controllers, VBUS is not available to the USB controller.
|
||||
* this means that the current connection state is derived from the bus suspension and wake up events by default,
|
||||
* which is not always accurate (host may suspend the bus while still connected). If the actual connection state
|
||||
* needs to be determined, VBUS should be routed to an external pin, and the auto-detect behaviour turned off by
|
||||
* passing the NO_LIMITED_CONTROLLER_CONNECT token to the compiler via the -D switch at compile time. The connection
|
||||
* and disconnection events may be manually fired by RAISE_EVENT(), and the USB_IsConnected global changed manually.
|
||||
*/
|
||||
extern volatile bool USB_IsConnected;
|
||||
|
||||
/** Indicates if the USB interface is currently initialized but not neccesarily connected to a host
|
||||
* or device (i.e. if USB_Init() has been run). If this is false, all other library globals are invalid.
|
||||
*
|
||||
* \note This variable should be treated as read-only in the user application, and never manually
|
||||
* changed in value.
|
||||
*/
|
||||
extern volatile bool USB_IsInitialized;
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__)
|
||||
/** Indicates if the USB interface is currently suspended by the host when in device mode. When suspended,
|
||||
* the device should consume minimal power, and cannot communicate to the host. If Remote Wakeup is
|
||||
* supported by the device and USB_RemoteWakeupEnabled is true, suspension can be terminated by the device
|
||||
* by issuing a Remote Wakup request.
|
||||
*
|
||||
* \note This global is only present if the user application can be a USB device.
|
||||
*
|
||||
* \note This variable should be treated as read-only in the user application, and never manually
|
||||
* changed in value.
|
||||
*/
|
||||
extern volatile bool USB_IsSuspended;
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_HOST) || defined(__DOXYGEN__)
|
||||
/** Indicates the current host state machine state. When in host mode, this indicates the state
|
||||
* via one of the values of the USB_Host_States_t enum values in Host.h.
|
||||
*
|
||||
* This value may be altered by the user application to implement the HOST_STATE_Addressed,
|
||||
* HOST_STATE_Configured, HOST_STATE_Ready and HOST_STATE_Suspended states which are not implemented
|
||||
* by the library.
|
||||
*
|
||||
* \note This global is only present if the user application can be a USB host.
|
||||
*/
|
||||
extern volatile uint8_t USB_HostState;
|
||||
#endif
|
||||
|
||||
/* Throwable Events: */
|
||||
#if defined(USB_CAN_BE_HOST) || defined(__DOXYGEN__)
|
||||
/** This module raises the USB Connect event when a USB device has been connected whilst in host
|
||||
* mode, but not yet enumerated.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_Connect);
|
||||
|
||||
/** This module raises the USB Device Attached event when in host mode, and a device is attached
|
||||
* to the AVR's USB interface.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_DeviceAttached);
|
||||
|
||||
/** This module raises the USB Device Unattached event when in host mode, and a device is removed
|
||||
* from the AVR's USB interface.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_DeviceUnattached);
|
||||
|
||||
/** This module raises the USB Device Enumeration Failed event when in host mode, and an
|
||||
* attached USB device has failed to successfully enumerated.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_DeviceEnumerationFailed);
|
||||
|
||||
/** This module raises the USB Device Enumeration Complete event when in host mode, and an
|
||||
* attached USB device has been successfully enumerated and ready to be used by the user
|
||||
* application.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_DeviceEnumerationComplete);
|
||||
|
||||
/** This module raises the USB Disconnect event when an attached USB device is removed from the USB
|
||||
* bus.
|
||||
*
|
||||
* \see Events.h for more information on this event.
|
||||
*/
|
||||
RAISES_EVENT(USB_Disconnect);
|
||||
#endif
|
||||
|
||||
/* Tasks: */
|
||||
/** This is the main USB management task. The USB driver requires that this task be executed
|
||||
* continuously when the USB system is active (device attached in host mode, or attached to a host
|
||||
* in device mode) in order to manage USB communications. This task may be executed inside an RTOS,
|
||||
* scheduler (e.g. the simple LUFA Scheduler), fast timer ISR or the main user application loop.
|
||||
*
|
||||
* The USB task must be serviced within 50mS in all modes, when needed. The task may be serviced
|
||||
* at all times, or (for minimum CPU consumption):
|
||||
*
|
||||
* - In device mode, it may be disabled at startup, enabled on the firing of the USB_Connect event
|
||||
* and disabled again on the firing of the USB_Disconnect event.
|
||||
*
|
||||
* - In host mode, it may be disabled at startup, enabled on the firing of the USB_DeviceAttached
|
||||
* event and disabled again on the firing of the USB_DeviceUnattached event.
|
||||
*
|
||||
* \see Events.h for more information on the USB events.
|
||||
*/
|
||||
TASK(USB_USBTask);
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Function Prototypes: */
|
||||
#if defined(INCLUDE_FROM_USBTASK_C)
|
||||
#if defined(USB_CAN_BE_HOST)
|
||||
static void USB_HostTask(void);
|
||||
#endif
|
||||
|
||||
#if defined(USB_CAN_BE_DEVICE)
|
||||
static void USB_DeviceTask(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Macros: */
|
||||
#define HOST_TASK_NONBLOCK_WAIT(duration, nextstate) {USB_HostState = HOST_STATE_WaitForDevice; WaitMSRemaining = duration; PostWaitState = nextstate; }
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue