Added start of a port of the core USB driver code to the AVR32 UC3B architecture.

pull/1469/head
Dean Camera 14 years ago
parent f3ec62b5c6
commit cad5e9ffca

File diff suppressed because one or more lines are too long

@ -62,7 +62,10 @@
/* Public Interface - May be used in end-application: */ /* Public Interface - May be used in end-application: */
/* Macros: */ /* Macros: */
/** Selects the Atmel 8-bit AVR (AT90USB* and ATMEGA*U* chips) architecture. */ /** Selects the Atmel 8-bit AVR (AT90USB* and ATMEGA*U* chips) architecture. */
#define ARCH_AVR8 1 #define ARCH_AVR8 0
/** Selects the Atmel 32-bit UC3B AVR (AT32UC3B* chips) architecture. */
#define ARCH_UC3B 1
#if !defined(__DOXYGEN__) #if !defined(__DOXYGEN__)
#define ARCH_ ARCH_AVR8 #define ARCH_ ARCH_AVR8

@ -144,6 +144,9 @@
/** Selects the Sparkfun ATMEGA8U2 specific board drivers, including the driver for the board LEDs. */ /** Selects the Sparkfun ATMEGA8U2 specific board drivers, including the driver for the board LEDs. */
#define BOARD_SPARKFUN8U2 26 #define BOARD_SPARKFUN8U2 26
/** Selects the Atmel EVK1101 specific board drivers, including the Button, Joystick and LED drivers. */
#define BOARD_EVK1101 27
#if !defined(__DOXYGEN__) #if !defined(__DOXYGEN__)
#define BOARD_ BOARD_NONE #define BOARD_ BOARD_NONE

@ -67,6 +67,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
#include <stddef.h>
#include "Architectures.h" #include "Architectures.h"
#include "Attributes.h" #include "Attributes.h"
@ -81,6 +82,16 @@
#include <avr/boot.h> #include <avr/boot.h>
#include <util/atomic.h> #include <util/atomic.h>
#include <util/delay.h> #include <util/delay.h>
typedef uint8_t uintN_t;
typedef int8_t intN_t;
#elif (ARCH == ARCH_UC3B)
#include <avr32/io.h>
typedef uint32_t uintN_t;
typedef int32_t intN_t;
#warning The UC3B architecture support is currently experimental and incomplete!
#endif #endif
/* Public Interface - May be used in end-application: */ /* Public Interface - May be used in end-application: */

@ -126,6 +126,8 @@
#include "MINIMUS/Buttons.h" #include "MINIMUS/Buttons.h"
#elif (BOARD == BOARD_MICROSIN162) #elif (BOARD == BOARD_MICROSIN162)
#include "MICROSIN162/Buttons.h" #include "MICROSIN162/Buttons.h"
#elif (BOARD == BOARD_EVK1101)
#include "EVK1101/Buttons.h"
#else #else
#include "Board/Buttons.h" #include "Board/Buttons.h"
#endif #endif

@ -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
/** @} */

@ -127,4 +127,3 @@
#endif #endif
/** @} */ /** @} */

@ -114,6 +114,8 @@
#include "BUMBLEB/Joystick.h" #include "BUMBLEB/Joystick.h"
#elif (BOARD == BOARD_EVK527) #elif (BOARD == BOARD_EVK527)
#include "EVK527/Joystick.h" #include "EVK527/Joystick.h"
#elif (BOARD == BOARD_EVK1101)
#include "EVK1101/Joystick.h"
#else #else
#include "Board/Joystick.h" #include "Board/Joystick.h"
#endif #endif

@ -166,6 +166,8 @@
#include "MICROSIN162/LEDs.h" #include "MICROSIN162/LEDs.h"
#elif (BOARD == BOARD_SPARKFUN8U2) #elif (BOARD == BOARD_SPARKFUN8U2)
#include "SPARKFUN8U2/LEDs.h" #include "SPARKFUN8U2/LEDs.h"
#elif (BOARD == BOARD_EVK1101)
#include "EVK1101/LEDs.h"
#else #else
#include "Board/LEDs.h" #include "Board/LEDs.h"
#endif #endif

@ -197,11 +197,6 @@
*/ */
#define ENDPOINT_EPDIR_MASK 0x80 #define ENDPOINT_EPDIR_MASK 0x80
/** Endpoint bank size mask, for masking against endpoint addresses to retrieve the endpoint's
* bank size in the device.
*/
#define ENDPOINT_EPSIZE_MASK 0x7F
/** Retrives the maximum bank size in bytes of a given endpoint. /** 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 * \note This macro will only work correctly on endpoint indexes that are compile-time constants
@ -306,7 +301,7 @@
const uint16_t Size, const uint16_t Size,
const uint8_t Banks) const uint8_t Banks)
{ {
return Endpoint_ConfigureEndpoint_Prv(Number, (((Type) << EPTYPE0) | (Direction)), return Endpoint_ConfigureEndpoint_Prv(Number, ((Type << EPTYPE0) | Direction),
((1 << ALLOC) | Banks | Endpoint_BytesToEPSizeMask(Size))); ((1 << ALLOC) | Banks | Endpoint_BytesToEPSizeMask(Size)));
} }
@ -406,6 +401,19 @@
return ((UECONX & (1 << EPEN)) ? true : false); return ((UECONX & (1 << EPEN)) ? 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 (UESTA0X & (0x03 << NBUSYBK0));
}
/** Aborts all pending IN transactions on the currently selected endpoint, once the bank /** 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 * 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 * will terminate all queued transactions, resetting the endpoint banks ready for a new
@ -415,26 +423,13 @@
*/ */
static inline void Endpoint_AbortPendingIN(void) static inline void Endpoint_AbortPendingIN(void)
{ {
while (UESTA0X & (0x03 << NBUSYBK0)) while (Endpoint_GetBusyBanks() != 0)
{ {
UEINTX |= (1 << RXOUTI); UEINTX |= (1 << RXOUTI);
while (UEINTX & (1 << RXOUTI)); while (UEINTX & (1 << RXOUTI));
} }
} }
/** 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 (UESTA0X & (0x03 << NBUSYBK0));
}
/** Determines if the currently selected endpoint may be read from (if data is waiting in the endpoint /** 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 * 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 * direction). This function will return false if an error has occurred in the endpoint, if the endpoint
@ -484,7 +479,7 @@
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) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
static inline bool Endpoint_HasEndpointInterrupted(const uint8_t EndpointNumber) static inline bool Endpoint_HasEndpointInterrupted(const uint8_t EndpointNumber)
{ {
return ((UEINT & (1 << EndpointNumber)) ? true : false); 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. /** Determines if the selected IN endpoint is ready for a new packet to be sent to the host.

@ -57,6 +57,8 @@
#if (ARCH == ARCH_AVR8) #if (ARCH == ARCH_AVR8)
#include "AVR8/Device.h" #include "AVR8/Device.h"
#elif (ARCH == ARCH_UC3B)
#include "UC3B/Device.h"
#endif #endif
/* Preprocessor Checks: */ /* Preprocessor Checks: */

@ -77,6 +77,8 @@
#if (ARCH == ARCH_AVR8) #if (ARCH == ARCH_AVR8)
#include "AVR8/Endpoint.h" #include "AVR8/Endpoint.h"
#elif (ARCH == ARCH_UC3B)
#include "UC3B/Endpoint.h"
#endif #endif
/* Preprocessor Checks: */ /* Preprocessor Checks: */

@ -54,6 +54,8 @@
#if (ARCH == ARCH_AVR8) #if (ARCH == ARCH_AVR8)
#include "AVR8/Host.h" #include "AVR8/Host.h"
#elif (ARCH == ARCH_UC3B)
#include "UC3B/Host.h"
#endif #endif
/* Preprocessor Checks: */ /* Preprocessor Checks: */

@ -55,6 +55,8 @@
#if (ARCH == ARCH_AVR8) #if (ARCH == ARCH_AVR8)
#include "AVR8/OTG.h" #include "AVR8/OTG.h"
#elif (ARCH == ARCH_UC3B)
#include "UC3B/OTG.h"
#endif #endif
/* Preprocessor Checks: */ /* Preprocessor Checks: */

@ -87,6 +87,8 @@
#if (ARCH == ARCH_AVR8) #if (ARCH == ARCH_AVR8)
#include "AVR8/Pipe.h" #include "AVR8/Pipe.h"
#elif (ARCH == ARCH_UC3B)
#include "UC3B/Pipe.h"
#endif #endif
/* Preprocessor Checks: */ /* Preprocessor Checks: */

@ -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

@ -53,6 +53,8 @@
#if (ARCH == ARCH_AVR8) #if (ARCH == ARCH_AVR8)
#include "AVR8/USBController.h" #include "AVR8/USBController.h"
#elif (ARCH == ARCH_UC3B)
#include "UC3B/USBController.h"
#endif #endif
/* Preprocessor Checks and Defines: */ /* Preprocessor Checks and Defines: */

@ -46,6 +46,8 @@
#if (ARCH == ARCH_AVR8) #if (ARCH == ARCH_AVR8)
#include "AVR8/USBInterrupt.h" #include "AVR8/USBInterrupt.h"
#elif (ARCH == ARCH_UC3B)
#include "UC3B/USBInterrupt.h"
#endif #endif
/* Preprocessor Checks: */ /* Preprocessor Checks: */

@ -82,6 +82,11 @@
*/ */
#define USB_SERIES_7_AVR #define USB_SERIES_7_AVR
/** Indicates that the target AVR microcontroller belongs to the UC3B Series USB controller
* (i.e. AT32UC3B*) when defined.
*/
#define USB_SERIES_UC3B_AVR
/** Indicates that the target microcontroller and compilation settings allow for the /** Indicates that the target microcontroller and compilation settings allow for the
* target to be configured in USB Device mode when defined. * target to be configured in USB Device mode when defined.
*/ */
@ -112,6 +117,13 @@
#define USB_SERIES_7_AVR #define USB_SERIES_7_AVR
#define USB_CAN_BE_DEVICE #define USB_CAN_BE_DEVICE
#define USB_CAN_BE_HOST #define USB_CAN_BE_HOST
#elif (defined(__AVR32_UC3B0512__) || defined(__AVR32_UC3B1512__) || \
defined(__AVR32_UC3B0256__) || defined(__AVR32_UC3B1256__) || \
defined(__AVR32_UC3B0128__) || defined(__AVR32_UC3B1128__) || \
defined(__AVR32_UC3B064__) || defined(__AVR32_UC3B164__))
#define USB_SERIES_UC3B_AVR
#define USB_CAN_BE_DEVICE
#define USB_CAN_BE_HOST
#endif #endif
#if (defined(USB_CAN_BE_DEVICE) && defined(USB_CAN_BE_HOST)) #if (defined(USB_CAN_BE_DEVICE) && defined(USB_CAN_BE_HOST))

@ -23,6 +23,7 @@
* - Added new Serial_SendData() function to the Serial driver * - Added new Serial_SendData() function to the Serial driver
* - Added board driver support for the Sparkfun ATMEGA8U2 breakout board * - Added board driver support for the Sparkfun ATMEGA8U2 breakout board
* - Started internal restructuring for eventual multiple architecture ports * - Started internal restructuring for eventual multiple architecture ports
* - Added start of an AVR32 UC3B architecture port (currently incomplete/experimental)
* - Library Applications: * - Library Applications:
* - Added ability to write protect Mass Storage disk write operations from the host OS * - Added ability to write protect Mass Storage disk write operations from the host OS
* - Added new MIDIToneGenerator project * - Added new MIDIToneGenerator project

@ -7,6 +7,22 @@
/** /**
* \page Page_DeviceSupport Device and Hardware Support * \page Page_DeviceSupport Device and Hardware Support
* *
* \section Sec_AVR8_Support Atmel 32-Bit UC3B AVR (UC3B)
* <i>The AVR32 UC3B device support is currently <b>experimental</b>, and is included for preview purposes only.</i>
*
* Currently supported UC3B models:
* - AT32UC3B064 (USB Host and Device)
* - AT32UC3B164 (USB Host and Device)
* - AT32UC3B0128 (USB Host and Device)
* - AT32UC3B1128 (USB Host and Device)
* - AT32UC3B0256 (USB Host and Device)
* - AT32UC3B1256 (USB Host and Device)
* - AT32UC3B0512 (USB Host and Device)
* - AT32UC3B1512 (USB Host and Device)
*
* Currently supported Atmel boards (see \ref Group_BoardTypes):
* - EVK1101
*
* \section Sec_AVR8_Support Atmel 8-Bit AVR (AVR8) * \section Sec_AVR8_Support Atmel 8-Bit AVR (AVR8)
* *
* Currently supported AVR8 models: * Currently supported AVR8 models:

Loading…
Cancel
Save