From 2eb47bea14a5c98eddcedbc4ff38583d9bfbb1d3 Mon Sep 17 00:00:00 2001 From: Dean Date: Mon, 16 Jul 2012 17:11:14 +0000 Subject: Tag for the LUFA-120730-BETA release. git-svn-id: http://lufa-lib.googlecode.com/svn/tags/LUFA-120730-BETA@2407 d5102386-fcda-11dd-9fdb-3debd5008f28 --- LUFA/Drivers/Board/AVR8/BIGMULTIO/LEDs.h | 322 ++--- LUFA/Drivers/Board/AVR8/MICROPENDOUS/Buttons.h | 414 +++---- LUFA/Drivers/Board/AVR8/MICROPENDOUS/LEDs.h | 4 +- LUFA/Drivers/Board/AVR8/MULTIO/LEDs.h | 322 ++--- LUFA/Drivers/Board/AVR8/USB2AX/Buttons.h | 224 ++-- LUFA/Drivers/Board/AVR8/USB2AX/LEDs.h | 390 +++--- LUFA/Drivers/Board/Buttons.h | 2 +- LUFA/Drivers/Board/Joystick.h | 2 +- LUFA/Drivers/Board/LEDs.h | 4 +- LUFA/Drivers/Board/UC3/EVK1101/Buttons.h | 2 +- LUFA/Drivers/Peripheral/AVR8/ADC_AVR8.h | 2 +- LUFA/Drivers/USB/Class/AndroidAccessoryClass.h | 150 +-- .../USB/Class/Common/AndroidAccessoryClassCommon.h | 254 ++-- LUFA/Drivers/USB/Class/Device/AudioClassDevice.h | 4 +- LUFA/Drivers/USB/Class/Device/CDCClassDevice.h | 4 +- LUFA/Drivers/USB/Class/Device/MIDIClassDevice.h | 2 +- .../USB/Class/Host/AndroidAccessoryClassHost.c | 842 ++++++------- .../USB/Class/Host/AndroidAccessoryClassHost.h | 626 +++++----- LUFA/Drivers/USB/Class/Host/CDCClassHost.h | 4 +- LUFA/Drivers/USB/Class/Host/HIDClassHost.h | 2 +- LUFA/Drivers/USB/Class/Host/MIDIClassHost.h | 2 +- LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.c | 546 ++++----- LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.h | 1294 ++++++++++---------- LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.h | 7 +- LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.c | 442 +++---- LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.h | 882 ++++++------- LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c | 3 + LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h | 2 +- LUFA/Drivers/USB/Core/ConfigDescriptor.c | 146 --- LUFA/Drivers/USB/Core/ConfigDescriptor.h | 286 ----- LUFA/Drivers/USB/Core/ConfigDescriptors.c | 146 +++ LUFA/Drivers/USB/Core/ConfigDescriptors.h | 286 +++++ LUFA/Drivers/USB/Core/Events.h | 4 +- LUFA/Drivers/USB/Core/HostStandardReq.h | 2 +- LUFA/Drivers/USB/Core/StdDescriptors.h | 2 +- LUFA/Drivers/USB/Core/UC3/EndpointStream_UC3.c | 466 +++---- LUFA/Drivers/USB/Core/UC3/EndpointStream_UC3.h | 866 ++++++------- LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c | 2 +- LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.h | 13 +- LUFA/Drivers/USB/Core/UC3/PipeStream_UC3.c | 332 ++--- LUFA/Drivers/USB/Core/UC3/PipeStream_UC3.h | 702 +++++------ LUFA/Drivers/USB/Core/UC3/Pipe_UC3.c | 5 +- LUFA/Drivers/USB/Core/UC3/Pipe_UC3.h | 2 +- LUFA/Drivers/USB/Core/UC3/USBController_UC3.c | 2 +- LUFA/Drivers/USB/Core/UC3/USBController_UC3.h | 2 +- LUFA/Drivers/USB/Core/XMEGA/EndpointStream_XMEGA.c | 546 ++++----- LUFA/Drivers/USB/Core/XMEGA/EndpointStream_XMEGA.h | 1294 ++++++++++---------- LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h | 14 +- LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.c | 2 +- LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.h | 2 +- LUFA/Drivers/USB/USB.h | 4 +- 51 files changed, 5954 insertions(+), 5926 deletions(-) delete mode 100644 LUFA/Drivers/USB/Core/ConfigDescriptor.c delete mode 100644 LUFA/Drivers/USB/Core/ConfigDescriptor.h create mode 100644 LUFA/Drivers/USB/Core/ConfigDescriptors.c create mode 100644 LUFA/Drivers/USB/Core/ConfigDescriptors.h (limited to 'LUFA/Drivers') diff --git a/LUFA/Drivers/Board/AVR8/BIGMULTIO/LEDs.h b/LUFA/Drivers/Board/AVR8/BIGMULTIO/LEDs.h index 89516dca..bafedcca 100644 --- a/LUFA/Drivers/Board/AVR8/BIGMULTIO/LEDs.h +++ b/LUFA/Drivers/Board/AVR8/BIGMULTIO/LEDs.h @@ -1,161 +1,161 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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 Board specific LED driver header for the Bitwizard Big-Multio. - * \copydetails Group_LEDs_BIGMULTIO - * - * \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_BIGMULTIO BIGMULTIO - * \brief Board specific LED driver header for the Bitwizard Big-Multio. - * - * Board specific LED driver header for the Bitwizard Big-Multio (http://www.bitwizard.nl/wiki/index.php/Usbbigmultio). - * - * - * - * - * - * - *
NameColorInfoActive LevelPort Pin
LEDS_LED1UnknownLED0HighPORTF.6
LEDS_LED2UnknownLED1HighPORTF.7
LEDS_LED3UnknownLED2HighPORTE.2
- * - * @{ - */ - -#ifndef __LEDS_BIGMULTIO_H__ -#define __LEDS_BIGMULTIO_H__ - - /* Includes: */ - #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_PORTF_LEDS (LEDS_LED1 | LEDS_LED2) - #define LEDS_PORTE_LEDS LEDS_LED3 - #endif - - /* Public Interface - May be used in end-application: */ - /* Macros: */ - /** LED mask for the first LED on the board. */ - #define LEDS_LED1 (1 << 6) - - /** LED mask for the second LED on the board. */ - #define LEDS_LED2 (1 << 7) - - /** LED mask for the second LED on the board. */ - #define LEDS_LED3 (1 << 2) - - /** LED mask for all the LEDs on the board. */ - #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3) - - /** LED mask for none of the board LEDs. */ - #define LEDS_NO_LEDS 0 - - /* Inline Functions: */ - #if !defined(__DOXYGEN__) - static inline void LEDs_Init(void) - { - DDRF |= LEDS_PORTF_LEDS; - DDRE |= LEDS_PORTE_LEDS; - - PORTF &= ~LEDS_PORTF_LEDS; - PORTE &= ~LEDS_PORTE_LEDS; - } - - static inline void LEDs_Disable(void) - { - DDRF |= LEDS_PORTF_LEDS; - DDRE |= LEDS_PORTE_LEDS; - - PORTF &= ~LEDS_PORTF_LEDS; - PORTE &= ~LEDS_PORTE_LEDS; - } - - static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) - { - PORTF |= (LEDMask & LEDS_PORTF_LEDS); - PORTE |= (LEDMask & LEDS_PORTE_LEDS); - } - - static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) - { - PORTF &= ~(LEDMask & LEDS_PORTF_LEDS); - PORTE &= ~(LEDMask & LEDS_PORTE_LEDS); - } - - static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) - { - PORTF = (PORTF & ~LEDS_PORTF_LEDS) | (LEDMask & LEDS_PORTF_LEDS); - PORTE = (PORTE & ~LEDS_PORTE_LEDS) | (LEDMask & LEDS_PORTE_LEDS); - } - - static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, - const uint8_t ActiveMask) - { - PORTF = (PORTF & ~(LEDMask & LEDS_PORTF_LEDS)) | (ActiveMask & LEDS_PORTF_LEDS); - PORTE = (PORTE & ~(LEDMask & LEDS_PORTE_LEDS)) | (ActiveMask & LEDS_PORTE_LEDS); - } - - static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) - { - PINF = (LEDMask & LEDS_PORTF_LEDS); - PINE = (LEDMask & LEDS_PORTE_LEDS); - } - - static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; - static inline uint8_t LEDs_GetLEDs(void) - { - return ((PORTF & LEDS_PORTF_LEDS) | (PORTE & LEDS_PORTE_LEDS)); - } - #endif - - /* Disable C linkage for C++ Compilers: */ - #if defined(__cplusplus) - } - #endif - -#endif - -/** @} */ - +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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 Board specific LED driver header for the Bitwizard Big-Multio. + * \copydetails Group_LEDs_BIGMULTIO + * + * \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_BIGMULTIO BIGMULTIO + * \brief Board specific LED driver header for the Bitwizard Big-Multio. + * + * Board specific LED driver header for the Bitwizard Big-Multio (http://www.bitwizard.nl/wiki/index.php/Usbbigmultio). + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1UnknownLED0HighPORTF.6
LEDS_LED2UnknownLED1HighPORTF.7
LEDS_LED3UnknownLED2HighPORTE.2
+ * + * @{ + */ + +#ifndef __LEDS_BIGMULTIO_H__ +#define __LEDS_BIGMULTIO_H__ + + /* Includes: */ + #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_PORTF_LEDS (LEDS_LED1 | LEDS_LED2) + #define LEDS_PORTE_LEDS LEDS_LED3 + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 6) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 7) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED3 (1 << 2) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRF |= LEDS_PORTF_LEDS; + DDRE |= LEDS_PORTE_LEDS; + + PORTF &= ~LEDS_PORTF_LEDS; + PORTE &= ~LEDS_PORTE_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRF |= LEDS_PORTF_LEDS; + DDRE |= LEDS_PORTE_LEDS; + + PORTF &= ~LEDS_PORTF_LEDS; + PORTE &= ~LEDS_PORTE_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTF |= (LEDMask & LEDS_PORTF_LEDS); + PORTE |= (LEDMask & LEDS_PORTE_LEDS); + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTF &= ~(LEDMask & LEDS_PORTF_LEDS); + PORTE &= ~(LEDMask & LEDS_PORTE_LEDS); + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTF = (PORTF & ~LEDS_PORTF_LEDS) | (LEDMask & LEDS_PORTF_LEDS); + PORTE = (PORTE & ~LEDS_PORTE_LEDS) | (LEDMask & LEDS_PORTE_LEDS); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTF = (PORTF & ~(LEDMask & LEDS_PORTF_LEDS)) | (ActiveMask & LEDS_PORTF_LEDS); + PORTE = (PORTE & ~(LEDMask & LEDS_PORTE_LEDS)) | (ActiveMask & LEDS_PORTE_LEDS); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PINF = (LEDMask & LEDS_PORTF_LEDS); + PINE = (LEDMask & LEDS_PORTE_LEDS); + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return ((PORTF & LEDS_PORTF_LEDS) | (PORTE & LEDS_PORTE_LEDS)); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/LUFA/Drivers/Board/AVR8/MICROPENDOUS/Buttons.h b/LUFA/Drivers/Board/AVR8/MICROPENDOUS/Buttons.h index 731d1b05..60d81b78 100644 --- a/LUFA/Drivers/Board/AVR8/MICROPENDOUS/Buttons.h +++ b/LUFA/Drivers/Board/AVR8/MICROPENDOUS/Buttons.h @@ -1,208 +1,208 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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 Board specific Buttons driver header for the Micropendous series boards. - * \copydetails Group_Buttons_MICROPENDOUS_32U2 - * - * \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_MICROPENDOUS_A MICROPENDOUS_A - * \brief Board specific Button driver header for the Micropendous A (https://code.google.com/p/micropendous/wiki/MicropendousA). - * - * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. - */ - -/** \ingroup Group_Buttons - * \defgroup Group_Buttons_MICROPENDOUS_1 MICROPENDOUS_1 - * \brief Board specific Button driver header for the Micropendous 1 (https://code.google.com/p/micropendous/wiki/Micropendous1). - * - * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. - */ - -/** \ingroup Group_Buttons - * \defgroup Group_Buttons_MICROPENDOUS_2 MICROPENDOUS_2 - * \brief Board specific Button driver header for the Micropendous 2 (https://code.google.com/p/micropendous/wiki/Micropendous2). - * - * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. - */ - -/** \ingroup Group_Buttons - * \defgroup Group_Buttons_MICROPENDOUS_3 MICROPENDOUS_3 - * \brief Board specific Button driver header for the Micropendous 3 (https://code.google.com/p/micropendous/wiki/Micropendous3). - * - * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. - */ - -/** \ingroup Group_Buttons - * \defgroup Group_Buttons_MICROPENDOUS_4 MICROPENDOUS_4 - * \brief Board specific Button driver header for the Micropendous 4 (https://code.google.com/p/micropendous/wiki/Micropendous4). - * - * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. - */ - -/** \ingroup Group_Buttons - * \defgroup Group_Buttons_MICROPENDOUS_DIP MICROPENDOUS_DIP - * \brief Board specific Button driver header for the Micropendous DIP (https://code.google.com/p/micropendous/wiki/MicropendousDIP). - * - * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. - */ - -/** \ingroup Group_Buttons - * \defgroup Group_Buttons_MICROPENDOUS_REV1 MICROPENDOUS_REV1 - * \brief Board specific Button driver header for the Micropendous Arduino-like Revision 1 (https://code.google.com/p/micropendous/wiki/Micropendous). - * - * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. - */ - -/** \ingroup Group_Buttons - * \defgroup Group_Buttons_MICROPENDOUS_REV2 MICROPENDOUS_REV2 - * \brief Board specific Button driver header for the Micropendous Arduino-like Revision 2 (https://code.google.com/p/micropendous/wiki/Micropendous). - * - * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. - */ - -/** \ingroup Group_Buttons - * \defgroup Group_Buttons_MICROPENDOUS_32U2 MICROPENDOUS_32U2 - * \brief Board specific Buttons driver header for the Micropendous 32U2. - * - * \note There are multiple supported Micropendous boards, compile with BOARD = MICROPENDOUS_{VERSION}. - * - * Board specific Buttons driver header for the Micropendous 32U2 (https://code.google.com/p/micropendous/wiki/Micropendous_32U2). - * - * BOARD_MICROPENDOUS_1 and BOARD_MICROPENDOUS_32U2: - * - * - * - *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTD.7
- * - * Other Revisions: - * - * - * - *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTE.2
- * - * @{ - */ - -#ifndef __BUTTONS_MICROPENDOUS_H__ -#define __BUTTONS_MICROPENDOUS_H__ - - /* Includes: */ - #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__) - #if (BOARD == BOARD_MICROPENDOUS_32U2) - #define _BOARD_BUTTON1_MASK (1 << 7) - #define _BOARD_BUTTON_PORTLETTER D - #elif (BOARD == BOARD_MICROPENDOUS_A) - #define _BOARD_BUTTON1_MASK (1 << 2) - #define _BOARD_BUTTON_PORTLETTER E - #elif (BOARD == BOARD_MICROPENDOUS_1) - #define _BOARD_BUTTON1_MASK (1 << 7) - #define _BOARD_BUTTON_PORTLETTER D - #elif (BOARD == BOARD_MICROPENDOUS_2) - #define _BOARD_BUTTON1_MASK (1 << 2) - #define _BOARD_BUTTON_PORTLETTER E - #elif (BOARD == BOARD_MICROPENDOUS_3) - #define _BOARD_BUTTON1_MASK (1 << 2) - #define _BOARD_BUTTON_PORTLETTER E - #elif (BOARD == BOARD_MICROPENDOUS_4) - #define _BOARD_BUTTON1_MASK (1 << 2) - #define _BOARD_BUTTON_PORTLETTER E - #elif (BOARD == BOARD_MICROPENDOUS_DIP) - #define _BOARD_BUTTON1_MASK (1 << 2) - #define _BOARD_BUTTON_PORTLETTER E - #elif (BOARD == BOARD_MICROPENDOUS_REV1) - #define _BOARD_BUTTON1_MASK (1 << 2) - #define _BOARD_BUTTON_PORTLETTER E - #elif (BOARD == BOARD_MICROPENDOUS_REV2) - #define _BOARD_BUTTON1_MASK (1 << 2) - #define _BOARD_BUTTON_PORTLETTER E - #endif - - #define _BOARD_BUTTON_CONCAT2(Reg, Letter) Reg ## Letter - #define _BOARD_BUTTON_CONCAT(Reg, Letter) _BOARD_BUTTON_CONCAT2(Reg, Letter) - - #define _BOARD_BUTTON_PORT _BOARD_BUTTON_CONCAT(PORT, _BOARD_BUTTON_PORTLETTER) - #define _BOARD_BUTTON_PIN _BOARD_BUTTON_CONCAT(PIN, _BOARD_BUTTON_PORTLETTER) - #define _BOARD_BUTTON_DDR _BOARD_BUTTON_CONCAT(DDR, _BOARD_BUTTON_PORTLETTER) - #endif - - /* Public Interface - May be used in end-application: */ - /* Macros: */ - /** Button mask for the first button on the board. */ - #define BUTTONS_BUTTON1 _BOARD_BUTTON1_MASK - - /* Inline Functions: */ - #if !defined(__DOXYGEN__) - static inline void Buttons_Init(void) - { - _BOARD_BUTTON_DDR &= ~BUTTONS_BUTTON1; - _BOARD_BUTTON_PORT |= BUTTONS_BUTTON1; - } - - static inline void Buttons_Disable(void) - { - _BOARD_BUTTON_DDR &= ~BUTTONS_BUTTON1; - _BOARD_BUTTON_PORT &= ~BUTTONS_BUTTON1; - } - - static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; - static inline uint8_t Buttons_GetStatus(void) - { - return ((_BOARD_BUTTON_PIN & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); - } - #endif - - /* Disable C linkage for C++ Compilers: */ - #if defined(__cplusplus) - } - #endif - -#endif - -/** @} */ - +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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 Board specific Buttons driver header for the Micropendous series boards. + * \copydetails Group_Buttons_MICROPENDOUS_32U2 + * + * \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_MICROPENDOUS_A MICROPENDOUS_A + * \brief Board specific Button driver header for the Micropendous A (https://code.google.com/p/micropendous/wiki/MicropendousA). + * + * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_MICROPENDOUS_1 MICROPENDOUS_1 + * \brief Board specific Button driver header for the Micropendous 1 (https://code.google.com/p/micropendous/wiki/Micropendous1). + * + * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_MICROPENDOUS_2 MICROPENDOUS_2 + * \brief Board specific Button driver header for the Micropendous 2 (https://code.google.com/p/micropendous/wiki/Micropendous2). + * + * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_MICROPENDOUS_3 MICROPENDOUS_3 + * \brief Board specific Button driver header for the Micropendous 3 (https://code.google.com/p/micropendous/wiki/Micropendous3). + * + * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_MICROPENDOUS_4 MICROPENDOUS_4 + * \brief Board specific Button driver header for the Micropendous 4 (https://code.google.com/p/micropendous/wiki/Micropendous4). + * + * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_MICROPENDOUS_DIP MICROPENDOUS_DIP + * \brief Board specific Button driver header for the Micropendous DIP (https://code.google.com/p/micropendous/wiki/MicropendousDIP). + * + * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_MICROPENDOUS_REV1 MICROPENDOUS_REV1 + * \brief Board specific Button driver header for the Micropendous Arduino-like Revision 1 (https://code.google.com/p/micropendous/wiki/Micropendous). + * + * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_MICROPENDOUS_REV2 MICROPENDOUS_REV2 + * \brief Board specific Button driver header for the Micropendous Arduino-like Revision 2 (https://code.google.com/p/micropendous/wiki/Micropendous). + * + * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_MICROPENDOUS_32U2 MICROPENDOUS_32U2 + * \brief Board specific Buttons driver header for the Micropendous 32U2. + * + * \note There are multiple supported Micropendous boards, compile with BOARD = MICROPENDOUS_{VERSION}. + * + * Board specific Buttons driver header for the Micropendous 32U2 (https://code.google.com/p/micropendous/wiki/Micropendous_32U2). + * + * BOARD_MICROPENDOUS_1 and BOARD_MICROPENDOUS_32U2: + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTD.7
+ * + * Other Revisions: + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTE.2
+ * + * @{ + */ + +#ifndef __BUTTONS_MICROPENDOUS_H__ +#define __BUTTONS_MICROPENDOUS_H__ + + /* Includes: */ + #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__) + #if (BOARD == BOARD_MICROPENDOUS_32U2) + #define _BOARD_BUTTON1_MASK (1 << 7) + #define _BOARD_BUTTON_PORTLETTER D + #elif (BOARD == BOARD_MICROPENDOUS_A) + #define _BOARD_BUTTON1_MASK (1 << 2) + #define _BOARD_BUTTON_PORTLETTER E + #elif (BOARD == BOARD_MICROPENDOUS_1) + #define _BOARD_BUTTON1_MASK (1 << 7) + #define _BOARD_BUTTON_PORTLETTER D + #elif (BOARD == BOARD_MICROPENDOUS_2) + #define _BOARD_BUTTON1_MASK (1 << 2) + #define _BOARD_BUTTON_PORTLETTER E + #elif (BOARD == BOARD_MICROPENDOUS_3) + #define _BOARD_BUTTON1_MASK (1 << 2) + #define _BOARD_BUTTON_PORTLETTER E + #elif (BOARD == BOARD_MICROPENDOUS_4) + #define _BOARD_BUTTON1_MASK (1 << 2) + #define _BOARD_BUTTON_PORTLETTER E + #elif (BOARD == BOARD_MICROPENDOUS_DIP) + #define _BOARD_BUTTON1_MASK (1 << 2) + #define _BOARD_BUTTON_PORTLETTER E + #elif (BOARD == BOARD_MICROPENDOUS_REV1) + #define _BOARD_BUTTON1_MASK (1 << 2) + #define _BOARD_BUTTON_PORTLETTER E + #elif (BOARD == BOARD_MICROPENDOUS_REV2) + #define _BOARD_BUTTON1_MASK (1 << 2) + #define _BOARD_BUTTON_PORTLETTER E + #endif + + #define _BOARD_BUTTON_CONCAT2(Reg, Letter) Reg ## Letter + #define _BOARD_BUTTON_CONCAT(Reg, Letter) _BOARD_BUTTON_CONCAT2(Reg, Letter) + + #define _BOARD_BUTTON_PORT _BOARD_BUTTON_CONCAT(PORT, _BOARD_BUTTON_PORTLETTER) + #define _BOARD_BUTTON_PIN _BOARD_BUTTON_CONCAT(PIN, _BOARD_BUTTON_PORTLETTER) + #define _BOARD_BUTTON_DDR _BOARD_BUTTON_CONCAT(DDR, _BOARD_BUTTON_PORTLETTER) + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 _BOARD_BUTTON1_MASK + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + _BOARD_BUTTON_DDR &= ~BUTTONS_BUTTON1; + _BOARD_BUTTON_PORT |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + _BOARD_BUTTON_DDR &= ~BUTTONS_BUTTON1; + _BOARD_BUTTON_PORT &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((_BOARD_BUTTON_PIN & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/LUFA/Drivers/Board/AVR8/MICROPENDOUS/LEDs.h b/LUFA/Drivers/Board/AVR8/MICROPENDOUS/LEDs.h index 60a49935..2d5bad42 100644 --- a/LUFA/Drivers/Board/AVR8/MICROPENDOUS/LEDs.h +++ b/LUFA/Drivers/Board/AVR8/MICROPENDOUS/LEDs.h @@ -145,13 +145,13 @@ static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) { - _BOARD_LED_PORT = ((PORTF & ~LEDS_ALL_LEDS) | LEDMask); + _BOARD_LED_PORT = ((_BOARD_LED_PORT & ~LEDS_ALL_LEDS) | LEDMask); } static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, const uint8_t ActiveMask) { - _BOARD_LED_PORT = ((PORTF & ~LEDMask) | ActiveMask); + _BOARD_LED_PORT = ((_BOARD_LED_PORT & ~LEDMask) | ActiveMask); } static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) diff --git a/LUFA/Drivers/Board/AVR8/MULTIO/LEDs.h b/LUFA/Drivers/Board/AVR8/MULTIO/LEDs.h index 64f68a53..14809df2 100644 --- a/LUFA/Drivers/Board/AVR8/MULTIO/LEDs.h +++ b/LUFA/Drivers/Board/AVR8/MULTIO/LEDs.h @@ -1,161 +1,161 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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 Board specific LED driver header for the Bitwizard Multio. - * \copydetails Group_LEDs_MULTIO - * - * \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_MULTIO MULTIO - * \brief Board specific LED driver header for the Bitwizard Multio. - * - * Board specific LED driver header for the Bitwizard Multio (http://www.bitwizard.nl/wiki/index.php/USB-multio). - * - * - * - * - * - * - *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorHighPORTD.0
LEDS_LED2GreenGeneral IndicatorHighPORTC.2
LEDS_LED3GreenGeneral IndicatorHighPORTD.7
- * - * @{ - */ - -#ifndef __LEDS_MULTIO_H__ -#define __LEDS_MULTIO_H__ - - /* Includes: */ - #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_PORTD_LEDS (LEDS_LED1 | LEDS_LED3) - #define LEDS_PORTC_LEDS LEDS_LED2 - #endif - - /* Public Interface - May be used in end-application: */ - /* Macros: */ - /** LED mask for the first LED on the board. */ - #define LEDS_LED1 (1 << 0) - - /** LED mask for the second LED on the board. */ - #define LEDS_LED2 (1 << 2) - - /** LED mask for the second LED on the board. */ - #define LEDS_LED3 (1 << 7) - - /** LED mask for all the LEDs on the board. */ - #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3) - - /** LED mask for none of the board LEDs. */ - #define LEDS_NO_LEDS 0 - - /* Inline Functions: */ - #if !defined(__DOXYGEN__) - static inline void LEDs_Init(void) - { - DDRD |= LEDS_PORTD_LEDS; - DDRC |= LEDS_PORTC_LEDS; - - PORTD &= ~LEDS_PORTD_LEDS; - PORTC &= ~LEDS_PORTC_LEDS; - } - - static inline void LEDs_Disable(void) - { - DDRD |= LEDS_PORTD_LEDS; - DDRC |= LEDS_PORTC_LEDS; - - PORTD &= ~LEDS_PORTD_LEDS; - PORTC &= ~LEDS_PORTC_LEDS; - } - - static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) - { - PORTD |= (LEDMask & LEDS_PORTD_LEDS); - PORTC |= (LEDMask & LEDS_PORTC_LEDS); - } - - static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) - { - PORTD &= ~(LEDMask & LEDS_PORTD_LEDS); - PORTC &= ~(LEDMask & LEDS_PORTC_LEDS); - } - - static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) - { - PORTD = (PORTD & ~LEDS_PORTD_LEDS) | (LEDMask & LEDS_PORTD_LEDS); - PORTC = (PORTC & ~LEDS_PORTC_LEDS) | (LEDMask & LEDS_PORTC_LEDS); - } - - static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, - const uint8_t ActiveMask) - { - PORTD = (PORTD & ~(LEDMask & LEDS_PORTD_LEDS)) | (ActiveMask & LEDS_PORTD_LEDS); - PORTC = (PORTC & ~(LEDMask & LEDS_PORTC_LEDS)) | (ActiveMask & LEDS_PORTC_LEDS); - } - - static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) - { - PIND = (LEDMask & LEDS_PORTD_LEDS); - PINC = (LEDMask & LEDS_PORTC_LEDS); - } - - static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; - static inline uint8_t LEDs_GetLEDs(void) - { - return ((PORTD & LEDS_PORTD_LEDS) | (PORTC & LEDS_PORTC_LEDS)); - } - #endif - - /* Disable C linkage for C++ Compilers: */ - #if defined(__cplusplus) - } - #endif - -#endif - -/** @} */ - +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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 Board specific LED driver header for the Bitwizard Multio. + * \copydetails Group_LEDs_MULTIO + * + * \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_MULTIO MULTIO + * \brief Board specific LED driver header for the Bitwizard Multio. + * + * Board specific LED driver header for the Bitwizard Multio (http://www.bitwizard.nl/wiki/index.php/USB-multio). + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorHighPORTD.0
LEDS_LED2GreenGeneral IndicatorHighPORTC.2
LEDS_LED3GreenGeneral IndicatorHighPORTD.7
+ * + * @{ + */ + +#ifndef __LEDS_MULTIO_H__ +#define __LEDS_MULTIO_H__ + + /* Includes: */ + #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_PORTD_LEDS (LEDS_LED1 | LEDS_LED3) + #define LEDS_PORTC_LEDS LEDS_LED2 + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 0) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 2) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED3 (1 << 7) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRD |= LEDS_PORTD_LEDS; + DDRC |= LEDS_PORTC_LEDS; + + PORTD &= ~LEDS_PORTD_LEDS; + PORTC &= ~LEDS_PORTC_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRD |= LEDS_PORTD_LEDS; + DDRC |= LEDS_PORTC_LEDS; + + PORTD &= ~LEDS_PORTD_LEDS; + PORTC &= ~LEDS_PORTC_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTD |= (LEDMask & LEDS_PORTD_LEDS); + PORTC |= (LEDMask & LEDS_PORTC_LEDS); + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTD &= ~(LEDMask & LEDS_PORTD_LEDS); + PORTC &= ~(LEDMask & LEDS_PORTC_LEDS); + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTD = (PORTD & ~LEDS_PORTD_LEDS) | (LEDMask & LEDS_PORTD_LEDS); + PORTC = (PORTC & ~LEDS_PORTC_LEDS) | (LEDMask & LEDS_PORTC_LEDS); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTD = (PORTD & ~(LEDMask & LEDS_PORTD_LEDS)) | (ActiveMask & LEDS_PORTD_LEDS); + PORTC = (PORTC & ~(LEDMask & LEDS_PORTC_LEDS)) | (ActiveMask & LEDS_PORTC_LEDS); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PIND = (LEDMask & LEDS_PORTD_LEDS); + PINC = (LEDMask & LEDS_PORTC_LEDS); + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return ((PORTD & LEDS_PORTD_LEDS) | (PORTC & LEDS_PORTC_LEDS)); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/LUFA/Drivers/Board/AVR8/USB2AX/Buttons.h b/LUFA/Drivers/Board/AVR8/USB2AX/Buttons.h index 73d05a5b..cb0eecdf 100644 --- a/LUFA/Drivers/Board/AVR8/USB2AX/Buttons.h +++ b/LUFA/Drivers/Board/AVR8/USB2AX/Buttons.h @@ -1,113 +1,113 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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 Board specific Buttons driver header for the Paranoid Studio USB2AX. - * \copydetails Group_Buttons_USB2AX - * - * \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_USB2AX_V3 USB2AX_V3 - * \brief Board specific Button driver header for the Paranoid Studio USB2AX revision 3. - * - * See \ref Group_Buttons_USB2AX for more details. - */ - -/** \ingroup Group_Buttons - * \defgroup Group_Buttons_USB2AX USB2AX - * \brief Board specific Buttons driver header for the Paranoid Studio USB2AX. - * - * \note For version 3 USB2AX boards, compile with BOARD = USB2AX_V3. - * - * Board specific Buttons driver header for the Paranoid Studio USB2AX (http://paranoidstudio.assembla.com/wiki/show/paranoidstudio/USB2AX). - * - * - * - * - *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTD.7
- * - * @{ - */ - -#ifndef __BUTTONS_USB2AX_H__ -#define __BUTTONS_USB2AX_H__ - - /* Includes: */ - #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 - - /* Public Interface - May be used in end-application: */ - /* Macros: */ - /** Button mask for the first button on the board. */ - #define BUTTONS_BUTTON1 (1 << 7) - - /* Inline Functions: */ - #if !defined(__DOXYGEN__) - static inline void Buttons_Init(void) - { - DDRD &= ~BUTTONS_BUTTON1; - PORTD |= BUTTONS_BUTTON1; - } - - static inline void Buttons_Disable(void) - { - DDRD &= ~BUTTONS_BUTTON1; - PORTD &= ~BUTTONS_BUTTON1; - } - - static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; - static inline uint8_t Buttons_GetStatus(void) - { - return ((PIND & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); - } - #endif - - /* Disable C linkage for C++ Compilers: */ - #if defined(__cplusplus) - } - #endif - -#endif - -/** @} */ - +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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 Board specific Buttons driver header for the Paranoid Studio USB2AX. + * \copydetails Group_Buttons_USB2AX + * + * \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_USB2AX_V3 USB2AX_V3 + * \brief Board specific Button driver header for the Paranoid Studio USB2AX revision 3. + * + * See \ref Group_Buttons_USB2AX for more details. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_USB2AX USB2AX + * \brief Board specific Buttons driver header for the Paranoid Studio USB2AX. + * + * \note For version 3 USB2AX boards, compile with BOARD = USB2AX_V3. + * + * Board specific Buttons driver header for the Paranoid Studio USB2AX (http://paranoidstudio.assembla.com/wiki/show/paranoidstudio/USB2AX). + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTD.7
+ * + * @{ + */ + +#ifndef __BUTTONS_USB2AX_H__ +#define __BUTTONS_USB2AX_H__ + + /* Includes: */ + #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 + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 7) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PIND & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/LUFA/Drivers/Board/AVR8/USB2AX/LEDs.h b/LUFA/Drivers/Board/AVR8/USB2AX/LEDs.h index 12fa73cd..364c88de 100644 --- a/LUFA/Drivers/Board/AVR8/USB2AX/LEDs.h +++ b/LUFA/Drivers/Board/AVR8/USB2AX/LEDs.h @@ -1,196 +1,196 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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 Board specific LED driver header for the Paranoid Studio USB2AX. - * \copydetails Group_LEDs_USB2AX - * - * \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_USB2AX_V3 USB2AX_V3 - * \brief Board specific LED driver header for the Paranoid Studio USB2AX revision 3. - * - * See \ref Group_LEDs_USB2AX for more details. - */ - -/** \ingroup Group_LEDs - * \defgroup Group_LEDs_USB2AX USB2AX - * \brief Board specific LED driver header for the Paranoid Studio USB2AX. - * - * \note For version 3 USB2AX boards, compile with BOARD = USB2AX_V3. - * - * Board specific LED driver header for the Paranoid Studio USB2AX (http://paranoidstudio.assembla.com/wiki/show/paranoidstudio/USB2AX). - * - * USB2AX: - * - * - * - *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorHighPORTC.6
- * - * USB2AX_V3: - * - * - * - *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorHighPORTD.1
- * - * @{ - */ - -#ifndef __LEDS_USB2AX_H__ -#define __LEDS_USB2AX_H__ - - /* Includes: */ - #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: */ - #if (BOARD == BOARD_USB2AX) - #define USB2AX_LEDS_LED1 (1 << 6) - #else - #define USB2AX_LEDS_LED1 (1 << 1) - #endif - #endif - - /* Public Interface - May be used in end-application: */ - /* Macros: */ - /** LED mask for the first LED on the board. */ - #define LEDS_LED1 USB2AX_LEDS_LED1 - - /** LED mask for all the LEDs on the board. */ - #define LEDS_ALL_LEDS LEDS_LED1 - - /** LED mask for none of the board LEDs. */ - #define LEDS_NO_LEDS 0 - - /* Inline Functions: */ - #if !defined(__DOXYGEN__) - static inline void LEDs_Init(void) - { - #if (BOARD == BOARD_USB2AX) - DDRC |= LEDS_ALL_LEDS; - PORTC &= ~LEDS_ALL_LEDS; - #else - DDRD |= LEDS_ALL_LEDS; - PORTD &= ~LEDS_ALL_LEDS; - #endif - } - - static inline void LEDs_Disable(void) - { - #if (BOARD == BOARD_USB2AX) - DDRC &= ~LEDS_ALL_LEDS; - PORTC &= ~LEDS_ALL_LEDS; - #else - DDRD &= ~LEDS_ALL_LEDS; - PORTD &= ~LEDS_ALL_LEDS; - #endif - } - - static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) - { - #if (BOARD == BOARD_USB2AX) - PORTC |= LEDMask; - #else - PORTD |= LEDMask; - #endif - } - - static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) - { - #if (BOARD == BOARD_USB2AX) - PORTC &= ~LEDMask; - #else - PORTD &= ~LEDMask; - #endif - } - - static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) - { - #if (BOARD == BOARD_USB2AX) - PORTC = ((PORTC & ~LEDS_ALL_LEDS) | LEDMask); - #else - PORTD = ((PORTD & ~LEDS_ALL_LEDS) | LEDMask); - #endif - } - - static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, - const uint8_t ActiveMask) - { - #if (BOARD == BOARD_USB2AX) - PORTC = ((PORTC & ~LEDMask) | ActiveMask); - #else - PORTD = ((PORTD & ~LEDMask) | ActiveMask); - #endif - } - - static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) - { - #if (BOARD == BOARD_USB2AX) - PINC = LEDMask; - #else - PIND = LEDMask; - #endif - } - - static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; - static inline uint8_t LEDs_GetLEDs(void) - { - #if (BOARD == BOARD_USB2AX) - return (PORTC & LEDS_ALL_LEDS); - #else - return (PORTD & LEDS_ALL_LEDS); - #endif - } - #endif - - /* Disable C linkage for C++ Compilers: */ - #if defined(__cplusplus) - } - #endif - -#endif - -/** @} */ - +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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 Board specific LED driver header for the Paranoid Studio USB2AX. + * \copydetails Group_LEDs_USB2AX + * + * \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_USB2AX_V3 USB2AX_V3 + * \brief Board specific LED driver header for the Paranoid Studio USB2AX revision 3. + * + * See \ref Group_LEDs_USB2AX for more details. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_USB2AX USB2AX + * \brief Board specific LED driver header for the Paranoid Studio USB2AX. + * + * \note For version 3 USB2AX boards, compile with BOARD = USB2AX_V3. + * + * Board specific LED driver header for the Paranoid Studio USB2AX (http://paranoidstudio.assembla.com/wiki/show/paranoidstudio/USB2AX). + * + * USB2AX: + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorHighPORTC.6
+ * + * USB2AX_V3: + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorHighPORTD.1
+ * + * @{ + */ + +#ifndef __LEDS_USB2AX_H__ +#define __LEDS_USB2AX_H__ + + /* Includes: */ + #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: */ + #if (BOARD == BOARD_USB2AX) + #define USB2AX_LEDS_LED1 (1 << 6) + #else + #define USB2AX_LEDS_LED1 (1 << 1) + #endif + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 USB2AX_LEDS_LED1 + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS LEDS_LED1 + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + #if (BOARD == BOARD_USB2AX) + DDRC |= LEDS_ALL_LEDS; + PORTC &= ~LEDS_ALL_LEDS; + #else + DDRD |= LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + #endif + } + + static inline void LEDs_Disable(void) + { + #if (BOARD == BOARD_USB2AX) + DDRC &= ~LEDS_ALL_LEDS; + PORTC &= ~LEDS_ALL_LEDS; + #else + DDRD &= ~LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + #endif + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + #if (BOARD == BOARD_USB2AX) + PORTC |= LEDMask; + #else + PORTD |= LEDMask; + #endif + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + #if (BOARD == BOARD_USB2AX) + PORTC &= ~LEDMask; + #else + PORTD &= ~LEDMask; + #endif + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + #if (BOARD == BOARD_USB2AX) + PORTC = ((PORTC & ~LEDS_ALL_LEDS) | LEDMask); + #else + PORTD = ((PORTD & ~LEDS_ALL_LEDS) | LEDMask); + #endif + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + #if (BOARD == BOARD_USB2AX) + PORTC = ((PORTC & ~LEDMask) | ActiveMask); + #else + PORTD = ((PORTD & ~LEDMask) | ActiveMask); + #endif + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + #if (BOARD == BOARD_USB2AX) + PINC = LEDMask; + #else + PIND = LEDMask; + #endif + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + #if (BOARD == BOARD_USB2AX) + return (PORTC & LEDS_ALL_LEDS); + #else + return (PORTD & LEDS_ALL_LEDS); + #endif + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/LUFA/Drivers/Board/Buttons.h b/LUFA/Drivers/Board/Buttons.h index 1b70a6bd..73ccb419 100644 --- a/LUFA/Drivers/Board/Buttons.h +++ b/LUFA/Drivers/Board/Buttons.h @@ -160,7 +160,7 @@ */ static inline void Buttons_Init(void); - /** Disables the buttons driver, releasing the I/O pins back to their default high-impedence input mode. */ + /** Disables the buttons driver, releasing the I/O pins back to their default high-impedance input mode. */ static inline void Buttons_Disable(void); /** Returns a mask indicating which board buttons are currently pressed. diff --git a/LUFA/Drivers/Board/Joystick.h b/LUFA/Drivers/Board/Joystick.h index 63d28e83..2f90a9ca 100644 --- a/LUFA/Drivers/Board/Joystick.h +++ b/LUFA/Drivers/Board/Joystick.h @@ -126,7 +126,7 @@ */ static inline void Joystick_Init(void); - /** Disables the joystick driver, releasing the I/O pins back to their default high-impedence input mode. */ + /** Disables the joystick driver, releasing the I/O pins back to their default high-impedance input mode. */ static inline void Joystick_Disable(void); /** Returns the current status of the joystick, as a mask indicating the direction the joystick is diff --git a/LUFA/Drivers/Board/LEDs.h b/LUFA/Drivers/Board/LEDs.h index 97cb81a5..21f89aa5 100644 --- a/LUFA/Drivers/Board/LEDs.h +++ b/LUFA/Drivers/Board/LEDs.h @@ -63,7 +63,7 @@ * * \note To make code as compatible as possible, it is assumed that all boards carry a minimum of four LEDs. If * a board contains less than four LEDs, the remaining LED masks are defined to 0 so as to have no effect. - * If other behaviour is desired, either alias the remaining LED masks to existing LED masks via the -D + * If other behavior is desired, either alias the remaining LED masks to existing LED masks via the -D * switch in the project makefile, or alias them to nothing in the makefile to cause compilation errors when * a non-existing LED is referenced in application code. Note that this means that it is possible to make * compatible code for a board with no LEDs by making a board LED driver (see \ref Page_WritingBoardDrivers) @@ -221,7 +221,7 @@ */ static inline void LEDs_Init(void); - /** Disables the board LED driver, releasing the I/O pins back to their default high-impedence input mode. */ + /** Disables the board LED driver, releasing the I/O pins back to their default high-impedance input mode. */ static inline void LEDs_Disable(void); /** Turns on the LEDs specified in the given LED mask. diff --git a/LUFA/Drivers/Board/UC3/EVK1101/Buttons.h b/LUFA/Drivers/Board/UC3/EVK1101/Buttons.h index 89714790..f1a9b992 100644 --- a/LUFA/Drivers/Board/UC3/EVK1101/Buttons.h +++ b/LUFA/Drivers/Board/UC3/EVK1101/Buttons.h @@ -98,7 +98,7 @@ static inline uint32_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; static inline uint32_t Buttons_GetStatus(void) { - return (~(AVR32_GPIO.port[JOY_MOVE_PORT].pvr & (BUTTONS_BUTTON1 | BUTTONS_BUTTON2))); + return (~(AVR32_GPIO.port[BUTTONS_PORT].pvr & (BUTTONS_BUTTON1 | BUTTONS_BUTTON2))); } #endif diff --git a/LUFA/Drivers/Peripheral/AVR8/ADC_AVR8.h b/LUFA/Drivers/Peripheral/AVR8/ADC_AVR8.h index c04d2ba8..d85fddc2 100644 --- a/LUFA/Drivers/Peripheral/AVR8/ADC_AVR8.h +++ b/LUFA/Drivers/Peripheral/AVR8/ADC_AVR8.h @@ -248,7 +248,7 @@ #define ADC_INT_TEMP_SENS ((1 << 8) | (0x07 << MUX0)) #endif - /** MUX mask define for the internal 1.1V bandgap channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). */ + /** MUX mask define for the internal 1.1V band-gap channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). */ #define ADC_1100MV_BANDGAP (0x1E << MUX0) /** Retrieves the ADC MUX mask for the given ADC channel number. diff --git a/LUFA/Drivers/USB/Class/AndroidAccessoryClass.h b/LUFA/Drivers/USB/Class/AndroidAccessoryClass.h index 3cede602..7b1fbfcc 100644 --- a/LUFA/Drivers/USB/Class/AndroidAccessoryClass.h +++ b/LUFA/Drivers/USB/Class/AndroidAccessoryClass.h @@ -1,76 +1,76 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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 Master include file for the library USB Android Open Accessory Class driver. - * - * Master include file for the library USB Android Open Accessory Class driver, for both host and device modes, where available. - * - * This file should be included in all user projects making use of this optional class driver, instead of - * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. - */ - -/** \ingroup Group_USBClassDrivers - * \defgroup Group_USBClassAOA Android Open Accessory Class Driver - * - * \section Sec_Dependencies Module Source Dependencies - * The following files must be built with any user project that uses this module: - * - LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) - * - * \section Sec_ModDescription Module Description - * Android Open Accessory Class Driver module. This module contains an internal implementation of the USB Android Open Accessory - * Class, for Host USB mode. User applications can use this class driver instead of implementing the Android Open Accessory Class - * manually via the low-level LUFA APIs. - * - * This module is designed to simplify the user code by exposing only the required interface needed to interface with - * Host using the USB Android Open Accessory Class. - * - * @{ - */ - -#ifndef _AOA_CLASS_H_ -#define _AOA_CLASS_H_ - - /* Macros: */ - #define __INCLUDE_FROM_USB_DRIVER - #define __INCLUDE_FROM_AOA_DRIVER - - /* Includes: */ - #include "../Core/USBMode.h" - - #if defined(USB_CAN_BE_HOST) - #include "Host/AndroidAccessoryClassHost.h" - #endif - -#endif - -/** @} */ - +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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 Master include file for the library USB Android Open Accessory Class driver. + * + * Master include file for the library USB Android Open Accessory Class driver, for both host and device modes, where available. + * + * This file should be included in all user projects making use of this optional class driver, instead of + * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. + */ + +/** \ingroup Group_USBClassDrivers + * \defgroup Group_USBClassAOA Android Open Accessory Class Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Android Open Accessory Class Driver module. This module contains an internal implementation of the USB Android Open Accessory + * Class, for Host USB mode. User applications can use this class driver instead of implementing the Android Open Accessory Class + * manually via the low-level LUFA APIs. + * + * This module is designed to simplify the user code by exposing only the required interface needed to interface with + * Host using the USB Android Open Accessory Class. + * + * @{ + */ + +#ifndef _AOA_CLASS_H_ +#define _AOA_CLASS_H_ + + /* Macros: */ + #define __INCLUDE_FROM_USB_DRIVER + #define __INCLUDE_FROM_AOA_DRIVER + + /* Includes: */ + #include "../Core/USBMode.h" + + #if defined(USB_CAN_BE_HOST) + #include "Host/AndroidAccessoryClassHost.h" + #endif + +#endif + +/** @} */ + diff --git a/LUFA/Drivers/USB/Class/Common/AndroidAccessoryClassCommon.h b/LUFA/Drivers/USB/Class/Common/AndroidAccessoryClassCommon.h index c1c0e8df..dc1289da 100644 --- a/LUFA/Drivers/USB/Class/Common/AndroidAccessoryClassCommon.h +++ b/LUFA/Drivers/USB/Class/Common/AndroidAccessoryClassCommon.h @@ -1,128 +1,128 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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 Common definitions and declarations for the library USB Android Open Accessory Class driver. - * - * Common definitions and declarations for the library USB Android Open Accessory Class driver. - * - * \note This file should not be included directly. It is automatically included as needed by the USB module driver - * dispatch header located in LUFA/Drivers/USB.h. - */ - -/** \ingroup Group_USBClassAOA - * \defgroup Group_USBClassAOACommon Common Class Definitions - * - * \section Sec_ModDescription Module Description - * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB - * Android Open Accessory Class. - * - * @{ - */ - -#ifndef _AOA_CLASS_COMMON_H_ -#define _AOA_CLASS_COMMON_H_ - - /* Includes: */ - #include "../../Core/StdDescriptors.h" - - /* Enable C linkage for C++ Compilers: */ - #if defined(__cplusplus) - extern "C" { - #endif - - /* Preprocessor Checks: */ - #if !defined(__INCLUDE_FROM_AOA_DRIVER) - #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. - #endif - - /* Macros: */ - /** Product ID value in a Device Descriptor to indicate an Android device in Open Accessory mode. */ - #define ANDROID_ACCESSORY_PRODUCT_ID 0x2D00 - - /** Product ID value in a Device Descriptor to indicate an Android device in Open Accessory and Android Debug mode. */ - #define ANDROID_ACCESSORY_ADB_PRODUCT_ID 0x2D01 - - /* Enums: */ - /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the - * Android Open Accessory class. - */ - enum AOA_Descriptor_ClassSubclassProtocol_t - { - AOA_CSCP_AOADataClass = 0xFF, /**< Descriptor Class value indicating that the device or interface - * belongs to the AOA data class. - */ - AOA_CSCP_AOADataSubclass = 0xFF, /**< Descriptor Subclass value indicating that the device or interface - * belongs to AOA data subclass. - */ - AOA_CSCP_AOADataProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or interface - * belongs to the AOA data class protocol. - */ - }; - - /** Enum for the Android Open Accessory class specific control requests that can be issued by the USB bus host. */ - enum AOA_ClassRequests_t - { - AOA_REQ_GetAccessoryProtocol = 0x33, /**< Android Open Accessory control request to retrieve the device's supported Accessory Protocol version. */ - AOA_REQ_SendString = 0x34, /**< Android Open Accessory control request to set an accessory property string in the device. */ - AOA_REQ_StartAccessoryMode = 0x35, /**< Android Open Accessory control request to switch the device into Accessory mode. */ - }; - - /** Enum for the possible Android Open Accessory property string indexes. */ - enum AOA_Strings_t - { - AOA_STRING_Manufacturer = 0, /**< Index of the Manufacturer property string. */ - AOA_STRING_Model = 1, /**< Index of the Model Name property string. */ - AOA_STRING_Description = 2, /**< Index of the Description property string. */ - AOA_STRING_Version = 3, /**< Index of the Version Number property string. */ - AOA_STRING_URI = 4, /**< Index of the URI Information property string. */ - AOA_STRING_Serial = 5, /**< Index of the Serial Number property string. */ - - #if !defined(__DOXYGEN__) - AOA_STRING_TOTAL_STRINGS - #endif - }; - - /** Enum for the possible Android Open Accessory protocol versions. */ - enum AOA_Protocols_t - { - AOA_PROTOCOL_AccessoryV1 = 0x0001, /**< Android Open Accessory version 1. */ - }; - - /* Disable C linkage for C++ Compilers: */ - #if defined(__cplusplus) - } - #endif - -#endif - -/** @} */ - +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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 Common definitions and declarations for the library USB Android Open Accessory Class driver. + * + * Common definitions and declarations for the library USB Android Open Accessory Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassAOA + * \defgroup Group_USBClassAOACommon Common Class Definitions + * + * \section Sec_ModDescription Module Description + * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB + * Android Open Accessory Class. + * + * @{ + */ + +#ifndef _AOA_CLASS_COMMON_H_ +#define _AOA_CLASS_COMMON_H_ + + /* Includes: */ + #include "../../Core/StdDescriptors.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_AOA_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Macros: */ + /** Product ID value in a Device Descriptor to indicate an Android device in Open Accessory mode. */ + #define ANDROID_ACCESSORY_PRODUCT_ID 0x2D00 + + /** Product ID value in a Device Descriptor to indicate an Android device in Open Accessory and Android Debug mode. */ + #define ANDROID_ACCESSORY_ADB_PRODUCT_ID 0x2D01 + + /* Enums: */ + /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the + * Android Open Accessory class. + */ + enum AOA_Descriptor_ClassSubclassProtocol_t + { + AOA_CSCP_AOADataClass = 0xFF, /**< Descriptor Class value indicating that the device or interface + * belongs to the AOA data class. + */ + AOA_CSCP_AOADataSubclass = 0xFF, /**< Descriptor Subclass value indicating that the device or interface + * belongs to AOA data subclass. + */ + AOA_CSCP_AOADataProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or interface + * belongs to the AOA data class protocol. + */ + }; + + /** Enum for the Android Open Accessory class specific control requests that can be issued by the USB bus host. */ + enum AOA_ClassRequests_t + { + AOA_REQ_GetAccessoryProtocol = 0x33, /**< Android Open Accessory control request to retrieve the device's supported Accessory Protocol version. */ + AOA_REQ_SendString = 0x34, /**< Android Open Accessory control request to set an accessory property string in the device. */ + AOA_REQ_StartAccessoryMode = 0x35, /**< Android Open Accessory control request to switch the device into Accessory mode. */ + }; + + /** Enum for the possible Android Open Accessory property string indexes. */ + enum AOA_Strings_t + { + AOA_STRING_Manufacturer = 0, /**< Index of the Manufacturer property string. */ + AOA_STRING_Model = 1, /**< Index of the Model Name property string. */ + AOA_STRING_Description = 2, /**< Index of the Description property string. */ + AOA_STRING_Version = 3, /**< Index of the Version Number property string. */ + AOA_STRING_URI = 4, /**< Index of the URI Information property string. */ + AOA_STRING_Serial = 5, /**< Index of the Serial Number property string. */ + + #if !defined(__DOXYGEN__) + AOA_STRING_TOTAL_STRINGS + #endif + }; + + /** Enum for the possible Android Open Accessory protocol versions. */ + enum AOA_Protocols_t + { + AOA_PROTOCOL_AccessoryV1 = 0x0001, /**< Android Open Accessory version 1. */ + }; + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/LUFA/Drivers/USB/Class/Device/AudioClassDevice.h b/LUFA/Drivers/USB/Class/Device/AudioClassDevice.h index a8bfc783..52c5a1aa 100644 --- a/LUFA/Drivers/USB/Class/Device/AudioClassDevice.h +++ b/LUFA/Drivers/USB/Class/Device/AudioClassDevice.h @@ -124,7 +124,7 @@ * * When the DataLength parameter is NULL, this callback should only indicate whether the specified operation is valid for * the given endpoint index, and should return as fast as possible. When non-NULL, this value may be altered for GET operations - * to indicate the size of the retreived data. + * to indicate the size of the retrieved data. * * \note The length of the retrieved data stored into the Data buffer on GET operations should not exceed the initial value * of the \c DataLength parameter. @@ -153,7 +153,7 @@ * * When the DataLength parameter is NULL, this callback should only indicate whether the specified operation is valid for * the given entity and should return as fast as possible. When non-NULL, this value may be altered for GET operations - * to indicate the size of the retreived data. + * to indicate the size of the retrieved data. * * \note The length of the retrieved data stored into the Data buffer on GET operations should not exceed the initial value * of the \c DataLength parameter. diff --git a/LUFA/Drivers/USB/Class/Device/CDCClassDevice.h b/LUFA/Drivers/USB/Class/Device/CDCClassDevice.h index 508c234d..3304775e 100644 --- a/LUFA/Drivers/USB/Class/Device/CDCClassDevice.h +++ b/LUFA/Drivers/USB/Class/Device/CDCClassDevice.h @@ -283,6 +283,7 @@ */ void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + #if defined(FDEV_SETUP_STREAM) || defined(__DOXYGEN__) /** Creates a standard character stream for the given CDC Device instance so that it can be used with all the regular * functions in the standard library that accept a \c FILE stream as a destination (e.g. \c fprintf()). The created * stream is bidirectional and can be used for both input and output functions. @@ -314,7 +315,8 @@ */ void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); - + #endif + /* Private Interface - For use in library only: */ #if !defined(__DOXYGEN__) /* Function Prototypes: */ diff --git a/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.h b/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.h index 2703600e..52aa9a15 100644 --- a/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.h +++ b/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.h @@ -130,7 +130,7 @@ /** Flushes the MIDI send buffer, sending any queued MIDI events to the host. This should be called to override the - * \ref MIDI_Device_SendEventPacket() function's packing behaviour, to flush queued events. + * \ref MIDI_Device_SendEventPacket() function's packing behavior, to flush queued events. * * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state. * diff --git a/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c b/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c index 7c564e01..f71fa2b9 100644 --- a/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c +++ b/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c @@ -1,422 +1,422 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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 "../../Core/USBMode.h" - -#if defined(USB_CAN_BE_HOST) - -#define __INCLUDE_FROM_AOA_DRIVER -#define __INCLUDE_FROM_ANDROIDACCESSORY_HOST_C -#include "AndroidAccessoryClassHost.h" - -bool AOA_Host_ValidateAccessoryDevice(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, - const USB_Descriptor_Device_t* const DeviceDescriptor, - bool* const NeedModeSwitch) -{ - (void)AOAInterfaceInfo; - - if (DeviceDescriptor->Header.Type != DTYPE_Device) - return false; - - *NeedModeSwitch = ((DeviceDescriptor->ProductID != ANDROID_ACCESSORY_PRODUCT_ID) && - (DeviceDescriptor->ProductID != ANDROID_ACCESSORY_ADB_PRODUCT_ID)); - - return true; -} - -uint8_t AOA_Host_ConfigurePipes(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, - uint16_t ConfigDescriptorSize, - void* ConfigDescriptorData) -{ - USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; - USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; - USB_Descriptor_Interface_t* AOAInterface = NULL; - - memset(&AOAInterfaceInfo->State, 0x00, sizeof(AOAInterfaceInfo->State)); - - if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) - return AOA_ENUMERROR_InvalidConfigDescriptor; - - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, - DCOMP_AOA_Host_NextAndroidAccessoryInterface) != DESCRIPTOR_SEARCH_COMP_Found) - { - return AOA_ENUMERROR_NoCompatibleInterfaceFound; - } - - AOAInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); - - while (!(DataINEndpoint) || !(DataOUTEndpoint)) - { - if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, - DCOMP_AOA_Host_NextInterfaceBulkEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) - { - return AOA_ENUMERROR_NoCompatibleInterfaceFound; - } - - USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); - - if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) - DataINEndpoint = EndpointData; - else - DataOUTEndpoint = EndpointData; - } - - AOAInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize); - AOAInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress; - AOAInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK; - - AOAInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize); - AOAInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress; - AOAInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK; - - if (!(Pipe_ConfigurePipeTable(&AOAInterfaceInfo->Config.DataINPipe, 1))) - return false; - - if (!(Pipe_ConfigurePipeTable(&AOAInterfaceInfo->Config.DataOUTPipe, 1))) - return false; - - AOAInterfaceInfo->State.IsActive = true; - AOAInterfaceInfo->State.InterfaceNumber = AOAInterface->InterfaceNumber; - - return AOA_ENUMERROR_NoError; -} - -static uint8_t DCOMP_AOA_Host_NextAndroidAccessoryInterface(void* const CurrentDescriptor) -{ - USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); - - if (Header->Type == DTYPE_Interface) - { - USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); - - if ((Interface->Class == AOA_CSCP_AOADataClass) && - (Interface->SubClass == AOA_CSCP_AOADataSubclass) && - (Interface->Protocol == AOA_CSCP_AOADataProtocol)) - { - return DESCRIPTOR_SEARCH_Found; - } - } - - return DESCRIPTOR_SEARCH_NotFound; -} - -static uint8_t DCOMP_AOA_Host_NextInterfaceBulkEndpoint(void* const CurrentDescriptor) -{ - USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); - - if (Header->Type == DTYPE_Endpoint) - { - USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t); - - uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK); - - if ((EndpointType == EP_TYPE_BULK) && (!(Pipe_IsEndpointBound(Endpoint->EndpointAddress)))) - return DESCRIPTOR_SEARCH_Found; - } - else if (Header->Type == DTYPE_Interface) - { - return DESCRIPTOR_SEARCH_Fail; - } - - return DESCRIPTOR_SEARCH_NotFound; -} - -void AOA_Host_USBTask(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) -{ - if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) - return; - - #if !defined(NO_CLASS_DRIVER_AUTOFLUSH) - AOA_Host_Flush(AOAInterfaceInfo); - #endif -} - -uint8_t AOA_Host_StartAccessoryMode(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) -{ - uint8_t ErrorCode; - - uint16_t AccessoryProtocol; - if ((ErrorCode = AOA_Host_GetAccessoryProtocol(&AccessoryProtocol)) != HOST_WAITERROR_Successful) - return ErrorCode; - - if (AccessoryProtocol != CPU_TO_LE16(AOA_PROTOCOL_AccessoryV1)) - return AOA_ERROR_LOGICAL_CMD_FAILED; - - for (uint8_t PropertyIndex = 0; PropertyIndex < AOA_STRING_TOTAL_STRINGS; PropertyIndex++) - { - if ((ErrorCode = AOA_Host_SendPropertyString(AOAInterfaceInfo, PropertyIndex)) != HOST_WAITERROR_Successful) - return ErrorCode; - } - - USB_ControlRequest = (USB_Request_Header_t) - { - .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | REQREC_DEVICE), - .bRequest = AOA_REQ_StartAccessoryMode, - .wValue = 0, - .wIndex = 0, - .wLength = 0, - }; - - Pipe_SelectPipe(PIPE_CONTROLPIPE); - return USB_Host_SendControlRequest(NULL); -} - -static uint8_t AOA_Host_GetAccessoryProtocol(uint16_t* const Protocol) -{ - USB_ControlRequest = (USB_Request_Header_t) - { - .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_DEVICE), - .bRequest = AOA_REQ_GetAccessoryProtocol, - .wValue = 0, - .wIndex = 0, - .wLength = sizeof(uint16_t), - }; - - Pipe_SelectPipe(PIPE_CONTROLPIPE); - return USB_Host_SendControlRequest(Protocol); -} - -static uint8_t AOA_Host_SendPropertyString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, - const uint8_t StringIndex) -{ - const char* String = AOAInterfaceInfo->Config.PropertyStrings[StringIndex]; - - if (String == NULL) - String = ""; - - USB_ControlRequest = (USB_Request_Header_t) - { - .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | REQREC_DEVICE), - .bRequest = AOA_REQ_SendString, - .wValue = 0, - .wIndex = StringIndex, - .wLength = (strlen(String) + 1), - }; - - Pipe_SelectPipe(PIPE_CONTROLPIPE); - return USB_Host_SendControlRequest((char*)String); -} - -uint8_t AOA_Host_SendData(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, - const uint8_t* const Buffer, - const uint16_t Length) -{ - if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) - return PIPE_READYWAIT_DeviceDisconnected; - - uint8_t ErrorCode; - - Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipe.Address); - - Pipe_Unfreeze(); - ErrorCode = Pipe_Write_Stream_LE(Buffer, Length, NULL); - Pipe_Freeze(); - - return ErrorCode; -} - -uint8_t AOA_Host_SendString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, - const char* const String) -{ - if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) - return PIPE_READYWAIT_DeviceDisconnected; - - uint8_t ErrorCode; - - Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipe.Address); - - Pipe_Unfreeze(); - ErrorCode = Pipe_Write_Stream_LE(String, strlen(String), NULL); - Pipe_Freeze(); - - return ErrorCode; -} - -uint8_t AOA_Host_SendByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, - const uint8_t Data) -{ - if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) - return PIPE_READYWAIT_DeviceDisconnected; - - uint8_t ErrorCode; - - Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipe.Address); - Pipe_Unfreeze(); - - if (!(Pipe_IsReadWriteAllowed())) - { - Pipe_ClearOUT(); - - if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) - return ErrorCode; - } - - Pipe_Write_8(Data); - Pipe_Freeze(); - - return PIPE_READYWAIT_NoError; -} - -uint16_t AOA_Host_BytesReceived(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) -{ - if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) - return 0; - - Pipe_SelectPipe(AOAInterfaceInfo->Config.DataINPipe.Address); - Pipe_Unfreeze(); - - if (Pipe_IsINReceived()) - { - if (!(Pipe_BytesInPipe())) - { - Pipe_ClearIN(); - Pipe_Freeze(); - return 0; - } - else - { - Pipe_Freeze(); - return Pipe_BytesInPipe(); - } - } - else - { - Pipe_Freeze(); - - return 0; - } -} - -int16_t AOA_Host_ReceiveByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) -{ - if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) - return -1; - - int16_t ReceivedByte = -1; - - Pipe_SelectPipe(AOAInterfaceInfo->Config.DataINPipe.Address); - Pipe_Unfreeze(); - - if (Pipe_IsINReceived()) - { - if (Pipe_BytesInPipe()) - ReceivedByte = Pipe_Read_8(); - - if (!(Pipe_BytesInPipe())) - Pipe_ClearIN(); - } - - Pipe_Freeze(); - - return ReceivedByte; -} - -uint8_t AOA_Host_Flush(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) -{ - if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) - return PIPE_READYWAIT_DeviceDisconnected; - - uint8_t ErrorCode; - - Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipe.Address); - Pipe_Unfreeze(); - - if (!(Pipe_BytesInPipe())) - return PIPE_READYWAIT_NoError; - - bool BankFull = !(Pipe_IsReadWriteAllowed()); - - Pipe_ClearOUT(); - - if (BankFull) - { - if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) - return ErrorCode; - - Pipe_ClearOUT(); - } - - Pipe_Freeze(); - - return PIPE_READYWAIT_NoError; -} - -#if defined(FDEV_SETUP_STREAM) -void AOA_Host_CreateStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, - FILE* const Stream) -{ - *Stream = (FILE)FDEV_SETUP_STREAM(AOA_Host_putchar, AOA_Host_getchar, _FDEV_SETUP_RW); - fdev_set_udata(Stream, AOAInterfaceInfo); -} - -void AOA_Host_CreateBlockingStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, - FILE* const Stream) -{ - *Stream = (FILE)FDEV_SETUP_STREAM(AOA_Host_putchar, AOA_Host_getchar_Blocking, _FDEV_SETUP_RW); - fdev_set_udata(Stream, AOAInterfaceInfo); -} - -static int AOA_Host_putchar(char c, - FILE* Stream) -{ - return AOA_Host_SendByte((USB_ClassInfo_AOA_Host_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0; -} - -static int AOA_Host_getchar(FILE* Stream) -{ - int16_t ReceivedByte = AOA_Host_ReceiveByte((USB_ClassInfo_AOA_Host_t*)fdev_get_udata(Stream)); - - if (ReceivedByte < 0) - return _FDEV_EOF; - - return ReceivedByte; -} - -static int AOA_Host_getchar_Blocking(FILE* Stream) -{ - int16_t ReceivedByte; - - while ((ReceivedByte = AOA_Host_ReceiveByte((USB_ClassInfo_AOA_Host_t*)fdev_get_udata(Stream))) < 0) - { - if (USB_HostState == HOST_STATE_Unattached) - return _FDEV_EOF; - - AOA_Host_USBTask((USB_ClassInfo_AOA_Host_t*)fdev_get_udata(Stream)); - USB_USBTask(); - } - - return ReceivedByte; -} -#endif - -#endif - +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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 "../../Core/USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#define __INCLUDE_FROM_AOA_DRIVER +#define __INCLUDE_FROM_ANDROIDACCESSORY_HOST_C +#include "AndroidAccessoryClassHost.h" + +bool AOA_Host_ValidateAccessoryDevice(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + const USB_Descriptor_Device_t* const DeviceDescriptor, + bool* const NeedModeSwitch) +{ + (void)AOAInterfaceInfo; + + if (DeviceDescriptor->Header.Type != DTYPE_Device) + return false; + + *NeedModeSwitch = ((DeviceDescriptor->ProductID != ANDROID_ACCESSORY_PRODUCT_ID) && + (DeviceDescriptor->ProductID != ANDROID_ACCESSORY_ADB_PRODUCT_ID)); + + return true; +} + +uint8_t AOA_Host_ConfigurePipes(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + uint16_t ConfigDescriptorSize, + void* ConfigDescriptorData) +{ + USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; + USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; + USB_Descriptor_Interface_t* AOAInterface = NULL; + + memset(&AOAInterfaceInfo->State, 0x00, sizeof(AOAInterfaceInfo->State)); + + if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) + return AOA_ENUMERROR_InvalidConfigDescriptor; + + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_AOA_Host_NextAndroidAccessoryInterface) != DESCRIPTOR_SEARCH_COMP_Found) + { + return AOA_ENUMERROR_NoCompatibleInterfaceFound; + } + + AOAInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); + + while (!(DataINEndpoint) || !(DataOUTEndpoint)) + { + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_AOA_Host_NextInterfaceBulkEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) + { + return AOA_ENUMERROR_NoCompatibleInterfaceFound; + } + + USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); + + if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) + DataINEndpoint = EndpointData; + else + DataOUTEndpoint = EndpointData; + } + + AOAInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize); + AOAInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress; + AOAInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK; + + AOAInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize); + AOAInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress; + AOAInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK; + + if (!(Pipe_ConfigurePipeTable(&AOAInterfaceInfo->Config.DataINPipe, 1))) + return false; + + if (!(Pipe_ConfigurePipeTable(&AOAInterfaceInfo->Config.DataOUTPipe, 1))) + return false; + + AOAInterfaceInfo->State.IsActive = true; + AOAInterfaceInfo->State.InterfaceNumber = AOAInterface->InterfaceNumber; + + return AOA_ENUMERROR_NoError; +} + +static uint8_t DCOMP_AOA_Host_NextAndroidAccessoryInterface(void* const CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Interface) + { + USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); + + if ((Interface->Class == AOA_CSCP_AOADataClass) && + (Interface->SubClass == AOA_CSCP_AOADataSubclass) && + (Interface->Protocol == AOA_CSCP_AOADataProtocol)) + { + return DESCRIPTOR_SEARCH_Found; + } + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +static uint8_t DCOMP_AOA_Host_NextInterfaceBulkEndpoint(void* const CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Endpoint) + { + USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t); + + uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK); + + if ((EndpointType == EP_TYPE_BULK) && (!(Pipe_IsEndpointBound(Endpoint->EndpointAddress)))) + return DESCRIPTOR_SEARCH_Found; + } + else if (Header->Type == DTYPE_Interface) + { + return DESCRIPTOR_SEARCH_Fail; + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +void AOA_Host_USBTask(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) + return; + + #if !defined(NO_CLASS_DRIVER_AUTOFLUSH) + AOA_Host_Flush(AOAInterfaceInfo); + #endif +} + +uint8_t AOA_Host_StartAccessoryMode(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) +{ + uint8_t ErrorCode; + + uint16_t AccessoryProtocol; + if ((ErrorCode = AOA_Host_GetAccessoryProtocol(&AccessoryProtocol)) != HOST_WAITERROR_Successful) + return ErrorCode; + + if (AccessoryProtocol != CPU_TO_LE16(AOA_PROTOCOL_AccessoryV1)) + return AOA_ERROR_LOGICAL_CMD_FAILED; + + for (uint8_t PropertyIndex = 0; PropertyIndex < AOA_STRING_TOTAL_STRINGS; PropertyIndex++) + { + if ((ErrorCode = AOA_Host_SendPropertyString(AOAInterfaceInfo, PropertyIndex)) != HOST_WAITERROR_Successful) + return ErrorCode; + } + + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | REQREC_DEVICE), + .bRequest = AOA_REQ_StartAccessoryMode, + .wValue = 0, + .wIndex = 0, + .wLength = 0, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + return USB_Host_SendControlRequest(NULL); +} + +static uint8_t AOA_Host_GetAccessoryProtocol(uint16_t* const Protocol) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_DEVICE), + .bRequest = AOA_REQ_GetAccessoryProtocol, + .wValue = 0, + .wIndex = 0, + .wLength = sizeof(uint16_t), + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + return USB_Host_SendControlRequest(Protocol); +} + +static uint8_t AOA_Host_SendPropertyString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + const uint8_t StringIndex) +{ + const char* String = AOAInterfaceInfo->Config.PropertyStrings[StringIndex]; + + if (String == NULL) + String = ""; + + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | REQREC_DEVICE), + .bRequest = AOA_REQ_SendString, + .wValue = 0, + .wIndex = StringIndex, + .wLength = (strlen(String) + 1), + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + return USB_Host_SendControlRequest((char*)String); +} + +uint8_t AOA_Host_SendData(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + const uint8_t* const Buffer, + const uint16_t Length) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) + return PIPE_READYWAIT_DeviceDisconnected; + + uint8_t ErrorCode; + + Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipe.Address); + + Pipe_Unfreeze(); + ErrorCode = Pipe_Write_Stream_LE(Buffer, Length, NULL); + Pipe_Freeze(); + + return ErrorCode; +} + +uint8_t AOA_Host_SendString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + const char* const String) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) + return PIPE_READYWAIT_DeviceDisconnected; + + uint8_t ErrorCode; + + Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipe.Address); + + Pipe_Unfreeze(); + ErrorCode = Pipe_Write_Stream_LE(String, strlen(String), NULL); + Pipe_Freeze(); + + return ErrorCode; +} + +uint8_t AOA_Host_SendByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + const uint8_t Data) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) + return PIPE_READYWAIT_DeviceDisconnected; + + uint8_t ErrorCode; + + Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Unfreeze(); + + if (!(Pipe_IsReadWriteAllowed())) + { + Pipe_ClearOUT(); + + if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) + return ErrorCode; + } + + Pipe_Write_8(Data); + Pipe_Freeze(); + + return PIPE_READYWAIT_NoError; +} + +uint16_t AOA_Host_BytesReceived(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) + return 0; + + Pipe_SelectPipe(AOAInterfaceInfo->Config.DataINPipe.Address); + Pipe_Unfreeze(); + + if (Pipe_IsINReceived()) + { + if (!(Pipe_BytesInPipe())) + { + Pipe_ClearIN(); + Pipe_Freeze(); + return 0; + } + else + { + Pipe_Freeze(); + return Pipe_BytesInPipe(); + } + } + else + { + Pipe_Freeze(); + + return 0; + } +} + +int16_t AOA_Host_ReceiveByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) + return -1; + + int16_t ReceivedByte = -1; + + Pipe_SelectPipe(AOAInterfaceInfo->Config.DataINPipe.Address); + Pipe_Unfreeze(); + + if (Pipe_IsINReceived()) + { + if (Pipe_BytesInPipe()) + ReceivedByte = Pipe_Read_8(); + + if (!(Pipe_BytesInPipe())) + Pipe_ClearIN(); + } + + Pipe_Freeze(); + + return ReceivedByte; +} + +uint8_t AOA_Host_Flush(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) + return PIPE_READYWAIT_DeviceDisconnected; + + uint8_t ErrorCode; + + Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Unfreeze(); + + if (!(Pipe_BytesInPipe())) + return PIPE_READYWAIT_NoError; + + bool BankFull = !(Pipe_IsReadWriteAllowed()); + + Pipe_ClearOUT(); + + if (BankFull) + { + if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) + return ErrorCode; + + Pipe_ClearOUT(); + } + + Pipe_Freeze(); + + return PIPE_READYWAIT_NoError; +} + +#if defined(FDEV_SETUP_STREAM) +void AOA_Host_CreateStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + FILE* const Stream) +{ + *Stream = (FILE)FDEV_SETUP_STREAM(AOA_Host_putchar, AOA_Host_getchar, _FDEV_SETUP_RW); + fdev_set_udata(Stream, AOAInterfaceInfo); +} + +void AOA_Host_CreateBlockingStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + FILE* const Stream) +{ + *Stream = (FILE)FDEV_SETUP_STREAM(AOA_Host_putchar, AOA_Host_getchar_Blocking, _FDEV_SETUP_RW); + fdev_set_udata(Stream, AOAInterfaceInfo); +} + +static int AOA_Host_putchar(char c, + FILE* Stream) +{ + return AOA_Host_SendByte((USB_ClassInfo_AOA_Host_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0; +} + +static int AOA_Host_getchar(FILE* Stream) +{ + int16_t ReceivedByte = AOA_Host_ReceiveByte((USB_ClassInfo_AOA_Host_t*)fdev_get_udata(Stream)); + + if (ReceivedByte < 0) + return _FDEV_EOF; + + return ReceivedByte; +} + +static int AOA_Host_getchar_Blocking(FILE* Stream) +{ + int16_t ReceivedByte; + + while ((ReceivedByte = AOA_Host_ReceiveByte((USB_ClassInfo_AOA_Host_t*)fdev_get_udata(Stream))) < 0) + { + if (USB_HostState == HOST_STATE_Unattached) + return _FDEV_EOF; + + AOA_Host_USBTask((USB_ClassInfo_AOA_Host_t*)fdev_get_udata(Stream)); + USB_USBTask(); + } + + return ReceivedByte; +} +#endif + +#endif + diff --git a/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.h b/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.h index 678feda4..c437a4b6 100644 --- a/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.h +++ b/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.h @@ -1,314 +1,314 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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 Host mode driver for the library USB Android Open Accessory Class driver. - * - * Host mode driver for the library USB Android Open Accessory Class driver. - * - * \note This file should not be included directly. It is automatically included as needed by the USB module driver - * dispatch header located in LUFA/Drivers/USB.h. - */ - -/** \ingroup Group_USBClassAOA - * \defgroup Group_USBClassAndroidAccessoryHost Android Open Accessory Class Host Mode Driver - * - * \section Sec_Dependencies Module Source Dependencies - * The following files must be built with any user project that uses this module: - * - LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) - * - * \section Sec_ModDescription Module Description - * Host Mode USB Class driver framework interface, for the Android Open Accessory USB Class driver. - * - * @{ - */ - -#ifndef __AOA_CLASS_HOST_H__ -#define __AOA_CLASS_HOST_H__ - - /* Includes: */ - #include "../../USB.h" - #include "../Common/AndroidAccessoryClassCommon.h" - - #include - - /* Enable C linkage for C++ Compilers: */ - #if defined(__cplusplus) - extern "C" { - #endif - - /* Preprocessor Checks: */ - #if !defined(__INCLUDE_FROM_AOA_DRIVER) - #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. - #endif - - /* Public Interface - May be used in end-application: */ - /* Macros: */ - /** Error code for some Android Open Accessory Host functions, indicating a logical (and not hardware) error. */ - #define AOA_ERROR_LOGICAL_CMD_FAILED 0x80 - - /* Type Defines: */ - /** \brief Android Open Accessory Class Host Mode Configuration and State Structure. - * - * Class state structure. An instance of this structure should be made within the user application, - * and passed to each of the Android Open Accessory class driver functions as the \c AOAInterfaceInfo - * parameter. This stores each Android Open Accessory interface's configuration and state information. - */ - typedef struct - { - struct - { - USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */ - USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */ - - char* PropertyStrings[AOA_STRING_TOTAL_STRINGS]; /**< Android Accessory property strings, sent to identify the accessory when the - * Android device is switched into Open Accessory mode. */ - } Config; /**< Config data for the USB class interface within the device. All elements in this section - * must be set or the interface will fail to enumerate and operate correctly. - */ - struct - { - bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid - * after \ref AOA_Host_ConfigurePipes() is called and the Host state machine is in the - * Configured state. - */ - uint8_t InterfaceNumber; /**< Interface index of the AOA interface within the attached device. */ - } State; /**< State data for the USB class interface within the device. All elements in this section - * may be set to initial values, but may also be ignored to default to sane values when - * the interface is enumerated. - */ - } USB_ClassInfo_AOA_Host_t; - - /* Enums: */ - /** Enum for the possible error codes returned by the \ref AOA_Host_ConfigurePipes() function. */ - enum AOA_Host_EnumerationFailure_ErrorCodes_t - { - AOA_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ - AOA_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ - AOA_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible Android Open Accessory interface was not found in the device's Configuration Descriptor. */ - AOA_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ - }; - - /* Function Prototypes: */ - /** General management task for a given Android Open Accessory host class interface, required for the correct operation of the interface. - * This should be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). - * - * \param[in,out] AOAInterfaceInfo Pointer to a structure containing an Android Open Accessory Class host configuration and state. - */ - void AOA_Host_USBTask(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); - - /** Validates a device descriptor, to check if the device is a valid Android device, and if it is currently in Android Open Accessory mode. - * - * \param[in,out] AOAInterfaceInfo Pointer to a structure containing an AOA Class host configuration and state. - * \param[in] DeviceDescriptor Pointer a buffer containing the attached device's Device Descriptor. - * \param[out] NeedModeSwitch Pointer to a boolean where the mode switch requirement of the attached device is to be stored. - * - * \return Boolean \c true if the attached device is a valid Android device, \c false otherwise. - */ - bool AOA_Host_ValidateAccessoryDevice(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, - const USB_Descriptor_Device_t* const DeviceDescriptor, - bool* const NeedModeSwitch) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(3); - - /** Host interface configuration routine, to configure a given Android Open Accessory host interface instance using the Configuration - * Descriptor read from an attached USB device. This function automatically updates the given Android Open Accessory Host instance's - * state values and configures the pipes required to communicate with the interface if it is found within the device. This should be - * called once after the stack has enumerated the attached device, while the host state machine is in the Addressed state. - * - * \param[in,out] AOAInterfaceInfo Pointer to a structure containing an AOA Class host configuration and state. - * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. - * \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor. - * - * \return A value from the \ref AOA_Host_EnumerationFailure_ErrorCodes_t enum. - */ - uint8_t AOA_Host_ConfigurePipes(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, - uint16_t ConfigDescriptorSize, - void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); - - /** Starts Accessory Mode in the attached Android device. This function will validate the device's Android Open Accessory protocol - * version, send the configured property strings, and request a switch to Android Open Accessory mode. - * - * \param[in,out] AOAInterfaceInfo Pointer to a structure containing an AOA Class host configuration and state. - * - * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum, or \ref AOA_ERROR_LOGICAL_CMD_FAILED if a logical error occured.. - */ - uint8_t AOA_Host_StartAccessoryMode(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); - - /** Sends a given data buffer to the attached USB device, if connected. If a device is not connected when the function is - * called, the data will be discarded. Bytes will be queued for transmission to the device until either the pipe bank - * becomes full, or the \ref AOA_Host_Flush() function is called to flush the pending data to the device. This allows for - * multiple bytes to be packed into a single pipe packet, increasing data throughput. - * - * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the - * call will fail. - * - * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. - * \param[in] Buffer Pointer to a buffer containing the data to send to the device. - * \param[in] Length Length of the data to send to the device. - * - * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. - */ - uint8_t AOA_Host_SendData(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, - const uint8_t* const Buffer, - const uint16_t Length); - - /** Sends a given null-terminated string to the attached USB device, if connected. If a device is not connected when the - * function is called, the string is discarded. Bytes will be queued for transmission to the device until either the pipe - * bank becomes full, or the \ref AOA_Host_Flush() function is called to flush the pending data to the device. This allows - * for multiple bytes to be packed into a single pipe packet, increasing data throughput. - * - * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the - * call will fail. - * - * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. - * \param[in] String Pointer to the null terminated string to send to the device. - * - * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. - */ - uint8_t AOA_Host_SendString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, - const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); - - /** Sends a given byte to the attached USB device, if connected. If a device is not connected when the function is called, the - * byte is discarded. Bytes will be queued for transmission to the device until either the pipe bank becomes full, or the - * \ref AOA_Host_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be - * packed into a single pipe packet, increasing data throughput. - * - * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the - * call will fail. - * - * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. - * \param[in] Data Byte of data to send to the device. - * - * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. - */ - uint8_t AOA_Host_SendByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, - const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1); - - /** Determines the number of bytes received by the AOA interface from the device, waiting to be read. This indicates the number - * of bytes in the IN pipe bank only, and thus the number of calls to \ref AOA_Host_ReceiveByte() which are guaranteed to succeed - * immediately. If multiple bytes are to be received, they should be buffered by the user application, as the pipe bank will not be - * released back to the USB controller until all bytes are read. - * - * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the - * call will fail. - * - * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. - * - * \return Total number of buffered bytes received from the device. - */ - uint16_t AOA_Host_BytesReceived(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); - - /** Reads a byte of data from the device. If no data is waiting to be read of if a USB device is not connected, the function - * returns a negative value. The \ref AOA_Host_BytesReceived() function may be queried in advance to determine how many bytes - * are currently buffered in the AOA interface's data receive pipe. - * - * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the - * call will fail. - * - * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. - * - * \return Next received byte from the device, or a negative value if no data received. - */ - int16_t AOA_Host_ReceiveByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); - - /** Flushes any data waiting to be sent, ensuring that the send buffer is cleared. - * - * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the - * call will fail. - * - * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. - * - * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. - */ - uint8_t AOA_Host_Flush(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); - - /** Creates a standard character stream for the given AOA Device instance so that it can be used with all the regular - * functions in the standard \c library that accept a \c FILE stream as a destination (e.g. \c fprintf). The created - * stream is bidirectional and can be used for both input and output functions. - * - * Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single - * fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may - * be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own - * line buffering. - * - * \note The created stream can be given as \c stdout if desired to direct the standard output from all \c functions - * to the given AOA interface. - * \n\n - * - * \note This function is not available on all microcontroller architectures. - * - * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class configuration and state. - * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed. - */ - void AOA_Host_CreateStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, - FILE* const Stream); - - /** Identical to \ref AOA_Host_CreateStream(), except that reads are blocking until the calling stream function terminates - * the transfer. While blocking, the USB and AOA service tasks are called repeatedly to maintain USB communications. - * - * \note This function is not available on all microcontroller architectures. - * - * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class configuration and state. - * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed. - */ - void AOA_Host_CreateBlockingStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, - FILE* const Stream); - - /* Private Interface - For use in library only: */ - #if !defined(__DOXYGEN__) - /* Function Prototypes: */ - #if defined(__INCLUDE_FROM_ANDROIDACCESSORY_HOST_C) - #if defined(FDEV_SETUP_STREAM) - static int AOA_Host_putchar(char c, - FILE* Stream) ATTR_NON_NULL_PTR_ARG(2); - static int AOA_Host_getchar(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1); - static int AOA_Host_getchar_Blocking(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1); - #endif - - static uint8_t AOA_Host_GetAccessoryProtocol(uint16_t* const Protocol) ATTR_NON_NULL_PTR_ARG(1); - static uint8_t AOA_Host_SendPropertyString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, - const uint8_t StringIndex) ATTR_NON_NULL_PTR_ARG(1); - - static uint8_t DCOMP_AOA_Host_NextAndroidAccessoryInterface(void* const CurrentDescriptor) - ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); - static uint8_t DCOMP_AOA_Host_NextInterfaceBulkEndpoint(void* const CurrentDescriptor) - ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); - #endif - #endif - - /* Disable C linkage for C++ Compilers: */ - #if defined(__cplusplus) - } - #endif - -#endif - -/** @} */ - +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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 Host mode driver for the library USB Android Open Accessory Class driver. + * + * Host mode driver for the library USB Android Open Accessory Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassAOA + * \defgroup Group_USBClassAndroidAccessoryHost Android Open Accessory Class Host Mode Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Host Mode USB Class driver framework interface, for the Android Open Accessory USB Class driver. + * + * @{ + */ + +#ifndef __AOA_CLASS_HOST_H__ +#define __AOA_CLASS_HOST_H__ + + /* Includes: */ + #include "../../USB.h" + #include "../Common/AndroidAccessoryClassCommon.h" + + #include + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_AOA_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Error code for some Android Open Accessory Host functions, indicating a logical (and not hardware) error. */ + #define AOA_ERROR_LOGICAL_CMD_FAILED 0x80 + + /* Type Defines: */ + /** \brief Android Open Accessory Class Host Mode Configuration and State Structure. + * + * Class state structure. An instance of this structure should be made within the user application, + * and passed to each of the Android Open Accessory class driver functions as the \c AOAInterfaceInfo + * parameter. This stores each Android Open Accessory interface's configuration and state information. + */ + typedef struct + { + struct + { + USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */ + USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */ + + char* PropertyStrings[AOA_STRING_TOTAL_STRINGS]; /**< Android Accessory property strings, sent to identify the accessory when the + * Android device is switched into Open Accessory mode. */ + } Config; /**< Config data for the USB class interface within the device. All elements in this section + * must be set or the interface will fail to enumerate and operate correctly. + */ + struct + { + bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid + * after \ref AOA_Host_ConfigurePipes() is called and the Host state machine is in the + * Configured state. + */ + uint8_t InterfaceNumber; /**< Interface index of the AOA interface within the attached device. */ + } State; /**< State data for the USB class interface within the device. All elements in this section + * may be set to initial values, but may also be ignored to default to sane values when + * the interface is enumerated. + */ + } USB_ClassInfo_AOA_Host_t; + + /* Enums: */ + /** Enum for the possible error codes returned by the \ref AOA_Host_ConfigurePipes() function. */ + enum AOA_Host_EnumerationFailure_ErrorCodes_t + { + AOA_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ + AOA_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ + AOA_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible Android Open Accessory interface was not found in the device's Configuration Descriptor. */ + AOA_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ + }; + + /* Function Prototypes: */ + /** General management task for a given Android Open Accessory host class interface, required for the correct operation of the interface. + * This should be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing an Android Open Accessory Class host configuration and state. + */ + void AOA_Host_USBTask(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Validates a device descriptor, to check if the device is a valid Android device, and if it is currently in Android Open Accessory mode. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing an AOA Class host configuration and state. + * \param[in] DeviceDescriptor Pointer a buffer containing the attached device's Device Descriptor. + * \param[out] NeedModeSwitch Pointer to a boolean where the mode switch requirement of the attached device is to be stored. + * + * \return Boolean \c true if the attached device is a valid Android device, \c false otherwise. + */ + bool AOA_Host_ValidateAccessoryDevice(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + const USB_Descriptor_Device_t* const DeviceDescriptor, + bool* const NeedModeSwitch) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(3); + + /** Host interface configuration routine, to configure a given Android Open Accessory host interface instance using the Configuration + * Descriptor read from an attached USB device. This function automatically updates the given Android Open Accessory Host instance's + * state values and configures the pipes required to communicate with the interface if it is found within the device. This should be + * called once after the stack has enumerated the attached device, while the host state machine is in the Addressed state. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing an AOA Class host configuration and state. + * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. + * \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor. + * + * \return A value from the \ref AOA_Host_EnumerationFailure_ErrorCodes_t enum. + */ + uint8_t AOA_Host_ConfigurePipes(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + uint16_t ConfigDescriptorSize, + void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); + + /** Starts Accessory Mode in the attached Android device. This function will validate the device's Android Open Accessory protocol + * version, send the configured property strings, and request a switch to Android Open Accessory mode. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing an AOA Class host configuration and state. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum, or \ref AOA_ERROR_LOGICAL_CMD_FAILED if a logical error occurred.. + */ + uint8_t AOA_Host_StartAccessoryMode(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Sends a given data buffer to the attached USB device, if connected. If a device is not connected when the function is + * called, the data will be discarded. Bytes will be queued for transmission to the device until either the pipe bank + * becomes full, or the \ref AOA_Host_Flush() function is called to flush the pending data to the device. This allows for + * multiple bytes to be packed into a single pipe packet, increasing data throughput. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. + * \param[in] Buffer Pointer to a buffer containing the data to send to the device. + * \param[in] Length Length of the data to send to the device. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t AOA_Host_SendData(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + const uint8_t* const Buffer, + const uint16_t Length); + + /** Sends a given null-terminated string to the attached USB device, if connected. If a device is not connected when the + * function is called, the string is discarded. Bytes will be queued for transmission to the device until either the pipe + * bank becomes full, or the \ref AOA_Host_Flush() function is called to flush the pending data to the device. This allows + * for multiple bytes to be packed into a single pipe packet, increasing data throughput. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. + * \param[in] String Pointer to the null terminated string to send to the device. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t AOA_Host_SendString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /** Sends a given byte to the attached USB device, if connected. If a device is not connected when the function is called, the + * byte is discarded. Bytes will be queued for transmission to the device until either the pipe bank becomes full, or the + * \ref AOA_Host_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be + * packed into a single pipe packet, increasing data throughput. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. + * \param[in] Data Byte of data to send to the device. + * + * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. + */ + uint8_t AOA_Host_SendByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1); + + /** Determines the number of bytes received by the AOA interface from the device, waiting to be read. This indicates the number + * of bytes in the IN pipe bank only, and thus the number of calls to \ref AOA_Host_ReceiveByte() which are guaranteed to succeed + * immediately. If multiple bytes are to be received, they should be buffered by the user application, as the pipe bank will not be + * released back to the USB controller until all bytes are read. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. + * + * \return Total number of buffered bytes received from the device. + */ + uint16_t AOA_Host_BytesReceived(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads a byte of data from the device. If no data is waiting to be read of if a USB device is not connected, the function + * returns a negative value. The \ref AOA_Host_BytesReceived() function may be queried in advance to determine how many bytes + * are currently buffered in the AOA interface's data receive pipe. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. + * + * \return Next received byte from the device, or a negative value if no data received. + */ + int16_t AOA_Host_ReceiveByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Flushes any data waiting to be sent, ensuring that the send buffer is cleared. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. + * + * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. + */ + uint8_t AOA_Host_Flush(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Creates a standard character stream for the given AOA Device instance so that it can be used with all the regular + * functions in the standard \c library that accept a \c FILE stream as a destination (e.g. \c fprintf). The created + * stream is bidirectional and can be used for both input and output functions. + * + * Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single + * fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may + * be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own + * line buffering. + * + * \note The created stream can be given as \c stdout if desired to direct the standard output from all \c functions + * to the given AOA interface. + * \n\n + * + * \note This function is not available on all microcontroller architectures. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class configuration and state. + * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed. + */ + void AOA_Host_CreateStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + FILE* const Stream); + + /** Identical to \ref AOA_Host_CreateStream(), except that reads are blocking until the calling stream function terminates + * the transfer. While blocking, the USB and AOA service tasks are called repeatedly to maintain USB communications. + * + * \note This function is not available on all microcontroller architectures. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class configuration and state. + * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed. + */ + void AOA_Host_CreateBlockingStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + FILE* const Stream); + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Function Prototypes: */ + #if defined(__INCLUDE_FROM_ANDROIDACCESSORY_HOST_C) + #if defined(FDEV_SETUP_STREAM) + static int AOA_Host_putchar(char c, + FILE* Stream) ATTR_NON_NULL_PTR_ARG(2); + static int AOA_Host_getchar(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1); + static int AOA_Host_getchar_Blocking(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1); + #endif + + static uint8_t AOA_Host_GetAccessoryProtocol(uint16_t* const Protocol) ATTR_NON_NULL_PTR_ARG(1); + static uint8_t AOA_Host_SendPropertyString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + const uint8_t StringIndex) ATTR_NON_NULL_PTR_ARG(1); + + static uint8_t DCOMP_AOA_Host_NextAndroidAccessoryInterface(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + static uint8_t DCOMP_AOA_Host_NextInterfaceBulkEndpoint(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + #endif + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/LUFA/Drivers/USB/Class/Host/CDCClassHost.h b/LUFA/Drivers/USB/Class/Host/CDCClassHost.h index 4d79ed95..b70a5023 100644 --- a/LUFA/Drivers/USB/Class/Host/CDCClassHost.h +++ b/LUFA/Drivers/USB/Class/Host/CDCClassHost.h @@ -271,6 +271,7 @@ */ uint8_t CDC_Host_Flush(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + #if defined(FDEV_SETUP_STREAM) || defined(__DOXYGEN__) /** Creates a standard character stream for the given CDC Device instance so that it can be used with all the regular * functions in the standard \c library that accept a \c FILE stream as a destination (e.g. \c fprintf). The created * stream is bidirectional and can be used for both input and output functions. @@ -302,7 +303,8 @@ */ void CDC_Host_CreateBlockingStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, FILE* const Stream); - + #endif + /** CDC class driver event for a control line state change on a CDC host interface. This event fires each time the device notifies * the host of a control line state change (containing the virtual serial control line states, such as DCD) and may be hooked in the * user program by declaring a handler function with the same name and parameters listed here. The new control line states diff --git a/LUFA/Drivers/USB/Class/Host/HIDClassHost.h b/LUFA/Drivers/USB/Class/Host/HIDClassHost.h index 882cc31d..21868d9c 100644 --- a/LUFA/Drivers/USB/Class/Host/HIDClassHost.h +++ b/LUFA/Drivers/USB/Class/Host/HIDClassHost.h @@ -246,7 +246,7 @@ uint8_t HID_Host_SetBootProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); /** Sets the idle period for the attached HID device to the specified interval. The HID idle period determines the rate - * at which the device should send a report, when no state changes have ocurred; i.e. on HID keyboards, this sets the + * at which the device should send a report, when no state changes have occurred; i.e. on HID keyboards, this sets the * hardware key repeat interval. * * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state. diff --git a/LUFA/Drivers/USB/Class/Host/MIDIClassHost.h b/LUFA/Drivers/USB/Class/Host/MIDIClassHost.h index b9e86114..06ede7f2 100644 --- a/LUFA/Drivers/USB/Class/Host/MIDIClassHost.h +++ b/LUFA/Drivers/USB/Class/Host/MIDIClassHost.h @@ -145,7 +145,7 @@ MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); /** Flushes the MIDI send buffer, sending any queued MIDI events to the device. This should be called to override the - * \ref MIDI_Host_SendEventPacket() function's packing behaviour, to flush queued events. Events are queued into the + * \ref MIDI_Host_SendEventPacket() function's packing behavior, to flush queued events. Events are queued into the * pipe bank until either the pipe bank is full, or \ref MIDI_Host_Flush() is called. This allows for multiple MIDI * events to be packed into a single pipe packet, increasing data throughput. * diff --git a/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.c b/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.c index 0117a1d6..a267be1e 100644 --- a/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.c +++ b/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.c @@ -1,275 +1,275 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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. -*/ - -#include "../../../../Common/Common.h" -#if (ARCH == ARCH_AVR8) - -#define __INCLUDE_FROM_USB_DRIVER -#include "../USBMode.h" - -#if defined(USB_CAN_BE_DEVICE) - -#include "EndpointStream_AVR8.h" - -#if !defined(CONTROL_ONLY_DEVICE) -uint8_t Endpoint_Discard_Stream(uint16_t Length, - uint16_t* const BytesProcessed) -{ - uint8_t ErrorCode; - uint16_t BytesInTransfer = 0; - - if ((ErrorCode = Endpoint_WaitUntilReady())) - return ErrorCode; - - if (BytesProcessed != NULL) - Length -= *BytesProcessed; - - while (Length) - { - if (!(Endpoint_IsReadWriteAllowed())) - { - Endpoint_ClearOUT(); - - if (BytesProcessed != NULL) - { - *BytesProcessed += BytesInTransfer; - return ENDPOINT_RWSTREAM_IncompleteTransfer; - } - - if ((ErrorCode = Endpoint_WaitUntilReady())) - return ErrorCode; - } - else - { - Endpoint_Discard_8(); - - Length--; - BytesInTransfer++; - } - } - - return ENDPOINT_RWSTREAM_NoError; -} - -uint8_t Endpoint_Null_Stream(uint16_t Length, - uint16_t* const BytesProcessed) -{ - uint8_t ErrorCode; - uint16_t BytesInTransfer = 0; - - if ((ErrorCode = Endpoint_WaitUntilReady())) - return ErrorCode; - - if (BytesProcessed != NULL) - Length -= *BytesProcessed; - - while (Length) - { - if (!(Endpoint_IsReadWriteAllowed())) - { - Endpoint_ClearIN(); - - if (BytesProcessed != NULL) - { - *BytesProcessed += BytesInTransfer; - return ENDPOINT_RWSTREAM_IncompleteTransfer; - } - - if ((ErrorCode = Endpoint_WaitUntilReady())) - return ErrorCode; - } - else - { - Endpoint_Write_8(0); - - Length--; - BytesInTransfer++; - } - } - - return ENDPOINT_RWSTREAM_NoError; -} - -/* The following abuses the C preprocessor in order to copy-paste common code with slight alterations, - * so that the code needs to be written once. It is a crude form of templating to reduce code maintenance. */ - -#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_LE -#define TEMPLATE_BUFFER_TYPE const void* -#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() -#define TEMPLATE_BUFFER_OFFSET(Length) 0 -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) -#include "Template/Template_Endpoint_RW.c" - -#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_BE -#define TEMPLATE_BUFFER_TYPE const void* -#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() -#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) -#include "Template/Template_Endpoint_RW.c" - -#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_LE -#define TEMPLATE_BUFFER_TYPE void* -#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() -#define TEMPLATE_BUFFER_OFFSET(Length) 0 -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() -#include "Template/Template_Endpoint_RW.c" - -#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_BE -#define TEMPLATE_BUFFER_TYPE void* -#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() -#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() -#include "Template/Template_Endpoint_RW.c" - -#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE) - #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_LE - #define TEMPLATE_BUFFER_TYPE const void* - #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() - #define TEMPLATE_BUFFER_OFFSET(Length) 0 - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) - #include "Template/Template_Endpoint_RW.c" - - #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_BE - #define TEMPLATE_BUFFER_TYPE const void* - #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() - #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) - #include "Template/Template_Endpoint_RW.c" -#endif - -#if defined(ARCH_HAS_EEPROM_ADDRESS_SPACE) - #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_LE - #define TEMPLATE_BUFFER_TYPE const void* - #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() - #define TEMPLATE_BUFFER_OFFSET(Length) 0 - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) - #include "Template/Template_Endpoint_RW.c" - - #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_BE - #define TEMPLATE_BUFFER_TYPE const void* - #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() - #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) - #include "Template/Template_Endpoint_RW.c" - - #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_LE - #define TEMPLATE_BUFFER_TYPE void* - #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() - #define TEMPLATE_BUFFER_OFFSET(Length) 0 - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) - #include "Template/Template_Endpoint_RW.c" - - #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_BE - #define TEMPLATE_BUFFER_TYPE void* - #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() - #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) - #include "Template/Template_Endpoint_RW.c" -#endif - -#endif - -#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_LE -#define TEMPLATE_BUFFER_OFFSET(Length) 0 -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) -#include "Template/Template_Endpoint_Control_W.c" - -#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_BE -#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) -#include "Template/Template_Endpoint_Control_W.c" - -#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_LE -#define TEMPLATE_BUFFER_OFFSET(Length) 0 -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() -#include "Template/Template_Endpoint_Control_R.c" - -#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_BE -#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() -#include "Template/Template_Endpoint_Control_R.c" - -#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE) - #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_PStream_LE - #define TEMPLATE_BUFFER_OFFSET(Length) 0 - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) - #include "Template/Template_Endpoint_Control_W.c" - - #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_PStream_BE - #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) - #include "Template/Template_Endpoint_Control_W.c" -#endif - -#if defined(ARCH_HAS_EEPROM_ADDRESS_SPACE) - #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_EStream_LE - #define TEMPLATE_BUFFER_OFFSET(Length) 0 - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) - #include "Template/Template_Endpoint_Control_W.c" - - #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_EStream_BE - #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) - #include "Template/Template_Endpoint_Control_W.c" - - #define TEMPLATE_FUNC_NAME Endpoint_Read_Control_EStream_LE - #define TEMPLATE_BUFFER_OFFSET(Length) 0 - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) - #include "Template/Template_Endpoint_Control_R.c" - - #define TEMPLATE_FUNC_NAME Endpoint_Read_Control_EStream_BE - #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) - #include "Template/Template_Endpoint_Control_R.c" -#endif - +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_AVR8) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#include "EndpointStream_AVR8.h" + +#if !defined(CONTROL_ONLY_DEVICE) +uint8_t Endpoint_Discard_Stream(uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t ErrorCode; + uint16_t BytesInTransfer = 0; + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + Length -= *BytesProcessed; + + while (Length) + { + if (!(Endpoint_IsReadWriteAllowed())) + { + Endpoint_ClearOUT(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return ENDPOINT_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + } + else + { + Endpoint_Discard_8(); + + Length--; + BytesInTransfer++; + } + } + + return ENDPOINT_RWSTREAM_NoError; +} + +uint8_t Endpoint_Null_Stream(uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t ErrorCode; + uint16_t BytesInTransfer = 0; + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + Length -= *BytesProcessed; + + while (Length) + { + if (!(Endpoint_IsReadWriteAllowed())) + { + Endpoint_ClearIN(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return ENDPOINT_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + } + else + { + Endpoint_Write_8(0); + + Length--; + BytesInTransfer++; + } + } + + return ENDPOINT_RWSTREAM_NoError; +} + +/* The following abuses the C preprocessor in order to copy-paste common code with slight alterations, + * so that the code needs to be written once. It is a crude form of templating to reduce code maintenance. */ + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_LE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_RW.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_BE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_RW.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_LE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_RW.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_BE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_RW.c" + +#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE) + #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_LE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_BE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" +#endif + +#if defined(ARCH_HAS_EEPROM_ADDRESS_SPACE) + #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_LE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_BE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_LE + #define TEMPLATE_BUFFER_TYPE void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_BE + #define TEMPLATE_BUFFER_TYPE void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) + #include "Template/Template_Endpoint_RW.c" #endif -#endif +#endif + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_LE +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_Control_W.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_BE +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_Control_W.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_LE +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_Control_R.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_BE +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_Control_R.c" + +#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE) + #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_PStream_LE + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_Control_W.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_PStream_BE + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_Control_W.c" +#endif + +#if defined(ARCH_HAS_EEPROM_ADDRESS_SPACE) + #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_EStream_LE + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_Control_W.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_EStream_BE + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_Control_W.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Read_Control_EStream_LE + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) + #include "Template/Template_Endpoint_Control_R.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Read_Control_EStream_BE + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) + #include "Template/Template_Endpoint_Control_R.c" +#endif + +#endif + +#endif diff --git a/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.h b/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.h index 072d8593..eb1f928f 100644 --- a/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.h +++ b/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.h @@ -1,648 +1,648 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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 Endpoint data stream transmission and reception management for the AVR8 microcontrollers. - * \copydetails Group_EndpointStreamRW_AVR8 - * - * \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_EndpointStreamRW - * \defgroup Group_EndpointStreamRW_AVR8 Read/Write of Multi-Byte Streams (AVR8) - * \brief Endpoint data stream transmission and reception management for the Atmel AVR8 architecture. - * - * Functions, macros, variables, enums and types related to data reading and writing of data streams from - * and to endpoints. - * - * @{ - */ - -#ifndef __ENDPOINT_STREAM_AVR8_H__ -#define __ENDPOINT_STREAM_AVR8_H__ - - /* Includes: */ - #include "../../../../Common/Common.h" - #include "../USBMode.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: */ - /* Function Prototypes: */ - /** \name Stream functions for null data */ - //@{ - - /** Reads and discards the given number of bytes from the currently selected endpoint's bank, - * discarding fully read packets from the host as needed. The last packet is not automatically - * discarded once the remaining bytes has been read; the user is responsible for manually - * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. - * - * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, - * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid - * storage location, the transfer will instead be performed as a series of chunks. Each time - * the endpoint bank becomes empty while there is still data to process (and after the current - * packet has been acknowledged) the BytesProcessed location will be updated with the total number - * of bytes processed in the stream, and the function will exit with an error code of - * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed - * in the user code - to continue the transfer, call the function again with identical parameters - * and it will resume until the BytesProcessed value reaches the total transfer length. - * - * Single Stream Transfer Example: - * \code - * uint8_t ErrorCode; - * - * if ((ErrorCode = Endpoint_Discard_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * Partial Stream Transfers Example: - * \code - * uint8_t ErrorCode; - * uint16_t BytesProcessed; - * - * BytesProcessed = 0; - * while ((ErrorCode = Endpoint_Discard_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) - * { - * // Stream not yet complete - do other actions here, abort if required - * } - * - * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * \note This routine should not be used on CONTROL type endpoints. - * - * \param[in] Length Number of bytes to discard via the currently selected endpoint. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Discard_Stream(uint16_t Length, - uint16_t* const BytesProcessed); - - /** Writes a given number of zeroed bytes to the currently selected endpoint's bank, sending - * full packets to the host as needed. The last packet is not automatically sent once the - * remaining bytes have been written; the user is responsible for manually sending the last - * packet to the host via the \ref Endpoint_ClearIN() macro. - * - * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, - * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid - * storage location, the transfer will instead be performed as a series of chunks. Each time - * the endpoint bank becomes full while there is still data to process (and after the current - * packet transmission has been initiated) the BytesProcessed location will be updated with the - * total number of bytes processed in the stream, and the function will exit with an error code of - * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed - * in the user code - to continue the transfer, call the function again with identical parameters - * and it will resume until the BytesProcessed value reaches the total transfer length. - * - * Single Stream Transfer Example: - * \code - * uint8_t ErrorCode; - * - * if ((ErrorCode = Endpoint_Null_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * Partial Stream Transfers Example: - * \code - * uint8_t ErrorCode; - * uint16_t BytesProcessed; - * - * BytesProcessed = 0; - * while ((ErrorCode = Endpoint_Null_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) - * { - * // Stream not yet complete - do other actions here, abort if required - * } - * - * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * \note This routine should not be used on CONTROL type endpoints. - * - * \param[in] Length Number of zero bytes to send via the currently selected endpoint. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Null_Stream(uint16_t Length, - uint16_t* const BytesProcessed); - - //@} - - /** \name Stream functions for RAM source/destination data */ - //@{ - - /** Writes the given number of bytes to the endpoint from the given buffer in little endian, - * sending full packets to the host as needed. The last packet filled is not automatically sent; - * the user is responsible for manually sending the last written packet to the host via the - * \ref Endpoint_ClearIN() macro. - * - * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, - * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid - * storage location, the transfer will instead be performed as a series of chunks. Each time - * the endpoint bank becomes full while there is still data to process (and after the current - * packet transmission has been initiated) the BytesProcessed location will be updated with the - * total number of bytes processed in the stream, and the function will exit with an error code of - * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed - * in the user code - to continue the transfer, call the function again with identical parameters - * and it will resume until the BytesProcessed value reaches the total transfer length. - * - * Single Stream Transfer Example: - * \code - * uint8_t DataStream[512]; - * uint8_t ErrorCode; - * - * if ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream), - * NULL)) != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * Partial Stream Transfers Example: - * \code - * uint8_t DataStream[512]; - * uint8_t ErrorCode; - * uint16_t BytesProcessed; - * - * BytesProcessed = 0; - * while ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream), - * &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) - * { - * // Stream not yet complete - do other actions here, abort if required - * } - * - * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * \note This routine should not be used on CONTROL type endpoints. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_Stream_LE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** Writes the given number of bytes to the endpoint from the given buffer in big endian, - * sending full packets to the host as needed. The last packet filled is not automatically sent; - * the user is responsible for manually sending the last written packet to the host via the - * \ref Endpoint_ClearIN() macro. - * - * \note This routine should not be used on CONTROL type endpoints. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_Stream_BE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** Reads the given number of bytes from the endpoint from the given buffer in little endian, - * discarding fully read packets from the host as needed. The last packet is not automatically - * discarded once the remaining bytes has been read; the user is responsible for manually - * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. - * - * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, - * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid - * storage location, the transfer will instead be performed as a series of chunks. Each time - * the endpoint bank becomes empty while there is still data to process (and after the current - * packet has been acknowledged) the BytesProcessed location will be updated with the total number - * of bytes processed in the stream, and the function will exit with an error code of - * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed - * in the user code - to continue the transfer, call the function again with identical parameters - * and it will resume until the BytesProcessed value reaches the total transfer length. - * - * Single Stream Transfer Example: - * \code - * uint8_t DataStream[512]; - * uint8_t ErrorCode; - * - * if ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream), - * NULL)) != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * Partial Stream Transfers Example: - * \code - * uint8_t DataStream[512]; - * uint8_t ErrorCode; - * uint16_t BytesProcessed; - * - * BytesProcessed = 0; - * while ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream), - * &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) - * { - * // Stream not yet complete - do other actions here, abort if required - * } - * - * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * \note This routine should not be used on CONTROL type endpoints. - * - * \param[out] Buffer Pointer to the destination data buffer to write to. - * \param[in] Length Number of bytes to send via the currently selected endpoint. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Read_Stream_LE(void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** Reads the given number of bytes from the endpoint from the given buffer in big endian, - * discarding fully read packets from the host as needed. The last packet is not automatically - * discarded once the remaining bytes has been read; the user is responsible for manually - * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. - * - * \note This routine should not be used on CONTROL type endpoints. - * - * \param[out] Buffer Pointer to the destination data buffer to write to. - * \param[in] Length Number of bytes to send via the currently selected endpoint. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Read_Stream_BE(void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in little endian, - * sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared - * in both failure and success states; the user is responsible for manually clearing the setup OUT to - * finalize the transfer via the \ref Endpoint_ClearOUT() macro. - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_Control_Stream_LE(const void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - - /** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in big endian, - * sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared - * in both failure and success states; the user is responsible for manually clearing the setup OUT to - * finalize the transfer via the \ref Endpoint_ClearOUT() macro. - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_Control_Stream_BE(const void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - - /** Reads the given number of bytes from the CONTROL endpoint from the given buffer in little endian, - * discarding fully read packets from the host as needed. The device IN acknowledgement is not - * automatically sent after success or failure states; the user is responsible for manually sending the - * setup IN to finalize the transfer via the \ref Endpoint_ClearIN() macro. - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[out] Buffer Pointer to the destination data buffer to write to. - * \param[in] Length Number of bytes to send via the currently selected endpoint. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Read_Control_Stream_LE(void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - - /** Reads the given number of bytes from the CONTROL endpoint from the given buffer in big endian, - * discarding fully read packets from the host as needed. The device IN acknowledgement is not - * automatically sent after success or failure states; the user is responsible for manually sending the - * setup IN to finalize the transfer via the \ref Endpoint_ClearIN() macro. - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[out] Buffer Pointer to the destination data buffer to write to. - * \param[in] Length Number of bytes to send via the currently selected endpoint. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Read_Control_Stream_BE(void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - //@} - - /** \name Stream functions for EEPROM source/destination data */ - //@{ - - /** EEPROM buffer source version of \ref Endpoint_Write_Stream_LE(). - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_EStream_LE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** EEPROM buffer source version of \ref Endpoint_Write_Stream_BE(). - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_EStream_BE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** EEPROM buffer destination version of \ref Endpoint_Read_Stream_LE(). - * - * \param[out] Buffer Pointer to the destination data buffer to write to, located in EEPROM memory space. - * \param[in] Length Number of bytes to send via the currently selected endpoint. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Read_EStream_LE(void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** EEPROM buffer destination version of \ref Endpoint_Read_Stream_BE(). - * - * \param[out] Buffer Pointer to the destination data buffer to write to, located in EEPROM memory space. - * \param[in] Length Number of bytes to send via the currently selected endpoint. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Read_EStream_BE(void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** EEPROM buffer source version of Endpoint_Write_Control_Stream_LE. - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * \n\n - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_Control_EStream_LE(const void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - - /** EEPROM buffer source version of \ref Endpoint_Write_Control_Stream_BE(). - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * \n\n - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_Control_EStream_BE(const void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - - /** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_LE(). - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * \n\n - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[out] Buffer Pointer to the destination data buffer to write to. - * \param[in] Length Number of bytes to send via the currently selected endpoint. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Read_Control_EStream_LE(void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - - /** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_BE(). - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * \n\n - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[out] Buffer Pointer to the destination data buffer to write to. - * \param[in] Length Number of bytes to send via the currently selected endpoint. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Read_Control_EStream_BE(void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - //@} - - /** \name Stream functions for PROGMEM source/destination data */ - //@{ - - /** FLASH buffer source version of \ref Endpoint_Write_Stream_LE(). - * - * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_PStream_LE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** FLASH buffer source version of \ref Endpoint_Write_Stream_BE(). - * - * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_PStream_BE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_LE(). - * - * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * \n\n - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_Control_PStream_LE(const void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - - /** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_BE(). - * - * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * \n\n - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_Control_PStream_BE(const void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - //@} - - /* Disable C linkage for C++ Compilers: */ - #if defined(__cplusplus) - } - #endif - -#endif - -/** @} */ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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 Endpoint data stream transmission and reception management for the AVR8 microcontrollers. + * \copydetails Group_EndpointStreamRW_AVR8 + * + * \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_EndpointStreamRW + * \defgroup Group_EndpointStreamRW_AVR8 Read/Write of Multi-Byte Streams (AVR8) + * \brief Endpoint data stream transmission and reception management for the Atmel AVR8 architecture. + * + * Functions, macros, variables, enums and types related to data reading and writing of data streams from + * and to endpoints. + * + * @{ + */ + +#ifndef __ENDPOINT_STREAM_AVR8_H__ +#define __ENDPOINT_STREAM_AVR8_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBMode.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: */ + /* Function Prototypes: */ + /** \name Stream functions for null data */ + //@{ + + /** Reads and discards the given number of bytes from the currently selected endpoint's bank, + * discarding fully read packets from the host as needed. The last packet is not automatically + * discarded once the remaining bytes has been read; the user is responsible for manually + * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes empty while there is still data to process (and after the current + * packet has been acknowledged) the BytesProcessed location will be updated with the total number + * of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Discard_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Discard_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Length Number of bytes to discard via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Discard_Stream(uint16_t Length, + uint16_t* const BytesProcessed); + + /** Writes a given number of zeroed bytes to the currently selected endpoint's bank, sending + * full packets to the host as needed. The last packet is not automatically sent once the + * remaining bytes have been written; the user is responsible for manually sending the last + * packet to the host via the \ref Endpoint_ClearIN() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes full while there is still data to process (and after the current + * packet transmission has been initiated) the BytesProcessed location will be updated with the + * total number of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Null_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Null_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Length Number of zero bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Null_Stream(uint16_t Length, + uint16_t* const BytesProcessed); + + //@} + + /** \name Stream functions for RAM source/destination data */ + //@{ + + /** Writes the given number of bytes to the endpoint from the given buffer in little endian, + * sending full packets to the host as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Endpoint_ClearIN() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes full while there is still data to process (and after the current + * packet transmission has been initiated) the BytesProcessed location will be updated with the + * total number of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream), + * NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream), + * &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Stream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the endpoint from the given buffer in big endian, + * sending full packets to the host as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Endpoint_ClearIN() macro. + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Stream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the endpoint from the given buffer in little endian, + * discarding fully read packets from the host as needed. The last packet is not automatically + * discarded once the remaining bytes has been read; the user is responsible for manually + * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes empty while there is still data to process (and after the current + * packet has been acknowledged) the BytesProcessed location will be updated with the total number + * of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream), + * NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream), + * &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Stream_LE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the endpoint from the given buffer in big endian, + * discarding fully read packets from the host as needed. The last packet is not automatically + * discarded once the remaining bytes has been read; the user is responsible for manually + * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Stream_BE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in little endian, + * sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared + * in both failure and success states; the user is responsible for manually clearing the status OUT packet + * to finalize the transfer's status stage via the \ref Endpoint_ClearOUT() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_Stream_LE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in big endian, + * sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared + * in both failure and success states; the user is responsible for manually clearing the status OUT packet + * to finalize the transfer's status stage via the \ref Endpoint_ClearOUT() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_Stream_BE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the CONTROL endpoint from the given buffer in little endian, + * discarding fully read packets from the host as needed. The device IN acknowledgement is not + * automatically sent after success or failure states; the user is responsible for manually sending the + * status IN packet to finalize the transfer's status stage via the \ref Endpoint_ClearIN() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Control_Stream_LE(void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the CONTROL endpoint from the given buffer in big endian, + * discarding fully read packets from the host as needed. The device IN acknowledgement is not + * automatically sent after success or failure states; the user is responsible for manually sending the + * status IN packet to finalize the transfer's status stage via the \ref Endpoint_ClearIN() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Control_Stream_BE(void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /** \name Stream functions for EEPROM source/destination data */ + //@{ + + /** EEPROM buffer source version of \ref Endpoint_Write_Stream_LE(). + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_EStream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Endpoint_Write_Stream_BE(). + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_EStream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer destination version of \ref Endpoint_Read_Stream_LE(). + * + * \param[out] Buffer Pointer to the destination data buffer to write to, located in EEPROM memory space. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_EStream_LE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer destination version of \ref Endpoint_Read_Stream_BE(). + * + * \param[out] Buffer Pointer to the destination data buffer to write to, located in EEPROM memory space. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_EStream_BE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of Endpoint_Write_Control_Stream_LE. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_EStream_LE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Endpoint_Write_Control_Stream_BE(). + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_EStream_BE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_LE(). + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Control_EStream_LE(void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_BE(). + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Control_EStream_BE(void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /** \name Stream functions for PROGMEM source/destination data */ + //@{ + + /** FLASH buffer source version of \ref Endpoint_Write_Stream_LE(). + * + * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_PStream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** FLASH buffer source version of \ref Endpoint_Write_Stream_BE(). + * + * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_PStream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_LE(). + * + * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_PStream_LE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_BE(). + * + * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_PStream_BE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ diff --git a/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.h b/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.h index 056981a2..57d9b0d4 100644 --- a/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.h +++ b/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.h @@ -202,7 +202,12 @@ const uint16_t Size, const uint8_t Banks) { - return Endpoint_ConfigureEndpoint_Prv((Address & ENDPOINT_EPNUM_MASK), + uint8_t Number = (Address & ENDPOINT_EPNUM_MASK); + + if (Number >= ENDPOINT_TOTAL_ENDPOINTS) + return false; + + return Endpoint_ConfigureEndpoint_Prv(Number, ((Type << EPTYPE0) | ((Address & ENDPOINT_DIR_IN) ? (1 << EPDIR) : 0)), ((1 << ALLOC) | ((Banks > 1) ? (1 << EPBK0) : 0) | Endpoint_BytesToEPSizeMask(Size))); } diff --git a/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.c b/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.c index e71a7bd3..3d80a33f 100644 --- a/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.c +++ b/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.c @@ -1,221 +1,221 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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. -*/ - -#include "../../../../Common/Common.h" -#if (ARCH == ARCH_AVR8) - -#define __INCLUDE_FROM_USB_DRIVER -#include "../USBMode.h" - -#if defined(USB_CAN_BE_HOST) - -#include "PipeStream_AVR8.h" - -uint8_t Pipe_Discard_Stream(uint16_t Length, - uint16_t* const BytesProcessed) -{ - uint8_t ErrorCode; - uint16_t BytesInTransfer = 0; - - Pipe_SetPipeToken(PIPE_TOKEN_IN); - - if ((ErrorCode = Pipe_WaitUntilReady())) - return ErrorCode; - - if (BytesProcessed != NULL) - Length -= *BytesProcessed; - - while (Length) - { - if (!(Pipe_IsReadWriteAllowed())) - { - Pipe_ClearIN(); - - if (BytesProcessed != NULL) - { - *BytesProcessed += BytesInTransfer; - return PIPE_RWSTREAM_IncompleteTransfer; - } - - if ((ErrorCode = Pipe_WaitUntilReady())) - return ErrorCode; - } - else - { - Pipe_Discard_8(); - - Length--; - BytesInTransfer++; - } - } - - return PIPE_RWSTREAM_NoError; -} - -uint8_t Pipe_Null_Stream(uint16_t Length, - uint16_t* const BytesProcessed) -{ - uint8_t ErrorCode; - uint16_t BytesInTransfer = 0; - - Pipe_SetPipeToken(PIPE_TOKEN_OUT); - - if ((ErrorCode = Pipe_WaitUntilReady())) - return ErrorCode; - - if (BytesProcessed != NULL) - Length -= *BytesProcessed; - - while (Length) - { - if (!(Pipe_IsReadWriteAllowed())) - { - Pipe_ClearOUT(); - - if (BytesProcessed != NULL) - { - *BytesProcessed += BytesInTransfer; - return PIPE_RWSTREAM_IncompleteTransfer; - } - - USB_USBTask(); - - if ((ErrorCode = Pipe_WaitUntilReady())) - return ErrorCode; - } - else - { - Pipe_Write_8(0); - - Length--; - BytesInTransfer++; - } - } - - return PIPE_RWSTREAM_NoError; -} - -/* The following abuses the C preprocessor in order to copy-paste common code with slight alterations, - * so that the code needs to be written once. It is a crude form of templating to reduce code maintenance. */ - -#define TEMPLATE_FUNC_NAME Pipe_Write_Stream_LE -#define TEMPLATE_BUFFER_TYPE const void* -#define TEMPLATE_TOKEN PIPE_TOKEN_OUT -#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() -#define TEMPLATE_BUFFER_OFFSET(Length) 0 -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(*BufferPtr) -#include "Template/Template_Pipe_RW.c" - -#define TEMPLATE_FUNC_NAME Pipe_Write_Stream_BE -#define TEMPLATE_BUFFER_TYPE const void* -#define TEMPLATE_TOKEN PIPE_TOKEN_OUT -#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() -#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(*BufferPtr) -#include "Template/Template_Pipe_RW.c" - -#define TEMPLATE_FUNC_NAME Pipe_Read_Stream_LE -#define TEMPLATE_BUFFER_TYPE void* -#define TEMPLATE_TOKEN PIPE_TOKEN_IN -#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN() -#define TEMPLATE_BUFFER_OFFSET(Length) 0 -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Pipe_Read_8() -#include "Template/Template_Pipe_RW.c" - -#define TEMPLATE_FUNC_NAME Pipe_Read_Stream_BE -#define TEMPLATE_BUFFER_TYPE void* -#define TEMPLATE_TOKEN PIPE_TOKEN_IN -#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN() -#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Pipe_Read_8() -#include "Template/Template_Pipe_RW.c" - -#define TEMPLATE_FUNC_NAME Pipe_Write_PStream_LE -#define TEMPLATE_BUFFER_TYPE const void* -#define TEMPLATE_TOKEN PIPE_TOKEN_OUT -#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() -#define TEMPLATE_BUFFER_OFFSET(Length) 0 -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(pgm_read_byte(BufferPtr)) -#include "Template/Template_Pipe_RW.c" - -#define TEMPLATE_FUNC_NAME Pipe_Write_PStream_BE -#define TEMPLATE_BUFFER_TYPE const void* -#define TEMPLATE_TOKEN PIPE_TOKEN_OUT -#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() -#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(pgm_read_byte(BufferPtr)) -#include "Template/Template_Pipe_RW.c" - -#define TEMPLATE_FUNC_NAME Pipe_Write_EStream_LE -#define TEMPLATE_BUFFER_TYPE const void* -#define TEMPLATE_TOKEN PIPE_TOKEN_OUT -#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() -#define TEMPLATE_BUFFER_OFFSET(Length) 0 -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(eeprom_read_byte(BufferPtr)) -#include "Template/Template_Pipe_RW.c" - -#define TEMPLATE_FUNC_NAME Pipe_Write_EStream_BE -#define TEMPLATE_BUFFER_TYPE const void* -#define TEMPLATE_TOKEN PIPE_TOKEN_OUT -#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() -#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(eeprom_read_byte(BufferPtr)) -#include "Template/Template_Pipe_RW.c" - -#define TEMPLATE_FUNC_NAME Pipe_Read_EStream_LE -#define TEMPLATE_BUFFER_TYPE void* -#define TEMPLATE_TOKEN PIPE_TOKEN_IN -#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN() -#define TEMPLATE_BUFFER_OFFSET(Length) 0 -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Pipe_Read_8()) -#include "Template/Template_Pipe_RW.c" - -#define TEMPLATE_FUNC_NAME Pipe_Read_EStream_BE -#define TEMPLATE_BUFFER_TYPE void* -#define TEMPLATE_TOKEN PIPE_TOKEN_IN -#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN() -#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Pipe_Read_8()) -#include "Template/Template_Pipe_RW.c" - -#endif - -#endif - +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_AVR8) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#include "PipeStream_AVR8.h" + +uint8_t Pipe_Discard_Stream(uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t ErrorCode; + uint16_t BytesInTransfer = 0; + + Pipe_SetPipeToken(PIPE_TOKEN_IN); + + if ((ErrorCode = Pipe_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + Length -= *BytesProcessed; + + while (Length) + { + if (!(Pipe_IsReadWriteAllowed())) + { + Pipe_ClearIN(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return PIPE_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Pipe_WaitUntilReady())) + return ErrorCode; + } + else + { + Pipe_Discard_8(); + + Length--; + BytesInTransfer++; + } + } + + return PIPE_RWSTREAM_NoError; +} + +uint8_t Pipe_Null_Stream(uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t ErrorCode; + uint16_t BytesInTransfer = 0; + + Pipe_SetPipeToken(PIPE_TOKEN_OUT); + + if ((ErrorCode = Pipe_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + Length -= *BytesProcessed; + + while (Length) + { + if (!(Pipe_IsReadWriteAllowed())) + { + Pipe_ClearOUT(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return PIPE_RWSTREAM_IncompleteTransfer; + } + + USB_USBTask(); + + if ((ErrorCode = Pipe_WaitUntilReady())) + return ErrorCode; + } + else + { + Pipe_Write_8(0); + + Length--; + BytesInTransfer++; + } + } + + return PIPE_RWSTREAM_NoError; +} + +/* The following abuses the C preprocessor in order to copy-paste common code with slight alterations, + * so that the code needs to be written once. It is a crude form of templating to reduce code maintenance. */ + +#define TEMPLATE_FUNC_NAME Pipe_Write_Stream_LE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_TOKEN PIPE_TOKEN_OUT +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(*BufferPtr) +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Write_Stream_BE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_TOKEN PIPE_TOKEN_OUT +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(*BufferPtr) +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Read_Stream_LE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_TOKEN PIPE_TOKEN_IN +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Pipe_Read_8() +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Read_Stream_BE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_TOKEN PIPE_TOKEN_IN +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Pipe_Read_8() +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Write_PStream_LE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_TOKEN PIPE_TOKEN_OUT +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(pgm_read_byte(BufferPtr)) +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Write_PStream_BE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_TOKEN PIPE_TOKEN_OUT +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(pgm_read_byte(BufferPtr)) +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Write_EStream_LE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_TOKEN PIPE_TOKEN_OUT +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(eeprom_read_byte(BufferPtr)) +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Write_EStream_BE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_TOKEN PIPE_TOKEN_OUT +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(eeprom_read_byte(BufferPtr)) +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Read_EStream_LE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_TOKEN PIPE_TOKEN_IN +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Pipe_Read_8()) +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Read_EStream_BE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_TOKEN PIPE_TOKEN_IN +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Pipe_Read_8()) +#include "Template/Template_Pipe_RW.c" + +#endif + +#endif + diff --git a/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.h b/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.h index 53316f2f..f69469f2 100644 --- a/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.h +++ b/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.h @@ -1,442 +1,442 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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 Pipe data stream transmission and reception management for the AVR8 microcontrollers - * \copydetails Group_PipeStreamRW_AVR8 - * - * \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_PipeStreamRW - * \defgroup Group_PipeStreamRW_AVR8 Read/Write of Multi-Byte Streams (AVR8) - * \brief Pipe data stream transmission and reception management for the Atmel AVR8 architecture. - * - * Functions, macros, variables, enums and types related to data reading and writing of data streams from - * and to pipes. - * - * @{ - */ - -#ifndef __PIPE_STREAM_AVR8_H__ -#define __PIPE_STREAM_AVR8_H__ - - /* Includes: */ - #include "../../../../Common/Common.h" - #include "../USBMode.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: */ - /* Function Prototypes: */ - /** \name Stream functions for null data */ - //@{ - - /** Reads and discards the given number of bytes from the pipe, discarding fully read packets from the host - * as needed. The last packet is not automatically discarded once the remaining bytes has been read; the - * user is responsible for manually discarding the last packet from the device via the \ref Pipe_ClearIN() macro. - * - * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, failing or - * succeeding as a single unit. If the BytesProcessed parameter points to a valid storage location, the transfer - * will instead be performed as a series of chunks. Each time the pipe bank becomes empty while there is still data - * to process (and after the current packet has been acknowledged) the BytesProcessed location will be updated with - * the total number of bytes processed in the stream, and the function will exit with an error code of - * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed in the user code - to - * continue the transfer, call the function again with identical parameters and it will resume until the BytesProcessed - * value reaches the total transfer length. - * - * Single Stream Transfer Example: - * \code - * uint8_t ErrorCode; - * - * if ((ErrorCode = Pipe_Discard_Stream(512, NULL)) != PIPE_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * Partial Stream Transfers Example: - * \code - * uint8_t ErrorCode; - * uint16_t BytesProcessed; - * - * BytesProcessed = 0; - * while ((ErrorCode = Pipe_Discard_Stream(512, &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) - * { - * // Stream not yet complete - do other actions here, abort if required - * } - * - * if (ErrorCode != PIPE_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without - * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). - * - * \param[in] Length Number of bytes to discard via the currently selected pipe. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should - * updated, \c NULL if the entire stream should be processed at once. - * - * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Pipe_Discard_Stream(uint16_t Length, - uint16_t* const BytesProcessed); - - /** Writes a given number of zeroed bytes to the pipe, sending full pipe packets from the host to the device - * as needed. The last packet is not automatically sent once the remaining bytes has been written; the - * user is responsible for manually discarding the last packet from the device via the \ref Pipe_ClearOUT() macro. - * - * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, failing or - * succeeding as a single unit. If the BytesProcessed parameter points to a valid storage location, the transfer - * will instead be performed as a series of chunks. Each time the pipe bank becomes full while there is still data - * to process (and after the current packet transmission has been initiated) the BytesProcessed location will be - * updated with the total number of bytes processed in the stream, and the function will exit with an error code of - * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed in the user code - to - * continue the transfer, call the function again with identical parameters and it will resume until the BytesProcessed - * value reaches the total transfer length. - * - * Single Stream Transfer Example: - * \code - * uint8_t ErrorCode; - * - * if ((ErrorCode = Pipe_Null_Stream(512, NULL)) != PIPE_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * Partial Stream Transfers Example: - * \code - * uint8_t ErrorCode; - * uint16_t BytesProcessed; - * - * BytesProcessed = 0; - * while ((ErrorCode = Pipe_Null_Stream(512, &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) - * { - * // Stream not yet complete - do other actions here, abort if required - * } - * - * if (ErrorCode != PIPE_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without - * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). - * - * \param[in] Length Number of zero bytes to write via the currently selected pipe. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should - * updated, \c NULL if the entire stream should be processed at once. - * - * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Pipe_Null_Stream(uint16_t Length, - uint16_t* const BytesProcessed); - - //@} - - /** \name Stream functions for RAM source/destination data */ - //@{ - - /** Writes the given number of bytes to the pipe from the given buffer in little endian, - * sending full packets to the device as needed. The last packet filled is not automatically sent; - * the user is responsible for manually sending the last written packet to the host via the - * \ref Pipe_ClearOUT() macro. Between each USB packet, the given stream callback function is - * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. - * - * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, - * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid - * storage location, the transfer will instead be performed as a series of chunks. Each time - * the pipe bank becomes full while there is still data to process (and after the current - * packet transmission has been initiated) the BytesProcessed location will be updated with the - * total number of bytes processed in the stream, and the function will exit with an error code of - * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed - * in the user code - to continue the transfer, call the function again with identical parameters - * and it will resume until the BytesProcessed value reaches the total transfer length. - * - * Single Stream Transfer Example: - * \code - * uint8_t DataStream[512]; - * uint8_t ErrorCode; - * - * if ((ErrorCode = Pipe_Write_Stream_LE(DataStream, sizeof(DataStream), - * NULL)) != PIPE_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * Partial Stream Transfers Example: - * \code - * uint8_t DataStream[512]; - * uint8_t ErrorCode; - * uint16_t BytesProcessed; - * - * BytesProcessed = 0; - * while ((ErrorCode = Pipe_Write_Stream_LE(DataStream, sizeof(DataStream), - * &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) - * { - * // Stream not yet complete - do other actions here, abort if required - * } - * - * if (ErrorCode != PIPE_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without - * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should - * updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Pipe_Write_Stream_LE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** Writes the given number of bytes to the pipe from the given buffer in big endian, - * sending full packets to the device as needed. The last packet filled is not automatically sent; - * the user is responsible for manually sending the last written packet to the host via the - * \ref Pipe_ClearOUT() macro. Between each USB packet, the given stream callback function is - * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. - * - * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without - * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should - * updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Pipe_Write_Stream_BE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** Reads the given number of bytes from the pipe into the given buffer in little endian, - * sending full packets to the device as needed. The last packet filled is not automatically sent; - * the user is responsible for manually sending the last written packet to the host via the - * \ref Pipe_ClearIN() macro. Between each USB packet, the given stream callback function is - * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. - * - * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, - * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid - * storage location, the transfer will instead be performed as a series of chunks. Each time - * the pipe bank becomes empty while there is still data to process (and after the current - * packet has been acknowledged) the BytesProcessed location will be updated with the total number - * of bytes processed in the stream, and the function will exit with an error code of - * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed - * in the user code - to continue the transfer, call the function again with identical parameters - * and it will resume until the BytesProcessed value reaches the total transfer length. - * - * Single Stream Transfer Example: - * \code - * uint8_t DataStream[512]; - * uint8_t ErrorCode; - * - * if ((ErrorCode = Pipe_Read_Stream_LE(DataStream, sizeof(DataStream), - * NULL)) != PIPE_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * Partial Stream Transfers Example: - * \code - * uint8_t DataStream[512]; - * uint8_t ErrorCode; - * uint16_t BytesProcessed; - * - * BytesProcessed = 0; - * while ((ErrorCode = Pipe_Read_Stream_LE(DataStream, sizeof(DataStream), - * &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) - * { - * // Stream not yet complete - do other actions here, abort if required - * } - * - * if (ErrorCode != PIPE_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without - * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). - * - * \param[out] Buffer Pointer to the source data buffer to write to. - * \param[in] Length Number of bytes to read for the currently selected pipe to read from. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should - * updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Pipe_Read_Stream_LE(void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** Reads the given number of bytes from the pipe into the given buffer in big endian, - * sending full packets to the device as needed. The last packet filled is not automatically sent; - * the user is responsible for manually sending the last written packet to the host via the - * \ref Pipe_ClearIN() macro. Between each USB packet, the given stream callback function is - * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. - * - * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without - * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). - * - * \param[out] Buffer Pointer to the source data buffer to write to. - * \param[in] Length Number of bytes to read for the currently selected pipe to read from. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should - * updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Pipe_Read_Stream_BE(void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - //@} - - /** \name Stream functions for EEPROM source/destination data */ - //@{ - - /** EEPROM buffer source version of \ref Pipe_Write_Stream_LE(). - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should - * updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Pipe_Write_EStream_LE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** EEPROM buffer source version of \ref Pipe_Write_Stream_BE(). - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should - * updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Pipe_Write_EStream_BE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** EEPROM buffer source version of \ref Pipe_Read_Stream_LE(). - * - * \param[out] Buffer Pointer to the source data buffer to write to. - * \param[in] Length Number of bytes to read for the currently selected pipe to read from. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should - * updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Pipe_Read_EStream_LE(void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** EEPROM buffer source version of \ref Pipe_Read_Stream_BE(). - * - * \param[out] Buffer Pointer to the source data buffer to write to. - * \param[in] Length Number of bytes to read for the currently selected pipe to read from. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should - * updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Pipe_Read_EStream_BE(void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - //@} - - /** \name Stream functions for PROGMEM source/destination data */ - //@{ - - /** FLASH buffer source version of \ref Pipe_Write_Stream_LE(). - * - * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should - * updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Pipe_Write_PStream_LE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** FLASH buffer source version of \ref Pipe_Write_Stream_BE(). - * - * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should - * updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Pipe_Write_PStream_BE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - //@} - - /* Disable C linkage for C++ Compilers: */ - #if defined(__cplusplus) - } - #endif - -#endif - -/** @} */ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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 Pipe data stream transmission and reception management for the AVR8 microcontrollers + * \copydetails Group_PipeStreamRW_AVR8 + * + * \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_PipeStreamRW + * \defgroup Group_PipeStreamRW_AVR8 Read/Write of Multi-Byte Streams (AVR8) + * \brief Pipe data stream transmission and reception management for the Atmel AVR8 architecture. + * + * Functions, macros, variables, enums and types related to data reading and writing of data streams from + * and to pipes. + * + * @{ + */ + +#ifndef __PIPE_STREAM_AVR8_H__ +#define __PIPE_STREAM_AVR8_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBMode.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: */ + /* Function Prototypes: */ + /** \name Stream functions for null data */ + //@{ + + /** Reads and discards the given number of bytes from the pipe, discarding fully read packets from the host + * as needed. The last packet is not automatically discarded once the remaining bytes has been read; the + * user is responsible for manually discarding the last packet from the device via the \ref Pipe_ClearIN() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, failing or + * succeeding as a single unit. If the BytesProcessed parameter points to a valid storage location, the transfer + * will instead be performed as a series of chunks. Each time the pipe bank becomes empty while there is still data + * to process (and after the current packet has been acknowledged) the BytesProcessed location will be updated with + * the total number of bytes processed in the stream, and the function will exit with an error code of + * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed in the user code - to + * continue the transfer, call the function again with identical parameters and it will resume until the BytesProcessed + * value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t ErrorCode; + * + * if ((ErrorCode = Pipe_Discard_Stream(512, NULL)) != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Pipe_Discard_Stream(512, &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[in] Length Number of bytes to discard via the currently selected pipe. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be processed at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Discard_Stream(uint16_t Length, + uint16_t* const BytesProcessed); + + /** Writes a given number of zeroed bytes to the pipe, sending full pipe packets from the host to the device + * as needed. The last packet is not automatically sent once the remaining bytes has been written; the + * user is responsible for manually discarding the last packet from the device via the \ref Pipe_ClearOUT() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, failing or + * succeeding as a single unit. If the BytesProcessed parameter points to a valid storage location, the transfer + * will instead be performed as a series of chunks. Each time the pipe bank becomes full while there is still data + * to process (and after the current packet transmission has been initiated) the BytesProcessed location will be + * updated with the total number of bytes processed in the stream, and the function will exit with an error code of + * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed in the user code - to + * continue the transfer, call the function again with identical parameters and it will resume until the BytesProcessed + * value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t ErrorCode; + * + * if ((ErrorCode = Pipe_Null_Stream(512, NULL)) != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Pipe_Null_Stream(512, &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[in] Length Number of zero bytes to write via the currently selected pipe. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be processed at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Null_Stream(uint16_t Length, + uint16_t* const BytesProcessed); + + //@} + + /** \name Stream functions for RAM source/destination data */ + //@{ + + /** Writes the given number of bytes to the pipe from the given buffer in little endian, + * sending full packets to the device as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Pipe_ClearOUT() macro. Between each USB packet, the given stream callback function is + * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the pipe bank becomes full while there is still data to process (and after the current + * packet transmission has been initiated) the BytesProcessed location will be updated with the + * total number of bytes processed in the stream, and the function will exit with an error code of + * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * + * if ((ErrorCode = Pipe_Write_Stream_LE(DataStream, sizeof(DataStream), + * NULL)) != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Pipe_Write_Stream_LE(DataStream, sizeof(DataStream), + * &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Write_Stream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the pipe from the given buffer in big endian, + * sending full packets to the device as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Pipe_ClearOUT() macro. Between each USB packet, the given stream callback function is + * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Write_Stream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the pipe into the given buffer in little endian, + * sending full packets to the device as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Pipe_ClearIN() macro. Between each USB packet, the given stream callback function is + * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the pipe bank becomes empty while there is still data to process (and after the current + * packet has been acknowledged) the BytesProcessed location will be updated with the total number + * of bytes processed in the stream, and the function will exit with an error code of + * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * + * if ((ErrorCode = Pipe_Read_Stream_LE(DataStream, sizeof(DataStream), + * NULL)) != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Pipe_Read_Stream_LE(DataStream, sizeof(DataStream), + * &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[out] Buffer Pointer to the source data buffer to write to. + * \param[in] Length Number of bytes to read for the currently selected pipe to read from. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Read_Stream_LE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the pipe into the given buffer in big endian, + * sending full packets to the device as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Pipe_ClearIN() macro. Between each USB packet, the given stream callback function is + * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[out] Buffer Pointer to the source data buffer to write to. + * \param[in] Length Number of bytes to read for the currently selected pipe to read from. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Read_Stream_BE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /** \name Stream functions for EEPROM source/destination data */ + //@{ + + /** EEPROM buffer source version of \ref Pipe_Write_Stream_LE(). + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Write_EStream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Pipe_Write_Stream_BE(). + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Write_EStream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Pipe_Read_Stream_LE(). + * + * \param[out] Buffer Pointer to the source data buffer to write to. + * \param[in] Length Number of bytes to read for the currently selected pipe to read from. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Read_EStream_LE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Pipe_Read_Stream_BE(). + * + * \param[out] Buffer Pointer to the source data buffer to write to. + * \param[in] Length Number of bytes to read for the currently selected pipe to read from. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Read_EStream_BE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /** \name Stream functions for PROGMEM source/destination data */ + //@{ + + /** FLASH buffer source version of \ref Pipe_Write_Stream_LE(). + * + * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Write_PStream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** FLASH buffer source version of \ref Pipe_Write_Stream_BE(). + * + * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Write_PStream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ diff --git a/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c b/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c index 1ddffb51..b6437083 100644 --- a/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c +++ b/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c @@ -66,6 +66,9 @@ bool Pipe_ConfigurePipe(const uint8_t Address, uint8_t Number = (Address & PIPE_EPNUM_MASK); uint8_t Token = (Address & PIPE_DIR_IN) ? PIPE_TOKEN_IN : PIPE_TOKEN_OUT; + if (Number >= PIPE_TOTAL_PIPES) + return false; + if (Type == EP_TYPE_CONTROL) Token = PIPE_TOKEN_SETUP; diff --git a/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h b/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h index 330dd981..8106988d 100644 --- a/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h +++ b/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h @@ -215,7 +215,7 @@ * 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 + * interface to control the USB interface's behavior. 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. diff --git a/LUFA/Drivers/USB/Core/ConfigDescriptor.c b/LUFA/Drivers/USB/Core/ConfigDescriptor.c deleted file mode 100644 index 5bdcdc66..00000000 --- a/LUFA/Drivers/USB/Core/ConfigDescriptor.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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 "ConfigDescriptor.h" - -#if defined(USB_CAN_BE_HOST) -uint8_t USB_Host_GetDeviceConfigDescriptor(const uint8_t ConfigNumber, - uint16_t* const ConfigSizePtr, - void* const BufferPtr, - const uint16_t BufferSize) -{ - uint8_t ErrorCode; - uint8_t ConfigHeader[sizeof(USB_Descriptor_Configuration_Header_t)]; - - USB_ControlRequest = (USB_Request_Header_t) - { - .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE), - .bRequest = REQ_GetDescriptor, - .wValue = ((DTYPE_Configuration << 8) | (ConfigNumber - 1)), - .wIndex = 0, - .wLength = sizeof(USB_Descriptor_Configuration_Header_t), - }; - - Pipe_SelectPipe(PIPE_CONTROLPIPE); - - if ((ErrorCode = USB_Host_SendControlRequest(ConfigHeader)) != HOST_SENDCONTROL_Successful) - return ErrorCode; - - *ConfigSizePtr = le16_to_cpu(DESCRIPTOR_PCAST(ConfigHeader, USB_Descriptor_Configuration_Header_t)->TotalConfigurationSize); - - if (*ConfigSizePtr > BufferSize) - return HOST_GETCONFIG_BuffOverflow; - - USB_ControlRequest.wLength = *ConfigSizePtr; - - if ((ErrorCode = USB_Host_SendControlRequest(BufferPtr)) != HOST_SENDCONTROL_Successful) - return ErrorCode; - - if (DESCRIPTOR_TYPE(BufferPtr) != DTYPE_Configuration) - return HOST_GETCONFIG_InvalidData; - - return HOST_GETCONFIG_Successful; -} -#endif - -void USB_GetNextDescriptorOfType(uint16_t* const BytesRem, - void** const CurrConfigLoc, - const uint8_t Type) -{ - while (*BytesRem) - { - USB_GetNextDescriptor(BytesRem, CurrConfigLoc); - - if (DESCRIPTOR_TYPE(*CurrConfigLoc) == Type) - return; - } -} - -void USB_GetNextDescriptorOfTypeBefore(uint16_t* const BytesRem, - void** const CurrConfigLoc, - const uint8_t Type, - const uint8_t BeforeType) -{ - while (*BytesRem) - { - USB_GetNextDescriptor(BytesRem, CurrConfigLoc); - - if (DESCRIPTOR_TYPE(*CurrConfigLoc) == Type) - { - return; - } - else if (DESCRIPTOR_TYPE(*CurrConfigLoc) == BeforeType) - { - *BytesRem = 0; - return; - } - } -} - -void USB_GetNextDescriptorOfTypeAfter(uint16_t* const BytesRem, - void** const CurrConfigLoc, - const uint8_t Type, - const uint8_t AfterType) -{ - USB_GetNextDescriptorOfType(BytesRem, CurrConfigLoc, AfterType); - - if (*BytesRem) - USB_GetNextDescriptorOfType(BytesRem, CurrConfigLoc, Type); -} - -uint8_t USB_GetNextDescriptorComp(uint16_t* const BytesRem, - void** const CurrConfigLoc, - ConfigComparatorPtr_t const ComparatorRoutine) -{ - uint8_t ErrorCode; - - while (*BytesRem) - { - uint8_t* PrevDescLoc = *CurrConfigLoc; - uint16_t PrevBytesRem = *BytesRem; - - USB_GetNextDescriptor(BytesRem, CurrConfigLoc); - - if ((ErrorCode = ComparatorRoutine(*CurrConfigLoc)) != DESCRIPTOR_SEARCH_NotFound) - { - if (ErrorCode == DESCRIPTOR_SEARCH_Fail) - { - *CurrConfigLoc = PrevDescLoc; - *BytesRem = PrevBytesRem; - } - - return ErrorCode; - } - } - - return DESCRIPTOR_SEARCH_COMP_EndOfDescriptor; -} - diff --git a/LUFA/Drivers/USB/Core/ConfigDescriptor.h b/LUFA/Drivers/USB/Core/ConfigDescriptor.h deleted file mode 100644 index 22e76cba..00000000 --- a/LUFA/Drivers/USB/Core/ConfigDescriptor.h +++ /dev/null @@ -1,286 +0,0 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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 Configuration Descriptor definitions. - * \copydetails Group_ConfigDescriptorParser - * - * \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_StdDescriptors - * \defgroup Group_ConfigDescriptorParser Configuration Descriptor Parser - * \brief USB Configuration Descriptor definitions. - * - * This section of the library gives a friendly API which can be used in host applications to easily - * parse an attached device's configuration descriptor so that endpoint, interface and other descriptor - * data can be extracted and used as needed. - * - * @{ - */ - -#ifndef __CONFIGDESCRIPTOR_H__ -#define __CONFIGDESCRIPTOR_H__ - - /* Includes: */ - #include "../../../Common/Common.h" - #include "USBMode.h" - #include "HostStandardReq.h" - #include "StdDescriptors.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: */ - /** Casts a pointer to a descriptor inside the configuration descriptor into a pointer to the given - * descriptor type. - * - * Usage Example: - * \code - * uint8_t* CurrDescriptor = &ConfigDescriptor[0]; // Pointing to the configuration header - * USB_Descriptor_Configuration_Header_t* ConfigHeaderPtr = DESCRIPTOR_PCAST(CurrDescriptor, - * USB_Descriptor_Configuration_Header_t); - * - * // Can now access elements of the configuration header struct using the -> indirection operator - * \endcode - */ - #define DESCRIPTOR_PCAST(DescriptorPtr, Type) ((Type*)(DescriptorPtr)) - - /** Casts a pointer to a descriptor inside the configuration descriptor into the given descriptor - * type (as an actual struct instance rather than a pointer to a struct). - * - * Usage Example: - * \code - * uint8_t* CurrDescriptor = &ConfigDescriptor[0]; // Pointing to the configuration header - * USB_Descriptor_Configuration_Header_t ConfigHeader = DESCRIPTOR_CAST(CurrDescriptor, - * USB_Descriptor_Configuration_Header_t); - * - * // Can now access elements of the configuration header struct using the . operator - * \endcode - */ - #define DESCRIPTOR_CAST(DescriptorPtr, Type) (*DESCRIPTOR_PCAST(DescriptorPtr, Type)) - - /** Returns the descriptor's type, expressed as the 8-bit type value in the header of the descriptor. - * This value's meaning depends on the descriptor's placement in the descriptor, but standard type - * values can be accessed in the \ref USB_DescriptorTypes_t enum. - */ - #define DESCRIPTOR_TYPE(DescriptorPtr) DESCRIPTOR_PCAST(DescriptorPtr, USB_Descriptor_Header_t)->Type - - /** Returns the descriptor's size, expressed as the 8-bit value indicating the number of bytes. */ - #define DESCRIPTOR_SIZE(DescriptorPtr) DESCRIPTOR_PCAST(DescriptorPtr, USB_Descriptor_Header_t)->Size - - /* Type Defines: */ - /** Type define for a Configuration Descriptor comparator function (function taking a pointer to an array - * of type void, returning a uint8_t value). - * - * \see \ref USB_GetNextDescriptorComp function for more details. - */ - typedef uint8_t (* ConfigComparatorPtr_t)(void*); - - /* Enums: */ - /** Enum for the possible return codes of the \ref USB_Host_GetDeviceConfigDescriptor() function. */ - enum USB_Host_GetConfigDescriptor_ErrorCodes_t - { - HOST_GETCONFIG_Successful = 0, /**< No error occurred while retrieving the configuration descriptor. */ - HOST_GETCONFIG_DeviceDisconnect = 1, /**< The attached device was disconnected while retrieving the configuration - * descriptor. - */ - HOST_GETCONFIG_PipeError = 2, /**< An error occurred in the pipe while sending the request. */ - HOST_GETCONFIG_SetupStalled = 3, /**< The attached device stalled the request to retrieve the configuration - * descriptor. - */ - HOST_GETCONFIG_SoftwareTimeOut = 4, /**< The request or data transfer timed out. */ - HOST_GETCONFIG_BuffOverflow = 5, /**< The device's configuration descriptor is too large to fit into the allocated - * buffer. - */ - HOST_GETCONFIG_InvalidData = 6, /**< The device returned invalid configuration descriptor data. */ - }; - - /** Enum for return values of a descriptor comparator function. */ - enum DSearch_Return_ErrorCodes_t - { - DESCRIPTOR_SEARCH_Found = 0, /**< Current descriptor matches comparator criteria. */ - DESCRIPTOR_SEARCH_Fail = 1, /**< No further descriptor could possibly match criteria, fail the search. */ - DESCRIPTOR_SEARCH_NotFound = 2, /**< Current descriptor does not match comparator criteria. */ - }; - - /** Enum for return values of \ref USB_GetNextDescriptorComp(). */ - enum DSearch_Comp_Return_ErrorCodes_t - { - DESCRIPTOR_SEARCH_COMP_Found = 0, /**< Configuration descriptor now points to descriptor which matches - * search criteria of the given comparator function. */ - DESCRIPTOR_SEARCH_COMP_Fail = 1, /**< Comparator function returned \ref DESCRIPTOR_SEARCH_Fail. */ - DESCRIPTOR_SEARCH_COMP_EndOfDescriptor = 2, /**< End of configuration descriptor reached before match found. */ - }; - - /* Function Prototypes: */ - /** Retrieves the configuration descriptor data from an attached device via a standard request into a buffer, - * including validity and size checking to prevent a buffer overflow. - * - * \param[in] ConfigNumber Device configuration descriptor number to fetch from the device (usually set to 1 for - * single configuration devices). - * \param[in,out] ConfigSizePtr Pointer to a location for storing the retrieved configuration descriptor size. - * \param[out] BufferPtr Pointer to the buffer for storing the configuration descriptor data. - * \param[out] BufferSize Size of the allocated buffer where the configuration descriptor is to be stored. - * - * \return A value from the \ref USB_Host_GetConfigDescriptor_ErrorCodes_t enum. - */ - uint8_t USB_Host_GetDeviceConfigDescriptor(const uint8_t ConfigNumber, - uint16_t* const ConfigSizePtr, - void* const BufferPtr, - const uint16_t BufferSize) ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(3); - - /** Skips to the next sub-descriptor inside the configuration descriptor of the specified type value. - * The bytes remaining value is automatically decremented. - * - * \param[in,out] BytesRem Pointer to the number of bytes remaining of the configuration descriptor. - * \param[in,out] CurrConfigLoc Pointer to the current descriptor inside the configuration descriptor. - * \param[in] Type Descriptor type value to search for. - */ - void USB_GetNextDescriptorOfType(uint16_t* const BytesRem, - void** const CurrConfigLoc, - const uint8_t Type) - ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); - - /** Skips to the next sub-descriptor inside the configuration descriptor of the specified type value, - * which must come before a descriptor of the second given type value. If the BeforeType type - * descriptor is reached first, the number of bytes remaining to process is set to zero and the - * function exits. The bytes remaining value is automatically decremented. - * - * \param[in,out] BytesRem Pointer to the number of bytes remaining of the configuration descriptor. - * \param[in,out] CurrConfigLoc Pointer to the current descriptor inside the configuration descriptor. - * \param[in] Type Descriptor type value to search for. - * \param[in] BeforeType Descriptor type value which must not be reached before the given Type descriptor. - */ - void USB_GetNextDescriptorOfTypeBefore(uint16_t* const BytesRem, - void** const CurrConfigLoc, - const uint8_t Type, - const uint8_t BeforeType) - ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); - - /** Skips to the next sub-descriptor inside the configuration descriptor of the specified type value, - * which must come after a descriptor of the second given type value. The bytes remaining value is - * automatically decremented. - * - * \param[in,out] BytesRem Pointer to the number of bytes remaining of the configuration descriptor. - * \param[in,out] CurrConfigLoc Pointer to the current descriptor inside the configuration descriptor. - * \param[in] Type Descriptor type value to search for. - * \param[in] AfterType Descriptor type value which must be reached before the given Type descriptor. - */ - void USB_GetNextDescriptorOfTypeAfter(uint16_t* const BytesRem, - void** const CurrConfigLoc, - const uint8_t Type, - const uint8_t AfterType) - ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); - - /** Searches for the next descriptor in the given configuration descriptor using a pre-made comparator - * function. The routine updates the position and remaining configuration descriptor bytes values - * automatically. If a comparator routine fails a search, the descriptor pointer is retreated back - * so that the next descriptor search invocation will start from the descriptor which first caused the - * original search to fail. This behaviour allows for one comparator to be used immediately after another - * has failed, starting the second search from the descriptor which failed the first. - * - * Comparator functions should be standard functions which accept a pointer to the header of the current - * descriptor inside the configuration descriptor which is being compared, and should return a value from - * the \ref DSearch_Return_ErrorCodes_t enum as a uint8_t value. - * - * \note This function is available in USB Host mode only. - * - * \param[in,out] BytesRem Pointer to an int storing the remaining bytes in the configuration descriptor. - * \param[in,out] CurrConfigLoc Pointer to the current position in the configuration descriptor. - * \param[in] ComparatorRoutine Name of the comparator search function to use on the configuration descriptor. - * - * \return Value of one of the members of the \ref DSearch_Comp_Return_ErrorCodes_t enum. - * - * Usage Example: - * \code - * uint8_t EndpointSearcher(void* CurrentDescriptor); // Comparator Prototype - * - * uint8_t EndpointSearcher(void* CurrentDescriptor) - * { - * if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint) - * return DESCRIPTOR_SEARCH_Found; - * else - * return DESCRIPTOR_SEARCH_NotFound; - * } - * - * //... - * - * // After retrieving configuration descriptor: - * if (USB_Host_GetNextDescriptorComp(&BytesRemaining, &CurrentConfigLoc, EndpointSearcher) == - * Descriptor_Search_Comp_Found) - * { - * // Do something with the endpoint descriptor - * } - * \endcode - */ - uint8_t USB_GetNextDescriptorComp(uint16_t* const BytesRem, - void** const CurrConfigLoc, - ConfigComparatorPtr_t const ComparatorRoutine); - - /* Inline Functions: */ - /** Skips over the current sub-descriptor inside the configuration descriptor, so that the pointer then - points to the next sub-descriptor. The bytes remaining value is automatically decremented. - * - * \param[in,out] BytesRem Pointer to the number of bytes remaining of the configuration descriptor. - * \param[in,out] CurrConfigLoc Pointer to the current descriptor inside the configuration descriptor. - */ - static inline void USB_GetNextDescriptor(uint16_t* const BytesRem, - void** CurrConfigLoc) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); - static inline void USB_GetNextDescriptor(uint16_t* const BytesRem, - void** CurrConfigLoc) - { - uint16_t CurrDescriptorSize = DESCRIPTOR_CAST(*CurrConfigLoc, USB_Descriptor_Header_t).Size; - - if (*BytesRem < CurrDescriptorSize) - CurrDescriptorSize = *BytesRem; - - *CurrConfigLoc = (void*)((uintptr_t)*CurrConfigLoc + CurrDescriptorSize); - *BytesRem -= CurrDescriptorSize; - } - - /* Disable C linkage for C++ Compilers: */ - #if defined(__cplusplus) - } - #endif - -#endif - -/** @} */ - diff --git a/LUFA/Drivers/USB/Core/ConfigDescriptors.c b/LUFA/Drivers/USB/Core/ConfigDescriptors.c new file mode 100644 index 00000000..47332d85 --- /dev/null +++ b/LUFA/Drivers/USB/Core/ConfigDescriptors.c @@ -0,0 +1,146 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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 "ConfigDescriptors.h" + +#if defined(USB_CAN_BE_HOST) +uint8_t USB_Host_GetDeviceConfigDescriptor(const uint8_t ConfigNumber, + uint16_t* const ConfigSizePtr, + void* const BufferPtr, + const uint16_t BufferSize) +{ + uint8_t ErrorCode; + uint8_t ConfigHeader[sizeof(USB_Descriptor_Configuration_Header_t)]; + + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE), + .bRequest = REQ_GetDescriptor, + .wValue = ((DTYPE_Configuration << 8) | (ConfigNumber - 1)), + .wIndex = 0, + .wLength = sizeof(USB_Descriptor_Configuration_Header_t), + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + if ((ErrorCode = USB_Host_SendControlRequest(ConfigHeader)) != HOST_SENDCONTROL_Successful) + return ErrorCode; + + *ConfigSizePtr = le16_to_cpu(DESCRIPTOR_PCAST(ConfigHeader, USB_Descriptor_Configuration_Header_t)->TotalConfigurationSize); + + if (*ConfigSizePtr > BufferSize) + return HOST_GETCONFIG_BuffOverflow; + + USB_ControlRequest.wLength = *ConfigSizePtr; + + if ((ErrorCode = USB_Host_SendControlRequest(BufferPtr)) != HOST_SENDCONTROL_Successful) + return ErrorCode; + + if (DESCRIPTOR_TYPE(BufferPtr) != DTYPE_Configuration) + return HOST_GETCONFIG_InvalidData; + + return HOST_GETCONFIG_Successful; +} +#endif + +void USB_GetNextDescriptorOfType(uint16_t* const BytesRem, + void** const CurrConfigLoc, + const uint8_t Type) +{ + while (*BytesRem) + { + USB_GetNextDescriptor(BytesRem, CurrConfigLoc); + + if (DESCRIPTOR_TYPE(*CurrConfigLoc) == Type) + return; + } +} + +void USB_GetNextDescriptorOfTypeBefore(uint16_t* const BytesRem, + void** const CurrConfigLoc, + const uint8_t Type, + const uint8_t BeforeType) +{ + while (*BytesRem) + { + USB_GetNextDescriptor(BytesRem, CurrConfigLoc); + + if (DESCRIPTOR_TYPE(*CurrConfigLoc) == Type) + { + return; + } + else if (DESCRIPTOR_TYPE(*CurrConfigLoc) == BeforeType) + { + *BytesRem = 0; + return; + } + } +} + +void USB_GetNextDescriptorOfTypeAfter(uint16_t* const BytesRem, + void** const CurrConfigLoc, + const uint8_t Type, + const uint8_t AfterType) +{ + USB_GetNextDescriptorOfType(BytesRem, CurrConfigLoc, AfterType); + + if (*BytesRem) + USB_GetNextDescriptorOfType(BytesRem, CurrConfigLoc, Type); +} + +uint8_t USB_GetNextDescriptorComp(uint16_t* const BytesRem, + void** const CurrConfigLoc, + ConfigComparatorPtr_t const ComparatorRoutine) +{ + uint8_t ErrorCode; + + while (*BytesRem) + { + uint8_t* PrevDescLoc = *CurrConfigLoc; + uint16_t PrevBytesRem = *BytesRem; + + USB_GetNextDescriptor(BytesRem, CurrConfigLoc); + + if ((ErrorCode = ComparatorRoutine(*CurrConfigLoc)) != DESCRIPTOR_SEARCH_NotFound) + { + if (ErrorCode == DESCRIPTOR_SEARCH_Fail) + { + *CurrConfigLoc = PrevDescLoc; + *BytesRem = PrevBytesRem; + } + + return ErrorCode; + } + } + + return DESCRIPTOR_SEARCH_COMP_EndOfDescriptor; +} + diff --git a/LUFA/Drivers/USB/Core/ConfigDescriptors.h b/LUFA/Drivers/USB/Core/ConfigDescriptors.h new file mode 100644 index 00000000..97fb39b5 --- /dev/null +++ b/LUFA/Drivers/USB/Core/ConfigDescriptors.h @@ -0,0 +1,286 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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 Configuration Descriptor definitions. + * \copydetails Group_ConfigDescriptorParser + * + * \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_StdDescriptors + * \defgroup Group_ConfigDescriptorParser Configuration Descriptor Parser + * \brief USB Configuration Descriptor definitions. + * + * This section of the library gives a friendly API which can be used in host applications to easily + * parse an attached device's configuration descriptor so that endpoint, interface and other descriptor + * data can be extracted and used as needed. + * + * @{ + */ + +#ifndef __CONFIGDESCRIPTOR_H__ +#define __CONFIGDESCRIPTOR_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + #include "USBMode.h" + #include "HostStandardReq.h" + #include "StdDescriptors.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: */ + /** Casts a pointer to a descriptor inside the configuration descriptor into a pointer to the given + * descriptor type. + * + * Usage Example: + * \code + * uint8_t* CurrDescriptor = &ConfigDescriptor[0]; // Pointing to the configuration header + * USB_Descriptor_Configuration_Header_t* ConfigHeaderPtr = DESCRIPTOR_PCAST(CurrDescriptor, + * USB_Descriptor_Configuration_Header_t); + * + * // Can now access elements of the configuration header struct using the -> indirection operator + * \endcode + */ + #define DESCRIPTOR_PCAST(DescriptorPtr, Type) ((Type*)(DescriptorPtr)) + + /** Casts a pointer to a descriptor inside the configuration descriptor into the given descriptor + * type (as an actual struct instance rather than a pointer to a struct). + * + * Usage Example: + * \code + * uint8_t* CurrDescriptor = &ConfigDescriptor[0]; // Pointing to the configuration header + * USB_Descriptor_Configuration_Header_t ConfigHeader = DESCRIPTOR_CAST(CurrDescriptor, + * USB_Descriptor_Configuration_Header_t); + * + * // Can now access elements of the configuration header struct using the . operator + * \endcode + */ + #define DESCRIPTOR_CAST(DescriptorPtr, Type) (*DESCRIPTOR_PCAST(DescriptorPtr, Type)) + + /** Returns the descriptor's type, expressed as the 8-bit type value in the header of the descriptor. + * This value's meaning depends on the descriptor's placement in the descriptor, but standard type + * values can be accessed in the \ref USB_DescriptorTypes_t enum. + */ + #define DESCRIPTOR_TYPE(DescriptorPtr) DESCRIPTOR_PCAST(DescriptorPtr, USB_Descriptor_Header_t)->Type + + /** Returns the descriptor's size, expressed as the 8-bit value indicating the number of bytes. */ + #define DESCRIPTOR_SIZE(DescriptorPtr) DESCRIPTOR_PCAST(DescriptorPtr, USB_Descriptor_Header_t)->Size + + /* Type Defines: */ + /** Type define for a Configuration Descriptor comparator function (function taking a pointer to an array + * of type void, returning a uint8_t value). + * + * \see \ref USB_GetNextDescriptorComp function for more details. + */ + typedef uint8_t (* ConfigComparatorPtr_t)(void*); + + /* Enums: */ + /** Enum for the possible return codes of the \ref USB_Host_GetDeviceConfigDescriptor() function. */ + enum USB_Host_GetConfigDescriptor_ErrorCodes_t + { + HOST_GETCONFIG_Successful = 0, /**< No error occurred while retrieving the configuration descriptor. */ + HOST_GETCONFIG_DeviceDisconnect = 1, /**< The attached device was disconnected while retrieving the configuration + * descriptor. + */ + HOST_GETCONFIG_PipeError = 2, /**< An error occurred in the pipe while sending the request. */ + HOST_GETCONFIG_SetupStalled = 3, /**< The attached device stalled the request to retrieve the configuration + * descriptor. + */ + HOST_GETCONFIG_SoftwareTimeOut = 4, /**< The request or data transfer timed out. */ + HOST_GETCONFIG_BuffOverflow = 5, /**< The device's configuration descriptor is too large to fit into the allocated + * buffer. + */ + HOST_GETCONFIG_InvalidData = 6, /**< The device returned invalid configuration descriptor data. */ + }; + + /** Enum for return values of a descriptor comparator function. */ + enum DSearch_Return_ErrorCodes_t + { + DESCRIPTOR_SEARCH_Found = 0, /**< Current descriptor matches comparator criteria. */ + DESCRIPTOR_SEARCH_Fail = 1, /**< No further descriptor could possibly match criteria, fail the search. */ + DESCRIPTOR_SEARCH_NotFound = 2, /**< Current descriptor does not match comparator criteria. */ + }; + + /** Enum for return values of \ref USB_GetNextDescriptorComp(). */ + enum DSearch_Comp_Return_ErrorCodes_t + { + DESCRIPTOR_SEARCH_COMP_Found = 0, /**< Configuration descriptor now points to descriptor which matches + * search criteria of the given comparator function. */ + DESCRIPTOR_SEARCH_COMP_Fail = 1, /**< Comparator function returned \ref DESCRIPTOR_SEARCH_Fail. */ + DESCRIPTOR_SEARCH_COMP_EndOfDescriptor = 2, /**< End of configuration descriptor reached before match found. */ + }; + + /* Function Prototypes: */ + /** Retrieves the configuration descriptor data from an attached device via a standard request into a buffer, + * including validity and size checking to prevent a buffer overflow. + * + * \param[in] ConfigNumber Device configuration descriptor number to fetch from the device (usually set to 1 for + * single configuration devices). + * \param[in,out] ConfigSizePtr Pointer to a location for storing the retrieved configuration descriptor size. + * \param[out] BufferPtr Pointer to the buffer for storing the configuration descriptor data. + * \param[out] BufferSize Size of the allocated buffer where the configuration descriptor is to be stored. + * + * \return A value from the \ref USB_Host_GetConfigDescriptor_ErrorCodes_t enum. + */ + uint8_t USB_Host_GetDeviceConfigDescriptor(const uint8_t ConfigNumber, + uint16_t* const ConfigSizePtr, + void* const BufferPtr, + const uint16_t BufferSize) ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(3); + + /** Skips to the next sub-descriptor inside the configuration descriptor of the specified type value. + * The bytes remaining value is automatically decremented. + * + * \param[in,out] BytesRem Pointer to the number of bytes remaining of the configuration descriptor. + * \param[in,out] CurrConfigLoc Pointer to the current descriptor inside the configuration descriptor. + * \param[in] Type Descriptor type value to search for. + */ + void USB_GetNextDescriptorOfType(uint16_t* const BytesRem, + void** const CurrConfigLoc, + const uint8_t Type) + ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /** Skips to the next sub-descriptor inside the configuration descriptor of the specified type value, + * which must come before a descriptor of the second given type value. If the BeforeType type + * descriptor is reached first, the number of bytes remaining to process is set to zero and the + * function exits. The bytes remaining value is automatically decremented. + * + * \param[in,out] BytesRem Pointer to the number of bytes remaining of the configuration descriptor. + * \param[in,out] CurrConfigLoc Pointer to the current descriptor inside the configuration descriptor. + * \param[in] Type Descriptor type value to search for. + * \param[in] BeforeType Descriptor type value which must not be reached before the given Type descriptor. + */ + void USB_GetNextDescriptorOfTypeBefore(uint16_t* const BytesRem, + void** const CurrConfigLoc, + const uint8_t Type, + const uint8_t BeforeType) + ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /** Skips to the next sub-descriptor inside the configuration descriptor of the specified type value, + * which must come after a descriptor of the second given type value. The bytes remaining value is + * automatically decremented. + * + * \param[in,out] BytesRem Pointer to the number of bytes remaining of the configuration descriptor. + * \param[in,out] CurrConfigLoc Pointer to the current descriptor inside the configuration descriptor. + * \param[in] Type Descriptor type value to search for. + * \param[in] AfterType Descriptor type value which must be reached before the given Type descriptor. + */ + void USB_GetNextDescriptorOfTypeAfter(uint16_t* const BytesRem, + void** const CurrConfigLoc, + const uint8_t Type, + const uint8_t AfterType) + ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /** Searches for the next descriptor in the given configuration descriptor using a pre-made comparator + * function. The routine updates the position and remaining configuration descriptor bytes values + * automatically. If a comparator routine fails a search, the descriptor pointer is retreated back + * so that the next descriptor search invocation will start from the descriptor which first caused the + * original search to fail. This behavior allows for one comparator to be used immediately after another + * has failed, starting the second search from the descriptor which failed the first. + * + * Comparator functions should be standard functions which accept a pointer to the header of the current + * descriptor inside the configuration descriptor which is being compared, and should return a value from + * the \ref DSearch_Return_ErrorCodes_t enum as a uint8_t value. + * + * \note This function is available in USB Host mode only. + * + * \param[in,out] BytesRem Pointer to an int storing the remaining bytes in the configuration descriptor. + * \param[in,out] CurrConfigLoc Pointer to the current position in the configuration descriptor. + * \param[in] ComparatorRoutine Name of the comparator search function to use on the configuration descriptor. + * + * \return Value of one of the members of the \ref DSearch_Comp_Return_ErrorCodes_t enum. + * + * Usage Example: + * \code + * uint8_t EndpointSearcher(void* CurrentDescriptor); // Comparator Prototype + * + * uint8_t EndpointSearcher(void* CurrentDescriptor) + * { + * if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint) + * return DESCRIPTOR_SEARCH_Found; + * else + * return DESCRIPTOR_SEARCH_NotFound; + * } + * + * //... + * + * // After retrieving configuration descriptor: + * if (USB_Host_GetNextDescriptorComp(&BytesRemaining, &CurrentConfigLoc, EndpointSearcher) == + * Descriptor_Search_Comp_Found) + * { + * // Do something with the endpoint descriptor + * } + * \endcode + */ + uint8_t USB_GetNextDescriptorComp(uint16_t* const BytesRem, + void** const CurrConfigLoc, + ConfigComparatorPtr_t const ComparatorRoutine); + + /* Inline Functions: */ + /** Skips over the current sub-descriptor inside the configuration descriptor, so that the pointer then + points to the next sub-descriptor. The bytes remaining value is automatically decremented. + * + * \param[in,out] BytesRem Pointer to the number of bytes remaining of the configuration descriptor. + * \param[in,out] CurrConfigLoc Pointer to the current descriptor inside the configuration descriptor. + */ + static inline void USB_GetNextDescriptor(uint16_t* const BytesRem, + void** CurrConfigLoc) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + static inline void USB_GetNextDescriptor(uint16_t* const BytesRem, + void** CurrConfigLoc) + { + uint16_t CurrDescriptorSize = DESCRIPTOR_CAST(*CurrConfigLoc, USB_Descriptor_Header_t).Size; + + if (*BytesRem < CurrDescriptorSize) + CurrDescriptorSize = *BytesRem; + + *CurrConfigLoc = (void*)((uintptr_t)*CurrConfigLoc + CurrDescriptorSize); + *BytesRem -= CurrDescriptorSize; + } + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/LUFA/Drivers/USB/Core/Events.h b/LUFA/Drivers/USB/Core/Events.h index 8d627d4f..f468b7e6 100644 --- a/LUFA/Drivers/USB/Core/Events.h +++ b/LUFA/Drivers/USB/Core/Events.h @@ -189,7 +189,7 @@ * \note For the microcontrollers with limited USB controller functionality, VBUS sensing is not available. * this means that the current connection state is derived from the bus suspension and wake up events by default, * which is not always accurate (host may suspend the bus while still connected). If the actual connection state - * needs to be determined, VBUS should be routed to an external pin, and the auto-detect behaviour turned off by + * needs to be determined, VBUS should be routed to an external pin, and the auto-detect behavior turned off by * passing the \c NO_LIMITED_CONTROLLER_CONNECT token to the compiler via the -D switch at compile time. The connection * and disconnection events may be manually fired, and the \ref USB_DeviceState global changed manually. * \n\n @@ -207,7 +207,7 @@ * \note For the microcontrollers with limited USB controllers, VBUS sense is not available to the USB controller. * this means that the current connection state is derived from the bus suspension and wake up events by default, * which is not always accurate (host may suspend the bus while still connected). If the actual connection state - * needs to be determined, VBUS should be routed to an external pin, and the auto-detect behaviour turned off by + * needs to be determined, VBUS should be routed to an external pin, and the auto-detect behavior turned off by * passing the \c NO_LIMITED_CONTROLLER_CONNECT token to the compiler via the -D switch at compile time. The connection * and disconnection events may be manually fired, and the \ref USB_DeviceState global changed manually. * \n\n diff --git a/LUFA/Drivers/USB/Core/HostStandardReq.h b/LUFA/Drivers/USB/Core/HostStandardReq.h index 5bdfe45e..6ad0d2e5 100644 --- a/LUFA/Drivers/USB/Core/HostStandardReq.h +++ b/LUFA/Drivers/USB/Core/HostStandardReq.h @@ -91,7 +91,7 @@ /* Global Variables: */ /** Indicates the currently set configuration number of the attached device. This indicates the currently - * selected configuration value if one has been set sucessfully, or 0 if no configuration has been selected. + * selected configuration value if one has been set successfully, or 0 if no configuration has been selected. * * To set a device configuration, call the \ref USB_Host_SetDeviceConfiguration() function. * diff --git a/LUFA/Drivers/USB/Core/StdDescriptors.h b/LUFA/Drivers/USB/Core/StdDescriptors.h index c46129c4..031e01d2 100644 --- a/LUFA/Drivers/USB/Core/StdDescriptors.h +++ b/LUFA/Drivers/USB/Core/StdDescriptors.h @@ -105,7 +105,7 @@ /** \name USB Configuration Descriptor Attribute Masks */ //@{ /** Mask for the reserved bit in the Configuration Descriptor's \c ConfigAttributes field, which must be set on all - * devices for historial purposes. + * devices for historical purposes. */ #define USB_CONFIG_ATTR_RESERVED 0x80 diff --git a/LUFA/Drivers/USB/Core/UC3/EndpointStream_UC3.c b/LUFA/Drivers/USB/Core/UC3/EndpointStream_UC3.c index b4e130e7..51546106 100644 --- a/LUFA/Drivers/USB/Core/UC3/EndpointStream_UC3.c +++ b/LUFA/Drivers/USB/Core/UC3/EndpointStream_UC3.c @@ -1,235 +1,235 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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. -*/ - -#include "../../../../Common/Common.h" -#if (ARCH == ARCH_UC3) - -#define __INCLUDE_FROM_USB_DRIVER -#include "../USBMode.h" - -#if defined(USB_CAN_BE_DEVICE) - -#include "EndpointStream_UC3.h" - -#if !defined(CONTROL_ONLY_DEVICE) -uint8_t Endpoint_Discard_Stream(uint16_t Length, - uint16_t* const BytesProcessed) -{ - uint8_t ErrorCode; - uint16_t BytesInTransfer = 0; - - if ((ErrorCode = Endpoint_WaitUntilReady())) - return ErrorCode; - - if (BytesProcessed != NULL) - Length -= *BytesProcessed; - - while (Length) - { - if (!(Endpoint_IsReadWriteAllowed())) - { - Endpoint_ClearOUT(); - - if (BytesProcessed != NULL) - { - *BytesProcessed += BytesInTransfer; - return ENDPOINT_RWSTREAM_IncompleteTransfer; - } - - if ((ErrorCode = Endpoint_WaitUntilReady())) - return ErrorCode; - } - else - { - Endpoint_Discard_8(); - - Length--; - BytesInTransfer++; - } - } - - return ENDPOINT_RWSTREAM_NoError; -} - -uint8_t Endpoint_Null_Stream(uint16_t Length, - uint16_t* const BytesProcessed) -{ - uint8_t ErrorCode; - uint16_t BytesInTransfer = 0; - - if ((ErrorCode = Endpoint_WaitUntilReady())) - return ErrorCode; - - if (BytesProcessed != NULL) - Length -= *BytesProcessed; - - while (Length) - { - if (!(Endpoint_IsReadWriteAllowed())) - { - Endpoint_ClearIN(); - - if (BytesProcessed != NULL) - { - *BytesProcessed += BytesInTransfer; - return ENDPOINT_RWSTREAM_IncompleteTransfer; - } - - if ((ErrorCode = Endpoint_WaitUntilReady())) - return ErrorCode; - } - else - { - Endpoint_Write_8(0); - - Length--; - BytesInTransfer++; - } - } - - return ENDPOINT_RWSTREAM_NoError; -} - -/* The following abuses the C preprocessor in order to copy-paste common code with slight alterations, - * so that the code needs to be written once. It is a crude form of templating to reduce code maintenance. */ - -#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_LE -#define TEMPLATE_BUFFER_TYPE const void* -#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() -#define TEMPLATE_BUFFER_OFFSET(Length) 0 -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) -#include "Template/Template_Endpoint_RW.c" - -#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_BE -#define TEMPLATE_BUFFER_TYPE const void* -#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() -#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) -#include "Template/Template_Endpoint_RW.c" - -#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_LE -#define TEMPLATE_BUFFER_TYPE void* -#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() -#define TEMPLATE_BUFFER_OFFSET(Length) 0 -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() -#include "Template/Template_Endpoint_RW.c" - -#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_BE -#define TEMPLATE_BUFFER_TYPE void* -#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() -#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() -#include "Template/Template_Endpoint_RW.c" - -#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE) - #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_LE - #define TEMPLATE_BUFFER_TYPE const void* - #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() - #define TEMPLATE_BUFFER_OFFSET(Length) 0 - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) - #include "Template/Template_Endpoint_RW.c" - - #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_BE - #define TEMPLATE_BUFFER_TYPE const void* - #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() - #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) - #include "Template/Template_Endpoint_RW.c" -#endif - -#if defined(ARCH_HAS_EEPROM_ADDRESS_SPACE) - #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_LE - #define TEMPLATE_BUFFER_TYPE const void* - #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() - #define TEMPLATE_BUFFER_OFFSET(Length) 0 - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) - #include "Template/Template_Endpoint_RW.c" - - #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_BE - #define TEMPLATE_BUFFER_TYPE const void* - #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() - #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) - #include "Template/Template_Endpoint_RW.c" - - #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_LE - #define TEMPLATE_BUFFER_TYPE void* - #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() - #define TEMPLATE_BUFFER_OFFSET(Length) 0 - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) - #include "Template/Template_Endpoint_RW.c" - - #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_BE - #define TEMPLATE_BUFFER_TYPE void* - #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() - #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) - #include "Template/Template_Endpoint_RW.c" -#endif - -#endif - -#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_LE -#define TEMPLATE_BUFFER_OFFSET(Length) 0 -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) -#include "Template/Template_Endpoint_Control_W.c" - -#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_BE -#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) -#include "Template/Template_Endpoint_Control_W.c" - -#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_LE -#define TEMPLATE_BUFFER_OFFSET(Length) 0 -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() -#include "Template/Template_Endpoint_Control_R.c" - -#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_BE -#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() -#include "Template/Template_Endpoint_Control_R.c" - +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_UC3) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#include "EndpointStream_UC3.h" + +#if !defined(CONTROL_ONLY_DEVICE) +uint8_t Endpoint_Discard_Stream(uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t ErrorCode; + uint16_t BytesInTransfer = 0; + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + Length -= *BytesProcessed; + + while (Length) + { + if (!(Endpoint_IsReadWriteAllowed())) + { + Endpoint_ClearOUT(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return ENDPOINT_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + } + else + { + Endpoint_Discard_8(); + + Length--; + BytesInTransfer++; + } + } + + return ENDPOINT_RWSTREAM_NoError; +} + +uint8_t Endpoint_Null_Stream(uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t ErrorCode; + uint16_t BytesInTransfer = 0; + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + Length -= *BytesProcessed; + + while (Length) + { + if (!(Endpoint_IsReadWriteAllowed())) + { + Endpoint_ClearIN(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return ENDPOINT_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + } + else + { + Endpoint_Write_8(0); + + Length--; + BytesInTransfer++; + } + } + + return ENDPOINT_RWSTREAM_NoError; +} + +/* The following abuses the C preprocessor in order to copy-paste common code with slight alterations, + * so that the code needs to be written once. It is a crude form of templating to reduce code maintenance. */ + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_LE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_RW.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_BE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_RW.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_LE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_RW.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_BE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_RW.c" + +#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE) + #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_LE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_BE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" +#endif + +#if defined(ARCH_HAS_EEPROM_ADDRESS_SPACE) + #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_LE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_BE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_LE + #define TEMPLATE_BUFFER_TYPE void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_BE + #define TEMPLATE_BUFFER_TYPE void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) + #include "Template/Template_Endpoint_RW.c" #endif -#endif +#endif + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_LE +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_Control_W.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_BE +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_Control_W.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_LE +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_Control_R.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_BE +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_Control_R.c" + +#endif + +#endif diff --git a/LUFA/Drivers/USB/Core/UC3/EndpointStream_UC3.h b/LUFA/Drivers/USB/Core/UC3/EndpointStream_UC3.h index 40a54ee1..551cf4b1 100644 --- a/LUFA/Drivers/USB/Core/UC3/EndpointStream_UC3.h +++ b/LUFA/Drivers/USB/Core/UC3/EndpointStream_UC3.h @@ -1,434 +1,434 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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 Endpoint data stream transmission and reception management for the AVR32 UC3 microcontrollers. - * \copydetails Group_EndpointStreamRW_UC3 - * - * \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_EndpointStreamRW - * \defgroup Group_EndpointStreamRW_UC3 Read/Write of Multi-Byte Streams (UC3) - * \brief Endpoint data stream transmission and reception management for the Atmel AVR32 UC3 architecture. - * - * Functions, macros, variables, enums and types related to data reading and writing of data streams from - * and to endpoints. - * - * @{ - */ - -#ifndef __ENDPOINT_STREAM_UC3_H__ -#define __ENDPOINT_STREAM_UC3_H__ - - /* Includes: */ - #include "../../../../Common/Common.h" - #include "../USBMode.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: */ - /* Function Prototypes: */ - /** \name Stream functions for null data */ - //@{ - - /** Reads and discards the given number of bytes from the currently selected endpoint's bank, - * discarding fully read packets from the host as needed. The last packet is not automatically - * discarded once the remaining bytes has been read; the user is responsible for manually - * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. - * - * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, - * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid - * storage location, the transfer will instead be performed as a series of chunks. Each time - * the endpoint bank becomes empty while there is still data to process (and after the current - * packet has been acknowledged) the BytesProcessed location will be updated with the total number - * of bytes processed in the stream, and the function will exit with an error code of - * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed - * in the user code - to continue the transfer, call the function again with identical parameters - * and it will resume until the BytesProcessed value reaches the total transfer length. - * - * Single Stream Transfer Example: - * \code - * uint8_t ErrorCode; - * - * if ((ErrorCode = Endpoint_Discard_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * Partial Stream Transfers Example: - * \code - * uint8_t ErrorCode; - * uint16_t BytesProcessed; - * - * BytesProcessed = 0; - * while ((ErrorCode = Endpoint_Discard_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) - * { - * // Stream not yet complete - do other actions here, abort if required - * } - * - * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * \note This routine should not be used on CONTROL type endpoints. - * - * \param[in] Length Number of bytes to discard via the currently selected endpoint. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Discard_Stream(uint16_t Length, - uint16_t* const BytesProcessed); - - /** Writes a given number of zeroed bytes to the currently selected endpoint's bank, sending - * full packets to the host as needed. The last packet is not automatically sent once the - * remaining bytes have been written; the user is responsible for manually sending the last - * packet to the host via the \ref Endpoint_ClearIN() macro. - * - * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, - * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid - * storage location, the transfer will instead be performed as a series of chunks. Each time - * the endpoint bank becomes full while there is still data to process (and after the current - * packet transmission has been initiated) the BytesProcessed location will be updated with the - * total number of bytes processed in the stream, and the function will exit with an error code of - * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed - * in the user code - to continue the transfer, call the function again with identical parameters - * and it will resume until the BytesProcessed value reaches the total transfer length. - * - * Single Stream Transfer Example: - * \code - * uint8_t ErrorCode; - * - * if ((ErrorCode = Endpoint_Null_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * Partial Stream Transfers Example: - * \code - * uint8_t ErrorCode; - * uint16_t BytesProcessed; - * - * BytesProcessed = 0; - * while ((ErrorCode = Endpoint_Null_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) - * { - * // Stream not yet complete - do other actions here, abort if required - * } - * - * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * \note This routine should not be used on CONTROL type endpoints. - * - * \param[in] Length Number of zero bytes to send via the currently selected endpoint. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Null_Stream(uint16_t Length, - uint16_t* const BytesProcessed); - - //@} - - /** \name Stream functions for RAM source/destination data */ - //@{ - - /** Writes the given number of bytes to the endpoint from the given buffer in little endian, - * sending full packets to the host as needed. The last packet filled is not automatically sent; - * the user is responsible for manually sending the last written packet to the host via the - * \ref Endpoint_ClearIN() macro. - * - * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, - * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid - * storage location, the transfer will instead be performed as a series of chunks. Each time - * the endpoint bank becomes full while there is still data to process (and after the current - * packet transmission has been initiated) the BytesProcessed location will be updated with the - * total number of bytes processed in the stream, and the function will exit with an error code of - * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed - * in the user code - to continue the transfer, call the function again with identical parameters - * and it will resume until the BytesProcessed value reaches the total transfer length. - * - * Single Stream Transfer Example: - * \code - * uint8_t DataStream[512]; - * uint8_t ErrorCode; - * - * if ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream), - * NULL)) != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * Partial Stream Transfers Example: - * \code - * uint8_t DataStream[512]; - * uint8_t ErrorCode; - * uint16_t BytesProcessed; - * - * BytesProcessed = 0; - * while ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream), - * &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) - * { - * // Stream not yet complete - do other actions here, abort if required - * } - * - * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * \note This routine should not be used on CONTROL type endpoints. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_Stream_LE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** Writes the given number of bytes to the endpoint from the given buffer in big endian, - * sending full packets to the host as needed. The last packet filled is not automatically sent; - * the user is responsible for manually sending the last written packet to the host via the - * \ref Endpoint_ClearIN() macro. - * - * \note This routine should not be used on CONTROL type endpoints. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_Stream_BE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** Reads the given number of bytes from the endpoint from the given buffer in little endian, - * discarding fully read packets from the host as needed. The last packet is not automatically - * discarded once the remaining bytes has been read; the user is responsible for manually - * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. - * - * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, - * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid - * storage location, the transfer will instead be performed as a series of chunks. Each time - * the endpoint bank becomes empty while there is still data to process (and after the current - * packet has been acknowledged) the BytesProcessed location will be updated with the total number - * of bytes processed in the stream, and the function will exit with an error code of - * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed - * in the user code - to continue the transfer, call the function again with identical parameters - * and it will resume until the BytesProcessed value reaches the total transfer length. - * - * Single Stream Transfer Example: - * \code - * uint8_t DataStream[512]; - * uint8_t ErrorCode; - * - * if ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream), - * NULL)) != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * Partial Stream Transfers Example: - * \code - * uint8_t DataStream[512]; - * uint8_t ErrorCode; - * uint16_t BytesProcessed; - * - * BytesProcessed = 0; - * while ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream), - * &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) - * { - * // Stream not yet complete - do other actions here, abort if required - * } - * - * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * \note This routine should not be used on CONTROL type endpoints. - * - * \param[out] Buffer Pointer to the destination data buffer to write to. - * \param[in] Length Number of bytes to send via the currently selected endpoint. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Read_Stream_LE(void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** Reads the given number of bytes from the endpoint from the given buffer in big endian, - * discarding fully read packets from the host as needed. The last packet is not automatically - * discarded once the remaining bytes has been read; the user is responsible for manually - * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. - * - * \note This routine should not be used on CONTROL type endpoints. - * - * \param[out] Buffer Pointer to the destination data buffer to write to. - * \param[in] Length Number of bytes to send via the currently selected endpoint. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Read_Stream_BE(void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in little endian, - * sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared - * in both failure and success states; the user is responsible for manually clearing the setup OUT to - * finalize the transfer via the \ref Endpoint_ClearOUT() macro. - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_Control_Stream_LE(const void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - - /** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in big endian, - * sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared - * in both failure and success states; the user is responsible for manually clearing the setup OUT to - * finalize the transfer via the \ref Endpoint_ClearOUT() macro. - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_Control_Stream_BE(const void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - - /** Reads the given number of bytes from the CONTROL endpoint from the given buffer in little endian, - * discarding fully read packets from the host as needed. The device IN acknowledgement is not - * automatically sent after success or failure states; the user is responsible for manually sending the - * setup IN to finalize the transfer via the \ref Endpoint_ClearIN() macro. - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[out] Buffer Pointer to the destination data buffer to write to. - * \param[in] Length Number of bytes to send via the currently selected endpoint. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Read_Control_Stream_LE(void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - - /** Reads the given number of bytes from the CONTROL endpoint from the given buffer in big endian, - * discarding fully read packets from the host as needed. The device IN acknowledgement is not - * automatically sent after success or failure states; the user is responsible for manually sending the - * setup IN to finalize the transfer via the \ref Endpoint_ClearIN() macro. - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[out] Buffer Pointer to the destination data buffer to write to. - * \param[in] Length Number of bytes to send via the currently selected endpoint. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Read_Control_Stream_BE(void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - //@} - - /* Disable C linkage for C++ Compilers: */ - #if defined(__cplusplus) - } - #endif - -#endif - -/** @} */ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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 Endpoint data stream transmission and reception management for the AVR32 UC3 microcontrollers. + * \copydetails Group_EndpointStreamRW_UC3 + * + * \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_EndpointStreamRW + * \defgroup Group_EndpointStreamRW_UC3 Read/Write of Multi-Byte Streams (UC3) + * \brief Endpoint data stream transmission and reception management for the Atmel AVR32 UC3 architecture. + * + * Functions, macros, variables, enums and types related to data reading and writing of data streams from + * and to endpoints. + * + * @{ + */ + +#ifndef __ENDPOINT_STREAM_UC3_H__ +#define __ENDPOINT_STREAM_UC3_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBMode.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: */ + /* Function Prototypes: */ + /** \name Stream functions for null data */ + //@{ + + /** Reads and discards the given number of bytes from the currently selected endpoint's bank, + * discarding fully read packets from the host as needed. The last packet is not automatically + * discarded once the remaining bytes has been read; the user is responsible for manually + * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes empty while there is still data to process (and after the current + * packet has been acknowledged) the BytesProcessed location will be updated with the total number + * of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Discard_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Discard_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Length Number of bytes to discard via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Discard_Stream(uint16_t Length, + uint16_t* const BytesProcessed); + + /** Writes a given number of zeroed bytes to the currently selected endpoint's bank, sending + * full packets to the host as needed. The last packet is not automatically sent once the + * remaining bytes have been written; the user is responsible for manually sending the last + * packet to the host via the \ref Endpoint_ClearIN() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes full while there is still data to process (and after the current + * packet transmission has been initiated) the BytesProcessed location will be updated with the + * total number of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Null_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Null_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Length Number of zero bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Null_Stream(uint16_t Length, + uint16_t* const BytesProcessed); + + //@} + + /** \name Stream functions for RAM source/destination data */ + //@{ + + /** Writes the given number of bytes to the endpoint from the given buffer in little endian, + * sending full packets to the host as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Endpoint_ClearIN() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes full while there is still data to process (and after the current + * packet transmission has been initiated) the BytesProcessed location will be updated with the + * total number of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream), + * NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream), + * &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Stream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the endpoint from the given buffer in big endian, + * sending full packets to the host as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Endpoint_ClearIN() macro. + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Stream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the endpoint from the given buffer in little endian, + * discarding fully read packets from the host as needed. The last packet is not automatically + * discarded once the remaining bytes has been read; the user is responsible for manually + * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes empty while there is still data to process (and after the current + * packet has been acknowledged) the BytesProcessed location will be updated with the total number + * of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream), + * NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream), + * &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Stream_LE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the endpoint from the given buffer in big endian, + * discarding fully read packets from the host as needed. The last packet is not automatically + * discarded once the remaining bytes has been read; the user is responsible for manually + * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Stream_BE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in little endian, + * sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared + * in both failure and success states; the user is responsible for manually clearing the status OUT packet + * to finalize the transfer's status stage via the \ref Endpoint_ClearOUT() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_Stream_LE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in big endian, + * sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared + * in both failure and success states; the user is responsible for manually clearing the status OUT packet + * to finalize the transfer's status stage via the \ref Endpoint_ClearOUT() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_Stream_BE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the CONTROL endpoint from the given buffer in little endian, + * discarding fully read packets from the host as needed. The device IN acknowledgement is not + * automatically sent after success or failure states; the user is responsible for manually sending the + * status IN packet to finalize the transfer's status stage via the \ref Endpoint_ClearIN() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Control_Stream_LE(void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the CONTROL endpoint from the given buffer in big endian, + * discarding fully read packets from the host as needed. The device IN acknowledgement is not + * automatically sent after success or failure states; the user is responsible for manually sending the + * status IN packet to finalize the transfer's status stage via the \ref Endpoint_ClearIN() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Control_Stream_BE(void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ diff --git a/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c b/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c index c027585a..f0f319db 100644 --- a/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c +++ b/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c @@ -65,7 +65,7 @@ bool Endpoint_ConfigureEndpointTable(const USB_Endpoint_Table_t* const Table, bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number, const uint32_t UECFG0Data) { - USB_Endpoint_FIFOPos[Number] = &AVR32_USBB_SLAVE[Number * 0x10000]; + USB_Endpoint_FIFOPos[Number] = &AVR32_USBB_SLAVE[Number * ENDPOINT_HSB_ADDRESS_SPACE_SIZE]; #if defined(CONTROL_ONLY_DEVICE) || defined(ORDERED_EP_CONFIG) Endpoint_SelectEndpoint(Number); diff --git a/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.h b/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.h index a1b2a16f..1356952b 100644 --- a/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.h +++ b/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.h @@ -208,11 +208,16 @@ const uint16_t Size, const uint8_t Banks) { - return Endpoint_ConfigureEndpoint_Prv((Address & ENDPOINT_EPNUM_MASK), + uint8_t Number = (Address & ENDPOINT_EPNUM_MASK); + + if (Number >= ENDPOINT_TOTAL_ENDPOINTS) + return false; + + return Endpoint_ConfigureEndpoint_Prv(Number, (AVR32_USBB_ALLOC_MASK | - ((uint32_t)Type << AVR32_USBB_EPTYPE_OFFSET) | - ((uint32_t)(Address & ENDPOINT_DIR_IN) ? AVR32_USBB_UECFG0_EPDIR_MASK : 0) | - ((uint32_t)Banks << AVR32_USBB_EPBK_OFFSET) | + ((uint32_t)Type << AVR32_USBB_EPTYPE_OFFSET) | + ((Address & ENDPOINT_DIR_IN) ? AVR32_USBB_UECFG0_EPDIR_MASK : 0) | + ((Banks > 1) ? AVR32_USBB_UECFG0_EPBK_SINGLE : AVR32_USBB_UECFG0_EPBK_DOUBLE) | Endpoint_BytesToEPSizeMask(Size))); } diff --git a/LUFA/Drivers/USB/Core/UC3/PipeStream_UC3.c b/LUFA/Drivers/USB/Core/UC3/PipeStream_UC3.c index bb4cbc65..76fbfd8f 100644 --- a/LUFA/Drivers/USB/Core/UC3/PipeStream_UC3.c +++ b/LUFA/Drivers/USB/Core/UC3/PipeStream_UC3.c @@ -1,166 +1,166 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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. -*/ - -#include "../../../../Common/Common.h" -#if (ARCH == ARCH_UC3) - -#define __INCLUDE_FROM_USB_DRIVER -#include "../USBMode.h" - -#if defined(USB_CAN_BE_HOST) - -#include "PipeStream_UC3.h" - -uint8_t Pipe_Discard_Stream(uint16_t Length, - uint16_t* const BytesProcessed) -{ - uint8_t ErrorCode; - uint16_t BytesInTransfer = 0; - - Pipe_SetPipeToken(PIPE_TOKEN_IN); - - if ((ErrorCode = Pipe_WaitUntilReady())) - return ErrorCode; - - if (BytesProcessed != NULL) - Length -= *BytesProcessed; - - while (Length) - { - if (!(Pipe_IsReadWriteAllowed())) - { - Pipe_ClearIN(); - - if (BytesProcessed != NULL) - { - *BytesProcessed += BytesInTransfer; - return PIPE_RWSTREAM_IncompleteTransfer; - } - - if ((ErrorCode = Pipe_WaitUntilReady())) - return ErrorCode; - } - else - { - Pipe_Discard_8(); - - Length--; - BytesInTransfer++; - } - } - - return PIPE_RWSTREAM_NoError; -} - -uint8_t Pipe_Null_Stream(uint16_t Length, - uint16_t* const BytesProcessed) -{ - uint8_t ErrorCode; - uint16_t BytesInTransfer = 0; - - Pipe_SetPipeToken(PIPE_TOKEN_OUT); - - if ((ErrorCode = Pipe_WaitUntilReady())) - return ErrorCode; - - if (BytesProcessed != NULL) - Length -= *BytesProcessed; - - while (Length) - { - if (!(Pipe_IsReadWriteAllowed())) - { - Pipe_ClearOUT(); - - if (BytesProcessed != NULL) - { - *BytesProcessed += BytesInTransfer; - return PIPE_RWSTREAM_IncompleteTransfer; - } - - USB_USBTask(); - - if ((ErrorCode = Pipe_WaitUntilReady())) - return ErrorCode; - } - else - { - Pipe_Write_8(0); - - Length--; - BytesInTransfer++; - } - } - - return PIPE_RWSTREAM_NoError; -} - -/* The following abuses the C preprocessor in order to copy-paste common code with slight alterations, - * so that the code needs to be written once. It is a crude form of templating to reduce code maintenance. */ - -#define TEMPLATE_FUNC_NAME Pipe_Write_Stream_LE -#define TEMPLATE_BUFFER_TYPE const void* -#define TEMPLATE_TOKEN PIPE_TOKEN_OUT -#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() -#define TEMPLATE_BUFFER_OFFSET(Length) 0 -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(*BufferPtr) -#include "Template/Template_Pipe_RW.c" - -#define TEMPLATE_FUNC_NAME Pipe_Write_Stream_BE -#define TEMPLATE_BUFFER_TYPE const void* -#define TEMPLATE_TOKEN PIPE_TOKEN_OUT -#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() -#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(*BufferPtr) -#include "Template/Template_Pipe_RW.c" - -#define TEMPLATE_FUNC_NAME Pipe_Read_Stream_LE -#define TEMPLATE_BUFFER_TYPE void* -#define TEMPLATE_TOKEN PIPE_TOKEN_IN -#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN() -#define TEMPLATE_BUFFER_OFFSET(Length) 0 -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Pipe_Read_8() -#include "Template/Template_Pipe_RW.c" - -#define TEMPLATE_FUNC_NAME Pipe_Read_Stream_BE -#define TEMPLATE_BUFFER_TYPE void* -#define TEMPLATE_TOKEN PIPE_TOKEN_IN -#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN() -#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Pipe_Read_8() -#include "Template/Template_Pipe_RW.c" - -#endif - -#endif +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_UC3) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#include "PipeStream_UC3.h" + +uint8_t Pipe_Discard_Stream(uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t ErrorCode; + uint16_t BytesInTransfer = 0; + + Pipe_SetPipeToken(PIPE_TOKEN_IN); + + if ((ErrorCode = Pipe_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + Length -= *BytesProcessed; + + while (Length) + { + if (!(Pipe_IsReadWriteAllowed())) + { + Pipe_ClearIN(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return PIPE_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Pipe_WaitUntilReady())) + return ErrorCode; + } + else + { + Pipe_Discard_8(); + + Length--; + BytesInTransfer++; + } + } + + return PIPE_RWSTREAM_NoError; +} + +uint8_t Pipe_Null_Stream(uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t ErrorCode; + uint16_t BytesInTransfer = 0; + + Pipe_SetPipeToken(PIPE_TOKEN_OUT); + + if ((ErrorCode = Pipe_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + Length -= *BytesProcessed; + + while (Length) + { + if (!(Pipe_IsReadWriteAllowed())) + { + Pipe_ClearOUT(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return PIPE_RWSTREAM_IncompleteTransfer; + } + + USB_USBTask(); + + if ((ErrorCode = Pipe_WaitUntilReady())) + return ErrorCode; + } + else + { + Pipe_Write_8(0); + + Length--; + BytesInTransfer++; + } + } + + return PIPE_RWSTREAM_NoError; +} + +/* The following abuses the C preprocessor in order to copy-paste common code with slight alterations, + * so that the code needs to be written once. It is a crude form of templating to reduce code maintenance. */ + +#define TEMPLATE_FUNC_NAME Pipe_Write_Stream_LE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_TOKEN PIPE_TOKEN_OUT +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(*BufferPtr) +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Write_Stream_BE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_TOKEN PIPE_TOKEN_OUT +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(*BufferPtr) +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Read_Stream_LE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_TOKEN PIPE_TOKEN_IN +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Pipe_Read_8() +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Read_Stream_BE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_TOKEN PIPE_TOKEN_IN +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Pipe_Read_8() +#include "Template/Template_Pipe_RW.c" + +#endif + +#endif diff --git a/LUFA/Drivers/USB/Core/UC3/PipeStream_UC3.h b/LUFA/Drivers/USB/Core/UC3/PipeStream_UC3.h index cb8a28c8..72bf83c6 100644 --- a/LUFA/Drivers/USB/Core/UC3/PipeStream_UC3.h +++ b/LUFA/Drivers/USB/Core/UC3/PipeStream_UC3.h @@ -1,352 +1,352 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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 Pipe data stream transmission and reception management for the AVR32 UC3 microcontrollers. - * \copydetails Group_PipeStreamRW_UC3 - * - * \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_PipeStreamRW - * \defgroup Group_PipeStreamRW_UC3 Read/Write of Multi-Byte Streams (UC3) - * \brief Pipe data stream transmission and reception management for the Atmel AVR32 UC3 architecture. - * - * Functions, macros, variables, enums and types related to data reading and writing of data streams from - * and to pipes. - * - * @{ - */ - -#ifndef __PIPE_STREAM_UC3_H__ -#define __PIPE_STREAM_UC3_H__ - - /* Includes: */ - #include "../../../../Common/Common.h" - #include "../USBMode.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: */ - /* Function Prototypes: */ - /** \name Stream functions for null data */ - //@{ - - /** Reads and discards the given number of bytes from the pipe, discarding fully read packets from the host - * as needed. The last packet is not automatically discarded once the remaining bytes has been read; the - * user is responsible for manually discarding the last packet from the device via the \ref Pipe_ClearIN() macro. - * - * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, failing or - * succeeding as a single unit. If the BytesProcessed parameter points to a valid storage location, the transfer - * will instead be performed as a series of chunks. Each time the pipe bank becomes empty while there is still data - * to process (and after the current packet has been acknowledged) the BytesProcessed location will be updated with - * the total number of bytes processed in the stream, and the function will exit with an error code of - * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed in the user code - to - * continue the transfer, call the function again with identical parameters and it will resume until the BytesProcessed - * value reaches the total transfer length. - * - * Single Stream Transfer Example: - * \code - * uint8_t ErrorCode; - * - * if ((ErrorCode = Pipe_Discard_Stream(512, NULL)) != PIPE_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * Partial Stream Transfers Example: - * \code - * uint8_t ErrorCode; - * uint16_t BytesProcessed; - * - * BytesProcessed = 0; - * while ((ErrorCode = Pipe_Discard_Stream(512, &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) - * { - * // Stream not yet complete - do other actions here, abort if required - * } - * - * if (ErrorCode != PIPE_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without - * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). - * - * \param[in] Length Number of bytes to discard via the currently selected pipe. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should - * updated, \c NULL if the entire stream should be processed at once. - * - * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Pipe_Discard_Stream(uint16_t Length, - uint16_t* const BytesProcessed); - - /** Writes a given number of zeroed bytes to the pipe, sending full pipe packets from the host to the device - * as needed. The last packet is not automatically sent once the remaining bytes has been written; the - * user is responsible for manually discarding the last packet from the device via the \ref Pipe_ClearOUT() macro. - * - * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, failing or - * succeeding as a single unit. If the BytesProcessed parameter points to a valid storage location, the transfer - * will instead be performed as a series of chunks. Each time the pipe bank becomes full while there is still data - * to process (and after the current packet transmission has been initiated) the BytesProcessed location will be - * updated with the total number of bytes processed in the stream, and the function will exit with an error code of - * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed in the user code - to - * continue the transfer, call the function again with identical parameters and it will resume until the BytesProcessed - * value reaches the total transfer length. - * - * Single Stream Transfer Example: - * \code - * uint8_t ErrorCode; - * - * if ((ErrorCode = Pipe_Null_Stream(512, NULL)) != PIPE_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * Partial Stream Transfers Example: - * \code - * uint8_t ErrorCode; - * uint16_t BytesProcessed; - * - * BytesProcessed = 0; - * while ((ErrorCode = Pipe_Null_Stream(512, &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) - * { - * // Stream not yet complete - do other actions here, abort if required - * } - * - * if (ErrorCode != PIPE_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without - * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). - * - * \param[in] Length Number of zero bytes to write via the currently selected pipe. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should - * updated, \c NULL if the entire stream should be processed at once. - * - * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Pipe_Null_Stream(uint16_t Length, - uint16_t* const BytesProcessed); - - //@} - - /** \name Stream functions for RAM source/destination data */ - //@{ - - /** Writes the given number of bytes to the pipe from the given buffer in little endian, - * sending full packets to the device as needed. The last packet filled is not automatically sent; - * the user is responsible for manually sending the last written packet to the host via the - * \ref Pipe_ClearOUT() macro. Between each USB packet, the given stream callback function is - * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. - * - * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, - * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid - * storage location, the transfer will instead be performed as a series of chunks. Each time - * the pipe bank becomes full while there is still data to process (and after the current - * packet transmission has been initiated) the BytesProcessed location will be updated with the - * total number of bytes processed in the stream, and the function will exit with an error code of - * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed - * in the user code - to continue the transfer, call the function again with identical parameters - * and it will resume until the BytesProcessed value reaches the total transfer length. - * - * Single Stream Transfer Example: - * \code - * uint8_t DataStream[512]; - * uint8_t ErrorCode; - * - * if ((ErrorCode = Pipe_Write_Stream_LE(DataStream, sizeof(DataStream), - * NULL)) != PIPE_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * Partial Stream Transfers Example: - * \code - * uint8_t DataStream[512]; - * uint8_t ErrorCode; - * uint16_t BytesProcessed; - * - * BytesProcessed = 0; - * while ((ErrorCode = Pipe_Write_Stream_LE(DataStream, sizeof(DataStream), - * &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) - * { - * // Stream not yet complete - do other actions here, abort if required - * } - * - * if (ErrorCode != PIPE_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without - * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should - * updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Pipe_Write_Stream_LE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** Writes the given number of bytes to the pipe from the given buffer in big endian, - * sending full packets to the device as needed. The last packet filled is not automatically sent; - * the user is responsible for manually sending the last written packet to the host via the - * \ref Pipe_ClearOUT() macro. Between each USB packet, the given stream callback function is - * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. - * - * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without - * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should - * updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Pipe_Write_Stream_BE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** Reads the given number of bytes from the pipe into the given buffer in little endian, - * sending full packets to the device as needed. The last packet filled is not automatically sent; - * the user is responsible for manually sending the last written packet to the host via the - * \ref Pipe_ClearIN() macro. Between each USB packet, the given stream callback function is - * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. - * - * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, - * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid - * storage location, the transfer will instead be performed as a series of chunks. Each time - * the pipe bank becomes empty while there is still data to process (and after the current - * packet has been acknowledged) the BytesProcessed location will be updated with the total number - * of bytes processed in the stream, and the function will exit with an error code of - * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed - * in the user code - to continue the transfer, call the function again with identical parameters - * and it will resume until the BytesProcessed value reaches the total transfer length. - * - * Single Stream Transfer Example: - * \code - * uint8_t DataStream[512]; - * uint8_t ErrorCode; - * - * if ((ErrorCode = Pipe_Read_Stream_LE(DataStream, sizeof(DataStream), - * NULL)) != PIPE_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * Partial Stream Transfers Example: - * \code - * uint8_t DataStream[512]; - * uint8_t ErrorCode; - * uint16_t BytesProcessed; - * - * BytesProcessed = 0; - * while ((ErrorCode = Pipe_Read_Stream_LE(DataStream, sizeof(DataStream), - * &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) - * { - * // Stream not yet complete - do other actions here, abort if required - * } - * - * if (ErrorCode != PIPE_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without - * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). - * - * \param[out] Buffer Pointer to the source data buffer to write to. - * \param[in] Length Number of bytes to read for the currently selected pipe to read from. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should - * updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Pipe_Read_Stream_LE(void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** Reads the given number of bytes from the pipe into the given buffer in big endian, - * sending full packets to the device as needed. The last packet filled is not automatically sent; - * the user is responsible for manually sending the last written packet to the host via the - * \ref Pipe_ClearIN() macro. Between each USB packet, the given stream callback function is - * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. - * - * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without - * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). - * - * \param[out] Buffer Pointer to the source data buffer to write to. - * \param[in] Length Number of bytes to read for the currently selected pipe to read from. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should - * updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Pipe_Read_Stream_BE(void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - //@} - - /* Disable C linkage for C++ Compilers: */ - #if defined(__cplusplus) - } - #endif - -#endif - -/** @} */ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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 Pipe data stream transmission and reception management for the AVR32 UC3 microcontrollers. + * \copydetails Group_PipeStreamRW_UC3 + * + * \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_PipeStreamRW + * \defgroup Group_PipeStreamRW_UC3 Read/Write of Multi-Byte Streams (UC3) + * \brief Pipe data stream transmission and reception management for the Atmel AVR32 UC3 architecture. + * + * Functions, macros, variables, enums and types related to data reading and writing of data streams from + * and to pipes. + * + * @{ + */ + +#ifndef __PIPE_STREAM_UC3_H__ +#define __PIPE_STREAM_UC3_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBMode.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: */ + /* Function Prototypes: */ + /** \name Stream functions for null data */ + //@{ + + /** Reads and discards the given number of bytes from the pipe, discarding fully read packets from the host + * as needed. The last packet is not automatically discarded once the remaining bytes has been read; the + * user is responsible for manually discarding the last packet from the device via the \ref Pipe_ClearIN() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, failing or + * succeeding as a single unit. If the BytesProcessed parameter points to a valid storage location, the transfer + * will instead be performed as a series of chunks. Each time the pipe bank becomes empty while there is still data + * to process (and after the current packet has been acknowledged) the BytesProcessed location will be updated with + * the total number of bytes processed in the stream, and the function will exit with an error code of + * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed in the user code - to + * continue the transfer, call the function again with identical parameters and it will resume until the BytesProcessed + * value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t ErrorCode; + * + * if ((ErrorCode = Pipe_Discard_Stream(512, NULL)) != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Pipe_Discard_Stream(512, &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[in] Length Number of bytes to discard via the currently selected pipe. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be processed at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Discard_Stream(uint16_t Length, + uint16_t* const BytesProcessed); + + /** Writes a given number of zeroed bytes to the pipe, sending full pipe packets from the host to the device + * as needed. The last packet is not automatically sent once the remaining bytes has been written; the + * user is responsible for manually discarding the last packet from the device via the \ref Pipe_ClearOUT() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, failing or + * succeeding as a single unit. If the BytesProcessed parameter points to a valid storage location, the transfer + * will instead be performed as a series of chunks. Each time the pipe bank becomes full while there is still data + * to process (and after the current packet transmission has been initiated) the BytesProcessed location will be + * updated with the total number of bytes processed in the stream, and the function will exit with an error code of + * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed in the user code - to + * continue the transfer, call the function again with identical parameters and it will resume until the BytesProcessed + * value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t ErrorCode; + * + * if ((ErrorCode = Pipe_Null_Stream(512, NULL)) != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Pipe_Null_Stream(512, &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[in] Length Number of zero bytes to write via the currently selected pipe. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be processed at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Null_Stream(uint16_t Length, + uint16_t* const BytesProcessed); + + //@} + + /** \name Stream functions for RAM source/destination data */ + //@{ + + /** Writes the given number of bytes to the pipe from the given buffer in little endian, + * sending full packets to the device as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Pipe_ClearOUT() macro. Between each USB packet, the given stream callback function is + * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the pipe bank becomes full while there is still data to process (and after the current + * packet transmission has been initiated) the BytesProcessed location will be updated with the + * total number of bytes processed in the stream, and the function will exit with an error code of + * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * + * if ((ErrorCode = Pipe_Write_Stream_LE(DataStream, sizeof(DataStream), + * NULL)) != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Pipe_Write_Stream_LE(DataStream, sizeof(DataStream), + * &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Write_Stream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the pipe from the given buffer in big endian, + * sending full packets to the device as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Pipe_ClearOUT() macro. Between each USB packet, the given stream callback function is + * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Write_Stream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the pipe into the given buffer in little endian, + * sending full packets to the device as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Pipe_ClearIN() macro. Between each USB packet, the given stream callback function is + * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the pipe bank becomes empty while there is still data to process (and after the current + * packet has been acknowledged) the BytesProcessed location will be updated with the total number + * of bytes processed in the stream, and the function will exit with an error code of + * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * + * if ((ErrorCode = Pipe_Read_Stream_LE(DataStream, sizeof(DataStream), + * NULL)) != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Pipe_Read_Stream_LE(DataStream, sizeof(DataStream), + * &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[out] Buffer Pointer to the source data buffer to write to. + * \param[in] Length Number of bytes to read for the currently selected pipe to read from. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Read_Stream_LE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the pipe into the given buffer in big endian, + * sending full packets to the device as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Pipe_ClearIN() macro. Between each USB packet, the given stream callback function is + * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[out] Buffer Pointer to the source data buffer to write to. + * \param[in] Length Number of bytes to read for the currently selected pipe to read from. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Read_Stream_BE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ diff --git a/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.c b/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.c index 787244b9..23c004db 100644 --- a/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.c +++ b/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.c @@ -69,10 +69,13 @@ bool Pipe_ConfigurePipe(const uint8_t Address, uint8_t Number = (Address & PIPE_EPNUM_MASK); uint8_t Token = (Address & PIPE_DIR_IN) ? PIPE_TOKEN_IN : PIPE_TOKEN_OUT; + if (Number >= PIPE_TOTAL_PIPES) + return false; + if (Type == EP_TYPE_CONTROL) Token = PIPE_TOKEN_SETUP; - USB_Pipe_FIFOPos[Number] = &AVR32_USBB_SLAVE[Number * 0x10000]; + USB_Pipe_FIFOPos[Number] = &AVR32_USBB_SLAVE[Number * PIPE_HSB_ADDRESS_SPACE_SIZE]; #if defined(ORDERED_EP_CONFIG) Pipe_SelectPipe(Number); diff --git a/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.h b/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.h index 0c3136e1..0d313fed 100644 --- a/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.h +++ b/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.h @@ -204,7 +204,7 @@ static inline uint8_t Pipe_GetPipeDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; static inline uint8_t Pipe_GetPipeDirection(void) { - return (((&AVR32_USBB.UPCFG0)[USB_Endpoint_SelectedEndpoint].ptoken == PIPE_TOKEN_OUT) ? PIPE_DIR_OUT : PIPE_DIR_IN); + return (((&AVR32_USBB.UPCFG0)[USB_Pipe_SelectedPipe].ptoken == PIPE_TOKEN_OUT) ? PIPE_DIR_OUT : PIPE_DIR_IN); } /** Returns the pipe address of the currently selected pipe. This is typically used to save the diff --git a/LUFA/Drivers/USB/Core/UC3/USBController_UC3.c b/LUFA/Drivers/USB/Core/UC3/USBController_UC3.c index 9e4e4a21..6a3df6e7 100644 --- a/LUFA/Drivers/USB/Core/UC3/USBController_UC3.c +++ b/LUFA/Drivers/USB/Core/UC3/USBController_UC3.c @@ -112,7 +112,7 @@ void USB_ResetInterface(void) AVR32_PM.GCCTRL[AVR32_PM_GCLK_USBB].pllsel = !(USB_Options & USB_OPT_GCLK_SRC_OSC); AVR32_PM.GCCTRL[AVR32_PM_GCLK_USBB].oscsel = !(USB_Options & USB_OPT_GCLK_CHANNEL_0); AVR32_PM.GCCTRL[AVR32_PM_GCLK_USBB].diven = (F_USB != USB_CLOCK_REQUIRED_FREQ); - AVR32_PM.GCCTRL[AVR32_PM_GCLK_USBB].div = (F_USB == USB_CLOCK_REQUIRED_FREQ) ? 0 : (uint32_t)(((F_USB / USB_CLOCK_REQUIRED_FREQ) - 1) / 2); + AVR32_PM.GCCTRL[AVR32_PM_GCLK_USBB].div = (F_USB == USB_CLOCK_REQUIRED_FREQ) ? 0 : (uint32_t)((F_USB / USB_CLOCK_REQUIRED_FREQ / 2) - 1); AVR32_PM.GCCTRL[AVR32_PM_GCLK_USBB].cen = true; USB_INT_DisableAllInterrupts(); diff --git a/LUFA/Drivers/USB/Core/UC3/USBController_UC3.h b/LUFA/Drivers/USB/Core/UC3/USBController_UC3.h index 92e245ca..4a5d267c 100644 --- a/LUFA/Drivers/USB/Core/UC3/USBController_UC3.h +++ b/LUFA/Drivers/USB/Core/UC3/USBController_UC3.h @@ -172,7 +172,7 @@ * 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 + * interface to control the USB interface's behavior. 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. diff --git a/LUFA/Drivers/USB/Core/XMEGA/EndpointStream_XMEGA.c b/LUFA/Drivers/USB/Core/XMEGA/EndpointStream_XMEGA.c index 774a574f..db804506 100644 --- a/LUFA/Drivers/USB/Core/XMEGA/EndpointStream_XMEGA.c +++ b/LUFA/Drivers/USB/Core/XMEGA/EndpointStream_XMEGA.c @@ -1,275 +1,275 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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. -*/ - -#include "../../../../Common/Common.h" -#if (ARCH == ARCH_XMEGA) - -#define __INCLUDE_FROM_USB_DRIVER -#include "../USBMode.h" - -#if defined(USB_CAN_BE_DEVICE) - -#include "EndpointStream_XMEGA.h" - -#if !defined(CONTROL_ONLY_DEVICE) -uint8_t Endpoint_Discard_Stream(uint16_t Length, - uint16_t* const BytesProcessed) -{ - uint8_t ErrorCode; - uint16_t BytesInTransfer = 0; - - if ((ErrorCode = Endpoint_WaitUntilReady())) - return ErrorCode; - - if (BytesProcessed != NULL) - Length -= *BytesProcessed; - - while (Length) - { - if (!(Endpoint_IsReadWriteAllowed())) - { - Endpoint_ClearOUT(); - - if (BytesProcessed != NULL) - { - *BytesProcessed += BytesInTransfer; - return ENDPOINT_RWSTREAM_IncompleteTransfer; - } - - if ((ErrorCode = Endpoint_WaitUntilReady())) - return ErrorCode; - } - else - { - Endpoint_Discard_8(); - - Length--; - BytesInTransfer++; - } - } - - return ENDPOINT_RWSTREAM_NoError; -} - -uint8_t Endpoint_Null_Stream(uint16_t Length, - uint16_t* const BytesProcessed) -{ - uint8_t ErrorCode; - uint16_t BytesInTransfer = 0; - - if ((ErrorCode = Endpoint_WaitUntilReady())) - return ErrorCode; - - if (BytesProcessed != NULL) - Length -= *BytesProcessed; - - while (Length) - { - if (!(Endpoint_IsReadWriteAllowed())) - { - Endpoint_ClearIN(); - - if (BytesProcessed != NULL) - { - *BytesProcessed += BytesInTransfer; - return ENDPOINT_RWSTREAM_IncompleteTransfer; - } - - if ((ErrorCode = Endpoint_WaitUntilReady())) - return ErrorCode; - } - else - { - Endpoint_Write_8(0); - - Length--; - BytesInTransfer++; - } - } - - return ENDPOINT_RWSTREAM_NoError; -} - -/* The following abuses the C preprocessor in order to copy-paste common code with slight alterations, - * so that the code needs to be written once. It is a crude form of templating to reduce code maintenance. */ - -#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_LE -#define TEMPLATE_BUFFER_TYPE const void* -#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() -#define TEMPLATE_BUFFER_OFFSET(Length) 0 -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) -#include "Template/Template_Endpoint_RW.c" - -#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_BE -#define TEMPLATE_BUFFER_TYPE const void* -#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() -#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) -#include "Template/Template_Endpoint_RW.c" - -#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_LE -#define TEMPLATE_BUFFER_TYPE void* -#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() -#define TEMPLATE_BUFFER_OFFSET(Length) 0 -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() -#include "Template/Template_Endpoint_RW.c" - -#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_BE -#define TEMPLATE_BUFFER_TYPE void* -#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() -#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() -#include "Template/Template_Endpoint_RW.c" - -#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE) - #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_LE - #define TEMPLATE_BUFFER_TYPE const void* - #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() - #define TEMPLATE_BUFFER_OFFSET(Length) 0 - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) - #include "Template/Template_Endpoint_RW.c" - - #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_BE - #define TEMPLATE_BUFFER_TYPE const void* - #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() - #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) - #include "Template/Template_Endpoint_RW.c" -#endif - -#if defined(ARCH_HAS_EEPROM_ADDRESS_SPACE) - #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_LE - #define TEMPLATE_BUFFER_TYPE const void* - #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() - #define TEMPLATE_BUFFER_OFFSET(Length) 0 - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) - #include "Template/Template_Endpoint_RW.c" - - #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_BE - #define TEMPLATE_BUFFER_TYPE const void* - #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() - #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) - #include "Template/Template_Endpoint_RW.c" - - #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_LE - #define TEMPLATE_BUFFER_TYPE void* - #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() - #define TEMPLATE_BUFFER_OFFSET(Length) 0 - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) - #include "Template/Template_Endpoint_RW.c" - - #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_BE - #define TEMPLATE_BUFFER_TYPE void* - #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() - #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) - #include "Template/Template_Endpoint_RW.c" -#endif - -#endif - -#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_LE -#define TEMPLATE_BUFFER_OFFSET(Length) 0 -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) -#include "Template/Template_Endpoint_Control_W.c" - -#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_BE -#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) -#include "Template/Template_Endpoint_Control_W.c" - -#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_LE -#define TEMPLATE_BUFFER_OFFSET(Length) 0 -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() -#include "Template/Template_Endpoint_Control_R.c" - -#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_BE -#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) -#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount -#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() -#include "Template/Template_Endpoint_Control_R.c" - -#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE) - #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_PStream_LE - #define TEMPLATE_BUFFER_OFFSET(Length) 0 - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) - #include "Template/Template_Endpoint_Control_W.c" - - #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_PStream_BE - #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) - #include "Template/Template_Endpoint_Control_W.c" -#endif - -#if defined(ARCH_HAS_EEPROM_ADDRESS_SPACE) - #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_EStream_LE - #define TEMPLATE_BUFFER_OFFSET(Length) 0 - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) - #include "Template/Template_Endpoint_Control_W.c" - - #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_EStream_BE - #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) - #include "Template/Template_Endpoint_Control_W.c" - - #define TEMPLATE_FUNC_NAME Endpoint_Read_Control_EStream_LE - #define TEMPLATE_BUFFER_OFFSET(Length) 0 - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) - #include "Template/Template_Endpoint_Control_R.c" - - #define TEMPLATE_FUNC_NAME Endpoint_Read_Control_EStream_BE - #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) - #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount - #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) - #include "Template/Template_Endpoint_Control_R.c" -#endif - +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_XMEGA) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#include "EndpointStream_XMEGA.h" + +#if !defined(CONTROL_ONLY_DEVICE) +uint8_t Endpoint_Discard_Stream(uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t ErrorCode; + uint16_t BytesInTransfer = 0; + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + Length -= *BytesProcessed; + + while (Length) + { + if (!(Endpoint_IsReadWriteAllowed())) + { + Endpoint_ClearOUT(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return ENDPOINT_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + } + else + { + Endpoint_Discard_8(); + + Length--; + BytesInTransfer++; + } + } + + return ENDPOINT_RWSTREAM_NoError; +} + +uint8_t Endpoint_Null_Stream(uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t ErrorCode; + uint16_t BytesInTransfer = 0; + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + Length -= *BytesProcessed; + + while (Length) + { + if (!(Endpoint_IsReadWriteAllowed())) + { + Endpoint_ClearIN(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return ENDPOINT_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + } + else + { + Endpoint_Write_8(0); + + Length--; + BytesInTransfer++; + } + } + + return ENDPOINT_RWSTREAM_NoError; +} + +/* The following abuses the C preprocessor in order to copy-paste common code with slight alterations, + * so that the code needs to be written once. It is a crude form of templating to reduce code maintenance. */ + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_LE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_RW.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_BE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_RW.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_LE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_RW.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_BE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_RW.c" + +#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE) + #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_LE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_BE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" +#endif + +#if defined(ARCH_HAS_EEPROM_ADDRESS_SPACE) + #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_LE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_BE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_LE + #define TEMPLATE_BUFFER_TYPE void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_BE + #define TEMPLATE_BUFFER_TYPE void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) + #include "Template/Template_Endpoint_RW.c" #endif -#endif +#endif + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_LE +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_Control_W.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_BE +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_Control_W.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_LE +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_Control_R.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_BE +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_Control_R.c" + +#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE) + #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_PStream_LE + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_Control_W.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_PStream_BE + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_Control_W.c" +#endif + +#if defined(ARCH_HAS_EEPROM_ADDRESS_SPACE) + #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_EStream_LE + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_Control_W.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_EStream_BE + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_Control_W.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Read_Control_EStream_LE + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) + #include "Template/Template_Endpoint_Control_R.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Read_Control_EStream_BE + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) + #include "Template/Template_Endpoint_Control_R.c" +#endif + +#endif + +#endif diff --git a/LUFA/Drivers/USB/Core/XMEGA/EndpointStream_XMEGA.h b/LUFA/Drivers/USB/Core/XMEGA/EndpointStream_XMEGA.h index 3269d2b1..f2fe2899 100644 --- a/LUFA/Drivers/USB/Core/XMEGA/EndpointStream_XMEGA.h +++ b/LUFA/Drivers/USB/Core/XMEGA/EndpointStream_XMEGA.h @@ -1,648 +1,648 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 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 Endpoint data stream transmission and reception management for the AVR XMEGA microcontrollers. - * \copydetails Group_EndpointStreamRW_XMEGA - * - * \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_EndpointStreamRW - * \defgroup Group_EndpointStreamRW_XMEGA Read/Write of Multi-Byte Streams (XMEGA) - * \brief Endpoint data stream transmission and reception management for the Atmel AVR XMEGA architecture. - * - * Functions, macros, variables, enums and types related to data reading and writing of data streams from - * and to endpoints. - * - * @{ - */ - -#ifndef __ENDPOINT_STREAM_XMEGA_H__ -#define __ENDPOINT_STREAM_XMEGA_H__ - - /* Includes: */ - #include "../../../../Common/Common.h" - #include "../USBMode.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: */ - /* Function Prototypes: */ - /** \name Stream functions for null data */ - //@{ - - /** Reads and discards the given number of bytes from the currently selected endpoint's bank, - * discarding fully read packets from the host as needed. The last packet is not automatically - * discarded once the remaining bytes has been read; the user is responsible for manually - * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. - * - * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, - * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid - * storage location, the transfer will instead be performed as a series of chunks. Each time - * the endpoint bank becomes empty while there is still data to process (and after the current - * packet has been acknowledged) the BytesProcessed location will be updated with the total number - * of bytes processed in the stream, and the function will exit with an error code of - * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed - * in the user code - to continue the transfer, call the function again with identical parameters - * and it will resume until the BytesProcessed value reaches the total transfer length. - * - * Single Stream Transfer Example: - * \code - * uint8_t ErrorCode; - * - * if ((ErrorCode = Endpoint_Discard_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * Partial Stream Transfers Example: - * \code - * uint8_t ErrorCode; - * uint16_t BytesProcessed; - * - * BytesProcessed = 0; - * while ((ErrorCode = Endpoint_Discard_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) - * { - * // Stream not yet complete - do other actions here, abort if required - * } - * - * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * \note This routine should not be used on CONTROL type endpoints. - * - * \param[in] Length Number of bytes to discard via the currently selected endpoint. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Discard_Stream(uint16_t Length, - uint16_t* const BytesProcessed); - - /** Writes a given number of zeroed bytes to the currently selected endpoint's bank, sending - * full packets to the host as needed. The last packet is not automatically sent once the - * remaining bytes have been written; the user is responsible for manually sending the last - * packet to the host via the \ref Endpoint_ClearIN() macro. - * - * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, - * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid - * storage location, the transfer will instead be performed as a series of chunks. Each time - * the endpoint bank becomes full while there is still data to process (and after the current - * packet transmission has been initiated) the BytesProcessed location will be updated with the - * total number of bytes processed in the stream, and the function will exit with an error code of - * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed - * in the user code - to continue the transfer, call the function again with identical parameters - * and it will resume until the BytesProcessed value reaches the total transfer length. - * - * Single Stream Transfer Example: - * \code - * uint8_t ErrorCode; - * - * if ((ErrorCode = Endpoint_Null_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * Partial Stream Transfers Example: - * \code - * uint8_t ErrorCode; - * uint16_t BytesProcessed; - * - * BytesProcessed = 0; - * while ((ErrorCode = Endpoint_Null_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) - * { - * // Stream not yet complete - do other actions here, abort if required - * } - * - * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * \note This routine should not be used on CONTROL type endpoints. - * - * \param[in] Length Number of zero bytes to send via the currently selected endpoint. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Null_Stream(uint16_t Length, - uint16_t* const BytesProcessed); - - //@} - - /** \name Stream functions for RAM source/destination data */ - //@{ - - /** Writes the given number of bytes to the endpoint from the given buffer in little endian, - * sending full packets to the host as needed. The last packet filled is not automatically sent; - * the user is responsible for manually sending the last written packet to the host via the - * \ref Endpoint_ClearIN() macro. - * - * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, - * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid - * storage location, the transfer will instead be performed as a series of chunks. Each time - * the endpoint bank becomes full while there is still data to process (and after the current - * packet transmission has been initiated) the BytesProcessed location will be updated with the - * total number of bytes processed in the stream, and the function will exit with an error code of - * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed - * in the user code - to continue the transfer, call the function again with identical parameters - * and it will resume until the BytesProcessed value reaches the total transfer length. - * - * Single Stream Transfer Example: - * \code - * uint8_t DataStream[512]; - * uint8_t ErrorCode; - * - * if ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream), - * NULL)) != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * Partial Stream Transfers Example: - * \code - * uint8_t DataStream[512]; - * uint8_t ErrorCode; - * uint16_t BytesProcessed; - * - * BytesProcessed = 0; - * while ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream), - * &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) - * { - * // Stream not yet complete - do other actions here, abort if required - * } - * - * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * \note This routine should not be used on CONTROL type endpoints. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_Stream_LE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** Writes the given number of bytes to the endpoint from the given buffer in big endian, - * sending full packets to the host as needed. The last packet filled is not automatically sent; - * the user is responsible for manually sending the last written packet to the host via the - * \ref Endpoint_ClearIN() macro. - * - * \note This routine should not be used on CONTROL type endpoints. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_Stream_BE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** Reads the given number of bytes from the endpoint from the given buffer in little endian, - * discarding fully read packets from the host as needed. The last packet is not automatically - * discarded once the remaining bytes has been read; the user is responsible for manually - * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. - * - * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, - * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid - * storage location, the transfer will instead be performed as a series of chunks. Each time - * the endpoint bank becomes empty while there is still data to process (and after the current - * packet has been acknowledged) the BytesProcessed location will be updated with the total number - * of bytes processed in the stream, and the function will exit with an error code of - * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed - * in the user code - to continue the transfer, call the function again with identical parameters - * and it will resume until the BytesProcessed value reaches the total transfer length. - * - * Single Stream Transfer Example: - * \code - * uint8_t DataStream[512]; - * uint8_t ErrorCode; - * - * if ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream), - * NULL)) != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * Partial Stream Transfers Example: - * \code - * uint8_t DataStream[512]; - * uint8_t ErrorCode; - * uint16_t BytesProcessed; - * - * BytesProcessed = 0; - * while ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream), - * &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) - * { - * // Stream not yet complete - do other actions here, abort if required - * } - * - * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) - * { - * // Stream failed to complete - check ErrorCode here - * } - * \endcode - * - * \note This routine should not be used on CONTROL type endpoints. - * - * \param[out] Buffer Pointer to the destination data buffer to write to. - * \param[in] Length Number of bytes to send via the currently selected endpoint. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Read_Stream_LE(void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** Reads the given number of bytes from the endpoint from the given buffer in big endian, - * discarding fully read packets from the host as needed. The last packet is not automatically - * discarded once the remaining bytes has been read; the user is responsible for manually - * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. - * - * \note This routine should not be used on CONTROL type endpoints. - * - * \param[out] Buffer Pointer to the destination data buffer to write to. - * \param[in] Length Number of bytes to send via the currently selected endpoint. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Read_Stream_BE(void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in little endian, - * sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared - * in both failure and success states; the user is responsible for manually clearing the setup OUT to - * finalize the transfer via the \ref Endpoint_ClearOUT() macro. - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_Control_Stream_LE(const void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - - /** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in big endian, - * sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared - * in both failure and success states; the user is responsible for manually clearing the setup OUT to - * finalize the transfer via the \ref Endpoint_ClearOUT() macro. - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_Control_Stream_BE(const void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - - /** Reads the given number of bytes from the CONTROL endpoint from the given buffer in little endian, - * discarding fully read packets from the host as needed. The device IN acknowledgement is not - * automatically sent after success or failure states; the user is responsible for manually sending the - * setup IN to finalize the transfer via the \ref Endpoint_ClearIN() macro. - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[out] Buffer Pointer to the destination data buffer to write to. - * \param[in] Length Number of bytes to send via the currently selected endpoint. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Read_Control_Stream_LE(void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - - /** Reads the given number of bytes from the CONTROL endpoint from the given buffer in big endian, - * discarding fully read packets from the host as needed. The device IN acknowledgement is not - * automatically sent after success or failure states; the user is responsible for manually sending the - * setup IN to finalize the transfer via the \ref Endpoint_ClearIN() macro. - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[out] Buffer Pointer to the destination data buffer to write to. - * \param[in] Length Number of bytes to send via the currently selected endpoint. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Read_Control_Stream_BE(void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - //@} - - /** \name Stream functions for EEPROM source/destination data */ - //@{ - - /** EEPROM buffer source version of \ref Endpoint_Write_Stream_LE(). - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_EStream_LE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** EEPROM buffer source version of \ref Endpoint_Write_Stream_BE(). - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_EStream_BE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** EEPROM buffer destination version of \ref Endpoint_Read_Stream_LE(). - * - * \param[out] Buffer Pointer to the destination data buffer to write to, located in EEPROM memory space. - * \param[in] Length Number of bytes to send via the currently selected endpoint. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Read_EStream_LE(void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** EEPROM buffer destination version of \ref Endpoint_Read_Stream_BE(). - * - * \param[out] Buffer Pointer to the destination data buffer to write to, located in EEPROM memory space. - * \param[in] Length Number of bytes to send via the currently selected endpoint. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be read at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Read_EStream_BE(void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** EEPROM buffer source version of Endpoint_Write_Control_Stream_LE. - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * \n\n - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_Control_EStream_LE(const void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - - /** EEPROM buffer source version of \ref Endpoint_Write_Control_Stream_BE(). - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * \n\n - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_Control_EStream_BE(const void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - - /** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_LE(). - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * \n\n - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[out] Buffer Pointer to the destination data buffer to write to. - * \param[in] Length Number of bytes to send via the currently selected endpoint. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Read_Control_EStream_LE(void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - - /** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_BE(). - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * \n\n - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[out] Buffer Pointer to the destination data buffer to write to. - * \param[in] Length Number of bytes to send via the currently selected endpoint. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Read_Control_EStream_BE(void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - //@} - - /** \name Stream functions for PROGMEM source/destination data */ - //@{ - - /** FLASH buffer source version of \ref Endpoint_Write_Stream_LE(). - * - * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_PStream_LE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** FLASH buffer source version of \ref Endpoint_Write_Stream_BE(). - * - * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current - * transaction should be updated, \c NULL if the entire stream should be written at once. - * - * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_PStream_BE(const void* const Buffer, - uint16_t Length, - uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); - - /** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_LE(). - * - * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * \n\n - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_Control_PStream_LE(const void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - - /** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_BE(). - * - * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. - * - * \note This function automatically clears the control transfer's status stage. Do not manually attempt - * to clear the status stage when using this routine in a control transaction. - * \n\n - * - * \note This routine should only be used on CONTROL type endpoints. - * \n\n - * - * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained - * together; i.e. the entire stream data must be read or written at the one time. - * - * \param[in] Buffer Pointer to the source data buffer to read from. - * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. - * - * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. - */ - uint8_t Endpoint_Write_Control_PStream_BE(const void* const Buffer, - uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); - //@} - - /* Disable C linkage for C++ Compilers: */ - #if defined(__cplusplus) - } - #endif - -#endif - -/** @} */ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 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 Endpoint data stream transmission and reception management for the AVR XMEGA microcontrollers. + * \copydetails Group_EndpointStreamRW_XMEGA + * + * \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_EndpointStreamRW + * \defgroup Group_EndpointStreamRW_XMEGA Read/Write of Multi-Byte Streams (XMEGA) + * \brief Endpoint data stream transmission and reception management for the Atmel AVR XMEGA architecture. + * + * Functions, macros, variables, enums and types related to data reading and writing of data streams from + * and to endpoints. + * + * @{ + */ + +#ifndef __ENDPOINT_STREAM_XMEGA_H__ +#define __ENDPOINT_STREAM_XMEGA_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBMode.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: */ + /* Function Prototypes: */ + /** \name Stream functions for null data */ + //@{ + + /** Reads and discards the given number of bytes from the currently selected endpoint's bank, + * discarding fully read packets from the host as needed. The last packet is not automatically + * discarded once the remaining bytes has been read; the user is responsible for manually + * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes empty while there is still data to process (and after the current + * packet has been acknowledged) the BytesProcessed location will be updated with the total number + * of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Discard_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Discard_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Length Number of bytes to discard via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Discard_Stream(uint16_t Length, + uint16_t* const BytesProcessed); + + /** Writes a given number of zeroed bytes to the currently selected endpoint's bank, sending + * full packets to the host as needed. The last packet is not automatically sent once the + * remaining bytes have been written; the user is responsible for manually sending the last + * packet to the host via the \ref Endpoint_ClearIN() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes full while there is still data to process (and after the current + * packet transmission has been initiated) the BytesProcessed location will be updated with the + * total number of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Null_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Null_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Length Number of zero bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Null_Stream(uint16_t Length, + uint16_t* const BytesProcessed); + + //@} + + /** \name Stream functions for RAM source/destination data */ + //@{ + + /** Writes the given number of bytes to the endpoint from the given buffer in little endian, + * sending full packets to the host as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Endpoint_ClearIN() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes full while there is still data to process (and after the current + * packet transmission has been initiated) the BytesProcessed location will be updated with the + * total number of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream), + * NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream), + * &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Stream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the endpoint from the given buffer in big endian, + * sending full packets to the host as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Endpoint_ClearIN() macro. + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Stream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the endpoint from the given buffer in little endian, + * discarding fully read packets from the host as needed. The last packet is not automatically + * discarded once the remaining bytes has been read; the user is responsible for manually + * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes empty while there is still data to process (and after the current + * packet has been acknowledged) the BytesProcessed location will be updated with the total number + * of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream), + * NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream), + * &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Stream_LE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the endpoint from the given buffer in big endian, + * discarding fully read packets from the host as needed. The last packet is not automatically + * discarded once the remaining bytes has been read; the user is responsible for manually + * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Stream_BE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in little endian, + * sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared + * in both failure and success states; the user is responsible for manually clearing the status OUT packet + * to finalize the transfer's status stage via the \ref Endpoint_ClearOUT() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_Stream_LE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in big endian, + * sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared + * in both failure and success states; the user is responsible for manually clearing the status OUT packet + * to finalize the transfer's status stage via the \ref Endpoint_ClearOUT() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_Stream_BE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the CONTROL endpoint from the given buffer in little endian, + * discarding fully read packets from the host as needed. The device IN acknowledgement is not + * automatically sent after success or failure states; the user is responsible for manually sending the + * status IN packet to finalize the transfer's status stage via the \ref Endpoint_ClearIN() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Control_Stream_LE(void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the CONTROL endpoint from the given buffer in big endian, + * discarding fully read packets from the host as needed. The device IN acknowledgement is not + * automatically sent after success or failure states; the user is responsible for manually sending the + * status IN packet to finalize the transfer's status stage via the \ref Endpoint_ClearIN() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Control_Stream_BE(void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /** \name Stream functions for EEPROM source/destination data */ + //@{ + + /** EEPROM buffer source version of \ref Endpoint_Write_Stream_LE(). + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_EStream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Endpoint_Write_Stream_BE(). + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_EStream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer destination version of \ref Endpoint_Read_Stream_LE(). + * + * \param[out] Buffer Pointer to the destination data buffer to write to, located in EEPROM memory space. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_EStream_LE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer destination version of \ref Endpoint_Read_Stream_BE(). + * + * \param[out] Buffer Pointer to the destination data buffer to write to, located in EEPROM memory space. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_EStream_BE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of Endpoint_Write_Control_Stream_LE. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_EStream_LE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Endpoint_Write_Control_Stream_BE(). + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_EStream_BE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_LE(). + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Control_EStream_LE(void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_BE(). + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Control_EStream_BE(void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /** \name Stream functions for PROGMEM source/destination data */ + //@{ + + /** FLASH buffer source version of \ref Endpoint_Write_Stream_LE(). + * + * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_PStream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** FLASH buffer source version of \ref Endpoint_Write_Stream_BE(). + * + * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_PStream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_LE(). + * + * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_PStream_LE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_BE(). + * + * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_PStream_BE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ diff --git a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h index 23de8fc0..3d2926c3 100644 --- a/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h +++ b/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h @@ -90,14 +90,18 @@ /* Public Interface - May be used in end-application: */ /* Macros: */ - #if !defined(CONTROL_ONLY_DEVICE) || defined(__DOXYGEN__) + #if (!defined(MAX_ENDPOINT_INDEX) && !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 16 #else - #define ENDPOINT_TOTAL_ENDPOINTS 1 + #if defined(CONTROL_ONLY_DEVICE) + #define ENDPOINT_TOTAL_ENDPOINTS 1 + #else + #define ENDPOINT_TOTAL_ENDPOINTS (MAX_ENDPOINT_INDEX + 1) + #endif #endif /* Private Interface - For use in library only: */ @@ -242,8 +246,12 @@ { uint8_t EPConfigMask = (USB_EP_INTDSBL_bm | ((Banks > 1) ? USB_EP_PINGPONG_bm : 0) | Endpoint_BytesToEPSizeMask(Size)); + if ((Address & ENDPOINT_EPNUM_MASK) >= ENDPOINT_TOTAL_ENDPOINTS) + return false; + // TODO - Fix once limitations are lifted - if ((Banks > 1) || (Size > 64)) + EPConfigMask &= ~USB_EP_PINGPONG_bm; + if (Size > 64) return false; switch (Type) diff --git a/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.c b/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.c index 844ef650..09d4ab62 100644 --- a/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.c +++ b/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.c @@ -76,7 +76,7 @@ void USB_Init( USB.CAL1 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL1)); NVM.CMD = 0; - /* Ugly workaround to ensure an aligned table, since __BIGGEST_ALIGNMENT__ == 1 for 8-bit AVR-GCC */ + /* Ugly workaround to ensure an aligned table, since __BIGGEST_ALIGNMENT__ == 1 for the 8-bit AVR-GCC toochain */ USB.EPPTR = ((intptr_t)&USB_EndpointTable[1] & ~(1 << 0)); USB.CTRLA = (USB_STFRNUM_bm | ((ENDPOINT_TOTAL_ENDPOINTS - 1) << USB_MAXEP_gp)); diff --git a/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.h b/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.h index 25402e85..e1c782db 100644 --- a/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.h +++ b/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.h @@ -180,7 +180,7 @@ * 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 + * interface to control the USB interface's behavior. 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. diff --git a/LUFA/Drivers/USB/USB.h b/LUFA/Drivers/USB/USB.h index 626635c8..512f7029 100644 --- a/LUFA/Drivers/USB/USB.h +++ b/LUFA/Drivers/USB/USB.h @@ -41,7 +41,7 @@ * * \section Sec_Dependencies Module Source Dependencies * The following files must be built with any user project that uses this module: - * - LUFA/Drivers/USB/Core/ConfigDescriptor.c (Makefile source module name: LUFA_SRC_USB) + * - LUFA/Drivers/USB/Core/ConfigDescriptors.c (Makefile source module name: LUFA_SRC_USB) * - LUFA/Drivers/USB/Core/DeviceStandardReq.c (Makefile source module name: LUFA_SRC_USB) * - LUFA/Drivers/USB/Core/Events.c (Makefile source module name: LUFA_SRC_USB) * - LUFA/Drivers/USB/Core/HostStandardReq.c (Makefile source module name: LUFA_SRC_USB) @@ -382,7 +382,7 @@ #include "Core/USBTask.h" #include "Core/Events.h" #include "Core/StdDescriptors.h" - #include "Core/ConfigDescriptor.h" + #include "Core/ConfigDescriptors.h" #include "Core/USBController.h" #include "Core/USBInterrupt.h" -- cgit v1.2.3