From 6a10d6b465be27db090d760dc0fbe722c94e4344 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Mon, 23 Feb 2009 07:08:22 +0000 Subject: Moved all source to the trunk directory. --- LUFA/Drivers/USB/HighLevel/Events.c | 39 +++ LUFA/Drivers/USB/HighLevel/Events.h | 440 +++++++++++++++++++++++ LUFA/Drivers/USB/HighLevel/StdDescriptors.c | 43 +++ LUFA/Drivers/USB/HighLevel/StdDescriptors.h | 523 ++++++++++++++++++++++++++++ LUFA/Drivers/USB/HighLevel/USBInterrupt.c | 252 ++++++++++++++ LUFA/Drivers/USB/HighLevel/USBInterrupt.h | 224 ++++++++++++ LUFA/Drivers/USB/HighLevel/USBTask.c | 253 ++++++++++++++ LUFA/Drivers/USB/HighLevel/USBTask.h | 198 +++++++++++ 8 files changed, 1972 insertions(+) create mode 100644 LUFA/Drivers/USB/HighLevel/Events.c create mode 100644 LUFA/Drivers/USB/HighLevel/Events.h create mode 100644 LUFA/Drivers/USB/HighLevel/StdDescriptors.c create mode 100644 LUFA/Drivers/USB/HighLevel/StdDescriptors.h create mode 100644 LUFA/Drivers/USB/HighLevel/USBInterrupt.c create mode 100644 LUFA/Drivers/USB/HighLevel/USBInterrupt.h create mode 100644 LUFA/Drivers/USB/HighLevel/USBTask.c create mode 100644 LUFA/Drivers/USB/HighLevel/USBTask.h (limited to 'LUFA/Drivers/USB/HighLevel') diff --git a/LUFA/Drivers/USB/HighLevel/Events.c b/LUFA/Drivers/USB/HighLevel/Events.c new file mode 100644 index 000000000..dbc428aae --- /dev/null +++ b/LUFA/Drivers/USB/HighLevel/Events.c @@ -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) +{ + +} diff --git a/LUFA/Drivers/USB/HighLevel/Events.h b/LUFA/Drivers/USB/HighLevel/Events.h new file mode 100644 index 000000000..eeb0ed37a --- /dev/null +++ b/LUFA/Drivers/USB/HighLevel/Events.h @@ -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 + + #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 diff --git a/LUFA/Drivers/USB/HighLevel/StdDescriptors.c b/LUFA/Drivers/USB/HighLevel/StdDescriptors.c new file mode 100644 index 000000000..5fdc72e80 --- /dev/null +++ b/LUFA/Drivers/USB/HighLevel/StdDescriptors.c @@ -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 diff --git a/LUFA/Drivers/USB/HighLevel/StdDescriptors.h b/LUFA/Drivers/USB/HighLevel/StdDescriptors.h new file mode 100644 index 000000000..d9075cc75 --- /dev/null +++ b/LUFA/Drivers/USB/HighLevel/StdDescriptors.h @@ -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 + #include + + #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 + * http://www.usb.org/developers/docs/InterfaceAssociationDescriptor_ecn.pdf. 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 diff --git a/LUFA/Drivers/USB/HighLevel/USBInterrupt.c b/LUFA/Drivers/USB/HighLevel/USBInterrupt.c new file mode 100644 index 000000000..58faa69de --- /dev/null +++ b/LUFA/Drivers/USB/HighLevel/USBInterrupt.c @@ -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 +} diff --git a/LUFA/Drivers/USB/HighLevel/USBInterrupt.h b/LUFA/Drivers/USB/HighLevel/USBInterrupt.h new file mode 100644 index 000000000..8438a589e --- /dev/null +++ b/LUFA/Drivers/USB/HighLevel/USBInterrupt.h @@ -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 + #include + + #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 diff --git a/LUFA/Drivers/USB/HighLevel/USBTask.c b/LUFA/Drivers/USB/HighLevel/USBTask.c new file mode 100644 index 000000000..69670232b --- /dev/null +++ b/LUFA/Drivers/USB/HighLevel/USBTask.c @@ -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 diff --git a/LUFA/Drivers/USB/HighLevel/USBTask.h b/LUFA/Drivers/USB/HighLevel/USBTask.h new file mode 100644 index 000000000..1fcc2bbb3 --- /dev/null +++ b/LUFA/Drivers/USB/HighLevel/USBTask.h @@ -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 + #include + #include + #include + #include + + #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 -- cgit v1.2.3