Moved all source to the trunk directory.

This commit is contained in:
Dean Camera 2009-02-23 07:08:22 +00:00
parent 9991321321
commit 6a10d6b465
88 changed files with 15575 additions and 0 deletions

View 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)
{
}

View 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

View 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

View 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

View 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
}

View 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

View 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

View 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