You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
465 lines
19 KiB
465 lines
19 KiB
/* |
|
LUFA Library |
|
Copyright (C) Dean Camera, 2010. |
|
|
|
dean [at] fourwalledcubicle [dot] com |
|
www.fourwalledcubicle.com |
|
*/ |
|
|
|
/* |
|
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) |
|
|
|
Permission to use, copy, modify, distribute, and sell this |
|
software and its documentation for any purpose is hereby granted |
|
without fee, provided that the above copyright notice appear in |
|
all copies and that both that the copyright notice and this |
|
permission notice and warranty disclaimer appear in supporting |
|
documentation, and that the name of the author not be used in |
|
advertising or publicity pertaining to distribution of the |
|
software without specific, written prior permission. |
|
|
|
The author disclaim all warranties with regard to this |
|
software, including all implied warranties of merchantability |
|
and fitness. In no event shall the author be liable for any |
|
special, indirect or consequential damages or any damages |
|
whatsoever resulting from loss of use, data or profits, whether |
|
in an action of contract, negligence or other tortious action, |
|
arising out of or in connection with the use or performance of |
|
this software. |
|
*/ |
|
|
|
/** \file |
|
* \brief USB low level USB controller definitions. |
|
* |
|
* This file contains structures, function prototypes and macros related to the low level configuration of the |
|
* USB controller, to start, stop and reset the USB library core. |
|
* |
|
* \note This file should not be included directly. It is automatically included as needed by the USB driver |
|
* dispatch header located in LUFA/Drivers/USB/USB.h. |
|
*/ |
|
|
|
/** \ingroup Group_USB |
|
* @defgroup Group_USBManagement USB Interface Management |
|
* |
|
* Functions, macros, variables, enums and types related to the setup and management of the USB interface. |
|
* |
|
* @{ |
|
*/ |
|
|
|
#ifndef __USBCONTROLLER_H__ |
|
#define __USBCONTROLLER_H__ |
|
|
|
/* Includes: */ |
|
#include <avr/io.h> |
|
#include <avr/interrupt.h> |
|
#include <stdbool.h> |
|
|
|
#include "../HighLevel/USBMode.h" |
|
|
|
#include "../../../Common/Common.h" |
|
#include "../HighLevel/USBMode.h" |
|
#include "../HighLevel/Events.h" |
|
#include "../HighLevel/USBTask.h" |
|
#include "USBInterrupt.h" |
|
|
|
#if defined(USB_CAN_BE_HOST) || defined(__DOXYGEN__) |
|
#include "Host.h" |
|
#include "Pipe.h" |
|
#include "OTG.h" |
|
#include "../HighLevel/HostStandardReq.h" |
|
#endif |
|
|
|
#if defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__) |
|
#include "Device.h" |
|
#include "Endpoint.h" |
|
#include "../HighLevel/DeviceStandardReq.h" |
|
#endif |
|
|
|
/* Enable C linkage for C++ Compilers: */ |
|
#if defined(__cplusplus) |
|
extern "C" { |
|
#endif |
|
|
|
/* Preprocessor Checks and Defines: */ |
|
#if !defined(__INCLUDE_FROM_USB_DRIVER) |
|
#error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. |
|
#endif |
|
|
|
#if !defined(F_CLOCK) |
|
#error F_CLOCK is not defined. You must define F_CLOCK to the frequency of the unprescaled input clock in your project makefile. |
|
#endif |
|
|
|
#if (F_CLOCK == 8000000) |
|
#if (defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || \ |
|
defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__) || \ |
|
defined(__AVR_ATmega32U2__)) |
|
#define USB_PLL_PSC 0 |
|
#elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) |
|
#define USB_PLL_PSC 0 |
|
#elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || defined(__AVR_ATmega32U6__)) |
|
#define USB_PLL_PSC ((1 << PLLP1) | (1 << PLLP0)) |
|
#elif (defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1287__)) |
|
#define USB_PLL_PSC ((1 << PLLP1) | (1 << PLLP0)) |
|
#endif |
|
#elif (F_CLOCK == 16000000) |
|
#if (defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || \ |
|
defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__) || \ |
|
defined(__AVR_ATmega32U2__)) |
|
#define USB_PLL_PSC (1 << PLLP0) |
|
#elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) |
|
#define USB_PLL_PSC (1 << PINDIV) |
|
#elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_ATmega32U6__)) |
|
#define USB_PLL_PSC ((1 << PLLP2) | (1 << PLLP1)) |
|
#elif (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)) |
|
#define USB_PLL_PSC ((1 << PLLP2) | (1 << PLLP0)) |
|
#endif |
|
#endif |
|
|
|
#if !defined(USB_PLL_PSC) |
|
#error No PLL prescale value available for chosen F_CPU value and AVR model. |
|
#endif |
|
|
|
/* Public Interface - May be used in end-application: */ |
|
/* Macros: */ |
|
/** Mode mask for the \ref USB_CurrentMode global. This indicates that the USB interface is currently not |
|
* initialized into any mode. |
|
*/ |
|
#define USB_MODE_NONE 0 |
|
|
|
/** Mode mask for the \ref USB_CurrentMode global and the \ref USB_Init() function. This indicates that the |
|
* USB interface is or should be initialized in the USB device mode. |
|
*/ |
|
#define USB_MODE_DEVICE 1 |
|
|
|
/** Mode mask for the \ref USB_CurrentMode global and the \ref USB_Init() function. This indicates that the |
|
* USB interface is or should be initialized in the USB host mode. |
|
*/ |
|
#define USB_MODE_HOST 2 |
|
|
|
#if defined(USB_CAN_BE_BOTH) || defined(__DOXYGEN__) |
|
/** Mode mask for the the \ref USB_Init() function. This indicates that the USB interface should be |
|
* initialized into whatever mode the UID pin of the USB AVR indicates, and that the device |
|
* should swap over its mode when the level of the UID pin changes during operation. |
|
* |
|
* \note This token is not available on AVR models which do not support both host and device modes. |
|
*/ |
|
#define USB_MODE_UID 3 |
|
#endif |
|
|
|
/** Regulator disable option mask for \ref USB_Init(). This indicates that the internal 3.3V USB data pad |
|
* regulator should be enabled to regulate the data pin voltages to within the USB standard. |
|
* |
|
* \note See USB AVR data sheet for more information on the internal pad regulator. |
|
*/ |
|
#define USB_OPT_REG_DISABLED (1 << 1) |
|
|
|
/** Regulator enable option mask for \ref USB_Init(). This indicates that the internal 3.3V USB data pad |
|
* regulator should be disabled and the AVR's VCC level used for the data pads. |
|
* |
|
* \note See USB AVR data sheet for more information on the internal pad regulator. |
|
*/ |
|
#define USB_OPT_REG_ENABLED (0 << 1) |
|
|
|
/** Manual PLL control option mask for \ref USB_Init(). This indicates to the library that the user application |
|
* will take full responsibility for controlling the AVR's PLL (used to generate the high frequency clock |
|
* that the USB controller requires) and ensuring that it is locked at the correct frequency for USB operations. |
|
*/ |
|
#define USB_OPT_MANUAL_PLL (1 << 2) |
|
|
|
/** Automatic PLL control option mask for \ref USB_Init(). This indicates to the library that the library should |
|
* take full responsibility for controlling the AVR's PLL (used to generate the high frequency clock |
|
* that the USB controller requires) and ensuring that it is locked at the correct frequency for USB operations. |
|
*/ |
|
#define USB_OPT_AUTO_PLL (0 << 2) |
|
|
|
/** Mask for a CONTROL type endpoint or pipe. |
|
* |
|
* \note See \ref Group_EndpointManagement and \ref Group_PipeManagement for endpoint/pipe functions. |
|
*/ |
|
#define EP_TYPE_CONTROL 0x00 |
|
|
|
/** Mask for an ISOCHRONOUS type endpoint or pipe. |
|
* |
|
* \note See \ref Group_EndpointManagement and \ref Group_PipeManagement for endpoint/pipe functions. |
|
*/ |
|
#define EP_TYPE_ISOCHRONOUS 0x01 |
|
|
|
/** Mask for a BULK type endpoint or pipe. |
|
* |
|
* \note See \ref Group_EndpointManagement and \ref Group_PipeManagement for endpoint/pipe functions. |
|
*/ |
|
#define EP_TYPE_BULK 0x02 |
|
|
|
/** Mask for an INTERRUPT type endpoint or pipe. |
|
* |
|
* \note See \ref Group_EndpointManagement and \ref Group_PipeManagement for endpoint/pipe functions. |
|
*/ |
|
#define EP_TYPE_INTERRUPT 0x03 |
|
|
|
#if !defined(USB_STREAM_TIMEOUT_MS) || defined(__DOXYGEN__) |
|
/** Constant for the maximum software timeout period of the USB data stream transfer functions |
|
* (both control and standard) when in either device or host mode. If the next packet of a stream |
|
* is not received or acknowledged within this time period, the stream function will fail. |
|
* |
|
* This value may be overridden in the user project makefile as the value of the |
|
* \ref USB_STREAM_TIMEOUT_MS token, and passed to the compiler using the -D switch. |
|
*/ |
|
#define USB_STREAM_TIMEOUT_MS 100 |
|
#endif |
|
|
|
/* Inline Functions: */ |
|
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) || defined(__DOXYGEN__) |
|
/** Returns boolean true if the VBUS line is currently high (i.e. the USB host is supplying power), |
|
* otherwise returns false. |
|
* |
|
* \note This function is not available on some AVR models which do not support hardware VBUS monitoring. |
|
*/ |
|
static inline bool USB_VBUS_GetStatus(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
|
static inline bool USB_VBUS_GetStatus(void) |
|
{ |
|
return ((USBSTA & (1 << VBUS)) ? true : false); |
|
} |
|
#endif |
|
|
|
/** Detaches the device from the USB bus. This has the effect of removing the device from any |
|
* attached host, ceasing USB communications. If no host is present, this prevents any host from |
|
* enumerating the device once attached until \ref USB_Attach() is called. |
|
*/ |
|
static inline void USB_Detach(void) ATTR_ALWAYS_INLINE; |
|
static inline void USB_Detach(void) |
|
{ |
|
UDCON |= (1 << DETACH); |
|
} |
|
|
|
/** Attaches the device to the USB bus. This announces the device's presence to any attached |
|
* USB host, starting the enumeration process. If no host is present, attaching the device |
|
* will allow for enumeration once a host is connected to the device. |
|
* |
|
* This is inexplicably also required for proper operation while in host mode, to enable the |
|
* attachment of a device to the host. This is despite the bit being located in the device-mode |
|
* register and despite the datasheet making no mention of its requirement in host mode. |
|
*/ |
|
static inline void USB_Attach(void) ATTR_ALWAYS_INLINE; |
|
static inline void USB_Attach(void) |
|
{ |
|
UDCON &= ~(1 << DETACH); |
|
} |
|
|
|
/* Function Prototypes: */ |
|
/** Main function to initialize and start the USB interface. Once active, the USB interface will |
|
* allow for device connection to a host when in device mode, or for device enumeration while in |
|
* host mode. |
|
* |
|
* As the USB library relies on interrupts for the device and host mode enumeration processes, |
|
* the user must enable global interrupts before or shortly after this function is called. In |
|
* device mode, interrupts must be enabled within 500ms of this function being called to ensure |
|
* that the host does not time out whilst enumerating the device. In host mode, interrupts may be |
|
* enabled at the application's leisure however enumeration will not begin of an attached device |
|
* until after this has occurred. |
|
* |
|
* Calling this function when the USB interface is already initialized will cause a complete USB |
|
* interface reset and re-enumeration. |
|
* |
|
* \param[in] Mode This is a mask indicating what mode the USB interface is to be initialized to. |
|
* Valid mode masks are \ref USB_MODE_DEVICE, \ref USB_MODE_HOST or \ref USB_MODE_UID. |
|
* |
|
* \param[in] Options Mask indicating the options which should be used when initializing the USB |
|
* interface to control the USB interface's behaviour. This should be comprised of |
|
* a USB_OPT_REG_* mask to control the regulator, a USB_OPT_*_PLL mask to control the |
|
* PLL, and a USB_DEVICE_OPT_* mask (when the device mode is enabled) to set the device |
|
* mode speed. |
|
* |
|
* \note To reduce the FLASH requirements of the library if only device or host mode is required, |
|
* the mode can be statically set in the project makefile by defining the token USB_DEVICE_ONLY |
|
* (for device mode) or USB_HOST_ONLY (for host mode), passing the token to the compiler |
|
* via the -D switch. If the mode is statically set, this parameter does not exist in the |
|
* function prototype. |
|
* \n\n |
|
* |
|
* \note To reduce the FLASH requirements of the library if only fixed settings are are required, |
|
* the options may be set statically in the same manner as the mode (see the Mode parameter of |
|
* this function). To statically set the USB options, pass in the USE_STATIC_OPTIONS token, |
|
* defined to the appropriate options masks. When the options are statically set, this |
|
* parameter does not exist in the function prototype. |
|
* \n\n |
|
* |
|
* \note The mode parameter does not exist on devices where only one mode is possible, such as USB |
|
* AVR models which only implement the USB device mode in hardware. |
|
* |
|
* \see Device.h for the USB_DEVICE_OPT_* masks. |
|
*/ |
|
void USB_Init( |
|
#if defined(USB_CAN_BE_BOTH) || defined(__DOXYGEN__) |
|
const uint8_t Mode |
|
#endif |
|
|
|
#if (defined(USB_CAN_BE_BOTH) && !defined(USE_STATIC_OPTIONS)) || defined(__DOXYGEN__) |
|
, |
|
#elif (!defined(USB_CAN_BE_BOTH) && defined(USE_STATIC_OPTIONS)) |
|
void |
|
#endif |
|
|
|
#if !defined(USE_STATIC_OPTIONS) || defined(__DOXYGEN__) |
|
const uint8_t Options |
|
#endif |
|
); |
|
|
|
/** Shuts down the USB interface. This turns off the USB interface after deallocating all USB FIFO |
|
* memory, endpoints and pipes. When turned off, no USB functionality can be used until the interface |
|
* is restarted with the \ref USB_Init() function. |
|
*/ |
|
void USB_ShutDown(void); |
|
|
|
/** Resets the interface, when already initialized. This will re-enumerate the device if already connected |
|
* to a host, or re-enumerate an already attached device when in host mode. |
|
*/ |
|
void USB_ResetInterface(void); |
|
|
|
/* Enums: */ |
|
/** Enum for error codes relating to the powering on of the USB interface. These error codes are |
|
* used in the ErrorCode parameter value of the \ref EVENT_USB_InitFailure() event. |
|
*/ |
|
enum USB_InitErrorCodes_t |
|
{ |
|
USB_INITERROR_NoUSBModeSpecified = 0, /**< Indicates that \ref USB_Init() was called with an |
|
* invalid or missing Mode parameter. |
|
*/ |
|
}; |
|
|
|
/* Global Variables: */ |
|
#if (!defined(USB_HOST_ONLY) && !defined(USB_DEVICE_ONLY)) || defined(__DOXYGEN__) |
|
/** Indicates the mode that the USB interface is currently initialized to. This value will be |
|
* one of the USB_MODE_* masks defined elsewhere in this module. |
|
* |
|
* \note This variable should be treated as read-only in the user application, and never manually |
|
* changed in value. |
|
*/ |
|
extern volatile uint8_t USB_CurrentMode; |
|
#elif defined(USB_HOST_ONLY) |
|
#define USB_CurrentMode USB_MODE_HOST |
|
#elif defined(USB_DEVICE_ONLY) |
|
#define USB_CurrentMode USB_MODE_DEVICE |
|
#endif |
|
|
|
#if !defined(USE_STATIC_OPTIONS) || defined(__DOXYGEN__) |
|
/** Indicates the current USB options that the USB interface was initialized with when \ref USB_Init() |
|
* was called. This value will be one of the USB_MODE_* masks defined elsewhere in this module. |
|
* |
|
* \note This variable should be treated as read-only in the user application, and never manually |
|
* changed in value. |
|
*/ |
|
extern volatile uint8_t USB_Options; |
|
#elif defined(USE_STATIC_OPTIONS) |
|
#define USB_Options USE_STATIC_OPTIONS |
|
#endif |
|
|
|
/* Private Interface - For use in library only: */ |
|
#if !defined(__DOXYGEN__) |
|
/* Inline Functions: */ |
|
static inline void USB_PLL_On(void) ATTR_ALWAYS_INLINE; |
|
static inline void USB_PLL_On(void) |
|
{ |
|
PLLCSR = USB_PLL_PSC; |
|
PLLCSR |= (1 << PLLE); |
|
} |
|
|
|
static inline void USB_PLL_Off(void) ATTR_ALWAYS_INLINE; |
|
static inline void USB_PLL_Off(void) |
|
{ |
|
PLLCSR = 0; |
|
} |
|
|
|
static inline bool USB_PLL_IsReady(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
|
static inline bool USB_PLL_IsReady(void) |
|
{ |
|
return ((PLLCSR & (1 << PLOCK)) ? true : false); |
|
} |
|
|
|
static inline void USB_REG_On(void) ATTR_ALWAYS_INLINE; |
|
static inline void USB_REG_On(void) |
|
{ |
|
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) |
|
UHWCON |= (1 << UVREGE); |
|
#else |
|
REGCR &= ~(1 << REGDIS); |
|
#endif |
|
} |
|
|
|
static inline void USB_REG_Off(void) ATTR_ALWAYS_INLINE; |
|
static inline void USB_REG_Off(void) |
|
{ |
|
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) |
|
UHWCON &= ~(1 << UVREGE); |
|
#else |
|
REGCR |= (1 << REGDIS); |
|
#endif |
|
} |
|
|
|
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) |
|
static inline void USB_OTGPAD_On(void) ATTR_ALWAYS_INLINE; |
|
static inline void USB_OTGPAD_On(void) |
|
{ |
|
USBCON |= (1 << OTGPADE); |
|
} |
|
|
|
static inline void USB_OTGPAD_Off(void) ATTR_ALWAYS_INLINE; |
|
static inline void USB_OTGPAD_Off(void) |
|
{ |
|
USBCON &= ~(1 << OTGPADE); |
|
} |
|
#endif |
|
|
|
static inline void USB_CLK_Freeze(void) ATTR_ALWAYS_INLINE; |
|
static inline void USB_CLK_Freeze(void) |
|
{ |
|
USBCON |= (1 << FRZCLK); |
|
} |
|
|
|
static inline void USB_CLK_Unfreeze(void) ATTR_ALWAYS_INLINE; |
|
static inline void USB_CLK_Unfreeze(void) |
|
{ |
|
USBCON &= ~(1 << FRZCLK); |
|
} |
|
|
|
static inline void USB_Controller_Enable(void) ATTR_ALWAYS_INLINE; |
|
static inline void USB_Controller_Enable(void) |
|
{ |
|
USBCON |= (1 << USBE); |
|
} |
|
|
|
static inline void USB_Controller_Disable(void) ATTR_ALWAYS_INLINE; |
|
static inline void USB_Controller_Disable(void) |
|
{ |
|
USBCON &= ~(1 << USBE); |
|
} |
|
|
|
static inline void USB_Controller_Reset(void) ATTR_ALWAYS_INLINE; |
|
static inline void USB_Controller_Reset(void) |
|
{ |
|
const uint8_t Temp = USBCON; |
|
|
|
USBCON = (Temp & ~(1 << USBE)); |
|
USBCON = (Temp | (1 << USBE)); |
|
} |
|
|
|
#if defined(USB_CAN_BE_BOTH) |
|
static inline uint8_t USB_GetUSBModeFromUID(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
|
static inline uint8_t USB_GetUSBModeFromUID(void) |
|
{ |
|
if (USBSTA & (1 << ID)) |
|
return USB_MODE_DEVICE; |
|
else |
|
return USB_MODE_HOST; |
|
} |
|
#endif |
|
|
|
#endif |
|
|
|
/* Disable C linkage for C++ Compilers: */ |
|
#if defined(__cplusplus) |
|
} |
|
#endif |
|
|
|
#endif |
|
|
|
/** @} */
|
|
|