/*
LUFA Library
Copyright (C) Dean Camera, 2010.
-
+
dean [at] fourwalledcubicle [dot] com
- www.fourwalledcubicle.com
+ www.lufa-lib.org
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
- Permission to use, copy, modify, distribute, and sell this
+ 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
+ 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
+ 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
* \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
*
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdbool.h>
-
+
#include "../HighLevel/USBMode.h"
#include "../../../Common/Common.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 "Pipe.h"
#include "../HighLevel/HostStandardReq.h"
+ #include "../HighLevel/PipeStream.h"
#endif
-
+
#if defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__)
#include "Device.h"
#include "Endpoint.h"
#include "../HighLevel/DeviceStandardReq.h"
+ #include "../HighLevel/EndpointStream.h"
#endif
/* Enable C linkage for C++ Compilers: */
#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__))
+ defined(__AVR_ATmega32U2__))
#define USB_PLL_PSC 0
#elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
#define USB_PLL_PSC 0
#elif (F_CLOCK == 16000000)
#if (defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || \
defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__) || \
- defined(__AVR_ATmega32U2__))
+ defined(__AVR_ATmega32U2__))
#define USB_PLL_PSC (1 << PLLP0)
#elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
#define USB_PLL_PSC (1 << PINDIV)
#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.
+ #error No PLL prescale value available for chosen F_CLOCK 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
-
+ /** \name USB Controller Option Masks */
+ //@{
/** 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_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.
* 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)
-
+ //@}
+
+ /** \name Endpoint/Pipe Type Masks */
+ //@{
/** Mask for a CONTROL type endpoint or pipe.
*
* \note See \ref Group_EndpointManagement and \ref Group_PipeManagement for endpoint/pipe functions.
* \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 token is not available on some AVR models which do not support hardware VBUS monitoring.
+ * \note This function is not available on some AVR models which do not support hardware VBUS monitoring.
*/
- #define USB_VBUS_GetStatus() ((USBSTA & (1 << VBUS)) ? true : false)
+ 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.
*/
- #define USB_Detach() MACROS{ UDCON |= (1 << DETACH); }MACROE
+ 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
* 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.
*/
- #define USB_Attach() MACROS{ UDCON &= ~(1 << DETACH); }MACROE
-
- #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
+ 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
* 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] Mode This is a mask indicating what mode the USB interface is to be initialized to, a value
+ * from the \ref USB_Modes_t enum.
*
* \param[in] Options Mask indicating the options which should be used when initializing the USB
- * interface to control the USB interface's behavior. This should be comprised of
+ * 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,
+ * \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
+ * (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
+ * 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
+ *
+ * \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
+ #endif
#if (defined(USB_CAN_BE_BOTH) && !defined(USE_STATIC_OPTIONS)) || defined(__DOXYGEN__)
,
- #elif (!defined(USB_CAN_BE_BOTH) && defined(USE_STATIC_OPTIONS))
- void
+ #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_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.
+ /** Indicates the mode that the USB interface is currently initialized to, a value from the
+ * \ref USB_Modes_t enum.
*
* \note This variable should be treated as read-only in the user application, and never manually
* changed in value.
+ * \n\n
+ *
+ * \note When the controller is initialized into UID autodetection mode, this variable will hold the
+ * currently selected USB mode (i.e. \ref USB_MODE_Device or \ref USB_MODE_Host). If the controller
+ * is fixed into a specific mode (either through the USB_DEVICE_ONLY or USB_HOST_ONLY compile time
+ * options, or a limitation of the USB controller in the chosen device model) this will evaluate to
+ * a constant of the appropriate value and will never evaluate to \ref USB_MODE_None even when the
+ * USB interface is not initialized.
*/
extern volatile uint8_t USB_CurrentMode;
#elif defined(USB_HOST_ONLY)
- #define USB_CurrentMode USB_MODE_HOST
+ #define USB_CurrentMode USB_MODE_Host
#elif defined(USB_DEVICE_ONLY)
- #define USB_CurrentMode USB_MODE_DEVICE
+ #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.
#define USB_Options USE_STATIC_OPTIONS
#endif
+ /* Enums: */
+ /** Enum for the possible USB controller modes, for initialization via \ref USB_Init() and indication back to the
+ * user application via \ref USB_CurrentMode.
+ */
+ enum USB_Modes_t
+ {
+ USB_MODE_None = 0, /**< Indicates that the controller is currently not initialized in any specific USB mode. */
+ USB_MODE_Device = 1, /**< Indicates that the controller is currently initialized in USB Device mode. */
+ USB_MODE_Host = 2, /**< Indicates that the controller is currently initialized in USB Host mode. */
+ USB_MODE_UID = 3, /**< Indicates that the controller should determine the USB mode from the UID pin of the
+ * USB connector.
+ */
+ };
+
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
- /* Macros: */
- #define USB_PLL_On() MACROS{ PLLCSR = USB_PLL_PSC; PLLCSR |= (1 << PLLE); }MACROE
- #define USB_PLL_Off() MACROS{ PLLCSR = 0; }MACROE
- #define USB_PLL_IsReady() ((PLLCSR & (1 << PLOCK)) ? true : false)
+ /* Function Prototypes: */
+ #if defined(__INCLUDE_FROM_USB_CONTROLLER_C)
+ #if defined(USB_CAN_BE_DEVICE)
+ static void USB_Init_Device(void);
+ #endif
+
+ #if defined(USB_CAN_BE_HOST)
+ static void USB_Init_Host(void);
+ #endif
+ #endif
+
+ /* 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)
- #define USB_REG_On() MACROS{ UHWCON |= (1 << UVREGE); }MACROE
- #define USB_REG_Off() MACROS{ UHWCON &= ~(1 << UVREGE); }MACROE
+ UHWCON |= (1 << UVREGE);
#else
- #define USB_REG_On() MACROS{ REGCR &= ~(1 << REGDIS); }MACROE
- #define USB_REG_Off() MACROS{ REGCR |= (1 << REGDIS); }MACROE
+ REGCR &= ~(1 << REGDIS);
#endif
-
- #define USB_OTGPAD_On() MACROS{ USBCON |= (1 << OTGPADE); }MACROE
- #define USB_OTGPAD_Off() MACROS{ USBCON &= ~(1 << OTGPADE); }MACROE
+ }
- #define USB_CLK_Freeze() MACROS{ USBCON |= (1 << FRZCLK); }MACROE
- #define USB_CLK_Unfreeze() MACROS{ USBCON &= ~(1 << FRZCLK); }MACROE
+ 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));
+ }
- #define USB_Controller_Enable() MACROS{ USBCON |= (1 << USBE); }MACROE
- #define USB_Controller_Disable() MACROS{ USBCON &= ~(1 << USBE); }MACROE
- #define USB_Controller_Reset() MACROS{ const uint8_t Temp = USBCON; USBCON = (Temp & ~(1 << USBE)); \
- USBCON = (Temp | (1 << USBE)); }MACROE
-
- /* Inline Functions: */
#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;
+ return USB_MODE_Device;
else
- return USB_MODE_HOST;
+ return USB_MODE_Host;
}
#endif
-
+
#endif
-
+
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
-
+
#endif
/** @} */
+