parent
f3ec62b5c6
commit
cad5e9ffca
File diff suppressed because one or more lines are too long
@ -0,0 +1,103 @@ |
||||
/*
|
||||
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
|
||||
* \brief Board specific Buttons driver header for the Atmel EVK1101. |
||||
* \copydetails Group_Buttons_EVK1101 |
||||
* |
||||
* \note This file should not be included directly. It is automatically included as needed by the Buttons driver |
||||
* dispatch header located in LUFA/Drivers/Board/Buttons.h. |
||||
*/ |
||||
|
||||
/** \ingroup Group_Buttons
|
||||
* \defgroup Group_Buttons_EVK1101 EVK1101 |
||||
* \brief Board specific Buttons driver header for the Atmel EVK1101. |
||||
* |
||||
* Board specific Buttons driver header for the Atmel EVK1101. |
||||
* |
||||
* @{ |
||||
*/ |
||||
|
||||
#ifndef __BUTTONS_EVK1101_H__ |
||||
#define __BUTTONS_EVK1101_H__ |
||||
|
||||
/* Includes: */ |
||||
#include <avr32/io.h> |
||||
#include <stdbool.h> |
||||
|
||||
#include "../../../Common/Common.h" |
||||
|
||||
/* Enable C linkage for C++ Compilers: */ |
||||
#if defined(__cplusplus) |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* Preprocessor Checks: */ |
||||
#if !defined(INCLUDE_FROM_BUTTONS_H) |
||||
#error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. |
||||
#endif |
||||
|
||||
/* Private Interface - For use in library only: */ |
||||
#if !defined(__DOXYGEN__) |
||||
/* Macros: */ |
||||
#define BUTTONS_PORT 1 |
||||
#endif |
||||
|
||||
/* Public Interface - May be used in end-application: */ |
||||
/* Macros: */ |
||||
/** Mask of the first button on the board */ |
||||
#define BUTTONS_BUTTON1 (1UL << 2) |
||||
|
||||
/** Mask of the second button on the board */ |
||||
#define BUTTONS_BUTTON2 (1UL << 3) |
||||
|
||||
/* Inline Functions: */ |
||||
#if !defined(__DOXYGEN__) |
||||
static inline void Buttons_Init(void) |
||||
{ |
||||
AVR32_GPIO.port[BUTTONS_PORT].gpers = (BUTTONS_BUTTON1 | BUTTONS_BUTTON2); |
||||
AVR32_GPIO.port[BUTTONS_PORT].puers = (BUTTONS_BUTTON1 | BUTTONS_BUTTON2); |
||||
} |
||||
|
||||
static inline uintN_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; |
||||
static inline uintN_t Buttons_GetStatus(void) |
||||
{ |
||||
return (~(AVR32_GPIO.port[JOY_MOVE_PORT].pvr & (BUTTONS_BUTTON1 | BUTTONS_BUTTON2))); |
||||
} |
||||
#endif |
||||
|
||||
/* Disable C linkage for C++ Compilers: */ |
||||
#if defined(__cplusplus) |
||||
} |
||||
#endif |
||||
|
||||
#endif |
||||
|
||||
/** @} */ |
@ -0,0 +1,120 @@ |
||||
/*
|
||||
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
|
||||
* \brief Board specific joystick driver header for the Atmel EVK1101. |
||||
* \copydetails Group_Joystick_EVK1101 |
||||
* |
||||
* \note This file should not be included directly. It is automatically included as needed by the joystick driver |
||||
* dispatch header located in LUFA/Drivers/Board/Joystick.h. |
||||
*/ |
||||
|
||||
/** \ingroup Group_Joystick
|
||||
* \defgroup Group_Joystick_EVK1101 EVK1101 |
||||
* \brief Board specific joystick driver header for the Atmel EVK1101. |
||||
* |
||||
* Board specific joystick driver header for the Atmel EVK1101. |
||||
* |
||||
* @{ |
||||
*/ |
||||
|
||||
#ifndef __JOYSTICK_EVK1101_H__ |
||||
#define __JOYSTICK_EVK1101_H__ |
||||
|
||||
/* Includes: */ |
||||
#include <avr32/io.h> |
||||
|
||||
#include "../../../Common/Common.h" |
||||
|
||||
/* Enable C linkage for C++ Compilers: */ |
||||
#if defined(__cplusplus) |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* Preprocessor Checks: */ |
||||
#if !defined(INCLUDE_FROM_JOYSTICK_H) |
||||
#error Do not include this file directly. Include LUFA/Drivers/Board/Joystick.h instead. |
||||
#endif |
||||
|
||||
/* Private Interface - For use in library only: */ |
||||
#if !defined(__DOXYGEN__) |
||||
/* Macros: */ |
||||
#define JOY_MOVE_PORT 1 |
||||
#define JOY_MOVE_MASK ((1 << 6) | (1 << 7) | (1 << 8) | (1 << 9)) |
||||
#define JOY_PRESS_PORT 0 |
||||
#define JOY_PRESS_MASK (1 << 13) |
||||
|
||||
#define JOY_SHIFT_LEFT 6 |
||||
#endif |
||||
|
||||
/* Public Interface - May be used in end-application: */ |
||||
/* Macros: */ |
||||
/** Mask for the joystick being pushed in the left direction. */ |
||||
#define JOY_LEFT (1 << 1) |
||||
|
||||
/** Mask for the joystick being pushed in the right direction. */ |
||||
#define JOY_RIGHT (1 << 2) |
||||
|
||||
/** Mask for the joystick being pushed in the upward direction. */ |
||||
#define JOY_UP (1 << 3) |
||||
|
||||
/** Mask for the joystick being pushed in the downward direction. */ |
||||
#define JOY_DOWN (1 << 4) |
||||
|
||||
/** Mask for the joystick being pushed inward. */ |
||||
#define JOY_PRESS (1 << 7) |
||||
|
||||
/* Inline Functions: */ |
||||
#if !defined(__DOXYGEN__) |
||||
static inline void Joystick_Init(void) |
||||
{ |
||||
AVR32_GPIO.port[JOY_MOVE_PORT].gpers = JOY_MOVE_MASK; |
||||
AVR32_GPIO.port[JOY_PRESS_PORT].gpers = JOY_PRESS_MASK; |
||||
|
||||
AVR32_GPIO.port[JOY_MOVE_PORT].puers = JOY_MOVE_MASK; |
||||
AVR32_GPIO.port[JOY_PRESS_PORT].puers = JOY_PRESS_MASK; |
||||
}; |
||||
|
||||
static inline uintN_t Joystick_GetStatus(void) ATTR_WARN_UNUSED_RESULT; |
||||
static inline uintN_t Joystick_GetStatus(void) |
||||
{ |
||||
return (uintN_t)(~(((AVR32_GPIO.port[JOY_MOVE_PORT].pvr & JOY_MOVE_MASK) | |
||||
(AVR32_GPIO.port[JOY_PRESS_PORT].pvr & JOY_PRESS_MASK)) << JOY_SHIFT_LEFT)); |
||||
} |
||||
#endif |
||||
|
||||
/* Disable C linkage for C++ Compilers: */ |
||||
#if defined(__cplusplus) |
||||
} |
||||
#endif |
||||
|
||||
#endif |
||||
|
||||
/** @} */ |
@ -0,0 +1,137 @@ |
||||
/*
|
||||
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
|
||||
* \brief Board specific LED driver header for the Atmel EVK1101. |
||||
* \copydetails Group_LEDs_EVK1101 |
||||
* |
||||
* \note This file should not be included directly. It is automatically included as needed by the LEDs driver |
||||
* dispatch header located in LUFA/Drivers/Board/LEDs.h. |
||||
*/ |
||||
|
||||
/** \ingroup Group_LEDs
|
||||
* \defgroup Group_LEDs_EVK1101 EVK1101 |
||||
* \brief Board specific LED driver header for the Atmel EVK1101. |
||||
* |
||||
* Board specific LED driver header for the Atmel EVK1101. |
||||
* |
||||
* @{ |
||||
*/ |
||||
|
||||
#ifndef __LEDS_EVK1101_H__ |
||||
#define __LEDS_EVK1101_H__ |
||||
|
||||
/* Includes: */ |
||||
#include <avr32/io.h> |
||||
|
||||
#include "../../../Common/Common.h" |
||||
|
||||
/* Enable C linkage for C++ Compilers: */ |
||||
#if defined(__cplusplus) |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* Preprocessor Checks: */ |
||||
#if !defined(INCLUDE_FROM_LEDS_H) |
||||
#error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. |
||||
#endif |
||||
|
||||
/* Private Interface - For use in library only: */ |
||||
#if !defined(__DOXYGEN__) |
||||
/* Macros: */ |
||||
#define LEDS_PORT 0 |
||||
#endif |
||||
|
||||
/* Public Interface - May be used in end-application: */ |
||||
/* Macros: */ |
||||
/** LED mask for the first LED on the board. */ |
||||
#define LEDS_LED1 (1UL << 7) |
||||
|
||||
/** LED mask for the second LED on the board. */ |
||||
#define LEDS_LED2 (1UL << 8) |
||||
|
||||
/** LED mask for the third LED on the board. */ |
||||
#define LEDS_LED3 (1UL << 21) |
||||
|
||||
/** LED mask for the fourth LED on the board. */ |
||||
#define LEDS_LED4 (1UL << 22) |
||||
|
||||
/** LED mask for all the LEDs on the board. */ |
||||
#define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4) |
||||
|
||||
/** LED mask for the none of the board LEDs */ |
||||
#define LEDS_NO_LEDS 0 |
||||
|
||||
/* Inline Functions: */ |
||||
#if !defined(__DOXYGEN__) |
||||
static inline void LEDs_Init(void) |
||||
{ |
||||
AVR32_GPIO.port[LEDS_PORT].gpers = LEDS_ALL_LEDS; |
||||
AVR32_GPIO.port[LEDS_PORT].oders = LEDS_ALL_LEDS; |
||||
AVR32_GPIO.port[LEDS_PORT].ovrs = LEDS_ALL_LEDS; |
||||
} |
||||
|
||||
static inline void LEDs_TurnOnLEDs(const uintN_t LedMask) |
||||
{ |
||||
AVR32_GPIO.port[LEDS_PORT].ovrc = LedMask; |
||||
} |
||||
|
||||
static inline void LEDs_TurnOffLEDs(const uintN_t LedMask) |
||||
{ |
||||
AVR32_GPIO.port[LEDS_PORT].ovrs = LedMask; |
||||
} |
||||
|
||||
static inline void LEDs_SetAllLEDs(const uintN_t LedMask) |
||||
{ |
||||
AVR32_GPIO.port[LEDS_PORT].ovrs = LEDS_ALL_LEDS; |
||||
AVR32_GPIO.port[LEDS_PORT].ovrc = LedMask; |
||||
} |
||||
|
||||
static inline void LEDs_ChangeLEDs(const uintN_t LedMask, const uintN_t ActiveMask) |
||||
{ |
||||
AVR32_GPIO.port[LEDS_PORT].ovrs = LedMask; |
||||
AVR32_GPIO.port[LEDS_PORT].ovrc = ActiveMask; |
||||
} |
||||
|
||||
static inline uintN_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; |
||||
static inline uintN_t LEDs_GetLEDs(void) |
||||
{ |
||||
return (AVR32_GPIO.port[LEDS_PORT].ovr & LEDS_ALL_LEDS); |
||||
} |
||||
#endif |
||||
|
||||
/* Disable C linkage for C++ Compilers: */ |
||||
#if defined(__cplusplus) |
||||
} |
||||
#endif |
||||
|
||||
#endif |
||||
|
||||
/** @} */ |
@ -0,0 +1,53 @@ |
||||
/*
|
||||
LUFA Library |
||||
Copyright (C) Dean Camera, 2011. |
||||
|
||||
dean [at] fourwalledcubicle [dot] com |
||||
www.lufa-lib.org |
||||
*/ |
||||
|
||||
/*
|
||||
Copyright 2011 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. |
||||
*/ |
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER |
||||
#include "../USBMode.h" |
||||
|
||||
#if defined(USB_CAN_BE_DEVICE) |
||||
|
||||
#include "Device.h" |
||||
|
||||
void USB_Device_SendRemoteWakeup(void) |
||||
{ |
||||
if (!(USB_Options & USB_OPT_MANUAL_PLL)) |
||||
{ |
||||
USB_PLL_On(); |
||||
while (!(USB_PLL_IsReady())); |
||||
} |
||||
|
||||
USB_CLK_Unfreeze(); |
||||
|
||||
AVR32_USBB.UDCON |= (1 << RMWKUP); |
||||
while (!(AVR32_USBB.UDCON & (1 << RMWKUP))); |
||||
} |
||||
|
||||
#endif |
||||
|
@ -0,0 +1,226 @@ |
||||
/*
|
||||
LUFA Library |
||||
Copyright (C) Dean Camera, 2011. |
||||
|
||||
dean [at] fourwalledcubicle [dot] com |
||||
www.lufa-lib.org |
||||
*/ |
||||
|
||||
/*
|
||||
Copyright 2011 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 Device definitions for the AVR32 UC3B microcontrollers. |
||||
* \copydetails Group_Device_UC3B |
||||
* |
||||
* \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_Device
|
||||
* \defgroup Group_Device_UC3B Device Management (UC3B) |
||||
* \brief USB Device definitions for the AVR32 UC3B microcontrollers. |
||||
* |
||||
* Architecture specific USB Device definitions for the Atmel 32-bit UC3B AVR microcontrollers. |
||||
* |
||||
* @{ |
||||
*/ |
||||
|
||||
#ifndef __USBDEVICE_UC3B_H__ |
||||
#define __USBDEVICE_UC3B_H__ |
||||
|
||||
/* Includes: */ |
||||
#include "../../../../Common/Common.h" |
||||
#include "../StdDescriptors.h" |
||||
#include "../USBInterrupt.h" |
||||
#include "../Endpoint.h" |
||||
|
||||
/* Preprocessor Checks: */ |
||||
#if !defined(__INCLUDE_FROM_USB_DRIVER) |
||||
#error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. |
||||
#endif |
||||
|
||||
#if (defined(USE_RAM_DESCRIPTORS) && defined(USE_EEPROM_DESCRIPTORS)) |
||||
#error USE_RAM_DESCRIPTORS and USE_EEPROM_DESCRIPTORS are mutually exclusive. |
||||
#endif |
||||
|
||||
/* Public Interface - May be used in end-application: */ |
||||
/* Macros: */ |
||||
/** \name USB Device Mode Option Masks */ |
||||
//@{
|
||||
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) || defined(__DOXYGEN__) |
||||
/** Mask for the Options parameter of the \ref USB_Init() function. This indicates that the
|
||||
* USB interface should be initialized in low speed (1.5Mb/s) mode. |
||||
* |
||||
* \note Low Speed mode is not available on all USB AVR models. |
||||
* \n |
||||
* |
||||
* \note Restrictions apply on the number, size and type of endpoints which can be used |
||||
* when running in low speed mode - refer to the USB 2.0 specification. |
||||
*/ |
||||
#define USB_DEVICE_OPT_LOWSPEED (1 << 0) |
||||
#endif |
||||
|
||||
/** Mask for the Options parameter of the \ref USB_Init() function. This indicates that the
|
||||
* USB interface should be initialized in full speed (12Mb/s) mode. |
||||
*/ |
||||
#define USB_DEVICE_OPT_FULLSPEED (0 << 0) |
||||
//@}
|
||||
|
||||
#if (!defined(NO_INTERNAL_SERIAL) && \ |
||||
(defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1287__) || \
|
||||
defined(__AVR_ATmega32U6__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || \
|
||||
defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__))) |
||||
/** String descriptor index for the device's unique serial number string descriptor within the device.
|
||||
* This unique serial number is used by the host to associate resources to the device (such as drivers or COM port |
||||
* number allocations) to a device regardless of the port it is plugged in to on the host. Some USB AVRs contain |
||||
* a unique serial number internally, and setting the device descriptors serial number string index to this value |
||||
* will cause it to use the internal serial number. |
||||
* |
||||
* On unsupported devices, this will evaluate to NO_DESCRIPTOR and so will force the host to create a pseudo-serial |
||||
* number for the device. |
||||
*/ |
||||
#define USE_INTERNAL_SERIAL 0xDC |
||||
#else |
||||
#define USE_INTERNAL_SERIAL NO_DESCRIPTOR |
||||
#endif |
||||
|
||||
/* Function Prototypes: */ |
||||
/** Sends a Remote Wakeup request to the host. This signals to the host that the device should
|
||||
* be taken out of suspended mode, and communications should resume. |
||||
* |
||||
* Typically, this is implemented so that HID devices (mice, keyboards, etc.) can wake up the |
||||
* host computer when the host has suspended all USB devices to enter a low power state. |
||||
* |
||||
* \note This macro should only be used if the device has indicated to the host that it |
||||
* supports the Remote Wakeup feature in the device descriptors, and should only be |
||||
* issued if the host is currently allowing remote wakeup events from the device (i.e., |
||||
* the \ref USB_RemoteWakeupEnabled flag is set). When the \c NO_DEVICE_REMOTE_WAKEUP compile |
||||
* time option is used, this macro is unavailable. |
||||
* \n\n |
||||
* |
||||
* \note The USB clock must be running for this function to operate. If the stack is initialized with |
||||
* the \ref USB_OPT_MANUAL_PLL option enabled, the user must ensure that the PLL is running |
||||
* before attempting to call this function. |
||||
* |
||||
* \see \ref Group_StdDescriptors for more information on the RMWAKEUP feature and device descriptors. |
||||
*/ |
||||
void USB_Device_SendRemoteWakeup(void); |
||||
|
||||
/* Type Defines: */ |
||||
enum USB_Device_States_t |
||||
{ |
||||
DEVICE_STATE_Unattached = 0, /**< Internally implemented by the library. This state indicates
|
||||
* that the device is not currently connected to a host. |
||||
*/ |
||||
DEVICE_STATE_Powered = 1, /**< Internally implemented by the library. This state indicates
|
||||
* that the device is connected to a host, but enumeration has not |
||||
* yet begun. |
||||
*/ |
||||
DEVICE_STATE_Default = 2, /**< Internally implemented by the library. This state indicates
|
||||
* that the device's USB bus has been reset by the host and it is |
||||
* now waiting for the host to begin the enumeration process. |
||||
*/ |
||||
DEVICE_STATE_Addressed = 3, /**< Internally implemented by the library. This state indicates
|
||||
* that the device has been addressed by the USB Host, but is not |
||||
* yet configured. |
||||
*/ |
||||
DEVICE_STATE_Configured = 4, /**< May be implemented by the user project. This state indicates
|
||||
* that the device has been enumerated by the host and is ready |
||||
* for USB communications to begin. |
||||
*/ |
||||
DEVICE_STATE_Suspended = 5, /**< May be implemented by the user project. This state indicates
|
||||
* that the USB bus has been suspended by the host, and the device |
||||
* should power down to a minimal power level until the bus is |
||||
* resumed. |
||||
*/ |
||||
}; |
||||
|
||||
/* Inline Functions: */ |
||||
/** Returns the current USB frame number, when in device mode. Every millisecond the USB bus is active (i.e. enumerated to a host)
|
||||
* the frame number is incremented by one. |
||||
*/ |
||||
static inline uint16_t USB_Device_GetFrameNumber(void) |
||||
{ |
||||
return AVR32_USBB.UDFNUM.fnum; |
||||
} |
||||
|
||||
#if !defined(NO_SOF_EVENTS) |
||||
/** Enables the device mode Start Of Frame events. When enabled, this causes the
|
||||
* \ref EVENT_USB_Device_StartOfFrame() event to fire once per millisecond, synchronized to the USB bus, |
||||
* at the start of each USB frame when enumerated in device mode. |
||||
* |
||||
* \note Not available when the \c NO_SOF_EVENTS compile time token is defined. |
||||
*/ |
||||
static inline void USB_Device_EnableSOFEvents(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Device_EnableSOFEvents(void) |
||||
{ |
||||
USB_INT_Enable(USB_INT_SOFI); |
||||
} |
||||
|
||||
/** Disables the device mode Start Of Frame events. When disabled, this stops the firing of the
|
||||
* \ref EVENT_USB_Device_StartOfFrame() event when enumerated in device mode. |
||||
* |
||||
* \note Not available when the \c NO_SOF_EVENTS compile time token is defined. |
||||
*/ |
||||
static inline void USB_Device_DisableSOFEvents(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Device_DisableSOFEvents(void) |
||||
{ |
||||
USB_INT_Disable(USB_INT_SOFI); |
||||
} |
||||
#endif |
||||
|
||||
/* Private Interface - For use in library only: */ |
||||
#if !defined(__DOXYGEN__) |
||||
/* Inline Functions: */ |
||||
#if (defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) |
||||
static inline void USB_Device_SetLowSpeed(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Device_SetLowSpeed(void) |
||||
{ |
||||
AVR32_USBB.UDCON.ls = true; |
||||
} |
||||
|
||||
static inline void USB_Device_SetFullSpeed(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Device_SetFullSpeed(void) |
||||
{ |
||||
AVR32_USBB.UDCON.ls = false; |
||||
} |
||||
#endif |
||||
|
||||
static inline void USB_Device_SetDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Device_SetDeviceAddress(const uint8_t Address) |
||||
{ |
||||
AVR32_USBB.UDCON = (AVR32_USBB_UDCON & ~AVR32_USBB_UDADDR) | Address; |
||||
AVR32_USBB.UDCON.adden = true; |
||||
} |
||||
|
||||
static inline bool USB_Device_IsAddressSet(void) ATTR_ALWAYS_INLINE; |
||||
static inline bool USB_Device_IsAddressSet(void) |
||||
{ |
||||
return AVR32_USBB.UDCON.adden; |
||||
} |
||||
#endif |
||||
|
||||
#endif |
||||
|
||||
/** @} */ |
||||
|
@ -0,0 +1,178 @@ |
||||
/*
|
||||
LUFA Library |
||||
Copyright (C) Dean Camera, 2011. |
||||
|
||||
dean [at] fourwalledcubicle [dot] com |
||||
www.lufa-lib.org |
||||
*/ |
||||
|
||||
/*
|
||||
Copyright 2011 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. |
||||
*/ |
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER |
||||
#include "../USBMode.h" |
||||
|
||||
#if defined(USB_CAN_BE_DEVICE) |
||||
|
||||
#include "Endpoint.h" |
||||
|
||||
#if !defined(FIXED_CONTROL_ENDPOINT_SIZE) |
||||
uint8_t USB_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE; |
||||
#endif |
||||
|
||||
uint8_t USB_SelectedEndpoint = ENDPOINT_CONTROLEP; |
||||
|
||||
bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number, |
||||
const uint32_t UECFGXData) |
||||
{ |
||||
#if defined(CONTROL_ONLY_DEVICE) || defined(ORDERED_EP_CONFIG) |
||||
Endpoint_SelectEndpoint(Number); |
||||
Endpoint_EnableEndpoint(); |
||||
|
||||
*((uint32_t*)AVR32_USBB_UECFG0)[USB_SelectedEndpoint] = 0; |
||||
*((uint32_t*)AVR32_USBB_UECFG0)[USB_SelectedEndpoint] = UECFGXData; |
||||
|
||||
return Endpoint_IsConfigured(); |
||||
#else |
||||
for (uint8_t EPNum = Number; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) |
||||
{ |
||||
uint32_t UECFGXTemp; |
||||
uint32_t UEIENXTemp; |
||||
|
||||
Endpoint_SelectEndpoint(EPNum); |
||||
|
||||
if (EPNum == Number) |
||||
{ |
||||
UECFGXTemp = UECFGXData; |
||||
UEIENXTemp = 0; |
||||
} |
||||
else |
||||
{ |
||||
UECFGXTemp = *((uint32_t*)AVR32_USBB_UECFG0)[EPNum]; |
||||
UEIENXTemp = *((uint32_t*)AVR32_USBB_UEINT0)[EPNum]; |
||||
} |
||||
|
||||
if (!(UECFGXTemp & AVR32_USBB_ALLOC)) |
||||
continue; |
||||
|
||||
Endpoint_DisableEndpoint(); |
||||
*((uint32_t*)AVR32_USBB_UECFG0)[USB_SelectedEndpoint] &= ~AVR32_USBB_ALLOC; |
||||
|
||||
Endpoint_EnableEndpoint(); |
||||
*((uint32_t*)AVR32_USBB_UECFG0)[EPNum] = UECFGXTemp; |
||||
*((uint32_t*)AVR32_USBB_UEINT0)[EPNum] = UEINTXTemp; |
||||
|
||||
if (!(Endpoint_IsConfigured())) |
||||
return false;
|
||||
} |
||||
|
||||
Endpoint_SelectEndpoint(Number); |
||||
return true; |
||||
#endif |
||||
} |
||||
|
||||
void Endpoint_ClearEndpoints(void) |
||||
{ |
||||
UEINT = 0; |
||||
|
||||
for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) |
||||
{ |
||||
Endpoint_SelectEndpoint(EPNum); |
||||
UEIENX = 0; |
||||
UEINTX = 0; |
||||
UECFG1X = 0; |
||||
Endpoint_DisableEndpoint(); |
||||
} |
||||
} |
||||
|
||||
void Endpoint_ClearStatusStage(void) |
||||
{ |
||||
if (USB_ControlRequest.bmRequestType & REQDIR_DEVICETOHOST) |
||||
{ |
||||
while (!(Endpoint_IsOUTReceived())) |
||||
{ |
||||
if (USB_DeviceState == DEVICE_STATE_Unattached) |
||||
return; |
||||
} |
||||
|
||||
Endpoint_ClearOUT(); |
||||
} |
||||
else |
||||
{ |
||||
while (!(Endpoint_IsINReady())) |
||||
{ |
||||
if (USB_DeviceState == DEVICE_STATE_Unattached) |
||||
return; |
||||
} |
||||
|
||||
Endpoint_ClearIN(); |
||||
} |
||||
} |
||||
|
||||
#if !defined(CONTROL_ONLY_DEVICE) |
||||
uint8_t Endpoint_WaitUntilReady(void) |
||||
{ |
||||
#if (USB_STREAM_TIMEOUT_MS < 0xFF) |
||||
uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; |
||||
#else |
||||
uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; |
||||
#endif |
||||
|
||||
uint16_t PreviousFrameNumber = USB_Device_GetFrameNumber(); |
||||
|
||||
for (;;) |
||||
{ |
||||
if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN) |
||||
{ |
||||
if (Endpoint_IsINReady()) |
||||
return ENDPOINT_READYWAIT_NoError; |
||||
} |
||||
else |
||||
{ |
||||
if (Endpoint_IsOUTReceived()) |
||||
return ENDPOINT_READYWAIT_NoError; |
||||
} |
||||
|
||||
uint8_t USB_DeviceState_LCL = USB_DeviceState; |
||||
|
||||
if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) |
||||
return ENDPOINT_READYWAIT_DeviceDisconnected; |
||||
else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) |
||||
return ENDPOINT_READYWAIT_BusSuspended; |
||||
else if (Endpoint_IsStalled()) |
||||
return ENDPOINT_READYWAIT_EndpointStalled; |
||||
|
||||
uint16_t CurrentFrameNumber = USB_Device_GetFrameNumber(); |
||||
|
||||
if (CurrentFrameNumber != PreviousFrameNumber) |
||||
{ |
||||
PreviousFrameNumber = CurrentFrameNumber; |
||||
|
||||
if (!(TimeoutMSRem--)) |
||||
return ENDPOINT_READYWAIT_Timeout; |
||||
} |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
#endif |
||||
|
@ -0,0 +1,889 @@ |
||||
/*
|
||||
LUFA Library |
||||
Copyright (C) Dean Camera, 2011. |
||||
|
||||
dean [at] fourwalledcubicle [dot] com |
||||
www.lufa-lib.org |
||||
*/ |
||||
|
||||
/*
|
||||
Copyright 2011 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 Endpoint definitions for the UC3B microcontrollers. |
||||
* \copydetails Group_EndpointManagement_UC3B |
||||
* |
||||
* \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_EndpointRW
|
||||
* \defgroup Group_EndpointRW_UC3B Endpoint Data Reading and Writing (UC3B) |
||||
* \brief Endpoint data read/write definitions for the Atmel AVR32 UC3B architecture. |
||||
* |
||||
* Functions, macros, variables, enums and types related to data reading and writing from and to endpoints. |
||||
*/ |
||||
|
||||
/** \ingroup Group_EndpointPrimitiveRW
|
||||
* \defgroup Group_EndpointPrimitiveRW_UC3B Read/Write of Primitive Data Types (UC3B) |
||||
* \brief Endpoint primative read/write definitions for the Atmel UC3B architecture. |
||||
* |
||||
* Functions, macros, variables, enums and types related to data reading and writing of primitive data types |
||||
* from and to endpoints. |
||||
*/ |
||||
|
||||
/** \ingroup Group_EndpointPacketManagement
|
||||
* \defgroup Group_EndpointPacketManagement_UC3B Endpoint Packet Management (UC3B) |
||||
* \brief Endpoint packet management definitions for the Atmel UC3B architecture. |
||||
* |
||||
* Functions, macros, variables, enums and types related to packet management of endpoints. |
||||
*/ |
||||
|
||||
/** \ingroup Group_EndpointManagement
|
||||
* \defgroup Group_EndpointManagement_UC3B Endpoint Management (UC3B) |
||||
* \brief Endpoint management definitions for the Atmel UC3B architecture. |
||||
* |
||||
* Functions, macros and enums related to endpoint management when in USB Device mode. This |
||||
* module contains the endpoint management macros, as well as endpoint interrupt and data |
||||
* send/receive functions for various data types. |
||||
* |
||||
* @{ |
||||
*/ |
||||
|
||||
#ifndef __ENDPOINT_UC3B_H__ |
||||
#define __ENDPOINT_UC3B_H__ |
||||
|
||||
/* Includes: */ |
||||
#include "../../../../Common/Common.h" |
||||
#include "../USBTask.h" |
||||
#include "../USBInterrupt.h" |
||||
|
||||
/* Enable C linkage for C++ Compilers: */ |
||||
#if defined(__cplusplus) |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* Preprocessor Checks: */ |
||||
#if !defined(__INCLUDE_FROM_USB_DRIVER) |
||||
#error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. |
||||
#endif |
||||
|
||||
/* Private Interface - For use in library only: */ |
||||
#if !defined(__DOXYGEN__) |
||||
/* Macros: */ |
||||
#define _ENDPOINT_GET_MAXSIZE(EPIndex) _ENDPOINT_GET_MAXSIZE2(ENDPOINT_DETAILS_EP ## EPIndex) |
||||
#define _ENDPOINT_GET_MAXSIZE2(EPDetails) _ENDPOINT_GET_MAXSIZE3(EPDetails) |
||||
#define _ENDPOINT_GET_MAXSIZE3(MaxSize, Banks) (MaxSize) |
||||
|
||||
#define _ENDPOINT_GET_BANKS(EPIndex) _ENDPOINT_GET_BANKS2(ENDPOINT_DETAILS_EP ## EPIndex) |
||||
#define _ENDPOINT_GET_BANKS2(EPDetails) _ENDPOINT_GET_BANKS3(EPDetails) |
||||
#define _ENDPOINT_GET_BANKS3(MaxSize, Banks) (Banks) |
||||
|
||||
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) |
||||
#define ENDPOINT_DETAILS_MAXEP 7 |
||||
|
||||
#define ENDPOINT_DETAILS_EP0 64, 2 |
||||
#define ENDPOINT_DETAILS_EP1 256, 2 |
||||
#define ENDPOINT_DETAILS_EP2 64, 2 |
||||
#define ENDPOINT_DETAILS_EP3 64, 2 |
||||
#define ENDPOINT_DETAILS_EP4 64, 2 |
||||
#define ENDPOINT_DETAILS_EP5 64, 2 |
||||
#define ENDPOINT_DETAILS_EP6 64, 2 |
||||
#else |
||||
#define ENDPOINT_DETAILS_MAXEP 5 |
||||
|
||||
#define ENDPOINT_DETAILS_EP0 64, 2 |
||||
#define ENDPOINT_DETAILS_EP1 64, 1 |
||||
#define ENDPOINT_DETAILS_EP2 64, 1 |
||||
#define ENDPOINT_DETAILS_EP3 64, 2 |
||||
#define ENDPOINT_DETAILS_EP4 64, 2 |
||||
#endif |
||||
|
||||
/* Inline Functions: */ |
||||
static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST |
||||
ATTR_ALWAYS_INLINE; |
||||
static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) |
||||
{ |
||||
uint8_t MaskVal = 0; |
||||
uint16_t CheckBytes = 8; |
||||
|
||||
while (CheckBytes < Bytes) |
||||
{ |
||||
MaskVal++; |
||||
CheckBytes <<= 1; |
||||
} |
||||
|
||||
return (MaskVal << AVR32_USBB_EPSIZE_OFFSET); |
||||
} |
||||
|
||||
/* Function Prototypes: */ |
||||
void Endpoint_ClearEndpoints(void); |
||||
bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number, |
||||
const uint32_t UECFGXData); |
||||
|
||||
/* External Variables: */ |
||||
extern uint8_t USB_SelectedEndpoint; |
||||
#endif |
||||
|
||||
/* Public Interface - May be used in end-application: */ |
||||
/* Macros: */ |
||||
/** \name Endpoint Direction Masks */ |
||||
//@{
|
||||
/** Endpoint data direction mask for \ref Endpoint_ConfigureEndpoint(). This indicates that the endpoint
|
||||
* should be initialized in the OUT direction - i.e. data flows from host to device. |
||||
*/ |
||||
#define ENDPOINT_DIR_OUT (0 << AVR32_USBB_UECFG0_EPDIR_OFFSET) |
||||
|
||||
/** Endpoint data direction mask for \ref Endpoint_ConfigureEndpoint(). This indicates that the endpoint
|
||||
* should be initialized in the IN direction - i.e. data flows from device to host. |
||||
*/ |
||||
#define ENDPOINT_DIR_IN (1 << AVR32_USBB_UECFG0_EPDIR_OFFSET) |
||||
//@}
|
||||
|
||||
/** \name Endpoint Bank Mode Masks */ |
||||
//@{
|
||||
/** Mask for the bank mode selection for the \ref Endpoint_ConfigureEndpoint() macro. This indicates
|
||||
* that the endpoint should have one single bank, which requires less USB FIFO memory but results |
||||
* in slower transfers as only one USB device (the AVR or the host) can access the endpoint's |
||||
* bank at the one time. |
||||
*/ |
||||
#define ENDPOINT_BANK_SINGLE (0 << AVR32_USBB_UECFG0_EPBK0_OFFSET) |
||||
|
||||
/** Mask for the bank mode selection for the \ref Endpoint_ConfigureEndpoint() macro. This indicates
|
||||
* that the endpoint should have two banks, which requires more USB FIFO memory but results |
||||
* in faster transfers as one USB device (the AVR or the host) can access one bank while the other |
||||
* accesses the second bank. |
||||
*/ |
||||
#define ENDPOINT_BANK_DOUBLE (1 << AVR32_USBB_UECFG0_EPBK0_OFFSET) |
||||
|
||||
/** Mask for the bank mode selection for the \ref Endpoint_ConfigureEndpoint() macro. This indicates
|
||||
* that the endpoint should have three banks, which requires more USB FIFO memory but results |
||||
* in faster transfers as one USB device (the AVR or the host) can access one bank while the other |
||||
* accesses the remaining banks. |
||||
*/ |
||||
#define ENDPOINT_BANK_TRIPLE (2 << AVR32_USBB_UECFG0_EPBK0_OFFSET) |
||||
//@}
|
||||
|
||||
/** Endpoint address for the default control endpoint, which always resides in address 0. This is
|
||||
* defined for convenience to give more readable code when used with the endpoint macros. |
||||
*/ |
||||
#define ENDPOINT_CONTROLEP 0 |
||||
|
||||
#if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__)) |
||||
/** Default size of the default control endpoint's bank, until altered by the control endpoint bank size
|
||||
* value in the device descriptor. Not available if the \c FIXED_CONTROL_ENDPOINT_SIZE token is defined. |
||||
*/ |
||||
#define ENDPOINT_CONTROLEP_DEFAULT_SIZE 8 |
||||
#endif |
||||
|
||||
/** Endpoint number mask, for masking against endpoint addresses to retrieve the endpoint's
|
||||
* numerical address in the device. |
||||
*/ |
||||
#define ENDPOINT_EPNUM_MASK 0x07 |
||||
|
||||
/** Endpoint direction mask, for masking against endpoint addresses to retrieve the endpoint's
|
||||
* direction for comparing with the \c ENDPOINT_DESCRIPTOR_DIR_* masks. |
||||
*/ |
||||
#define ENDPOINT_EPDIR_MASK 0x80 |
||||
|
||||
/** Retrives the maximum bank size in bytes of a given endpoint.
|
||||
* |
||||
* \note This macro will only work correctly on endpoint indexes that are compile-time constants |
||||
* defined by the preprocessor. |
||||
* |
||||
* \param[in] EPIndex Endpoint number, a value between 0 and (\ref ENDPOINT_TOTAL_ENDPOINTS - 1) |
||||
*/ |
||||
#define ENDPOINT_MAX_SIZE(EPIndex) _ENDPOINT_GET_MAXSIZE(EPIndex) |
||||
|
||||
/** Retrieves the total number of banks supported by the given endpoint.
|
||||
* |
||||
* \note This macro will only work correctly on endpoint indexes that are compile-time constants |
||||
* defined by the preprocessor. |
||||
* |
||||
* \param[in] EPIndex Endpoint number, a value between 0 and (\ref ENDPOINT_TOTAL_ENDPOINTS - 1) |
||||
*/ |
||||
#define ENDPOINT_BANKS_SUPPORTED(EPIndex) _ENDPOINT_GET_BANKS(EPIndex) |
||||
|
||||
#if !defined(CONTROL_ONLY_DEVICE) || defined(__DOXYGEN__) |
||||
/** Total number of endpoints (including the default control endpoint at address 0) which may
|
||||
* be used in the device. Different USB AVR models support different amounts of endpoints, |
||||
* this value reflects the maximum number of endpoints for the currently selected AVR model. |
||||
*/ |
||||
#define ENDPOINT_TOTAL_ENDPOINTS ENDPOINT_DETAILS_MAXEP |
||||
#else |
||||
#define ENDPOINT_TOTAL_ENDPOINTS 1 |
||||
#endif |
||||
|
||||
/* Enums: */ |
||||
/** Enum for the possible error return codes of the \ref Endpoint_WaitUntilReady() function.
|
||||
* |
||||
* \ingroup Group_EndpointRW_AVR8 |
||||
*/ |
||||
enum Endpoint_WaitUntilReady_ErrorCodes_t |
||||
{ |
||||
ENDPOINT_READYWAIT_NoError = 0, /**< Endpoint is ready for next packet, no error. */ |
||||
ENDPOINT_READYWAIT_EndpointStalled = 1, /**< The endpoint was stalled during the stream
|
||||
* transfer by the host or device. |
||||
*/ |
||||
ENDPOINT_READYWAIT_DeviceDisconnected = 2, /**< Device was disconnected from the host while
|
||||
* waiting for the endpoint to become ready. |
||||
*/ |
||||
ENDPOINT_READYWAIT_BusSuspended = 3, /**< The USB bus has been suspended by the host and
|
||||
* no USB endpoint traffic can occur until the bus |
||||
* has resumed. |
||||
*/ |
||||
ENDPOINT_READYWAIT_Timeout = 4, /**< The host failed to accept or send the next packet
|
||||
* within the software timeout period set by the |
||||
* \ref USB_STREAM_TIMEOUT_MS macro. |
||||
*/ |
||||
}; |
||||
|
||||
/* Inline Functions: */ |
||||
/** Configures the specified endpoint number with the given endpoint type, direction, bank size
|
||||
* and banking mode. Once configured, the endpoint may be read from or written to, depending |
||||
* on its direction. |
||||
* |
||||
* \param[in] Number Endpoint number to configure. This must be more than 0 and less than |
||||
* \ref ENDPOINT_TOTAL_ENDPOINTS. |
||||
* |
||||
* \param[in] Type Type of endpoint to configure, a \c EP_TYPE_* mask. Not all endpoint types |
||||
* are available on Low Speed USB devices - refer to the USB 2.0 specification. |
||||
* |
||||
* \param[in] Direction Endpoint data direction, either \ref ENDPOINT_DIR_OUT or \ref ENDPOINT_DIR_IN. |
||||
* All endpoints (except Control type) are unidirectional - data may only be read |
||||
* from or written to the endpoint bank based on its direction, not both. |
||||
* |
||||
* \param[in] Size Size of the endpoint's bank, where packets are stored before they are transmitted |
||||
* to the USB host, or after they have been received from the USB host (depending on |
||||
* the endpoint's data direction). The bank size must indicate the maximum packet size |
||||
* that the endpoint can handle. |
||||
* |
||||
* \param[in] Banks Number of banks to use for the endpoint being configured, an \c ENDPOINT_BANK_* mask. |
||||
* More banks uses more USB DPRAM, but offers better performance. Isochronous type |
||||
* endpoints <b>must</b> have at least two banks. |
||||
* |
||||
* \note When the \c ORDERED_EP_CONFIG compile time option is used, Endpoints <b>must</b> be configured in |
||||
* ascending order, or bank corruption will occur. |
||||
* \n\n |
||||
* |
||||
* \note Certain models of USB AVR's endpoints may have different maximum packet sizes based on the endpoint's |
||||
* index - refer to the chosen USB AVR's datasheet to determine the maximum bank size for each endpoint. |
||||
* \n\n |
||||
* |
||||
* \note The default control endpoint should not be manually configured by the user application, as |
||||
* it is automatically configured by the library internally. |
||||
* \n\n |
||||
* |
||||
* \note This routine will automatically select the specified endpoint upon success. Upon failure, the endpoint |
||||
* which failed to reconfigure correctly will be selected. |
||||
* |
||||
* \return Boolean \c true if the configuration succeeded, \c false otherwise. |
||||
*/ |
||||
static inline bool Endpoint_ConfigureEndpoint(const uint8_t Number, |
||||
const uint8_t Type, |
||||
const uint8_t Direction, |
||||
const uint16_t Size, |
||||
const uint8_t Banks) ATTR_ALWAYS_INLINE; |
||||
static inline bool Endpoint_ConfigureEndpoint(const uint8_t Number, |
||||
const uint8_t Type, |
||||
const uint8_t Direction, |
||||
const uint16_t Size, |
||||
const uint8_t Banks) |
||||
{ |
||||
return Endpoint_ConfigureEndpoint_Prv(Number, ((Type << AVR32_USBB_EPTYPE_OFFSET) | AVR32_USBB_ALLOC | |
||||
(Direction << AVR32_USBB_EPDIR_OFFSET) | |
||||
(Banks << AVR32_USBB_EPBK_OFFSET) | |
||||
Endpoint_BytesToEPSizeMask(Size))); |
||||
} |
||||
|
||||
/** Indicates the number of bytes currently stored in the current endpoint's selected bank.
|
||||
* |
||||
* \note The return width of this function may differ, depending on the maximum endpoint bank size |
||||
* of the selected AVR model. |
||||
* |
||||
* \ingroup Group_EndpointRW_AVR8 |
||||
* |
||||
* \return Total number of bytes in the currently selected Endpoint's FIFO buffer. |
||||
*/ |
||||
static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline uint16_t Endpoint_BytesInEndpoint(void) |
||||
{ |
||||
return ((avr32_usbb_uesta0_t*)AVR32_USBB_UESTA0)[USB_SelectedEndpoint].byct; |
||||
} |
||||
|
||||
/** Get the endpoint address of the currently selected endpoint. This is typically used to save
|
||||
* the currently selected endpoint number so that it can be restored after another endpoint has |
||||
* been manipulated. |
||||
* |
||||
* \return Index of the currently selected endpoint. |
||||
*/ |
||||
static inline uint8_t Endpoint_GetCurrentEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline uint8_t Endpoint_GetCurrentEndpoint(void) |
||||
{ |
||||
return USB_SelectedEndpoint; |
||||
} |
||||
|
||||
/** Selects the given endpoint number. If the address from the device descriptors is used, the
|
||||
* value should be masked with the \ref ENDPOINT_EPNUM_MASK constant to extract only the endpoint |
||||
* number (and discarding the endpoint direction bit). |
||||
* |
||||
* Any endpoint operations which do not require the endpoint number to be indicated will operate on |
||||
* the currently selected endpoint. |
||||
* |
||||
* \param[in] EndpointNumber Endpoint number to select. |
||||
*/ |
||||
static inline void Endpoint_SelectEndpoint(const uint8_t EndpointNumber) ATTR_ALWAYS_INLINE; |
||||
static inline void Endpoint_SelectEndpoint(const uint8_t EndpointNumber) |
||||
{ |
||||
USB_SelectedEndpoint = EndpointNumber; |
||||
} |
||||
|
||||
/** Resets the endpoint bank FIFO. This clears all the endpoint banks and resets the USB controller's
|
||||
* data In and Out pointers to the bank's contents. |
||||
* |
||||
* \param[in] EndpointNumber Endpoint number whose FIFO buffers are to be reset. |
||||
*/ |
||||
static inline void Endpoint_ResetFIFO(const uint8_t EndpointNumber) ATTR_ALWAYS_INLINE; |
||||
static inline void Endpoint_ResetFIFO(const uint8_t EndpointNumber) |
||||
{ |
||||
AVR32_USBB.uerst |= (AVR32_USBB_EPRST0_OFFSET << EndpointNumber); |
||||
AVR32_USBB.uerst &= ~(AVR32_USBB_EPRST0_OFFSET << EndpointNumber); |
||||
} |
||||
|
||||
/** Enables the currently selected endpoint so that data can be sent and received through it to
|
||||
* and from a host. |
||||
* |
||||
* \note Endpoints must first be configured properly via \ref Endpoint_ConfigureEndpoint(). |
||||
*/ |
||||
static inline void Endpoint_EnableEndpoint(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Endpoint_EnableEndpoint(void) |
||||
{ |
||||
AVR32_USBB.uerst |= (AVR32_USBB_EPEN0 << USB_SelectedEndpoint); |
||||
} |
||||
|
||||
/** Disables the currently selected endpoint so that data cannot be sent and received through it
|
||||
* to and from a host. |
||||
*/ |
||||
static inline void Endpoint_DisableEndpoint(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Endpoint_DisableEndpoint(void) |
||||
{ |
||||
AVR32_USBB.uerst &= ~(AVR32_USBB_EPEN0_OFFSET << USB_SelectedEndpoint); |
||||
} |
||||
|
||||
/** Determines if the currently selected endpoint is enabled, but not necessarily configured.
|
||||
* |
||||
* \return Boolean \c true if the currently selected endpoint is enabled, \c false otherwise. |
||||
*/ |
||||
static inline bool Endpoint_IsEnabled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool Endpoint_IsEnabled(void) |
||||
{ |
||||
return ((AVR32_USBB.uerst & (AVR32_USBB_EPEN0_OFFSET << USB_SelectedEndpoint)) ? true : false); |
||||
} |
||||
|
||||
/** Retrieves the number of busy banks in the currently selected endpoint, which have been queued for
|
||||
* transmission via the \ref Endpoint_ClearIN() command, or are awaiting acknowledgement via the |
||||
* \ref Endpoint_ClearOUT() command. |
||||
* |
||||
* \ingroup Group_EndpointPacketManagement_AVR8 |
||||
* |
||||
* \return Total number of busy banks in the selected endpoint. |
||||
*/ |
||||
static inline uint8_t Endpoint_GetBusyBanks(void) |
||||
{ |
||||
return ((avr32_usbb_uesta0_t*)AVR32_USBB_UESTA0)[USB_SelectedEndpoint].nbusybk; |
||||
} |
||||
|
||||
/** Aborts all pending IN transactions on the currently selected endpoint, once the bank
|
||||
* has been queued for transmission to the host via \ref Endpoint_ClearIN(). This function |
||||
* will terminate all queued transactions, resetting the endpoint banks ready for a new |
||||
* packet. |
||||
* |
||||
* \ingroup Group_EndpointPacketManagement_AVR8 |
||||
*/ |
||||
static inline void Endpoint_AbortPendingIN(void) |
||||
{ |
||||
while (Endpoint_GetBusyBanks() != 0) |
||||
{ |
||||
((avr32_usbb_uecon0_t*)AVR32_USBB_UECON0SET)[USB_SelectedEndpoint].killbk = true; |
||||
while (((avr32_usbb_uecon0_t*)AVR32_USBB_UECON0)[USB_SelectedEndpoint].killbk); |
||||
} |
||||
} |
||||
|
||||
/** Determines if the currently selected endpoint may be read from (if data is waiting in the endpoint
|
||||
* bank and the endpoint is an OUT direction, or if the bank is not yet full if the endpoint is an IN |
||||
* direction). This function will return false if an error has occurred in the endpoint, if the endpoint |
||||
* is an OUT direction and no packet (or an empty packet) has been received, or if the endpoint is an IN |
||||
* direction and the endpoint bank is full. |
||||
* |
||||
* \ingroup Group_EndpointPacketManagement_AVR8 |
||||
* |
||||
* \return Boolean \c true if the currently selected endpoint may be read from or written to, depending |
||||
* on its direction. |
||||
*/ |
||||
static inline bool Endpoint_IsReadWriteAllowed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool Endpoint_IsReadWriteAllowed(void) |
||||
{ |
||||
return ((avr32_usbb_uesta0_t*)AVR32_USBB_UESTA0)[USB_SelectedEndpoint].rwall; |
||||
} |
||||
|
||||
/** Determines if the currently selected endpoint is configured.
|
||||
* |
||||
* \return Boolean \c true if the currently selected endpoint has been configured, \c false otherwise. |
||||
*/ |
||||
static inline bool Endpoint_IsConfigured(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool Endpoint_IsConfigured(void) |
||||
{ |
||||
return ((avr32_usbb_uesta0_t*)AVR32_USBB_UESTA0)[USB_SelectedEndpoint].cfgok; |
||||
} |
||||
|
||||
/** Returns a mask indicating which INTERRUPT type endpoints have interrupted - i.e. their
|
||||
* interrupt duration has elapsed. Which endpoints have interrupted can be determined by |
||||
* masking the return value against <tt>(1 << <i>{Endpoint Number}</i>)</tt>. |
||||
* |
||||
* \return Mask whose bits indicate which endpoints have interrupted. |
||||
*/ |
||||
static inline uint8_t Endpoint_GetEndpointInterrupts(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline uint8_t Endpoint_GetEndpointInterrupts(void) |
||||
{ |
||||
return ((AVR32_USBB.udint & (AVR32_USBB_EP6INTES_MASK | AVR32_USBB_EP5INTES_MASK | |
||||
AVR32_USBB_EP4INTES_MASK | AVR32_USBB_EP3INTES_MASK | |
||||
AVR32_USBB_EP2INTES_MASK | AVR32_USBB_EP1INTES_MASK | |
||||
AVR32_USBB_EP0INTES_MASK)) >> AVR32_USBB_EP0INT_OFFSET); |
||||
} |
||||
|
||||
/** Determines if the specified endpoint number has interrupted (valid only for INTERRUPT type
|
||||
* endpoints). |
||||
* |
||||
* \param[in] EndpointNumber Index of the endpoint whose interrupt flag should be tested. |
||||
* |
||||
* \return Boolean \c true if the specified endpoint has interrupted, \c false otherwise. |
||||
*/ |
||||
static inline bool Endpoint_HasEndpointInterrupted(const uint8_t EndpointNumber) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool Endpoint_HasEndpointInterrupted(const uint8_t EndpointNumber) |
||||
{ |
||||
return ((Endpoint_GetEndpointInterrupts() & (1 << EndpointNumber)) ? true : false); |
||||
} |
||||
|
||||
/** Determines if the selected IN endpoint is ready for a new packet to be sent to the host.
|
||||
* |
||||
* \ingroup Group_EndpointPacketManagement_AVR8 |
||||
* |
||||
* \return Boolean \c true if the current endpoint is ready for an IN packet, \c false otherwise. |
||||
*/ |
||||
static inline bool Endpoint_IsINReady(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool Endpoint_IsINReady(void) |
||||
{ |
||||
return ((avr32_usbb_uesta0_t*)AVR32_USBB_UESTA0)[USB_SelectedEndpoint].txini; |
||||
} |
||||
|
||||
/** Determines if the selected OUT endpoint has received new packet from the host.
|
||||
* |
||||
* \ingroup Group_EndpointPacketManagement_AVR8 |
||||
* |
||||
* \return Boolean \c true if current endpoint is has received an OUT packet, \c false otherwise. |
||||
*/ |
||||
static inline bool Endpoint_IsOUTReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool Endpoint_IsOUTReceived(void) |
||||
{ |
||||
return ((avr32_usbb_uesta0_t*)AVR32_USBB_UESTA0)[USB_SelectedEndpoint].rxouti; |
||||
} |
||||
|
||||
/** Determines if the current CONTROL type endpoint has received a SETUP packet.
|
||||
* |
||||
* \ingroup Group_EndpointPacketManagement_AVR8 |
||||
* |
||||
* \return Boolean \c true if the selected endpoint has received a SETUP packet, \c false otherwise. |
||||
*/ |
||||
static inline bool Endpoint_IsSETUPReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool Endpoint_IsSETUPReceived(void) |
||||
{ |
||||
return ((avr32_usbb_uesta0_t*)AVR32_USBB_UESTA0)[USB_SelectedEndpoint].rxstpi; |
||||
} |
||||
|
||||
/** Clears a received SETUP packet on the currently selected CONTROL type endpoint, freeing up the
|
||||
* endpoint for the next packet. |
||||
* |
||||
* \ingroup Group_EndpointPacketManagement_AVR8 |
||||
* |
||||
* \note This is not applicable for non CONTROL type endpoints. |
||||
*/ |
||||
static inline void Endpoint_ClearSETUP(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Endpoint_ClearSETUP(void) |
||||
{ |
||||
((avr32_usbb_uesta0_t*)AVR32_USBB_UESTA0CLR)[USB_SelectedEndpoint].rxstpi = true; |
||||
} |
||||
|
||||
/** Sends an IN packet to the host on the currently selected endpoint, freeing up the endpoint for the
|
||||
* next packet and switching to the alternative endpoint bank if double banked. |
||||
* |
||||
* \ingroup Group_EndpointPacketManagement_AVR8 |
||||
*/ |
||||
static inline void Endpoint_ClearIN(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Endpoint_ClearIN(void) |
||||
{ |
||||
((avr32_usbb_uesta0_t*)AVR32_USBB_UESTA0CLR)[USB_SelectedEndpoint].txini = true; |
||||
((avr32_usbb_uecon0_t*)AVR32_USBB_UECON0CLR)[USB_SelectedEndpoint].fifocon = true; |
||||
} |
||||
|
||||
/** Acknowledges an OUT packet to the host on the currently selected endpoint, freeing up the endpoint
|
||||
* for the next packet and switching to the alternative endpoint bank if double banked. |
||||
* |
||||
* \ingroup Group_EndpointPacketManagement_AVR8 |
||||
*/ |
||||
static inline void Endpoint_ClearOUT(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Endpoint_ClearOUT(void) |
||||
{ |
||||
((avr32_usbb_uesta0_t*)AVR32_USBB_UESTA0CLR)[USB_SelectedEndpoint].rxouti = true; |
||||
((avr32_usbb_uecon0_t*)AVR32_USBB_UECON0CLR)[USB_SelectedEndpoint].fifocon = true; |
||||
} |
||||
|
||||
/** Stalls the current endpoint, indicating to the host that a logical problem occurred with the
|
||||
* indicated endpoint and that the current transfer sequence should be aborted. This provides a |
||||
* way for devices to indicate invalid commands to the host so that the current transfer can be |
||||
* aborted and the host can begin its own recovery sequence. |
||||
* |
||||
* The currently selected endpoint remains stalled until either the \ref Endpoint_ClearStall() macro |
||||
* is called, or the host issues a CLEAR FEATURE request to the device for the currently selected |
||||
* endpoint. |
||||
* |
||||
* \ingroup Group_EndpointPacketManagement_AVR8 |
||||
*/ |
||||
static inline void Endpoint_StallTransaction(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Endpoint_StallTransaction(void) |
||||
{ |
||||
((avr32_usbb_uecon0_t*)AVR32_USBB_UECON0SET)[USB_SelectedEndpoint].stallrq = true; |
||||
} |
||||
|
||||
/** Clears the STALL condition on the currently selected endpoint.
|
||||
* |
||||
* \ingroup Group_EndpointPacketManagement_AVR8 |
||||
*/ |
||||
static inline void Endpoint_ClearStall(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Endpoint_ClearStall(void) |
||||
{ |
||||
((avr32_usbb_uecon0_t*)AVR32_USBB_UECON0CLR)[USB_SelectedEndpoint].stallrq = true; |
||||
} |
||||
|
||||
/** Determines if the currently selected endpoint is stalled, false otherwise.
|
||||
* |
||||
* \ingroup Group_EndpointPacketManagement_AVR8 |
||||
* |
||||
* \return Boolean \c true if the currently selected endpoint is stalled, \c false otherwise. |
||||
*/ |
||||
static inline bool Endpoint_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool Endpoint_IsStalled(void) |
||||
{ |
||||
return ((avr32_usbb_uecon0_t*)AVR32_USBB_UECON0)[USB_SelectedEndpoint].stallrq; |
||||
} |
||||
|
||||
/** Resets the data toggle of the currently selected endpoint. */ |
||||
static inline void Endpoint_ResetDataToggle(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Endpoint_ResetDataToggle(void) |
||||
{ |
||||
((avr32_usbb_uecon0_t*)AVR32_USBB_UECON0SET)[USB_SelectedEndpoint].rstdt = true; |
||||
} |
||||
|
||||
/** Determines the currently selected endpoint's direction.
|
||||
* |
||||
* \return The currently selected endpoint's direction, as a \c ENDPOINT_DIR_* mask. |
||||
*/ |
||||
static inline uint8_t Endpoint_GetEndpointDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline uint8_t Endpoint_GetEndpointDirection(void) |
||||
{ |
||||
return (((uint32_t*)AVR32_USBB_UECFG0)[USB_SelectedEndpoint] & AVR32_USBB_UECFG0_EPDIR_MASK); |
||||
} |
||||
|
||||
/** Sets the direction of the currently selected endpoint.
|
||||
* |
||||
* \param[in] DirectionMask New endpoint direction, as a \c ENDPOINT_DIR_* mask. |
||||
*/ |
||||
static inline void Endpoint_SetEndpointDirection(const uint32_t DirectionMask) ATTR_ALWAYS_INLINE; |
||||
static inline void Endpoint_SetEndpointDirection(const uint32_t DirectionMask) |
||||
{ |
||||
((avr32_usbb_uecfg0_t*)AVR32_USBB_UECFG0)[USB_SelectedEndpoint].epdir = (DirectionMask == ENDPOINT_DIR_IN); |
||||
} |
||||
|
||||
/** Reads one byte from the currently selected endpoint's bank, for OUT direction endpoints.
|
||||
* |
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8 |
||||
* |
||||
* \return Next byte in the currently selected endpoint's FIFO buffer. |
||||
*/ |
||||
static inline uint8_t Endpoint_Read_Byte(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline uint8_t Endpoint_Read_Byte(void) |
||||
{ |
||||
return *((uint8_t*)AVR32_USBB_EP_DATA); |
||||
} |
||||
|
||||
/** Writes one byte from the currently selected endpoint's bank, for IN direction endpoints.
|
||||
* |
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8 |
||||
* |
||||
* \param[in] Byte Next byte to write into the the currently selected endpoint's FIFO buffer. |
||||
*/ |
||||
static inline void Endpoint_Write_Byte(const uint8_t Byte) ATTR_ALWAYS_INLINE; |
||||
static inline void Endpoint_Write_Byte(const uint8_t Byte) |
||||
{ |
||||
*((uint8_t*)AVR32_USBB_EP_DATA) = Byte; |
||||
} |
||||
|
||||
/** Discards one byte from the currently selected endpoint's bank, for OUT direction endpoints.
|
||||
* |
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8 |
||||
*/ |
||||
static inline void Endpoint_Discard_Byte(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Endpoint_Discard_Byte(void) |
||||
{ |
||||
uint8_t Dummy; |
||||
|
||||
Dummy = *((uint8_t*)AVR32_USBB_EP_DATA); |
||||
} |
||||
|
||||
/** Reads two bytes from the currently selected endpoint's bank in little endian format, for OUT
|
||||
* direction endpoints. |
||||
* |
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8 |
||||
* |
||||
* \return Next word in the currently selected endpoint's FIFO buffer. |
||||
*/ |
||||
static inline uint16_t Endpoint_Read_Word_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline uint16_t Endpoint_Read_Word_LE(void) |
||||
{ |
||||
union |
||||
{ |
||||
uint16_t Word; |
||||
uint8_t Bytes[2]; |
||||
} Data; |
||||
|
||||
Data.Bytes[0] = *((uint8_t*)AVR32_USBB_EP_DATA); |
||||
Data.Bytes[1] = *((uint8_t*)AVR32_USBB_EP_DATA); |
||||
|
||||
return Data.Word; |
||||
} |
||||
|
||||
/** Reads two bytes from the currently selected endpoint's bank in big endian format, for OUT
|
||||
* direction endpoints. |
||||
* |
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8 |
||||
* |
||||
* \return Next word in the currently selected endpoint's FIFO buffer. |
||||
*/ |
||||
static inline uint16_t Endpoint_Read_Word_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline uint16_t Endpoint_Read_Word_BE(void) |
||||
{ |
||||
union |
||||
{ |
||||
uint16_t Word; |
||||
uint8_t Bytes[2]; |
||||
} Data; |
||||
|
||||
Data.Bytes[1] = *((uint8_t*)AVR32_USBB_EP_DATA); |
||||
Data.Bytes[0] = *((uint8_t*)AVR32_USBB_EP_DATA); |
||||
|
||||
return Data.Word; |
||||
} |
||||
|
||||
/** Writes two bytes to the currently selected endpoint's bank in little endian format, for IN
|
||||
* direction endpoints. |
||||
* |
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8 |
||||
* |
||||
* \param[in] Word Next word to write to the currently selected endpoint's FIFO buffer. |
||||
*/ |
||||
static inline void Endpoint_Write_Word_LE(const uint16_t Word) ATTR_ALWAYS_INLINE; |
||||
static inline void Endpoint_Write_Word_LE(const uint16_t Word) |
||||
{ |
||||
*((uint8_t*)AVR32_USBB_EP_DATA) = (Word & 0xFF); |
||||
*((uint8_t*)AVR32_USBB_EP_DATA) = (Word >> 8); |
||||
} |
||||
|
||||
/** Writes two bytes to the currently selected endpoint's bank in big endian format, for IN
|
||||
* direction endpoints. |
||||
* |
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8 |
||||
* |
||||
* \param[in] Word Next word to write to the currently selected endpoint's FIFO buffer. |
||||
*/ |
||||
static inline void Endpoint_Write_Word_BE(const uint16_t Word) ATTR_ALWAYS_INLINE; |
||||
static inline void Endpoint_Write_Word_BE(const uint16_t Word) |
||||
{ |
||||
*((uint8_t*)AVR32_USBB_EP_DATA) = (Word >> 8); |
||||
*((uint8_t*)AVR32_USBB_EP_DATA) = (Word & 0xFF); |
||||
} |
||||
|
||||
/** Discards two bytes from the currently selected endpoint's bank, for OUT direction endpoints.
|
||||
* |
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8 |
||||
*/ |
||||
static inline void Endpoint_Discard_Word(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Endpoint_Discard_Word(void) |
||||
{ |
||||
uint8_t Dummy; |
||||
|
||||
Dummy = *((uint8_t*)AVR32_USBB_EP_DATA); |
||||
Dummy = *((uint8_t*)AVR32_USBB_EP_DATA); |
||||
} |
||||
|
||||
/** Reads four bytes from the currently selected endpoint's bank in little endian format, for OUT
|
||||
* direction endpoints. |
||||
* |
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8 |
||||
* |
||||
* \return Next double word in the currently selected endpoint's FIFO buffer. |
||||
*/ |
||||
static inline uint32_t Endpoint_Read_DWord_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline uint32_t Endpoint_Read_DWord_LE(void) |
||||
{ |
||||
union |
||||
{ |
||||
uint32_t DWord; |
||||
uint8_t Bytes[4]; |
||||
} Data; |
||||
|
||||
Data.Bytes[0] = *((uint8_t*)AVR32_USBB_EP_DATA); |
||||
Data.Bytes[1] = *((uint8_t*)AVR32_USBB_EP_DATA); |
||||
Data.Bytes[2] = *((uint8_t*)AVR32_USBB_EP_DATA); |
||||
Data.Bytes[3] = *((uint8_t*)AVR32_USBB_EP_DATA); |
||||
|
||||
return Data.DWord; |
||||
} |
||||
|
||||
/** Reads four bytes from the currently selected endpoint's bank in big endian format, for OUT
|
||||
* direction endpoints. |
||||
* |
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8 |
||||
* |
||||
* \return Next double word in the currently selected endpoint's FIFO buffer. |
||||
*/ |
||||
static inline uint32_t Endpoint_Read_DWord_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline uint32_t Endpoint_Read_DWord_BE(void) |
||||
{ |
||||
union |
||||
{ |
||||
uint32_t DWord; |
||||
uint8_t Bytes[4]; |
||||
} Data; |
||||
|
||||
Data.Bytes[3] = *((uint8_t*)AVR32_USBB_EP_DATA); |
||||
Data.Bytes[2] = *((uint8_t*)AVR32_USBB_EP_DATA); |
||||
Data.Bytes[1] = *((uint8_t*)AVR32_USBB_EP_DATA); |
||||
Data.Bytes[0] = *((uint8_t*)AVR32_USBB_EP_DATA); |
||||
|
||||
return Data.DWord; |
||||
} |
||||
|
||||
/** Writes four bytes to the currently selected endpoint's bank in little endian format, for IN
|
||||
* direction endpoints. |
||||
* |
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8 |
||||
* |
||||
* \param[in] DWord Next double word to write to the currently selected endpoint's FIFO buffer. |
||||
*/ |
||||
static inline void Endpoint_Write_DWord_LE(const uint32_t DWord) ATTR_ALWAYS_INLINE; |
||||
static inline void Endpoint_Write_DWord_LE(const uint32_t DWord) |
||||
{ |
||||
*((uint8_t*)AVR32_USBB_EP_DATA) = (DWord & 0xFF); |
||||
*((uint8_t*)AVR32_USBB_EP_DATA) = (DWord >> 8); |
||||
*((uint8_t*)AVR32_USBB_EP_DATA) = (DWord >> 16); |
||||
*((uint8_t*)AVR32_USBB_EP_DATA) = (DWord >> 24); |
||||
} |
||||
|
||||
/** Writes four bytes to the currently selected endpoint's bank in big endian format, for IN
|
||||
* direction endpoints. |
||||
* |
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8 |
||||
* |
||||
* \param[in] DWord Next double word to write to the currently selected endpoint's FIFO buffer. |
||||
*/ |
||||
static inline void Endpoint_Write_DWord_BE(const uint32_t DWord) ATTR_ALWAYS_INLINE; |
||||
static inline void Endpoint_Write_DWord_BE(const uint32_t DWord) |
||||
{ |
||||
*((uint8_t*)AVR32_USBB_EP_DATA) = (DWord >> 24); |
||||
*((uint8_t*)AVR32_USBB_EP_DATA) = (DWord >> 16); |
||||
*((uint8_t*)AVR32_USBB_EP_DATA) = (DWord >> 8); |
||||
*((uint8_t*)AVR32_USBB_EP_DATA) = (DWord & 0xFF); |
||||
} |
||||
|
||||
/** Discards four bytes from the currently selected endpoint's bank, for OUT direction endpoints.
|
||||
* |
||||
* \ingroup Group_EndpointPrimitiveRW_AVR8 |
||||
*/ |
||||
static inline void Endpoint_Discard_DWord(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Endpoint_Discard_DWord(void) |
||||
{ |
||||
uint8_t Dummy; |
||||
|
||||
Dummy = *((uint8_t*)AVR32_USBB_EP_DATA); |
||||
Dummy = *((uint8_t*)AVR32_USBB_EP_DATA); |
||||
Dummy = *((uint8_t*)AVR32_USBB_EP_DATA); |
||||
Dummy = *((uint8_t*)AVR32_USBB_EP_DATA); |
||||
} |
||||
|
||||
/* External Variables: */ |
||||
/** Global indicating the maximum packet size of the default control endpoint located at address
|
||||
* 0 in the device. This value is set to the value indicated in the device descriptor in the user |
||||
* project once the USB interface is initialized into device mode. |
||||
* |
||||
* If space is an issue, it is possible to fix this to a static value by defining the control |
||||
* endpoint size in the \c FIXED_CONTROL_ENDPOINT_SIZE token passed to the compiler in the makefile |
||||
* via the -D switch. When a fixed control endpoint size is used, the size is no longer dynamically |
||||
* read from the descriptors at runtime and instead fixed to the given value. When used, it is |
||||
* important that the descriptor control endpoint size value matches the size given as the |
||||
* \c FIXED_CONTROL_ENDPOINT_SIZE token - it is recommended that the \c FIXED_CONTROL_ENDPOINT_SIZE token |
||||
* be used in the device descriptors to ensure this. |
||||
* |
||||
* \note This variable should be treated as read-only in the user application, and never manually |
||||
* changed in value. |
||||
*/ |
||||
#if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__)) |
||||
extern uint8_t USB_ControlEndpointSize; |
||||
#else |
||||
#define USB_ControlEndpointSize FIXED_CONTROL_ENDPOINT_SIZE |
||||
#endif |
||||
|
||||
/* Function Prototypes: */ |
||||
/** Completes the status stage of a control transfer on a CONTROL type endpoint automatically,
|
||||
* with respect to the data direction. This is a convenience function which can be used to |
||||
* simplify user control request handling. |
||||
*/ |
||||
void Endpoint_ClearStatusStage(void); |
||||
|
||||
/** Spin-loops until the currently selected non-control endpoint is ready for the next packet of data
|
||||
* to be read or written to it. |
||||
* |
||||
* \note This routine should not be called on CONTROL type endpoints. |
||||
* |
||||
* \ingroup Group_EndpointRW_AVR8 |
||||
* |
||||
* \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum. |
||||
*/ |
||||
uint8_t Endpoint_WaitUntilReady(void); |
||||
|
||||
/* Disable C linkage for C++ Compilers: */ |
||||
#if defined(__cplusplus) |
||||
} |
||||
#endif |
||||
|
||||
#endif |
||||
|
||||
/** @} */ |
||||
|
@ -0,0 +1,355 @@ |
||||
/*
|
||||
LUFA Library |
||||
Copyright (C) Dean Camera, 2011. |
||||
|
||||
dean [at] fourwalledcubicle [dot] com |
||||
www.lufa-lib.org |
||||
*/ |
||||
|
||||
/*
|
||||
Copyright 2011 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. |
||||
*/ |
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER |
||||
#include "../USBMode.h" |
||||
|
||||
#if defined(USB_CAN_BE_HOST) |
||||
|
||||
#define __INCLUDE_FROM_HOST_C |
||||
#include "Host.h" |
||||
|
||||
void USB_Host_ProcessNextHostState(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; |
||||
} |
||||
|
||||
if (!(--WaitMSRemaining)) |
||||
USB_HostState = PostWaitState; |
||||
} |
||||
|
||||
break; |
||||
case HOST_STATE_Powered: |
||||
WaitMSRemaining = HOST_DEVICE_SETTLE_DELAY_MS; |
||||
|
||||
USB_HostState = HOST_STATE_Powered_WaitForDeviceSettle; |
||||
break; |
||||
case HOST_STATE_Powered_WaitForDeviceSettle: |
||||
if (WaitMSRemaining--) |
||||
{ |
||||
_delay_ms(1); |
||||
break; |
||||
} |
||||
else |
||||
{ |
||||
USB_Host_VBUS_Manual_Off(); |
||||
|
||||
USB_OTGPAD_On(); |
||||
USB_Host_VBUS_Auto_Enable(); |
||||
USB_Host_VBUS_Auto_On(); |
||||
|
||||
USB_HostState = HOST_STATE_Powered_WaitForConnect; |
||||
} |
||||
|
||||
break; |
||||
case HOST_STATE_Powered_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_Host_ResumeBus(); |
||||
Pipe_ClearPipes(); |
||||
|
||||
HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Powered_DoReset); |
||||
} |
||||
|
||||
break; |
||||
case HOST_STATE_Powered_DoReset: |
||||
USB_Host_ResetDevice(); |
||||
|
||||
HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Powered_ConfigPipe); |
||||
break; |
||||
case HOST_STATE_Powered_ConfigPipe: |
||||
Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL, |
||||
PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP, |
||||
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_ControlRequest = (USB_Request_Header_t) |
||||
{ |
||||
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE), |
||||
.bRequest = REQ_GetDescriptor, |
||||
.wValue = (DTYPE_Device << 8), |
||||
.wIndex = 0, |
||||
.wLength = 8, |
||||
}; |
||||
|
||||
uint8_t DataBuffer[8]; |
||||
|
||||
if ((SubErrorCode = USB_Host_SendControlRequest(DataBuffer)) != HOST_SENDCONTROL_Successful) |
||||
{ |
||||
ErrorCode = HOST_ENUMERROR_ControlError; |
||||
break; |
||||
} |
||||
|
||||
USB_ControlPipeSize = DataBuffer[offsetof(USB_Descriptor_Device_t, Endpoint0Size)]; |
||||
|
||||
USB_Host_ResetDevice(); |
||||
|
||||
HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Default_PostReset); |
||||
break; |
||||
case HOST_STATE_Default_PostReset: |
||||
Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL, |
||||
PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP, |
||||
USB_ControlPipeSize, PIPE_BANK_SINGLE); |
||||
|
||||
if (!(Pipe_IsConfigured())) |
||||
{ |
||||
ErrorCode = HOST_ENUMERROR_PipeConfigError; |
||||
SubErrorCode = 0; |
||||
break; |
||||
} |
||||
|
||||
USB_ControlRequest = (USB_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); |
||||
|
||||
EVENT_USB_Host_DeviceEnumerationComplete(); |
||||
USB_HostState = HOST_STATE_Addressed; |
||||
break; |
||||
} |
||||
|
||||
if ((ErrorCode != HOST_ENUMERROR_NoError) && (USB_HostState != HOST_STATE_Unattached)) |
||||
{ |
||||
EVENT_USB_Host_DeviceEnumerationFailed(ErrorCode, SubErrorCode); |
||||
|
||||
USB_Host_VBUS_Auto_Off(); |
||||
|
||||
EVENT_USB_Host_DeviceUnattached(); |
||||
|
||||
USB_ResetInterface(); |
||||
} |
||||
} |
||||
|
||||
uint8_t USB_Host_WaitMS(uint8_t MS) |
||||
{ |
||||
bool BusSuspended = USB_Host_IsBusSuspended(); |
||||
uint8_t ErrorCode = HOST_WAITERROR_Successful; |
||||
bool HSOFIEnabled = USB_INT_IsEnabled(USB_INT_HSOFI); |
||||
|
||||
USB_INT_Disable(USB_INT_HSOFI); |
||||
USB_INT_Clear(USB_INT_HSOFI); |
||||
|
||||
USB_Host_ResumeBus(); |
||||
|
||||
while (MS) |
||||
{ |
||||
if (USB_INT_HasOccurred(USB_INT_HSOFI)) |
||||
{ |
||||
USB_INT_Clear(USB_INT_HSOFI); |
||||
MS--; |
||||
} |
||||
|
||||
if ((USB_HostState == HOST_STATE_Unattached) || (USB_CurrentMode != USB_MODE_Host)) |
||||
{ |
||||
ErrorCode = HOST_WAITERROR_DeviceDisconnect; |
||||
|
||||
break; |
||||
} |
||||
|
||||
if (Pipe_IsError() == true) |
||||
{ |
||||
Pipe_ClearError(); |
||||
ErrorCode = HOST_WAITERROR_PipeError; |
||||
|
||||
break; |
||||
} |
||||
|
||||
if (Pipe_IsStalled() == true) |
||||
{ |
||||
Pipe_ClearStall(); |
||||
ErrorCode = HOST_WAITERROR_SetupStalled; |
||||
|
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (BusSuspended) |
||||
USB_Host_SuspendBus(); |
||||
|
||||
if (HSOFIEnabled) |
||||
USB_INT_Enable(USB_INT_HSOFI); |
||||
|
||||
return ErrorCode; |
||||
} |
||||
|
||||
static void USB_Host_ResetDevice(void) |
||||
{ |
||||
bool BusSuspended = USB_Host_IsBusSuspended(); |
||||
|
||||
USB_INT_Disable(USB_INT_DDISCI); |
||||
|
||||
USB_Host_ResetBus(); |
||||
while (!(USB_Host_IsBusResetComplete())); |
||||
USB_Host_ResumeBus(); |
||||
|
||||
bool HSOFIEnabled = USB_INT_IsEnabled(USB_INT_HSOFI); |
||||
|
||||
USB_INT_Disable(USB_INT_HSOFI); |
||||
USB_INT_Clear(USB_INT_HSOFI); |
||||
|
||||
for (uint8_t MSRem = 10; MSRem != 0; MSRem--) |
||||
{ |
||||
/* Workaround for powerless-pull-up devices. After a USB bus reset,
|
||||
all disconnection interrupts are suppressed while a USB frame is |
||||
looked for - if it is found within 10ms, the device is still |
||||
present. */ |
||||
|
||||
if (USB_INT_HasOccurred(USB_INT_HSOFI)) |
||||
{ |
||||
USB_INT_Clear(USB_INT_HSOFI); |
||||
USB_INT_Clear(USB_INT_DDISCI); |
||||
break; |
||||
} |
||||
|
||||
_delay_ms(1); |
||||
} |
||||
|
||||
if (HSOFIEnabled) |
||||
USB_INT_Enable(USB_INT_HSOFI); |
||||
|
||||
if (BusSuspended) |
||||
USB_Host_SuspendBus(); |
||||
|
||||
USB_INT_Enable(USB_INT_DDISCI); |
||||
} |
||||
|
||||
uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber) |
||||
{ |
||||
USB_ControlRequest = (USB_Request_Header_t) |
||||
{ |
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE), |
||||
.bRequest = REQ_SetConfiguration, |
||||
.wValue = ConfigNumber, |
||||
.wIndex = 0, |
||||
.wLength = 0, |
||||
}; |
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE); |
||||
|
||||
return USB_Host_SendControlRequest(NULL); |
||||
} |
||||
|
||||
uint8_t USB_Host_GetDeviceDescriptor(void* const DeviceDescriptorPtr) |
||||
{ |
||||
USB_ControlRequest = (USB_Request_Header_t) |
||||
{ |
||||
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE), |
||||
.bRequest = REQ_GetDescriptor, |
||||
.wValue = (DTYPE_Device << 8), |
||||
.wIndex = 0, |
||||
.wLength = sizeof(USB_Descriptor_Device_t), |
||||
}; |
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE); |
||||
|
||||
return USB_Host_SendControlRequest(DeviceDescriptorPtr); |
||||
} |
||||
|
||||
uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t Index, |
||||
void* const Buffer, |
||||
const uint8_t BufferLength) |
||||
{ |
||||
USB_ControlRequest = (USB_Request_Header_t) |
||||
{ |
||||
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE), |
||||
.bRequest = REQ_GetDescriptor, |
||||
.wValue = (DTYPE_String << 8) | Index, |
||||
.wIndex = 0, |
||||
.wLength = BufferLength, |
||||
}; |
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE); |
||||
|
||||
return USB_Host_SendControlRequest(Buffer); |
||||
} |
||||
|
||||
uint8_t USB_Host_ClearPipeStall(const uint8_t EndpointNum) |
||||
{ |
||||
USB_ControlRequest = (USB_Request_Header_t) |
||||
{ |
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT), |
||||
.bRequest = REQ_ClearFeature, |
||||
.wValue = FEATURE_SEL_EndpointHalt, |
||||
.wIndex = EndpointNum, |
||||
.wLength = 0, |
||||
}; |
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE); |
||||
|
||||
return USB_Host_SendControlRequest(NULL); |
||||
} |
||||
|
||||
#endif |
||||
|
@ -0,0 +1,522 @@ |
||||
/*
|
||||
LUFA Library |
||||
Copyright (C) Dean Camera, 2011. |
||||
|
||||
dean [at] fourwalledcubicle [dot] com |
||||
www.lufa-lib.org |
||||
*/ |
||||
|
||||
/*
|
||||
Copyright 2011 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 Host definitions for the AVR32 UC3B microcontrollers. |
||||
* \copydetails Group_Host_UC3B |
||||
* |
||||
* \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_Host
|
||||
* \defgroup Group_Host_UC3B Host Management (UC3B) |
||||
* \brief USB Host definitions for the AVR32 UC3B microcontrollers. |
||||
* |
||||
* Architecture specific USB Host definitions for the Atmel 32-bit AVR UC3B microcontrollers. |
||||
* |
||||
* @{ |
||||
*/ |
||||
|
||||
#ifndef __USBHOST_UC3B_H__ |
||||
#define __USBHOST_UC3B_H__ |
||||
|
||||
/* Includes: */ |
||||
#include "../../../../Common/Common.h" |
||||
#include "../StdDescriptors.h" |
||||
#include "../Pipe.h" |
||||
#include "../USBInterrupt.h" |
||||
|
||||
/* Enable C linkage for C++ Compilers: */ |
||||
#if defined(__cplusplus) |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* Preprocessor Checks: */ |
||||
#if !defined(__INCLUDE_FROM_USB_DRIVER) |
||||
#error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. |
||||
#endif |
||||
|
||||
/* Public Interface - May be used in end-application: */ |
||||
/* Macros: */ |
||||
/** Indicates the fixed USB device address which any attached device is enumerated to when in
|
||||
* host mode. As only one USB device may be attached to the AVR in host mode at any one time |
||||
* and that the address used is not important (other than the fact that it is non-zero), a |
||||
* fixed value is specified by the library. |
||||
*/ |
||||
#define USB_HOST_DEVICEADDRESS 1 |
||||
|
||||
#if !defined(USB_HOST_TIMEOUT_MS) || defined(__DOXYGEN__) |
||||
/** Constant for the maximum software timeout period of sent USB control transactions to an attached
|
||||
* device. If a device fails to respond to a sent control request within this period, the |
||||
* library will return a timeout error code. |
||||
* |
||||
* This value may be overridden in the user project makefile as the value of the |
||||
* \ref USB_HOST_TIMEOUT_MS token, and passed to the compiler using the -D switch. |
||||
*/ |
||||
#define USB_HOST_TIMEOUT_MS 1000 |
||||
#endif |
||||
|
||||
#if !defined(HOST_DEVICE_SETTLE_DELAY_MS) || defined(__DOXYGEN__) |
||||
/** Constant for the delay in milliseconds after a device is connected before the library
|
||||
* will start the enumeration process. Some devices require a delay of up to 5 seconds |
||||
* after connection before the enumeration process can start or incorrect operation will |
||||
* occur. |
||||
* |
||||
* The default delay value may be overridden in the user project makefile by defining the |
||||
* \c HOST_DEVICE_SETTLE_DELAY_MS token to the required delay in milliseconds, and passed to the |
||||
* compiler using the -D switch. |
||||
*/ |
||||
#define HOST_DEVICE_SETTLE_DELAY_MS 1000 |
||||
#endif |
||||
|
||||
/* Enums: */ |
||||
/** Enum for the various states of the USB Host state machine. Only some states are
|
||||
* implemented in the LUFA library - other states are left to the user to implement. |
||||
* |
||||
* For information on each possible USB host state, refer to the USB 2.0 specification. |
||||
* Several of the USB host states are broken up further into multiple smaller sub-states, |
||||
* so that they can be internally implemented inside the library in an efficient manner. |
||||
* |
||||
* \see \ref USB_HostState, which stores the current host state machine state. |
||||
*/ |
||||
enum USB_Host_States_t |
||||
{ |
||||
HOST_STATE_WaitForDeviceRemoval = 0, /**< Internally implemented by the library. This state can be
|
||||
* used by the library to wait until the attached device is |
||||
* removed by the user - useful for when an error occurs or |
||||
* further communication with the device is not needed. This |
||||
* allows for other code to run while the state machine is |
||||
* effectively disabled. |
||||
*/ |
||||
HOST_STATE_WaitForDevice = 1, /**< Internally implemented by the library. This state indicates
|
||||
* that the stack is waiting for an interval to elapse before |
||||
* continuing with the next step of the device enumeration |
||||
* process. |
||||
* |
||||
* \note Do not manually change to this state in the user code. |
||||
*/ |
||||
HOST_STATE_Unattached = 2, /**< Internally implemented by the library. This state indicates
|
||||
* that the host state machine is waiting for a device to be |
||||
* attached so that it can start the enumeration process. |
||||
* |
||||
* \note Do not manually change to this state in the user code. |
||||
*/ |
||||
HOST_STATE_Powered = 3, /**< Internally implemented by the library. This state indicates
|
||||
* that a device has been attached, and the library's internals |
||||
* are being configured to begin the enumeration process. |
||||
* |
||||
* \note Do not manually change to this state in the user code. |
||||
*/ |
||||
HOST_STATE_Powered_WaitForDeviceSettle = 4, /**< Internally implemented by the library. This state indicates
|
||||
* that the stack is waiting for the initial settling period to |
||||
* elapse before beginning the enumeration process. |
||||
* |
||||
* \note Do not manually change to this state in the user code. |
||||
*/ |
||||
HOST_STATE_Powered_WaitForConnect = 5, /**< Internally implemented by the library. This state indicates
|
||||
* that the stack is waiting for a connection event from the USB |
||||
* controller to indicate a valid USB device has been attached to |
||||
* the bus and is ready to be enumerated. |
||||
* |
||||
* \note Do not manually change to this state in the user code. |
||||
*/ |
||||
HOST_STATE_Powered_DoReset = 6, /**< Internally implemented by the library. This state indicates
|
||||
* that a valid USB device has been attached, and that it is |
||||
* will now be reset to ensure it is ready for enumeration. |
||||
* |
||||
* \note Do not manually change to this state in the user code. |
||||
*/ |
||||
HOST_STATE_Powered_ConfigPipe = 7, /**< Internally implemented by the library. This state indicates
|
||||
* that the attached device is currently powered and reset, and |
||||
* that the control pipe is now being configured by the stack. |
||||
* |
||||
* \note Do not manually change to this state in the user code. |
||||
*/ |
||||
HOST_STATE_Default = 8, /**< Internally implemented by the library. This state indicates
|
||||
* that the stack is currently retrieving the control endpoint's |
||||
* size from the device, so that the control pipe can be altered |
||||
* to match. |
||||
* |
||||
* \note Do not manually change to this state in the user code. |
||||
*/ |
||||
HOST_STATE_Default_PostReset = 9, /**< Internally implemented by the library. This state indicates that
|
||||
* the control pipe is being reconfigured to match the retrieved |
||||
* control endpoint size from the device, and the device's USB bus |
||||
* address is being set. |
||||
* |
||||
* \note Do not manually change to this state in the user code. |
||||
*/ |
||||
HOST_STATE_Default_PostAddressSet = 10, /**< Internally implemented by the library. This state indicates that
|
||||
* the device's address has now been set, and the stack is has now |
||||
* completed the device enumeration process. This state causes the |
||||
* stack to change the current USB device address to that set for |
||||
* the connected device, before progressing to the user-implemented |
||||
* \ref HOST_STATE_Addressed state for further communications. |
||||
* |
||||
* \note Do not manually change to this state in the user code. |
||||
*/ |
||||
HOST_STATE_Addressed = 11, /**< May be implemented by the user project. This state should
|
||||
* set the device configuration before progressing to the |
||||
* \ref HOST_STATE_Configured state. Other processing (such as the |
||||
* retrieval and processing of the device descriptor) should also |
||||
* be placed in this state. |
||||
*/ |
||||
HOST_STATE_Configured = 12, /**< May be implemented by the user project. This state should implement the
|
||||
* actual work performed on the attached device and changed to the |
||||
* \ref HOST_STATE_Suspended or \ref HOST_STATE_WaitForDeviceRemoval states as needed. |
||||
*/ |
||||
HOST_STATE_Suspended = 15, /**< May be implemented by the user project. This state should be maintained
|
||||
* while the bus is suspended, and changed to either the \ref HOST_STATE_Configured |
||||
* (after resuming the bus with the USB_Host_ResumeBus() macro) or the |
||||
* \ref HOST_STATE_WaitForDeviceRemoval states as needed. |
||||
*/ |
||||
}; |
||||
|
||||
/** Enum for the error codes for the \ref EVENT_USB_Host_HostError() event.
|
||||
* |
||||
* \see \ref Group_Events for more information on this event. |
||||
*/ |
||||
enum USB_Host_ErrorCodes_t |
||||
{ |
||||
HOST_ERROR_VBusVoltageDip = 0, /**< VBUS voltage dipped to an unacceptable level. This
|
||||
* error may be the result of an attached device drawing |
||||
* too much current from the VBUS line, or due to the |
||||
* AVR's power source being unable to supply sufficient |
||||
* current. |
||||
*/ |
||||
}; |
||||
|
||||
/** Enum for the error codes for the \ref EVENT_USB_Host_DeviceEnumerationFailed() event.
|
||||
* |
||||
* \see \ref Group_Events for more information on this event. |
||||
*/ |
||||
enum USB_Host_EnumerationErrorCodes_t |
||||
{ |
||||
HOST_ENUMERROR_NoError = 0, /**< No error occurred. Used internally, this is not a valid
|
||||
* ErrorCode parameter value for the \ref EVENT_USB_Host_DeviceEnumerationFailed() |
||||
* event. |
||||
*/ |
||||
HOST_ENUMERROR_WaitStage = 1, /**< One of the delays between enumeration steps failed
|
||||
* to complete successfully, due to a timeout or other |
||||
* error. |
||||
*/ |
||||
HOST_ENUMERROR_NoDeviceDetected = 2, /**< No device was detected, despite the USB data lines
|
||||
* indicating the attachment of a device. |
||||
*/ |
||||
HOST_ENUMERROR_ControlError = 3, /**< One of the enumeration control requests failed to
|
||||
* complete successfully. |
||||
*/ |
||||
HOST_ENUMERROR_PipeConfigError = 4, /**< The default control pipe (address 0) failed to
|
||||
* configure correctly. |
||||
*/ |
||||
}; |
||||
|
||||
/* Inline Functions: */ |
||||
/** Returns the current USB frame number, when in host mode. Every millisecond the USB bus is active (i.e. not suspended)
|
||||
* the frame number is incremented by one. |
||||
*/ |
||||
static inline uint16_t USB_Host_GetFrameNumber(void) |
||||
{ |
||||
return UHFNUM; |
||||
} |
||||
|
||||
#if !defined(NO_SOF_EVENTS) |
||||
/** Enables the host mode Start Of Frame events. When enabled, this causes the
|
||||
* \ref EVENT_USB_Host_StartOfFrame() event to fire once per millisecond, synchronized to the USB bus, |
||||
* at the start of each USB frame when a device is enumerated while in host mode. |
||||
* |
||||
* \note Not available when the \c NO_SOF_EVENTS compile time token is defined. |
||||
*/ |
||||
static inline void USB_Host_EnableSOFEvents(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Host_EnableSOFEvents(void) |
||||
{ |
||||
USB_INT_Enable(USB_INT_HSOFI); |
||||
} |
||||
|
||||
/** Disables the host mode Start Of Frame events. When disabled, this stops the firing of the
|
||||
* \ref EVENT_USB_Host_StartOfFrame() event when enumerated in host mode. |
||||
* |
||||
* \note Not available when the NO_SOF_EVENTS compile time token is defined. |
||||
*/ |
||||
static inline void USB_Host_DisableSOFEvents(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Host_DisableSOFEvents(void) |
||||
{ |
||||
USB_INT_Disable(USB_INT_HSOFI); |
||||
} |
||||
#endif |
||||
|
||||
/** Resets the USB bus, including the endpoints in any attached device and pipes on the AVR host.
|
||||
* USB bus resets leave the default control pipe configured (if already configured). |
||||
* |
||||
* If the USB bus has been suspended prior to issuing a bus reset, the attached device will be |
||||
* woken up automatically and the bus resumed after the reset has been correctly issued. |
||||
*/ |
||||
static inline void USB_Host_ResetBus(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Host_ResetBus(void) |
||||
{ |
||||
UHCON |= (1 << RESET); |
||||
} |
||||
|
||||
/** Determines if a previously issued bus reset (via the \ref USB_Host_ResetBus() macro) has
|
||||
* completed. |
||||
* |
||||
* \return Boolean \c true if no bus reset is currently being sent, \c false otherwise. |
||||
*/ |
||||
static inline bool USB_Host_IsBusResetComplete(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool USB_Host_IsBusResetComplete(void) |
||||
{ |
||||
return ((UHCON & (1 << RESET)) ? false : true); |
||||
} |
||||
|
||||
/** Resumes USB communications with an attached and enumerated device, by resuming the transmission
|
||||
* of the 1MS Start Of Frame messages to the device. When resumed, USB communications between the |
||||
* host and attached device may occur. |
||||
*/ |
||||
static inline void USB_Host_ResumeBus(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Host_ResumeBus(void) |
||||
{ |
||||
UHCON |= (1 << SOFEN); |
||||
} |
||||
|
||||
/** Suspends the USB bus, preventing any communications from occurring between the host and attached
|
||||
* device until the bus has been resumed. This stops the transmission of the 1MS Start Of Frame |
||||
* messages to the device. |
||||
*/ |
||||
static inline void USB_Host_SuspendBus(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Host_SuspendBus(void) |
||||
{ |
||||
UHCON &= ~(1 << SOFEN); |
||||
} |
||||
|
||||
/** Determines if the USB bus has been suspended via the use of the \ref USB_Host_SuspendBus() macro,
|
||||
* false otherwise. While suspended, no USB communications can occur until the bus is resumed, |
||||
* except for the Remote Wakeup event from the device if supported. |
||||
* |
||||
* \return Boolean \c true if the bus is currently suspended, \c false otherwise. |
||||
*/ |
||||
static inline bool USB_Host_IsBusSuspended(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool USB_Host_IsBusSuspended(void) |
||||
{ |
||||
return ((UHCON & (1 << SOFEN)) ? false : true); |
||||
} |
||||
|
||||
/** Determines if the attached device is currently enumerated in Full Speed mode (12Mb/s), or
|
||||
* false if the attached device is enumerated in Low Speed mode (1.5Mb/s). |
||||
* |
||||
* \return Boolean \c true if the attached device is enumerated in Full Speed mode, \c false otherwise. |
||||
*/ |
||||
static inline bool USB_Host_IsDeviceFullSpeed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool USB_Host_IsDeviceFullSpeed(void) |
||||
{ |
||||
return ((USBSTA & (1 << SPEED)) ? true : false); |
||||
} |
||||
|
||||
/** Determines if the attached device is currently issuing a Remote Wakeup request, requesting
|
||||
* that the host resume the USB bus and wake up the device, false otherwise. |
||||
* |
||||
* \return Boolean \c true if the attached device has sent a Remote Wakeup request, \c false otherwise. |
||||
*/ |
||||
static inline bool USB_Host_IsRemoteWakeupSent(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool USB_Host_IsRemoteWakeupSent(void) |
||||
{ |
||||
return ((UHINT & (1 << RXRSMI)) ? true : false); |
||||
} |
||||
|
||||
/** Clears the flag indicating that a Remote Wakeup request has been issued by an attached device. */ |
||||
static inline void USB_Host_ClearRemoteWakeupSent(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Host_ClearRemoteWakeupSent(void) |
||||
{ |
||||
UHINT &= ~(1 << RXRSMI); |
||||
} |
||||
|
||||
/** Accepts a Remote Wakeup request from an attached device. This must be issued in response to
|
||||
* a device's Remote Wakeup request within 2ms for the request to be accepted and the bus to |
||||
* be resumed. |
||||
*/ |
||||
static inline void USB_Host_ResumeFromWakeupRequest(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Host_ResumeFromWakeupRequest(void) |
||||
{ |
||||
UHCON |= (1 << RESUME); |
||||
} |
||||
|
||||
/** Determines if a resume from Remote Wakeup request is currently being sent to an attached
|
||||
* device. |
||||
* |
||||
* \return Boolean \c true if no resume request is currently being sent, \c false otherwise. |
||||
*/ |
||||
static inline bool USB_Host_IsResumeFromWakeupRequestSent(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool USB_Host_IsResumeFromWakeupRequestSent(void) |
||||
{ |
||||
return ((UHCON & (1 << RESUME)) ? false : true); |
||||
} |
||||
|
||||
/* Function Prototypes: */ |
||||
/** Convenience function. This routine sends a SET CONFIGURATION standard request to the attached
|
||||
* device, with the given configuration index. This can be used to easily set the device |
||||
* configuration without creating and sending the request manually. |
||||
* |
||||
* \note After this routine returns, the control pipe will be selected. |
||||
* |
||||
* \param[in] ConfigNumber Configuration index to send to the device. |
||||
* |
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. |
||||
*/ |
||||
uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber); |
||||
|
||||
/** Convenience function. This routine sends a GET DESCRIPTOR standard request to the attached
|
||||
* device, requesting the device descriptor. This can be used to easily retrieve information |
||||
* about the device such as its VID, PID and power requirements. |
||||
* |
||||
* \note After this routine returns, the control pipe will be selected. |
||||
* |
||||
* \param[out] DeviceDescriptorPtr Pointer to the destination device descriptor structure where |
||||
* the read data is to be stored. |
||||
* |
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. |
||||
*/ |
||||
uint8_t USB_Host_GetDeviceDescriptor(void* const DeviceDescriptorPtr); |
||||
|
||||
/** Convenience function. This routine sends a GET DESCRIPTOR standard request to the attached
|
||||
* device, requesting the string descriptor of the specified index. This can be used to easily |
||||
* retrieve string descriptors from the device by index, after the index is obtained from the |
||||
* Device or Configuration descriptors. |
||||
* |
||||
* \note After this routine returns, the control pipe will be selected. |
||||
* |
||||
* \param[in] Index Index of the string index to retrieve. |
||||
* \param[out] Buffer Pointer to the destination buffer where the retrieved string descriptor is |
||||
* to be stored. |
||||
* \param[in] BufferLength Maximum size of the string descriptor which can be stored into the buffer. |
||||
* |
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. |
||||
*/ |
||||
uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t Index, |
||||
void* const Buffer, |
||||
const uint8_t BufferLength); |
||||
|
||||
/** Clears a stall condition on the given pipe, via a CLEAR FEATURE standard request to the attached device.
|
||||
* |
||||
* \note After this routine returns, the control pipe will be selected. |
||||
* |
||||
* \param[in] EndpointIndex Index of the endpoint to clear, including the endpoint's direction. |
||||
* |
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. |
||||
*/ |
||||
uint8_t USB_Host_ClearPipeStall(const uint8_t EndpointIndex); |
||||
|
||||
/* Private Interface - For use in library only: */ |
||||
#if !defined(__DOXYGEN__) |
||||
/* Macros: */ |
||||
static inline void USB_Host_HostMode_On(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Host_HostMode_On(void) |
||||
{ |
||||
USBCON |= (1 << HOST); |
||||
} |
||||
|
||||
static inline void USB_Host_HostMode_Off(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Host_HostMode_Off(void) |
||||
{ |
||||
USBCON &= ~(1 << HOST); |
||||
} |
||||
|
||||
static inline void USB_Host_VBUS_Auto_Enable(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Host_VBUS_Auto_Enable(void) |
||||
{ |
||||
OTGCON &= ~(1 << VBUSHWC); |
||||
UHWCON |= (1 << UVCONE); |
||||
} |
||||
|
||||
static inline void USB_Host_VBUS_Manual_Enable(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Host_VBUS_Manual_Enable(void) |
||||
{ |
||||
OTGCON |= (1 << VBUSHWC); |
||||
UHWCON &= ~(1 << UVCONE); |
||||
|
||||
DDRE |= (1 << 7); |
||||
} |
||||
|
||||
static inline void USB_Host_VBUS_Auto_On(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Host_VBUS_Auto_On(void) |
||||
{ |
||||
OTGCON |= (1 << VBUSREQ); |
||||
} |
||||
|
||||
static inline void USB_Host_VBUS_Manual_On(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Host_VBUS_Manual_On(void) |
||||
{ |
||||
PORTE |= (1 << 7); |
||||
} |
||||
|
||||
static inline void USB_Host_VBUS_Auto_Off(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Host_VBUS_Auto_Off(void) |
||||
{ |
||||
OTGCON |= (1 << VBUSRQC); |
||||
} |
||||
|
||||
static inline void USB_Host_VBUS_Manual_Off(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Host_VBUS_Manual_Off(void) |
||||
{ |
||||
PORTE &= ~(1 << 7); |
||||
} |
||||
|
||||
static inline void USB_Host_SetDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_Host_SetDeviceAddress(const uint8_t Address) |
||||
{ |
||||
UHADDR = (Address & 0x7F); |
||||
} |
||||
|
||||
/* Enums: */ |
||||
enum USB_Host_WaitMSErrorCodes_t |
||||
{ |
||||
HOST_WAITERROR_Successful = 0, |
||||
HOST_WAITERROR_DeviceDisconnect = 1, |
||||
HOST_WAITERROR_PipeError = 2, |
||||
HOST_WAITERROR_SetupStalled = 3, |
||||
}; |
||||
|
||||
/* Function Prototypes: */ |
||||
void USB_Host_ProcessNextHostState(void); |
||||
uint8_t USB_Host_WaitMS(uint8_t MS); |
||||
|
||||
#if defined(__INCLUDE_FROM_HOST_C) |
||||
static void USB_Host_ResetDevice(void); |
||||
#endif |
||||
#endif |
||||
|
||||
/* Disable C linkage for C++ Compilers: */ |
||||
#if defined(__cplusplus) |
||||
} |
||||
#endif |
||||
|
||||
#endif |
||||
|
||||
/** @} */ |
||||
|
@ -0,0 +1,149 @@ |
||||
/*
|
||||
LUFA Library |
||||
Copyright (C) Dean Camera, 2011. |
||||
|
||||
dean [at] fourwalledcubicle [dot] com |
||||
www.lufa-lib.org |
||||
*/ |
||||
|
||||
/*
|
||||
Copyright 2011 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 OTG definitions for the UC3B microcontrollers. |
||||
* \copydetails Group_OTG_UC3B |
||||
* |
||||
* \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_OTG
|
||||
* \defgroup Group_OTG_UC3B USB On The Go (OTG) Management (UC3B) |
||||
* \brief USB OTG definitions for the UC3B microcontrollers. |
||||
* |
||||
* Architecture specific USB OTG definitions for the Atmel 32-bit AVR UC3B microcontrollers. |
||||
* |
||||
* @{ |
||||
*/ |
||||
|
||||
#ifndef __USBOTG_UC3B_H__ |
||||
#define __USBOTG_UC3B_H__ |
||||
|
||||
/* Includes: */ |
||||
#include "../../../../Common/Common.h" |
||||
|
||||
/* Preprocessor Checks: */ |
||||
#if !defined(__INCLUDE_FROM_USB_DRIVER) |
||||
#error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. |
||||
#endif |
||||
|
||||
/* Public Interface - May be used in end-application: */ |
||||
/* Macros: */ |
||||
/** Mask for the VBUS pulsing method of SRP, supported by some OTG devices.
|
||||
* |
||||
* \see \ref USB_OTG_Device_InitiateSRP(). |
||||
*/ |
||||
#define USB_OTG_SRP_VBUS (1 << SRPSEL) |
||||
|
||||
/** Mask for the Data + pulsing method of SRP, supported by some OTG devices.
|
||||
* |
||||
* \see \ref USB_OTG_Device_InitiateSRP(). |
||||
*/ |
||||
#define USB_OTG_STP_DATA 0 |
||||
|
||||
/* Inline Functions: */ |
||||
/** Initiate a Host Negotiation Protocol request. This indicates to the other connected device
|
||||
* that the device wishes to change device/host roles. |
||||
*/ |
||||
static inline void USB_OTG_Device_RequestHNP(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_OTG_Device_RequestHNP(void) |
||||
{ |
||||
OTGCON |= (1 << HNPREQ); |
||||
} |
||||
|
||||
/** Cancel a Host Negotiation Protocol request. This stops a pending HNP request to the other
|
||||
* connected device. |
||||
*/ |
||||
static inline void USB_OTG_Device_CancelHNPRequest(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_OTG_Device_CancelHNPRequest(void) |
||||
{ |
||||
OTGCON &= ~(1 << HNPREQ); |
||||
} |
||||
|
||||
/** Determines if the device is currently sending a HNP to an attached host.
|
||||
* |
||||
* \return Boolean \c true if currently sending a HNP to the other connected device, \c false otherwise |
||||
*/ |
||||
static inline bool USB_OTG_Device_IsSendingHNP(void) ATTR_ALWAYS_INLINE; |
||||
static inline bool USB_OTG_Device_IsSendingHNP(void) |
||||
{ |
||||
return ((OTGCON & (1 << HNPREQ)) ? true : false); |
||||
} |
||||
|
||||
/** Initiates a Session Request Protocol request. Most OTG devices turn off VBUS when the USB
|
||||
* interface is not in use, to conserve power. Sending a SRP to a USB OTG device running in |
||||
* host mode indicates that VBUS should be applied and a session started. |
||||
* |
||||
* There are two different methods of sending a SRP - either pulses on the VBUS line, or by |
||||
* pulsing the Data + line via the internal pull-up resistor. |
||||
* |
||||
* \param[in] SRPTypeMask Mask indicating the type of SRP to use, either \ref USB_OTG_SRP_VBUS or |
||||
* \ref USB_OTG_STP_DATA. |
||||
*/ |
||||
static inline void USB_OTG_Device_InitiateSRP(const uint8_t SRPTypeMask) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_OTG_Device_InitiateSRP(const uint8_t SRPTypeMask) |
||||
{ |
||||
OTGCON = ((OTGCON & ~(1 << SRPSEL)) | (SRPTypeMask | (1 << SRPREQ))); |
||||
} |
||||
|
||||
/** Accepts a HNP from a connected device, indicating that both devices should exchange
|
||||
* device/host roles. |
||||
*/ |
||||
static inline void USB_OTG_Host_AcceptHNP(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_OTG_Host_AcceptHNP(void) |
||||
{ |
||||
OTGCON |= (1 << HNPREQ); |
||||
} |
||||
|
||||
/** Rejects a HNP from a connected device, indicating that both devices should remain in their
|
||||
* current device/host roles. |
||||
*/ |
||||
static inline void USB_OTG_Host_RejectHNP(void) ATTR_ALWAYS_INLINE; |
||||
static inline void USB_OTG_Host_RejectHNP(void) |
||||
{ |
||||
OTGCON &= ~(1 << HNPREQ); |
||||
} |
||||
|
||||
/** Indicates if the connected device is not currently sending a HNP request.
|
||||
* |
||||
* \return Boolean \c true if a HNP is currently being issued by the connected device, \c false otherwise. |
||||
*/ |
||||
static inline bool USB_OTG_Host_IsHNPReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool USB_OTG_Host_IsHNPReceived(void) |
||||
{ |
||||
return ((OTGCON & (1 << HNPREQ)) ? true : false); |
||||
} |
||||
|
||||
#endif |
||||
|
||||
/** @} */ |
||||
|
@ -0,0 +1,193 @@ |
||||
/*
|
||||
LUFA Library |
||||
Copyright (C) Dean Camera, 2011. |
||||
|
||||
dean [at] fourwalledcubicle [dot] com |
||||
www.lufa-lib.org |
||||
*/ |
||||
|
||||
/*
|
||||
Copyright 2011 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. |
||||
*/ |
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER |
||||
#include "../USBMode.h" |
||||
|
||||
#if defined(USB_CAN_BE_HOST) |
||||
|
||||
#include "Pipe.h" |
||||
|
||||
uint8_t USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE; |
||||
|
||||
bool Pipe_ConfigurePipe(const uint8_t Number, |
||||
const uint8_t Type, |
||||
const uint8_t Token, |
||||
const uint8_t EndpointNumber, |
||||
const uint16_t Size, |
||||
const uint8_t Banks) |
||||
{ |
||||
#if defined(ORDERED_EP_CONFIG) |
||||
Pipe_SelectPipe(Number); |
||||
Pipe_EnablePipe(); |
||||
|
||||
UPCFG1X = 0; |
||||
|
||||
UPCFG0X = ((Type << EPTYPE0) | Token | ((EndpointNumber & PIPE_EPNUM_MASK) << PEPNUM0)); |
||||
UPCFG1X = ((1 << ALLOC) | Banks | Pipe_BytesToEPSizeMask(Size)); |
||||
|
||||
Pipe_SetInfiniteINRequests(); |
||||
|
||||
return Pipe_IsConfigured(); |
||||
#else |
||||
for (uint8_t PNum = Number; PNum < PIPE_TOTAL_PIPES; PNum++) |
||||
{ |
||||
uint8_t UPCFG0XTemp; |
||||
uint8_t UPCFG1XTemp; |
||||
uint8_t UPCFG2XTemp; |
||||
uint8_t UPCONXTemp; |
||||
uint8_t UPINRQXTemp; |
||||
uint8_t UPIENXTemp; |
||||
|
||||
Pipe_SelectPipe(PNum); |
||||
|
||||
if (PNum == Number) |
||||
{ |
||||
UPCFG0XTemp = ((Type << EPTYPE0) | Token | ((EndpointNumber & PIPE_EPNUM_MASK) << PEPNUM0)); |
||||
UPCFG1XTemp = ((1 << ALLOC) | Banks | Pipe_BytesToEPSizeMask(Size)); |
||||
UPCFG2XTemp = 0; |
||||
UPCONXTemp = ((1 << PEN) | (1 << INMODE)); |
||||
UPINRQXTemp = 0; |
||||
UPIENXTemp = 0; |
||||
} |
||||
else |
||||
{ |
||||
UPCFG0XTemp = UPCFG0X; |
||||
UPCFG1XTemp = UPCFG1X; |
||||
UPCFG2XTemp = UPCFG2X; |
||||
UPCONXTemp = UPCONX; |
||||
UPINRQXTemp = UPINRQX; |
||||
UPIENXTemp = UPIENX; |
||||
} |
||||
|
||||
if (!(UPCFG1XTemp & (1 << ALLOC))) |
||||
continue; |
||||
|
||||
Pipe_DisablePipe(); |
||||
UPCFG1X &= (1 << ALLOC); |
||||
|
||||
Pipe_EnablePipe(); |
||||
UPCFG0X = UPCFG0XTemp; |
||||
UPCFG1X = UPCFG1XTemp; |
||||
UPCFG2X = UPCFG2XTemp; |
||||
UPCONX = UPCONXTemp; |
||||
UPINRQX = UPINRQXTemp; |
||||
UPIENX = UPIENXTemp; |
||||
|
||||
if (!(Pipe_IsConfigured())) |
||||
return false;
|
||||
} |
||||
|
||||
Pipe_SelectPipe(Number);
|
||||
return true; |
||||
#endif |
||||
} |
||||
|
||||
void Pipe_ClearPipes(void) |
||||
{ |
||||
UPINT = 0; |
||||
|
||||
for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++) |
||||
{ |
||||
Pipe_SelectPipe(PNum); |
||||
UPIENX = 0; |
||||
UPINTX = 0; |
||||
UPCFG1X = 0; |
||||
Pipe_DisablePipe(); |
||||
} |
||||
} |
||||
|
||||
bool Pipe_IsEndpointBound(const uint8_t EndpointAddress) |
||||
{ |
||||
uint8_t PrevPipeNumber = Pipe_GetCurrentPipe(); |
||||
|
||||
for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++) |
||||
{ |
||||
Pipe_SelectPipe(PNum); |
||||
|
||||
if (!(Pipe_IsConfigured())) |
||||
continue; |
||||
|
||||
uint8_t PipeToken = Pipe_GetPipeToken(); |
||||
bool PipeTokenCorrect = true; |
||||
|
||||
if (PipeToken != PIPE_TOKEN_SETUP) |
||||
PipeTokenCorrect = (PipeToken == ((EndpointAddress & PIPE_EPDIR_MASK) ? PIPE_TOKEN_IN : PIPE_TOKEN_OUT)); |
||||
|
||||
if (PipeTokenCorrect && (Pipe_BoundEndpointNumber() == (EndpointAddress & PIPE_EPNUM_MASK))) |
||||
return true; |
||||
} |
||||
|
||||
Pipe_SelectPipe(PrevPipeNumber); |
||||
return false; |
||||
} |
||||
|
||||
uint8_t Pipe_WaitUntilReady(void) |
||||
{ |
||||
#if (USB_STREAM_TIMEOUT_MS < 0xFF) |
||||
uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; |
||||
#else |
||||
uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; |
||||
#endif |
||||
|
||||
uint16_t PreviousFrameNumber = USB_Host_GetFrameNumber(); |
||||
|
||||
for (;;) |
||||
{ |
||||
if (Pipe_GetPipeToken() == PIPE_TOKEN_IN) |
||||
{ |
||||
if (Pipe_IsINReceived()) |
||||
return PIPE_READYWAIT_NoError; |
||||
} |
||||
else |
||||
{ |
||||
if (Pipe_IsOUTReady()) |
||||
return PIPE_READYWAIT_NoError; |
||||
} |
||||
|
||||
if (Pipe_IsStalled()) |
||||
return PIPE_READYWAIT_PipeStalled; |
||||
else if (USB_HostState == HOST_STATE_Unattached) |
||||
return PIPE_READYWAIT_DeviceDisconnected; |
||||
|
||||
uint16_t CurrentFrameNumber = USB_Host_GetFrameNumber(); |
||||
|
||||
if (CurrentFrameNumber != PreviousFrameNumber) |
||||
{ |
||||
PreviousFrameNumber = CurrentFrameNumber; |
||||
|
||||
if (!(TimeoutMSRem--)) |
||||
return PIPE_READYWAIT_Timeout; |
||||
} |
||||
} |
||||
} |
||||
|
||||
#endif |
||||
|
@ -0,0 +1,943 @@ |
||||
/*
|
||||
LUFA Library |
||||
Copyright (C) Dean Camera, 2011. |
||||
|
||||
dean [at] fourwalledcubicle [dot] com |
||||
www.lufa-lib.org |
||||
*/ |
||||
|
||||
/*
|
||||
Copyright 2011 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 Pipe definitions for the UC3B microcontrollers. |
||||
* \copydetails Group_PipeManagement_UC3B |
||||
* |
||||
* \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_PipeRW
|
||||
* \defgroup Group_PipeRW_UC3B Pipe Data Reading and Writing (UC3B) |
||||
* \brief Pipe data read/write definitions for the Atmel AVR32 UC3B architecture. |
||||
* |
||||
* Functions, macros, variables, enums and types related to data reading and writing from and to pipes. |
||||
*/ |
||||
|
||||
/** \ingroup Group_PipePrimitiveRW
|
||||
* \defgroup Group_PipePrimitiveRW_UC3B Read/Write of Primitive Data Types (UC3B) |
||||
* \brief Pipe primative data read/write definitions for the Atmel AVR32 UC3B architecture. |
||||
* |
||||
* Functions, macros, variables, enums and types related to data reading and writing of primitive data types |
||||
* from and to pipes. |
||||
*/ |
||||
|
||||
/** \ingroup Group_PipePacketManagement
|
||||
* \defgroup Group_PipePacketManagement_UC3B Pipe Packet Management (UC3B) |
||||
* \brief Pipe packet management definitions for the Atmel AVR32 UC3B architecture. |
||||
* |
||||
* Functions, macros, variables, enums and types related to packet management of pipes. |
||||
*/ |
||||
|
||||
/** \ingroup Group_PipeControlReq
|
||||
* \defgroup Group_PipeControlReq_UC3B Pipe Control Request Management (UC3B) |
||||
* \brief Pipe control request management definitions for the Atmel AVR32 UC3B architecture. |
||||
* |
||||
* Module for host mode request processing. This module allows for the transmission of standard, class and |
||||
* vendor control requests to the default control endpoint of an attached device while in host mode. |
||||
* |
||||
* \see Chapter 9 of the USB 2.0 specification. |
||||
*/ |
||||
|
||||
/** \ingroup Group_PipeManagement
|
||||
* \defgroup Group_PipeManagement_UC3B Pipe Management (UC3B) |
||||
* \brief Pipe management definitions for the Atmel AVR32 UC3B architecture. |
||||
* |
||||
* This module contains functions, macros and enums related to pipe management when in USB Host mode. This |
||||
* module contains the pipe management macros, as well as pipe interrupt and data send/receive functions |
||||
* for various data types. |
||||
* |
||||
* @{ |
||||
*/ |
||||
|
||||
#ifndef __PIPE_UC3B_H__ |
||||
#define __PIPE_UC3B_H__ |
||||
|
||||
/* Includes: */ |
||||
#include "../../../../Common/Common.h" |
||||
#include "../USBTask.h" |
||||
|
||||
/* Enable C linkage for C++ Compilers: */ |
||||
#if defined(__cplusplus) |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* Preprocessor Checks: */ |
||||
#if !defined(__INCLUDE_FROM_USB_DRIVER) |
||||
#error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. |
||||
#endif |
||||
|
||||
/* Public Interface - May be used in end-application: */ |
||||
/* Macros: */ |
||||
/** \name Pipe Error Flag Masks */ |
||||
//@{
|
||||
/** Mask for \ref Pipe_GetErrorFlags(), indicating that an overflow error occurred in the pipe on the received data. */ |
||||
#define PIPE_ERRORFLAG_OVERFLOW (1 << 6) |
||||
|
||||
/** Mask for \ref Pipe_GetErrorFlags(), indicating that an underflow error occurred in the pipe on the received data. */ |
||||
#define PIPE_ERRORFLAG_UNDERFLOW (1 << 5) |
||||
|
||||
/** Mask for \ref Pipe_GetErrorFlags(), indicating that a CRC error occurred in the pipe on the received data. */ |
||||
#define PIPE_ERRORFLAG_CRC16 (1 << 4) |
||||
|
||||
/** Mask for \ref Pipe_GetErrorFlags(), indicating that a hardware timeout error occurred in the pipe. */ |
||||
#define PIPE_ERRORFLAG_TIMEOUT (1 << 3) |
||||
|
||||
/** Mask for \ref Pipe_GetErrorFlags(), indicating that a hardware PID error occurred in the pipe. */ |
||||
#define PIPE_ERRORFLAG_PID (1 << 2) |
||||
|
||||
/** Mask for \ref Pipe_GetErrorFlags(), indicating that a hardware data PID error occurred in the pipe. */ |
||||
#define PIPE_ERRORFLAG_DATAPID (1 << 1) |
||||
|
||||
/** Mask for \ref Pipe_GetErrorFlags(), indicating that a hardware data toggle error occurred in the pipe. */ |
||||
#define PIPE_ERRORFLAG_DATATGL (1 << 0) |
||||
//@}
|
||||
|
||||
/** \name Pipe Token Masks */ |
||||
//@{
|
||||
/** Token mask for \ref Pipe_ConfigurePipe(). This sets the pipe as a SETUP token (for CONTROL type pipes),
|
||||
* which will trigger a control request on the attached device when data is written to the pipe. |
||||
*/ |
||||
#define PIPE_TOKEN_SETUP (0 << PTOKEN0) |
||||
|
||||
/** Token mask for \ref Pipe_ConfigurePipe(). This sets the pipe as a IN token (for non-CONTROL type pipes),
|
||||
* indicating that the pipe data will flow from device to host. |
||||
*/ |
||||
#define PIPE_TOKEN_IN (1 << PTOKEN0) |
||||
|
||||
/** Token mask for \ref Pipe_ConfigurePipe(). This sets the pipe as a OUT token (for non-CONTROL type pipes),
|
||||
* indicating that the pipe data will flow from host to device. |
||||
*/ |
||||
#define PIPE_TOKEN_OUT (2 << PTOKEN0) |
||||
//@}
|
||||
|
||||
/** \name Pipe Bank Mode Masks */ |
||||
//@{
|
||||
/** Mask for the bank mode selection for the \ref Pipe_ConfigurePipe() macro. This indicates that the pipe
|
||||
* should have one single bank, which requires less USB FIFO memory but results in slower transfers as |
||||
* only one USB device (the AVR or the attached device) can access the pipe's bank at the one time. |
||||
*/ |
||||
#define PIPE_BANK_SINGLE (0 << EPBK0) |
||||
|
||||
/** Mask for the bank mode selection for the \ref Pipe_ConfigurePipe() macro. This indicates that the pipe
|
||||
* should have two banks, which requires more USB FIFO memory but results in faster transfers as one |
||||
* USB device (the AVR or the attached device) can access one bank while the other accesses the second |
||||
* bank. |
||||
*/ |
||||
#define PIPE_BANK_DOUBLE (1 << EPBK0) |
||||
//@}
|
||||
|
||||
/** Pipe address for the default control pipe, which always resides in address 0. This is
|
||||
* defined for convenience to give more readable code when used with the pipe macros. |
||||
*/ |
||||
#define PIPE_CONTROLPIPE 0 |
||||
|
||||
/** Default size of the default control pipe's bank, until altered by the Endpoint0Size value
|
||||
* in the device descriptor of the attached device. |
||||
*/ |
||||
#define PIPE_CONTROLPIPE_DEFAULT_SIZE 64 |
||||
|
||||
/** Pipe number mask, for masking against pipe addresses to retrieve the pipe's numerical address
|
||||
* in the device. |
||||
*/ |
||||
#define PIPE_PIPENUM_MASK 0x07 |
||||
|
||||
/** Total number of pipes (including the default control pipe at address 0) which may be used in
|
||||
* the device. Different USB AVR models support different amounts of pipes, this value reflects |
||||
* the maximum number of pipes for the currently selected AVR model. |
||||
*/ |
||||
#define PIPE_TOTAL_PIPES 7 |
||||
|
||||
/** Size in bytes of the largest pipe bank size possible in the device. Not all banks on each AVR
|
||||
* model supports the largest bank size possible on the device; different pipe numbers support |
||||
* different maximum bank sizes. This value reflects the largest possible bank of any pipe on the |
||||
* currently selected USB AVR model. |
||||
*/ |
||||
#define PIPE_MAX_SIZE 256 |
||||
|
||||
/** Endpoint number mask, for masking against endpoint addresses to retrieve the endpoint's
|
||||
* numerical address in the attached device. |
||||
*/ |
||||
#define PIPE_EPNUM_MASK 0x0F |
||||
|
||||
/** Endpoint direction mask, for masking against endpoint addresses to retrieve the endpoint's
|
||||
* direction for comparing with the \c ENDPOINT_DESCRIPTOR_DIR_* masks. |
||||
*/ |
||||
#define PIPE_EPDIR_MASK 0x80 |
||||
|
||||
/* Enums: */ |
||||
/** Enum for the possible error return codes of the \ref Pipe_WaitUntilReady() function.
|
||||
* |
||||
* \ingroup Group_PipeRW_AVR8 |
||||
*/ |
||||
enum Pipe_WaitUntilReady_ErrorCodes_t |
||||
{ |
||||
PIPE_READYWAIT_NoError = 0, /**< Pipe ready for next packet, no error. */ |
||||
PIPE_READYWAIT_PipeStalled = 1, /**< The device stalled the pipe while waiting. */ |
||||
PIPE_READYWAIT_DeviceDisconnected = 2, /**< Device was disconnected from the host while waiting. */ |
||||
PIPE_READYWAIT_Timeout = 3, /**< The device failed to accept or send the next packet
|
||||
* within the software timeout period set by the |
||||
* \ref USB_STREAM_TIMEOUT_MS macro. |
||||
*/ |
||||
}; |
||||
|
||||
/* Inline Functions: */ |
||||
/** Indicates the number of bytes currently stored in the current pipes's selected bank.
|
||||
* |
||||
* \note The return width of this function may differ, depending on the maximum pipe bank size |
||||
* of the selected AVR model. |
||||
* |
||||
* \ingroup Group_PipeRW_AVR8 |
||||
* |
||||
* \return Total number of bytes in the currently selected pipe's FIFO buffer. |
||||
*/ |
||||
static inline uint16_t Pipe_BytesInPipe(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline uint16_t Pipe_BytesInPipe(void) |
||||
{ |
||||
return UPBCX; |
||||
} |
||||
|
||||
/** Returns the pipe address of the currently selected pipe. This is typically used to save the
|
||||
* currently selected pipe number so that it can be restored after another pipe has been manipulated. |
||||
* |
||||
* \return Index of the currently selected pipe. |
||||
*/ |
||||
static inline uint8_t Pipe_GetCurrentPipe(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline uint8_t Pipe_GetCurrentPipe(void) |
||||
{ |
||||
return (UPNUM & PIPE_PIPENUM_MASK); |
||||
} |
||||
|
||||
/** Selects the given pipe number. Any pipe operations which do not require the pipe number to be
|
||||
* indicated will operate on the currently selected pipe. |
||||
* |
||||
* \param[in] PipeNumber Index of the pipe to select. |
||||
*/ |
||||
static inline void Pipe_SelectPipe(const uint8_t PipeNumber) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_SelectPipe(const uint8_t PipeNumber) |
||||
{ |
||||
UPNUM = PipeNumber; |
||||
} |
||||
|
||||
/** Resets the desired pipe, including the pipe banks and flags.
|
||||
* |
||||
* \param[in] PipeNumber Index of the pipe to reset. |
||||
*/ |
||||
static inline void Pipe_ResetPipe(const uint8_t PipeNumber) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_ResetPipe(const uint8_t PipeNumber) |
||||
{ |
||||
UPRST = (1 << PipeNumber); |
||||
UPRST = 0; |
||||
} |
||||
|
||||
/** Enables the currently selected pipe so that data can be sent and received through it to and from
|
||||
* an attached device. |
||||
* |
||||
* \pre The currently selected pipe must first be configured properly via \ref Pipe_ConfigurePipe(). |
||||
*/ |
||||
static inline void Pipe_EnablePipe(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_EnablePipe(void) |
||||
{ |
||||
UPCONX |= (1 << PEN); |
||||
} |
||||
|
||||
/** Disables the currently selected pipe so that data cannot be sent and received through it to and
|
||||
* from an attached device. |
||||
*/ |
||||
static inline void Pipe_DisablePipe(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_DisablePipe(void) |
||||
{ |
||||
UPCONX &= ~(1 << PEN); |
||||
} |
||||
|
||||
/** Determines if the currently selected pipe is enabled, but not necessarily configured.
|
||||
* |
||||
* \return Boolean \c true if the currently selected pipe is enabled, \c false otherwise. |
||||
*/ |
||||
static inline bool Pipe_IsEnabled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool Pipe_IsEnabled(void) |
||||
{ |
||||
return ((UPCONX & (1 << PEN)) ? true : false); |
||||
} |
||||
|
||||
/** Gets the current pipe token, indicating the pipe's data direction and type.
|
||||
* |
||||
* \return The current pipe token, as a \c PIPE_TOKEN_* mask. |
||||
*/ |
||||
static inline uint8_t Pipe_GetPipeToken(void) ATTR_ALWAYS_INLINE; |
||||
static inline uint8_t Pipe_GetPipeToken(void) |
||||
{ |
||||
return (UPCFG0X & (0x03 << PTOKEN0)); |
||||
} |
||||
|
||||
/** Sets the token for the currently selected pipe to one of the tokens specified by the \c PIPE_TOKEN_*
|
||||
* masks. This can be used on CONTROL type pipes, to allow for bidirectional transfer of data during |
||||
* control requests, or on regular pipes to allow for half-duplex bidirectional data transfer to devices |
||||
* which have two endpoints of opposite direction sharing the same endpoint address within the device. |
||||
* |
||||
* \param[in] Token New pipe token to set the selected pipe to, as a \c PIPE_TOKEN_* mask. |
||||
*/ |
||||
static inline void Pipe_SetPipeToken(const uint8_t Token) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_SetPipeToken(const uint8_t Token) |
||||
{ |
||||
UPCFG0X = ((UPCFG0X & ~(0x03 << PTOKEN0)) | Token); |
||||
} |
||||
|
||||
/** Configures the currently selected pipe to allow for an unlimited number of IN requests. */ |
||||
static inline void Pipe_SetInfiniteINRequests(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_SetInfiniteINRequests(void) |
||||
{ |
||||
UPCONX |= (1 << INMODE); |
||||
} |
||||
|
||||
/** Configures the currently selected pipe to only allow the specified number of IN requests to be
|
||||
* accepted by the pipe before it is automatically frozen. |
||||
* |
||||
* \param[in] TotalINRequests Total number of IN requests that the pipe may receive before freezing. |
||||
*/ |
||||
static inline void Pipe_SetFiniteINRequests(const uint8_t TotalINRequests) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_SetFiniteINRequests(const uint8_t TotalINRequests) |
||||
{ |
||||
UPCONX &= ~(1 << INMODE); |
||||
UPINRQX = TotalINRequests; |
||||
} |
||||
|
||||
/** Determines if the currently selected pipe is configured.
|
||||
* |
||||
* \return Boolean \c true if the selected pipe is configured, \c false otherwise. |
||||
*/ |
||||
static inline bool Pipe_IsConfigured(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool Pipe_IsConfigured(void) |
||||
{ |
||||
return ((UPSTAX & (1 << CFGOK)) ? true : false); |
||||
} |
||||
|
||||
/** Retrieves the endpoint number of the endpoint within the attached device that the currently selected
|
||||
* pipe is bound to. |
||||
* |
||||
* \return Endpoint number the currently selected pipe is bound to. |
||||
*/ |
||||
static inline uint8_t Pipe_BoundEndpointNumber(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline uint8_t Pipe_BoundEndpointNumber(void) |
||||
{ |
||||
return ((UPCFG0X >> PEPNUM0) & PIPE_EPNUM_MASK); |
||||
} |
||||
|
||||
/** Sets the period between interrupts for an INTERRUPT type pipe to a specified number of milliseconds.
|
||||
* |
||||
* \param[in] Milliseconds Number of milliseconds between each pipe poll. |
||||
*/ |
||||
static inline void Pipe_SetInterruptPeriod(const uint8_t Milliseconds) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_SetInterruptPeriod(const uint8_t Milliseconds) |
||||
{ |
||||
UPCFG2X = Milliseconds; |
||||
} |
||||
|
||||
/** Returns a mask indicating which pipe's interrupt periods have elapsed, indicating that the pipe should
|
||||
* be serviced. |
||||
* |
||||
* \return Mask whose bits indicate which pipes have interrupted. |
||||
*/ |
||||
static inline uint8_t Pipe_GetPipeInterrupts(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline uint8_t Pipe_GetPipeInterrupts(void) |
||||
{ |
||||
return UPINT; |
||||
} |
||||
|
||||
/** Determines if the specified pipe number has interrupted (valid only for INTERRUPT type
|
||||
* pipes). |
||||
* |
||||
* \param[in] PipeNumber Index of the pipe whose interrupt flag should be tested. |
||||
* |
||||
* \return Boolean \c true if the specified pipe has interrupted, \c false otherwise. |
||||
*/ |
||||
static inline bool Pipe_HasPipeInterrupted(const uint8_t PipeNumber) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool Pipe_HasPipeInterrupted(const uint8_t PipeNumber) |
||||
{ |
||||
return ((UPINT & (1 << PipeNumber)) ? true : false); |
||||
} |
||||
|
||||
/** Unfreezes the selected pipe, allowing it to communicate with an attached device. */ |
||||
static inline void Pipe_Unfreeze(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_Unfreeze(void) |
||||
{ |
||||
UPCONX &= ~(1 << PFREEZE); |
||||
} |
||||
|
||||
/** Freezes the selected pipe, preventing it from communicating with an attached device. */ |
||||
static inline void Pipe_Freeze(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_Freeze(void) |
||||
{ |
||||
UPCONX |= (1 << PFREEZE); |
||||
} |
||||
|
||||
/** Determines if the currently selected pipe is frozen, and not able to accept data.
|
||||
* |
||||
* \return Boolean \c true if the currently selected pipe is frozen, \c false otherwise. |
||||
*/ |
||||
static inline bool Pipe_IsFrozen(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool Pipe_IsFrozen(void) |
||||
{ |
||||
return ((UPCONX & (1 << PFREEZE)) ? true : false); |
||||
} |
||||
|
||||
/** Clears the master pipe error flag. */ |
||||
static inline void Pipe_ClearError(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_ClearError(void) |
||||
{ |
||||
UPINTX &= ~(1 << PERRI); |
||||
} |
||||
|
||||
/** Determines if the master pipe error flag is set for the currently selected pipe, indicating that
|
||||
* some sort of hardware error has occurred on the pipe. |
||||
* |
||||
* \see \ref Pipe_GetErrorFlags() macro for information on retrieving the exact error flag. |
||||
* |
||||
* \return Boolean \c true if an error has occurred on the selected pipe, \c false otherwise. |
||||
*/ |
||||
static inline bool Pipe_IsError(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool Pipe_IsError(void) |
||||
{ |
||||
return ((UPINTX & (1 << PERRI)) ? true : false); |
||||
} |
||||
|
||||
/** Clears all the currently selected pipe's hardware error flags, but does not clear the master error
|
||||
* flag for the pipe. |
||||
*/ |
||||
static inline void Pipe_ClearErrorFlags(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_ClearErrorFlags(void) |
||||
{ |
||||
UPERRX = 0; |
||||
} |
||||
|
||||
/** Gets a mask of the hardware error flags which have occurred on the currently selected pipe. This
|
||||
* value can then be masked against the \c PIPE_ERRORFLAG_* masks to determine what error has occurred. |
||||
* |
||||
* \return Mask comprising of \c PIPE_ERRORFLAG_* bits indicating what error has occurred on the selected pipe. |
||||
*/ |
||||
static inline uint8_t Pipe_GetErrorFlags(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline uint8_t Pipe_GetErrorFlags(void) |
||||
{ |
||||
return ((UPERRX & (PIPE_ERRORFLAG_CRC16 | PIPE_ERRORFLAG_TIMEOUT | |
||||
PIPE_ERRORFLAG_PID | PIPE_ERRORFLAG_DATAPID | |
||||
PIPE_ERRORFLAG_DATATGL)) | |
||||
(UPSTAX & (PIPE_ERRORFLAG_OVERFLOW | PIPE_ERRORFLAG_UNDERFLOW))); |
||||
} |
||||
|
||||
/** Retrieves the number of busy banks in the currently selected pipe, which have been queued for
|
||||
* transmission via the \ref Pipe_ClearOUT() command, or are awaiting acknowledgement via the |
||||
* \ref Pipe_ClearIN() command. |
||||
* |
||||
* \ingroup Group_PipePacketManagement_AVR8 |
||||
* |
||||
* \return Total number of busy banks in the selected pipe. |
||||
*/ |
||||
static inline uint8_t Pipe_GetBusyBanks(void) |
||||
{ |
||||
return (UPSTAX & (0x03 << NBUSYBK0)); |
||||
} |
||||
|
||||
/** Determines if the currently selected pipe may be read from (if data is waiting in the pipe
|
||||
* bank and the pipe is an IN direction, or if the bank is not yet full if the pipe is an OUT |
||||
* direction). This function will return false if an error has occurred in the pipe, or if the pipe |
||||
* is an IN direction and no packet (or an empty packet) has been received, or if the pipe is an OUT |
||||
* direction and the pipe bank is full. |
||||
* |
||||
* \note This function is not valid on CONTROL type pipes. |
||||
* |
||||
* \ingroup Group_PipePacketManagement_AVR8 |
||||
* |
||||
* \return Boolean \c true if the currently selected pipe may be read from or written to, depending |
||||
* on its direction. |
||||
*/ |
||||
static inline bool Pipe_IsReadWriteAllowed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool Pipe_IsReadWriteAllowed(void) |
||||
{ |
||||
return ((UPINTX & (1 << RWAL)) ? true : false); |
||||
} |
||||
|
||||
/** Determines if a packet has been received on the currently selected IN pipe from the attached device.
|
||||
* |
||||
* \ingroup Group_PipePacketManagement_AVR8 |
||||
* |
||||
* \return Boolean \c true if the current pipe has received an IN packet, \c false otherwise. |
||||
*/ |
||||
static inline bool Pipe_IsINReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool Pipe_IsINReceived(void) |
||||
{ |
||||
return ((UPINTX & (1 << RXINI)) ? true : false); |
||||
} |
||||
|
||||
/** Determines if the currently selected OUT pipe is ready to send an OUT packet to the attached device.
|
||||
* |
||||
* \ingroup Group_PipePacketManagement_AVR8 |
||||
* |
||||
* \return Boolean \c true if the current pipe is ready for an OUT packet, \c false otherwise. |
||||
*/ |
||||
static inline bool Pipe_IsOUTReady(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool Pipe_IsOUTReady(void) |
||||
{ |
||||
return ((UPINTX & (1 << TXOUTI)) ? true : false); |
||||
} |
||||
|
||||
/** Determines if no SETUP request is currently being sent to the attached device on the selected
|
||||
* CONTROL type pipe. |
||||
* |
||||
* \ingroup Group_PipePacketManagement_AVR8 |
||||
* |
||||
* \return Boolean \c true if the current pipe is ready for a SETUP packet, \c false otherwise. |
||||
*/ |
||||
static inline bool Pipe_IsSETUPSent(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool Pipe_IsSETUPSent(void) |
||||
{ |
||||
return ((UPINTX & (1 << TXSTPI)) ? true : false); |
||||
} |
||||
|
||||
/** Sends the currently selected CONTROL type pipe's contents to the device as a SETUP packet.
|
||||
* |
||||
* \ingroup Group_PipePacketManagement_AVR8 |
||||
*/ |
||||
static inline void Pipe_ClearSETUP(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_ClearSETUP(void) |
||||
{ |
||||
UPINTX &= ~((1 << TXSTPI) | (1 << FIFOCON)); |
||||
} |
||||
|
||||
/** Acknowledges the reception of a setup IN request from the attached device on the currently selected
|
||||
* pipe, freeing the bank ready for the next packet. |
||||
* |
||||
* \ingroup Group_PipePacketManagement_AVR8 |
||||
*/ |
||||
static inline void Pipe_ClearIN(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_ClearIN(void) |
||||
{ |
||||
UPINTX &= ~((1 << RXINI) | (1 << FIFOCON)); |
||||
} |
||||
|
||||
/** Sends the currently selected pipe's contents to the device as an OUT packet on the selected pipe, freeing
|
||||
* the bank ready for the next packet. |
||||
* |
||||
* \ingroup Group_PipePacketManagement_AVR8 |
||||
*/ |
||||
static inline void Pipe_ClearOUT(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_ClearOUT(void) |
||||
{ |
||||
UPINTX &= ~((1 << TXOUTI) | (1 << FIFOCON)); |
||||
} |
||||
|
||||
/** Determines if the device sent a NAK (Negative Acknowledge) in response to the last sent packet on
|
||||
* the currently selected pipe. This occurs when the host sends a packet to the device, but the device |
||||
* is not currently ready to handle the packet (i.e. its endpoint banks are full). Once a NAK has been |
||||
* received, it must be cleared using \ref Pipe_ClearNAKReceived() before the previous (or any other) packet |
||||
* can be re-sent. |
||||
* |
||||
* \ingroup Group_PipePacketManagement_AVR8 |
||||
* |
||||
* \return Boolean \c true if an NAK has been received on the current pipe, \c false otherwise. |
||||
*/ |
||||
static inline bool Pipe_IsNAKReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool Pipe_IsNAKReceived(void) |
||||
{ |
||||
return ((UPINTX & (1 << NAKEDI)) ? true : false); |
||||
} |
||||
|
||||
/** Clears the NAK condition on the currently selected pipe.
|
||||
* |
||||
* \ingroup Group_PipePacketManagement_AVR8 |
||||
* |
||||
* \see \ref Pipe_IsNAKReceived() for more details. |
||||
*/ |
||||
static inline void Pipe_ClearNAKReceived(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_ClearNAKReceived(void) |
||||
{ |
||||
UPINTX &= ~(1 << NAKEDI); |
||||
} |
||||
|
||||
/** Determines if the currently selected pipe has had the STALL condition set by the attached device.
|
||||
* |
||||
* \ingroup Group_PipePacketManagement_AVR8 |
||||
* |
||||
* \return Boolean \c true if the current pipe has been stalled by the attached device, \c false otherwise. |
||||
*/ |
||||
static inline bool Pipe_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline bool Pipe_IsStalled(void) |
||||
{ |
||||
return ((UPINTX & (1 << RXSTALLI)) ? true : false); |
||||
} |
||||
|
||||
/** Clears the STALL condition detection flag on the currently selected pipe, but does not clear the
|
||||
* STALL condition itself (this must be done via a ClearFeature control request to the device). |
||||
* |
||||
* \ingroup Group_PipePacketManagement_AVR8 |
||||
*/ |
||||
static inline void Pipe_ClearStall(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_ClearStall(void) |
||||
{ |
||||
UPINTX &= ~(1 << RXSTALLI); |
||||
} |
||||
|
||||
/** Reads one byte from the currently selected pipe's bank, for OUT direction pipes.
|
||||
* |
||||
* \ingroup Group_PipePrimitiveRW_AVR8 |
||||
* |
||||
* \return Next byte in the currently selected pipe's FIFO buffer. |
||||
*/ |
||||
static inline uint8_t Pipe_Read_Byte(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline uint8_t Pipe_Read_Byte(void) |
||||
{ |
||||
return UPDATX; |
||||
} |
||||
|
||||
/** Writes one byte from the currently selected pipe's bank, for IN direction pipes.
|
||||
* |
||||
* \ingroup Group_PipePrimitiveRW_AVR8 |
||||
* |
||||
* \param[in] Byte Next byte to write into the the currently selected pipe's FIFO buffer. |
||||
*/ |
||||
static inline void Pipe_Write_Byte(const uint8_t Byte) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_Write_Byte(const uint8_t Byte) |
||||
{ |
||||
UPDATX = Byte; |
||||
} |
||||
|
||||
/** Discards one byte from the currently selected pipe's bank, for OUT direction pipes.
|
||||
* |
||||
* \ingroup Group_PipePrimitiveRW_AVR8 |
||||
*/ |
||||
static inline void Pipe_Discard_Byte(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_Discard_Byte(void) |
||||
{ |
||||
uint8_t Dummy; |
||||
|
||||
Dummy = UPDATX; |
||||
} |
||||
|
||||
/** Reads two bytes from the currently selected pipe's bank in little endian format, for OUT
|
||||
* direction pipes. |
||||
* |
||||
* \ingroup Group_PipePrimitiveRW_AVR8 |
||||
* |
||||
* \return Next word in the currently selected pipe's FIFO buffer. |
||||
*/ |
||||
static inline uint16_t Pipe_Read_Word_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline uint16_t Pipe_Read_Word_LE(void) |
||||
{ |
||||
union |
||||
{ |
||||
uint16_t Word; |
||||
uint8_t Bytes[2]; |
||||
} Data; |
||||
|
||||
Data.Bytes[0] = UPDATX; |
||||
Data.Bytes[1] = UPDATX; |
||||
|
||||
return Data.Word; |
||||
} |
||||
|
||||
/** Reads two bytes from the currently selected pipe's bank in big endian format, for OUT
|
||||
* direction pipes. |
||||
* |
||||
* \ingroup Group_PipePrimitiveRW_AVR8 |
||||
* |
||||
* \return Next word in the currently selected pipe's FIFO buffer. |
||||
*/ |
||||
static inline uint16_t Pipe_Read_Word_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline uint16_t Pipe_Read_Word_BE(void) |
||||
{ |
||||
union |
||||
{ |
||||
uint16_t Word; |
||||
uint8_t Bytes[2]; |
||||
} Data; |
||||
|
||||
Data.Bytes[1] = UPDATX; |
||||
Data.Bytes[0] = UPDATX; |
||||
|
||||
return Data.Word; |
||||
} |
||||
|
||||
/** Writes two bytes to the currently selected pipe's bank in little endian format, for IN
|
||||
* direction pipes. |
||||
* |
||||
* \ingroup Group_PipePrimitiveRW_AVR8 |
||||
* |
||||
* \param[in] Word Next word to write to the currently selected pipe's FIFO buffer. |
||||
*/ |
||||
static inline void Pipe_Write_Word_LE(const uint16_t Word) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_Write_Word_LE(const uint16_t Word) |
||||
{ |
||||
UPDATX = (Word & 0xFF); |
||||
UPDATX = (Word >> 8); |
||||
} |
||||
|
||||
/** Writes two bytes to the currently selected pipe's bank in big endian format, for IN
|
||||
* direction pipes. |
||||
* |
||||
* \ingroup Group_PipePrimitiveRW_AVR8 |
||||
* |
||||
* \param[in] Word Next word to write to the currently selected pipe's FIFO buffer. |
||||
*/ |
||||
static inline void Pipe_Write_Word_BE(const uint16_t Word) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_Write_Word_BE(const uint16_t Word) |
||||
{ |
||||
UPDATX = (Word >> 8); |
||||
UPDATX = (Word & 0xFF); |
||||
} |
||||
|
||||
/** Discards two bytes from the currently selected pipe's bank, for OUT direction pipes.
|
||||
* |
||||
* \ingroup Group_PipePrimitiveRW_AVR8 |
||||
*/ |
||||
static inline void Pipe_Discard_Word(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_Discard_Word(void) |
||||
{ |
||||
uint8_t Dummy; |
||||
|
||||
Dummy = UPDATX; |
||||
Dummy = UPDATX; |
||||
} |
||||
|
||||
/** Reads four bytes from the currently selected pipe's bank in little endian format, for OUT
|
||||
* direction pipes. |
||||
* |
||||
* \ingroup Group_PipePrimitiveRW_AVR8 |
||||
* |
||||
* \return Next double word in the currently selected pipe's FIFO buffer. |
||||
*/ |
||||
static inline uint32_t Pipe_Read_DWord_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline uint32_t Pipe_Read_DWord_LE(void) |
||||
{ |
||||
union |
||||
{ |
||||
uint32_t DWord; |
||||
uint8_t Bytes[4]; |
||||
} Data; |
||||
|
||||
Data.Bytes[0] = UPDATX; |
||||
Data.Bytes[1] = UPDATX; |
||||
Data.Bytes[2] = UPDATX; |
||||
Data.Bytes[3] = UPDATX; |
||||
|
||||
return Data.DWord; |
||||
} |
||||
|
||||
/** Reads four bytes from the currently selected pipe's bank in big endian format, for OUT
|
||||
* direction pipes. |
||||
* |
||||
* \ingroup Group_PipePrimitiveRW_AVR8 |
||||
* |
||||
* \return Next double word in the currently selected pipe's FIFO buffer. |
||||
*/ |
||||
static inline uint32_t Pipe_Read_DWord_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; |
||||
static inline uint32_t Pipe_Read_DWord_BE(void) |
||||
{ |
||||
union |
||||
{ |
||||
uint32_t DWord; |
||||
uint8_t Bytes[4]; |
||||
} Data; |
||||
|
||||
Data.Bytes[3] = UPDATX; |
||||
Data.Bytes[2] = UPDATX; |
||||
Data.Bytes[1] = UPDATX; |
||||
Data.Bytes[0] = UPDATX; |
||||
|
||||
return Data.DWord; |
||||
} |
||||
|
||||
/** Writes four bytes to the currently selected pipe's bank in little endian format, for IN
|
||||
* direction pipes. |
||||
* |
||||
* \ingroup Group_PipePrimitiveRW_AVR8 |
||||
* |
||||
* \param[in] DWord Next double word to write to the currently selected pipe's FIFO buffer. |
||||
*/ |
||||
static inline void Pipe_Write_DWord_LE(const uint32_t DWord) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_Write_DWord_LE(const uint32_t DWord) |
||||
{ |
||||
UPDATX = (DWord & 0xFF); |
||||
UPDATX = (DWord >> 8); |
||||
UPDATX = (DWord >> 16); |
||||
UPDATX = (DWord >> 24); |
||||
} |
||||
|
||||
/** Writes four bytes to the currently selected pipe's bank in big endian format, for IN
|
||||
* direction pipes. |
||||
* |
||||
* \ingroup Group_PipePrimitiveRW_AVR8 |
||||
* |
||||
* \param[in] DWord Next double word to write to the currently selected pipe's FIFO buffer. |
||||
*/ |
||||
static inline void Pipe_Write_DWord_BE(const uint32_t DWord) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_Write_DWord_BE(const uint32_t DWord) |
||||
{ |
||||
UPDATX = (DWord >> 24); |
||||
UPDATX = (DWord >> 16); |
||||
UPDATX = (DWord >> 8); |
||||
UPDATX = (DWord & 0xFF); |
||||
} |
||||
|
||||
/** Discards four bytes from the currently selected pipe's bank, for OUT direction pipes.
|
||||
* |
||||
* \ingroup Group_PipePrimitiveRW_AVR8 |
||||
*/ |
||||
static inline void Pipe_Discard_DWord(void) ATTR_ALWAYS_INLINE; |
||||
static inline void Pipe_Discard_DWord(void) |
||||
{ |
||||
uint8_t Dummy; |
||||
|
||||
Dummy = UPDATX; |
||||
Dummy = UPDATX; |
||||
Dummy = UPDATX; |
||||
Dummy = UPDATX; |
||||
} |
||||
|
||||
/* External Variables: */ |
||||
/** Global indicating the maximum packet size of the default control pipe located at address
|
||||
* 0 in the device. This value is set to the value indicated in the attached device's device |
||||
* descriptor once the USB interface is initialized into host mode and a device is attached |
||||
* to the USB bus. |
||||
* |
||||
* \note This variable should be treated as read-only in the user application, and never manually |
||||
* changed in value. |
||||
*/ |
||||
extern uint8_t USB_ControlPipeSize; |
||||
|
||||
/* Function Prototypes: */ |
||||
/** Configures the specified pipe number with the given pipe type, token, target endpoint number in the
|
||||
* attached device, bank size and banking mode. |
||||
* |
||||
* A newly configured pipe is frozen by default, and must be unfrozen before use via the \ref Pipe_Unfreeze() |
||||
* before being used. Pipes should be kept frozen unless waiting for data from a device while in IN mode, or |
||||
* sending data to the device in OUT mode. IN type pipes are also automatically configured to accept infinite |
||||
* numbers of IN requests without automatic freezing - this can be overridden by a call to |
||||
* \ref Pipe_SetFiniteINRequests(). |
||||
* |
||||
* \param[in] Number Pipe number to configure. This must be more than 0 and less than \ref PIPE_TOTAL_PIPES. |
||||
* |
||||
* \param[in] Type Type of pipe to configure, an \c EP_TYPE_* mask. Not all pipe types are available on Low |
||||
* Speed USB devices - refer to the USB 2.0 specification. |
||||
* |
||||
* \param[in] Token Pipe data token, either \ref PIPE_TOKEN_SETUP, \ref PIPE_TOKEN_OUT or \ref PIPE_TOKEN_IN. |
||||
* All pipes (except Control type) are unidirectional - data may only be read from or |
||||
* written to the pipe bank based on its direction, not both. |
||||
* |
||||
* \param[in] EndpointNumber Endpoint index within the attached device that the pipe should interface to. |
||||
* |
||||
* \param[in] Size Size of the pipe's bank, where packets are stored before they are transmitted to |
||||
* the USB device, or after they have been received from the USB device (depending on |
||||
* the pipe's data direction). The bank size must indicate the maximum packet size that |
||||
* the pipe can handle. |
||||
* |
||||
* \param[in] Banks Number of banks to use for the pipe being configured, a \c PIPE_BANK_* mask. More banks |
||||
* uses more USB DPRAM, but offers better performance. Isochronous type pipes <b>must</b> |
||||
* have at least two banks. |
||||
* |
||||
* \note When the \c ORDERED_EP_CONFIG compile time option is used, Pipes <b>must</b> be configured in ascending order, |
||||
* or bank corruption will occur. |
||||
* \n\n |
||||
* |
||||
* \note Certain models of USB AVR's pipes may have different maximum packet sizes based on the pipe's |
||||
* index - refer to the chosen USB AVR's datasheet to determine the maximum bank size for each pipe. |
||||
* \n\n |
||||
* |
||||
* \note The default control pipe should not be manually configured by the user application, as it is |
||||
* automatically configured by the library internally. |
||||
* \n\n |
||||
* |
||||
* \note This routine will automatically select the specified pipe upon success. Upon failure, the pipe which |
||||
* failed to reconfigure correctly will be selected. |
||||
* |
||||
* \return Boolean \c true if the configuration succeeded, \c false otherwise. |
||||
*/ |
||||
bool Pipe_ConfigurePipe(const uint8_t Number, |
||||
const uint8_t Type, |
||||
const uint8_t Token, |
||||
const uint8_t EndpointNumber, |
||||
const uint16_t Size, |
||||
const uint8_t Banks); |
||||
|
||||
/** Spin-loops until the currently selected non-control pipe is ready for the next packed of data to be read
|
||||
* or written to it, aborting in the case of an error condition (such as a timeout or device disconnect). |
||||
* |
||||
* \ingroup Group_PipeRW_AVR8 |
||||
* |
||||
* \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. |
||||
*/ |
||||
uint8_t Pipe_WaitUntilReady(void); |
||||
|
||||
/** Determines if a pipe has been bound to the given device endpoint address. If a pipe which is bound to the given
|
||||
* endpoint is found, it is automatically selected. |
||||
* |
||||
* \param[in] EndpointAddress Address and direction mask of the endpoint within the attached device to check. |
||||
* |
||||
* \return Boolean \c true if a pipe bound to the given endpoint address of the specified direction is found, |
||||
* \c false otherwise. |
||||
*/ |
||||
bool Pipe_IsEndpointBound(const uint8_t EndpointAddress); |
||||
|
||||
/* Private Interface - For use in library only: */ |
||||
#if !defined(__DOXYGEN__) |
||||
/* Macros: */ |
||||
#if !defined(ENDPOINT_CONTROLEP) |
||||
#define ENDPOINT_CONTROLEP 0 |
||||
#endif |
||||
|
||||
/* Inline Functions: */ |
||||
static inline uint8_t Pipe_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST ATTR_ALWAYS_INLINE; |
||||
static inline uint8_t Pipe_BytesToEPSizeMask(const uint16_t Bytes) |
||||
{ |
||||
uint8_t MaskVal = 0; |
||||
uint16_t CheckBytes = 8; |
||||
|
||||
while ((CheckBytes < Bytes) && (CheckBytes < PIPE_MAX_SIZE)) |
||||
{ |
||||
MaskVal++; |
||||
CheckBytes <<= 1; |
||||
} |
||||
|
||||
return (MaskVal << EPSIZE0); |
||||
} |
||||
|
||||
/* Function Prototypes: */ |
||||
void Pipe_ClearPipes(void); |
||||
#endif |
||||
|
||||
/* Disable C linkage for C++ Compilers: */ |
||||
#if defined(__cplusplus) |
||||
} |
||||
#endif |
||||
|
||||
#endif |
||||
|
||||
/** @} */ |
||||
|
@ -0,0 +1,233 @@ |
||||
/*
|
||||
LUFA Library |
||||
Copyright (C) Dean Camera, 2011. |
||||
|
||||
dean [at] fourwalledcubicle [dot] com |
||||
www.lufa-lib.org |
||||
*/ |
||||
|
||||
/*
|
||||
Copyright 2011 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. |
||||
*/ |
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER |
||||
#define __INCLUDE_FROM_USB_CONTROLLER_C |
||||
#include "USBController.h" |
||||
|
||||
#if (!defined(USB_HOST_ONLY) && !defined(USB_DEVICE_ONLY)) |
||||
volatile uint8_t USB_CurrentMode = USB_MODE_None; |
||||
#endif |
||||
|
||||
#if !defined(USE_STATIC_OPTIONS) |
||||
volatile uint8_t USB_Options; |
||||
#endif |
||||
|
||||
void USB_Init( |
||||
#if defined(USB_CAN_BE_BOTH) |
||||
const uint8_t Mode |
||||
#endif |
||||
|
||||
#if (defined(USB_CAN_BE_BOTH) && !defined(USE_STATIC_OPTIONS)) |
||||
, |
||||
#elif (!defined(USB_CAN_BE_BOTH) && defined(USE_STATIC_OPTIONS)) |
||||
void |
||||
#endif |
||||
|
||||
#if !defined(USE_STATIC_OPTIONS) |
||||
const uint8_t Options |
||||
#endif |
||||
) |
||||
{ |
||||
#if !defined(USE_STATIC_OPTIONS) |
||||
USB_Options = Options; |
||||
#endif |
||||
|
||||
if (!(USB_Options & USB_OPT_REG_DISABLED)) |
||||
USB_REG_On(); |
||||
else |
||||
USB_REG_Off(); |
||||
|
||||
#if defined(USB_CAN_BE_BOTH) |
||||
if (Mode == USB_MODE_UID) |
||||
{ |
||||
UHWCON |= (1 << UIDE); |
||||
USB_INT_Enable(USB_INT_IDTI); |
||||
USB_CurrentMode = USB_GetUSBModeFromUID(); |
||||
} |
||||
else |
||||
{ |
||||
USB_CurrentMode = Mode; |
||||
} |
||||
#endif |
||||
|
||||
USB_IsInitialized = true; |
||||
|
||||
USB_ResetInterface(); |
||||
} |
||||
|
||||
void USB_Disable(void) |
||||
{ |
||||
USB_INT_DisableAllInterrupts(); |
||||
USB_INT_ClearAllInterrupts(); |
||||
|
||||
USB_Detach(); |
||||
USB_Controller_Disable(); |
||||
|
||||
if (!(USB_Options & USB_OPT_MANUAL_PLL)) |
||||
USB_PLL_Off(); |
||||
|
||||
USB_REG_Off(); |
||||
|
||||
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) |
||||
USB_OTGPAD_Off(); |
||||
#endif |
||||
|
||||
#if defined(USB_CAN_BE_BOTH) |
||||
USB_CurrentMode = USB_MODE_None; |
||||
#endif |
||||
|
||||
USB_IsInitialized = false; |
||||
} |
||||
|
||||
void USB_ResetInterface(void) |
||||
{ |
||||
#if defined(USB_CAN_BE_BOTH) |
||||
bool UIDModeSelectEnabled = ((UHWCON & (1 << UIDE)) != 0); |
||||
#endif |
||||
|
||||
USB_INT_DisableAllInterrupts(); |
||||
USB_INT_ClearAllInterrupts(); |
||||
|
||||
USB_Controller_Reset(); |
||||
|
||||
if (!(USB_Options & USB_OPT_MANUAL_PLL)) |
||||
{ |
||||
#if defined(USB_SERIES_4_AVR) |
||||
PLLFRQ = ((1 << PLLUSB) | (1 << PDIV3) | (1 << PDIV1)); |
||||
#endif |
||||
|
||||
USB_PLL_On(); |
||||
while (!(USB_PLL_IsReady())); |
||||
} |
||||
|
||||
#if defined(USB_CAN_BE_BOTH) |
||||
if (UIDModeSelectEnabled) |
||||
{ |
||||
UHWCON |= (1 << UIDE); |
||||
USB_INT_Enable(USB_INT_IDTI); |
||||
} |
||||
#endif |
||||
|
||||
USB_CLK_Unfreeze(); |
||||
|
||||
if (USB_CurrentMode == USB_MODE_Device) |
||||
{ |
||||
#if defined(USB_CAN_BE_DEVICE) |
||||
#if (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) |
||||
UHWCON |= (1 << UIMOD); |
||||
#endif |
||||
|
||||
USB_Init_Device(); |
||||
#endif |
||||
} |
||||
else if (USB_CurrentMode == USB_MODE_Host) |
||||
{ |
||||
#if defined(USB_CAN_BE_HOST) |
||||
UHWCON &= ~(1 << UIMOD); |
||||
|
||||
USB_Init_Host(); |
||||
#endif |
||||
} |
||||
|
||||
#if (defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) |
||||
USB_OTGPAD_On(); |
||||
#endif |
||||
} |
||||
|
||||
#if defined(USB_CAN_BE_DEVICE) |
||||
static void USB_Init_Device(void) |
||||
{ |
||||
USB_DeviceState = DEVICE_STATE_Unattached; |
||||
USB_ConfigurationNumber = 0; |
||||
|
||||
#if !defined(NO_DEVICE_REMOTE_WAKEUP) |
||||
USB_RemoteWakeupEnabled = false; |
||||
#endif |
||||
|
||||
#if !defined(NO_DEVICE_SELF_POWER) |
||||
USB_CurrentlySelfPowered = false; |
||||
#endif |
||||
|
||||
#if !defined(FIXED_CONTROL_ENDPOINT_SIZE) |
||||
USB_Descriptor_Device_t* DeviceDescriptorPtr; |
||||
|
||||
if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr) != NO_DESCRIPTOR) |
||||
{ |
||||
#if defined(USE_RAM_DESCRIPTORS) |
||||
USB_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size; |
||||
#elif defined(USE_EEPROM_DESCRIPTORS) |
||||
USB_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size); |
||||
#else |
||||
USB_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size); |
||||
#endif |
||||
} |
||||
#endif |
||||
|
||||
#if (defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) |
||||
if (USB_Options & USB_DEVICE_OPT_LOWSPEED) |
||||
USB_Device_SetLowSpeed(); |
||||
else |
||||
USB_Device_SetFullSpeed(); |
||||
|
||||
USB_INT_Enable(USB_INT_VBUS); |
||||
#endif |
||||
|
||||
Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL, |
||||
ENDPOINT_DIR_OUT, USB_ControlEndpointSize, |
||||
ENDPOINT_BANK_SINGLE); |
||||
|
||||
USB_INT_Clear(USB_INT_SUSPI); |
||||
USB_INT_Enable(USB_INT_SUSPI); |
||||
USB_INT_Enable(USB_INT_EORSTI); |
||||
|
||||
USB_Attach(); |
||||
} |
||||
#endif |
||||
|
||||
#if defined(USB_CAN_BE_HOST) |
||||
static void USB_Init_Host(void) |
||||
{ |
||||
USB_HostState = HOST_STATE_Unattached; |
||||
USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE; |
||||
|
||||
USB_Host_HostMode_On(); |
||||
|
||||
USB_Host_VBUS_Auto_Off(); |
||||
USB_Host_VBUS_Manual_Enable(); |
||||
USB_Host_VBUS_Manual_On(); |
||||
|
||||
USB_INT_Enable(USB_INT_SRPI); |
||||
USB_INT_Enable(USB_INT_BCERRI); |
||||
|
||||
USB_Attach(); |
||||
} |
||||
#endif |
||||
|
@ -0,0 +1,451 @@ |
||||
/*
|
||||
LUFA Library |
||||
Copyright (C) Dean Camera, 2011. |
||||
|
||||
dean [at] fourwalledcubicle [dot] com |
||||
www.lufa-lib.org |
||||
*/ |
||||
|
||||
/*
|
||||
Copyright 2011 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 Controller definitions for the AVR32 UC3B microcontrollers. |
||||
* \copydetails Group_USBManagement_UC3B |
||||
* |
||||
* \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_USBManagement
|
||||
* \defgroup Group_USBManagement_UC3B USB Interface Management (UC3B) |
||||
* \brief USB Controller definitions for the AVR32 UC3B microcontrollers. |
||||
* |
||||
* Functions, macros, variables, enums and types related to the setup and management of the USB interface. |
||||
* |
||||
* @{ |
||||
*/ |
||||
|
||||
#ifndef __USBCONTROLLER_UC3B_H__ |
||||
#define __USBCONTROLLER_UC3B_H__ |
||||
|
||||
/* Includes: */ |
||||
#include "../../../../Common/Common.h" |
||||
#include "../USBMode.h" |
||||
#include "../Events.h" |
||||
#include "../USBTask.h" |
||||
#include "../USBInterrupt.h" |
||||
|
||||
#if defined(USB_CAN_BE_HOST) || defined(__DOXYGEN__) |
||||
#include "../Host.h" |
||||
#include "../OTG.h" |
||||
#include "../Pipe.h" |
||||
#include "../HostStandardReq.h" |
||||
#include "../PipeStream.h" |
||||
#endif |
||||
|
||||
#if defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__) |
||||
#include "../Device.h" |
||||
#include "../Endpoint.h" |
||||
#include "../DeviceStandardReq.h" |
||||
#include "../EndpointStream.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 USB controller 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_CLOCK value and AVR model. |
||||
#endif |
||||
|
||||
/* Public Interface - May be used in end-application: */ |
||||
/* Macros: */ |
||||
/** \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_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) |
||||
//@}
|
||||
|
||||
/** \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. |
||||
*/ |
||||
#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: */ |
||||
/** 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, 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 behaviour. This should be comprised of |
||||
* a \c USB_OPT_REG_* mask to control the regulator, a \c USB_OPT_*_PLL mask to control the |
||||
* PLL, and a \c 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 \c USB_DEVICE_ONLY |
||||
* (for device mode) or \c 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 \c 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 \ref Group_Device for the \c 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_Disable(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); |
||||
|
||||
/* Global Variables: */ |
||||
#if (!defined(USB_HOST_ONLY) && !defined(USB_DEVICE_ONLY)) || defined(__DOXYGEN__) |
||||
/** 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 auto-detection 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 \c USB_DEVICE_ONLY or \c 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 |
||||
#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 \c 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 |
||||
|
||||
/* 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__) |
||||
/* 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) |
||||
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 |
||||
|
||||
/** @} */ |
||||
|
@ -0,0 +1,269 @@ |
||||
/*
|
||||
LUFA Library |
||||
Copyright (C) Dean Camera, 2011. |
||||
|
||||
dean [at] fourwalledcubicle [dot] com |
||||
www.lufa-lib.org |
||||
*/ |
||||
|
||||
/*
|
||||
Copyright 2011 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. |
||||
*/ |
||||
|
||||
#define __INCLUDE_FROM_USB_DRIVER |
||||
#include "USBInterrupt.h" |
||||
|
||||
void USB_INT_DisableAllInterrupts(void) |
||||
{ |
||||
#if defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) |
||||
USBCON &= ~((1 << VBUSTE) | (1 << IDTE)); |
||||
#elif defined(USB_SERIES_4_AVR) |
||||
USBCON &= ~(1 << VBUSTE); |
||||
#endif |
||||
|
||||
#if defined(USB_CAN_BE_BOTH) |
||||
OTGIEN = 0; |
||||
#endif |
||||
|
||||
#if defined(USB_CAN_BE_HOST) |
||||
UHIEN = 0; |
||||
#endif |
||||
|
||||
#if defined(USB_CAN_BE_DEVICE) |
||||
UDIEN = 0; |
||||
#endif |
||||
} |
||||
|
||||
void USB_INT_ClearAllInterrupts(void) |
||||
{ |
||||
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) |
||||
USBINT = 0; |
||||
#endif |
||||
|
||||
#if defined(USB_CAN_BE_BOTH) |
||||
OTGINT = 0; |
||||
#endif |
||||
|
||||
#if defined(USB_CAN_BE_HOST) |
||||
UHINT = 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(NO_SOF_EVENTS) |
||||
if (USB_INT_HasOccurred(USB_INT_SOFI) && USB_INT_IsEnabled(USB_INT_SOFI)) |
||||
{ |
||||
USB_INT_Clear(USB_INT_SOFI); |
||||
|
||||
EVENT_USB_Device_StartOfFrame(); |
||||
} |
||||
#endif |
||||
|
||||
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) |
||||
if (USB_INT_HasOccurred(USB_INT_VBUS) && USB_INT_IsEnabled(USB_INT_VBUS)) |
||||
{ |
||||
USB_INT_Clear(USB_INT_VBUS); |
||||
|
||||
if (USB_VBUS_GetStatus()) |
||||
{ |
||||
USB_DeviceState = DEVICE_STATE_Powered; |
||||
EVENT_USB_Device_Connect(); |
||||
} |
||||
else |
||||
{ |
||||
USB_DeviceState = DEVICE_STATE_Unattached; |
||||
EVENT_USB_Device_Disconnect(); |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
if (USB_INT_HasOccurred(USB_INT_SUSPI) && USB_INT_IsEnabled(USB_INT_SUSPI)) |
||||
{ |
||||
USB_INT_Clear(USB_INT_SUSPI); |
||||
|
||||
USB_INT_Disable(USB_INT_SUSPI); |
||||
USB_INT_Enable(USB_INT_WAKEUPI); |
||||
|
||||
USB_CLK_Freeze(); |
||||
|
||||
if (!(USB_Options & USB_OPT_MANUAL_PLL)) |
||||
USB_PLL_Off(); |
||||
|
||||
#if defined(USB_SERIES_2_AVR) && !defined(NO_LIMITED_CONTROLLER_CONNECT) |
||||
USB_DeviceState = DEVICE_STATE_Unattached; |
||||
EVENT_USB_Device_Disconnect(); |
||||
#else |
||||
USB_DeviceState = DEVICE_STATE_Suspended; |
||||
EVENT_USB_Device_Suspend(); |
||||
#endif |
||||
} |
||||
|
||||
if (USB_INT_HasOccurred(USB_INT_WAKEUPI) && USB_INT_IsEnabled(USB_INT_WAKEUPI)) |
||||
{ |
||||
if (!(USB_Options & USB_OPT_MANUAL_PLL)) |
||||
{ |
||||
USB_PLL_On(); |
||||
while (!(USB_PLL_IsReady())); |
||||
} |
||||
|
||||
USB_CLK_Unfreeze(); |
||||
|
||||
USB_INT_Clear(USB_INT_WAKEUPI); |
||||
|
||||
USB_INT_Disable(USB_INT_WAKEUPI); |
||||
USB_INT_Enable(USB_INT_SUSPI); |
||||
|
||||
if (USB_ConfigurationNumber) |
||||
USB_DeviceState = DEVICE_STATE_Configured; |
||||
else |
||||
USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered; |
||||
|
||||
#if defined(USB_SERIES_2_AVR) && !defined(NO_LIMITED_CONTROLLER_CONNECT) |
||||
EVENT_USB_Device_Connect(); |
||||
#else |
||||
EVENT_USB_Device_WakeUp(); |
||||
#endif |
||||
} |
||||
|
||||
if (USB_INT_HasOccurred(USB_INT_EORSTI) && USB_INT_IsEnabled(USB_INT_EORSTI)) |
||||
{ |
||||
USB_INT_Clear(USB_INT_EORSTI); |
||||
|
||||
USB_DeviceState = DEVICE_STATE_Default; |
||||
USB_ConfigurationNumber = 0; |
||||
|
||||
USB_INT_Clear(USB_INT_SUSPI); |
||||
USB_INT_Disable(USB_INT_SUSPI); |
||||
USB_INT_Enable(USB_INT_WAKEUPI); |
||||
|
||||
Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL, |
||||
ENDPOINT_DIR_OUT, USB_ControlEndpointSize, |
||||
ENDPOINT_BANK_SINGLE); |
||||
|
||||
#if defined(INTERRUPT_CONTROL_ENDPOINT) |
||||
USB_INT_Enable(USB_INT_RXSTPI); |
||||
#endif |
||||
|
||||
EVENT_USB_Device_Reset(); |
||||
} |
||||
#endif |
||||
|
||||
#if defined(USB_CAN_BE_HOST) |
||||
#if !defined(NO_SOF_EVENTS) |
||||
if (USB_INT_HasOccurred(USB_INT_HSOFI) && USB_INT_IsEnabled(USB_INT_HSOFI)) |
||||
{ |
||||
USB_INT_Clear(USB_INT_HSOFI); |
||||
|
||||
EVENT_USB_Host_StartOfFrame(); |
||||
} |
||||
#endif |
||||
|
||||
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); |
||||
|
||||
EVENT_USB_Host_DeviceUnattached(); |
||||
|
||||
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(); |
||||
|
||||
EVENT_USB_Host_HostError(HOST_ERROR_VBusVoltageDip); |
||||
EVENT_USB_Host_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); |
||||
|
||||
EVENT_USB_Host_DeviceAttached(); |
||||
|
||||
USB_INT_Enable(USB_INT_DDISCI); |
||||
|
||||
USB_HostState = HOST_STATE_Powered; |
||||
} |
||||
|
||||
if (USB_INT_HasOccurred(USB_INT_BCERRI) && USB_INT_IsEnabled(USB_INT_BCERRI)) |
||||
{ |
||||
USB_INT_Clear(USB_INT_BCERRI); |
||||
|
||||
EVENT_USB_Host_DeviceEnumerationFailed(HOST_ENUMERROR_NoDeviceDetected, 0); |
||||
EVENT_USB_Host_DeviceUnattached(); |
||||
|
||||
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_DeviceState != DEVICE_STATE_Unattached) |
||||
EVENT_USB_Device_Disconnect(); |
||||
|
||||
if (USB_HostState != HOST_STATE_Unattached) |
||||
EVENT_USB_Host_DeviceUnattached(); |
||||
|
||||
USB_CurrentMode = USB_GetUSBModeFromUID(); |
||||
USB_ResetInterface(); |
||||
|
||||
EVENT_USB_UIDChange(); |
||||
} |
||||
#endif |
||||
} |
||||
|
||||
#if defined(INTERRUPT_CONTROL_ENDPOINT) && defined(USB_CAN_BE_DEVICE) |
||||
ISR(USB_COM_vect, ISR_BLOCK) |
||||
{ |
||||
uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint(); |
||||
|
||||
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); |
||||
USB_INT_Disable(USB_INT_RXSTPI); |
||||
|
||||
NONATOMIC_BLOCK(NONATOMIC_FORCEOFF) |
||||
{ |
||||
USB_Device_ProcessControlRequest(); |
||||
} |
||||
|
||||
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); |
||||
USB_INT_Enable(USB_INT_RXSTPI); |
||||
Endpoint_SelectEndpoint(PrevSelectedEndpoint); |
||||
} |
||||
#endif |
||||
|
@ -0,0 +1,102 @@ |
||||
/*
|
||||
LUFA Library |
||||
Copyright (C) Dean Camera, 2011. |
||||
|
||||
dean [at] fourwalledcubicle [dot] com |
||||
www.lufa-lib.org |
||||
*/ |
||||
|
||||
/*
|
||||
Copyright 2011 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 Controller Interrupt definitions for the AVR32 UC3B microcontrollers. |
||||
* |
||||
* This file contains definitions required for the correct handling of low level USB service routine interrupts |
||||
* from the USB controller. |
||||
* |
||||
* \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. |
||||
*/ |
||||
|
||||
#ifndef __USBINTERRUPT_UC3B_H__ |
||||
#define __USBINTERRUPT_UC3B_H__ |
||||
|
||||
/* Includes: */ |
||||
#include "../../../../Common/Common.h" |
||||
|
||||
/* Enable C linkage for C++ Compilers: */ |
||||
#if defined(__cplusplus) |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* Preprocessor Checks: */ |
||||
#if !defined(__INCLUDE_FROM_USB_DRIVER) |
||||
#error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. |
||||
#endif |
||||
|
||||
/* Private Interface - For use in library only: */ |
||||
#if !defined(__DOXYGEN__) |
||||
/* Macros: */ |
||||
#define USB_INT_Enable(int) MACROS{ USB_INT_GET_EN_REG(int) |= USB_INT_GET_EN_MASK(int); }MACROE |
||||
#define USB_INT_Disable(int) MACROS{ USB_INT_GET_EN_REG(int) &= ~(USB_INT_GET_EN_MASK(int)); }MACROE |
||||
#define USB_INT_Clear(int) MACROS{ USB_INT_GET_INT_REG(int) &= ~(USB_INT_GET_INT_MASK(int)); }MACROE |
||||
#define USB_INT_IsEnabled(int) ((USB_INT_GET_EN_REG(int) & USB_INT_GET_EN_MASK(int)) ? true : false) |
||||
#define USB_INT_HasOccurred(int) ((USB_INT_GET_INT_REG(int) & USB_INT_GET_INT_MASK(int)) ? true : false) |
||||
|
||||
#define USB_INT_GET_EN_REG(EnableReg, EnableMask, FlagReg, FlagMask) EnableReg |
||||
#define USB_INT_GET_EN_MASK(EnableReg, EnableMask, FlagReg, FlagMask) EnableMask |
||||
#define USB_INT_GET_INT_REG(EnableReg, EnableMask, FlagReg, FlagMask) FlagReg |
||||
#define USB_INT_GET_INT_MASK(EnableReg, EnableMask, FlagReg, FlagMask) FlagMask |
||||
|
||||
#define USB_INT_VBUS USBCON, (1 << VBUSTE) , USBINT, (1 << VBUSTI) |
||||
#define USB_INT_IDTI USBCON, (1 << IDTE) , USBINT, (1 << IDTI) |
||||
#define USB_INT_WAKEUPI UDIEN , (1 << WAKEUPE), UDINT , (1 << WAKEUPI) |
||||
#define USB_INT_SUSPI 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) |
||||
#define USB_INT_RXSTPI UEIENX, (1 << RXSTPE) , UEINTX, (1 << RXSTPI) |
||||
|
||||
/* Includes: */ |
||||
#include "../USBMode.h" |
||||
#include "../Events.h" |
||||
#include "../USBController.h" |
||||
|
||||
/* Function Prototypes: */ |
||||
void USB_INT_ClearAllInterrupts(void); |
||||
void USB_INT_DisableAllInterrupts(void); |
||||
#endif |
||||
|
||||
/* Disable C linkage for C++ Compilers: */ |
||||
#if defined(__cplusplus) |
||||
} |
||||
#endif |
||||
|
||||
#endif |
||||
|
Loading…
Reference in new issue