summaryrefslogtreecommitdiff
path: root/firmware/LUFA/Drivers/USB/Class
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/LUFA/Drivers/USB/Class')
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Audio.h75
-rw-r--r--firmware/LUFA/Drivers/USB/Class/CDC.h80
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Common/Audio.h701
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Common/CDC.h372
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Common/HID.h451
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Common/MIDI.h293
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Common/MassStorage.h362
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Common/Printer.h121
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Common/RNDIS.h399
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Common/StillImage.h161
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/Audio.c98
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/Audio.h336
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/Audio.lst184
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/Audio.obin0 -> 7724 bytes
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/CDC.c332
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/CDC.h342
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/CDC.lst1059
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/CDC.obin0 -> 25224 bytes
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/HID.c190
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/HID.h222
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/HID.lst769
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/HID.obin0 -> 13920 bytes
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/MIDI.c148
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/MIDI.h189
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/MIDI.lst346
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/MIDI.obin0 -> 12248 bytes
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/MassStorage.c247
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/MassStorage.h177
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/MassStorage.lst643
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/MassStorage.obin0 -> 15196 bytes
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/RNDIS.c496
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/RNDIS.h186
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/RNDIS.lst1519
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Device/RNDIS.obin0 -> 23344 bytes
-rw-r--r--firmware/LUFA/Drivers/USB/Class/HID.h81
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/CDC.c465
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/CDC.h334
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/CDC.lst19
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/CDC.obin0 -> 920 bytes
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/HID.c387
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/HID.h316
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/HID.lst19
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/HID.obin0 -> 920 bytes
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/HIDParser.c361
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/HIDParser.h356
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/HIDParser.lst19
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/HIDParser.obin0 -> 928 bytes
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/HIDReportData.h142
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/MIDI.c215
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/MIDI.h201
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/MIDI.lst19
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/MIDI.obin0 -> 920 bytes
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/MassStorage.c629
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/MassStorage.h344
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/MassStorage.lst19
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/MassStorage.obin0 -> 928 bytes
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/Printer.c392
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/Printer.h282
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/Printer.lst19
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/Printer.obin0 -> 924 bytes
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/RNDIS.c480
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/RNDIS.h290
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/RNDIS.lst19
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/RNDIS.obin0 -> 924 bytes
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/StillImage.c443
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/StillImage.h331
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/StillImage.lst19
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Host/StillImage.obin0 -> 928 bytes
-rw-r--r--firmware/LUFA/Drivers/USB/Class/MIDI.h83
-rw-r--r--firmware/LUFA/Drivers/USB/Class/MassStorage.h80
-rw-r--r--firmware/LUFA/Drivers/USB/Class/Printer.h77
-rw-r--r--firmware/LUFA/Drivers/USB/Class/RNDIS.h80
-rw-r--r--firmware/LUFA/Drivers/USB/Class/StillImage.h75
73 files changed, 17094 insertions, 0 deletions
diff --git a/firmware/LUFA/Drivers/USB/Class/Audio.h b/firmware/LUFA/Drivers/USB/Class/Audio.h
new file mode 100644
index 0000000..70ababe
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Audio.h
@@ -0,0 +1,75 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Master include file for the library USB Audio Class driver.
+ *
+ * Master include file for the library USB Audio 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_USBClassAudio Audio 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/Device/Audio.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ *
+ * \section Module Description
+ * Audio Class Driver module. This module contains an internal implementation of the USB Audio 1.0 Class, for Device
+ * USB mode only. User applications can use this class driver instead of implementing the Audio 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
+ * Hosts or Devices using the USB Audio Class.
+ *
+ * @{
+ */
+
+#ifndef _AUDIO_CLASS_H_
+#define _AUDIO_CLASS_H_
+
+ /* Macros: */
+ #define __INCLUDE_FROM_USB_DRIVER
+ #define __INCLUDE_FROM_AUDIO_DRIVER
+
+ /* Includes: */
+ #include "../HighLevel/USBMode.h"
+
+ #if defined(USB_CAN_BE_DEVICE)
+ #include "Device/Audio.h"
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/CDC.h b/firmware/LUFA/Drivers/USB/Class/CDC.h
new file mode 100644
index 0000000..d8b7b58
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/CDC.h
@@ -0,0 +1,80 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Master include file for the library USB CDC-ACM Class driver.
+ *
+ * Master include file for the library USB CDC 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_USBClassCDC CDC-ACM (Virtual Serial) 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/Device/CDC.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ * - LUFA/Drivers/USB/Class/Host/CDC.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ *
+ * \section Module Description
+ * CDC Class Driver module. This module contains an internal implementation of the USB CDC-ACM class Virtual Serial
+ * Ports, for both Device and Host USB modes. User applications can use this class driver instead of implementing the
+ * CDC 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
+ * Hosts or Devices using the USB CDC Class.
+ *
+ * @{
+ */
+
+#ifndef _CDC_CLASS_H_
+#define _CDC_CLASS_H_
+
+ /* Macros: */
+ #define __INCLUDE_FROM_USB_DRIVER
+ #define __INCLUDE_FROM_CDC_DRIVER
+
+ /* Includes: */
+ #include "../HighLevel/USBMode.h"
+
+ #if defined(USB_CAN_BE_DEVICE)
+ #include "Device/CDC.h"
+ #endif
+
+ #if defined(USB_CAN_BE_HOST)
+ #include "Host/CDC.h"
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Common/Audio.h b/firmware/LUFA/Drivers/USB/Class/Common/Audio.h
new file mode 100644
index 0000000..a635947
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Common/Audio.h
@@ -0,0 +1,701 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Common definitions and declarations for the library USB Audio 1.0 Class driver.
+ *
+ * Common definitions and declarations for the library USB Audio 1.0 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_USBClassAudio
+ * @defgroup Group_USBClassAudioCommon Common Class Definitions
+ *
+ * \section Module Description
+ * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
+ * Audio 1.0 Class.
+ *
+ * @{
+ */
+
+#ifndef _AUDIO_CLASS_COMMON_H_
+#define _AUDIO_CLASS_COMMON_H_
+
+ /* Includes: */
+ #include "../../HighLevel/StdDescriptors.h"
+
+ #include <string.h>
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_AUDIO_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ /* Macros: */
+ #if !defined(AUDIO_TOTAL_SAMPLE_RATES) || defined(__DOXYGEN__)
+ /** Total number of discrete audio sample rates supported by the device. This value can be overridden by defining this
+ * token in the project makefile to the desired value, and passing it to the compiler via the -D switch.
+ */
+ #define AUDIO_TOTAL_SAMPLE_RATES 1
+ #endif
+
+ /** \name Audio Channel Masks */
+ //@{
+ /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_CHANNEL_LEFT_FRONT (1 << 0)
+
+ /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_CHANNEL_RIGHT_FRONT (1 << 1)
+
+ /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_CHANNEL_CENTER_FRONT (1 << 2)
+
+ /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_CHANNEL_LOW_FREQ_ENHANCE (1 << 3)
+
+ /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_CHANNEL_LEFT_SURROUND (1 << 4)
+
+ /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_CHANNEL_RIGHT_SURROUND (1 << 5)
+
+ /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_CHANNEL_LEFT_OF_CENTER (1 << 6)
+
+ /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_CHANNEL_RIGHT_OF_CENTER (1 << 7)
+
+ /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_CHANNEL_SURROUND (1 << 8)
+
+ /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_CHANNEL_SIDE_LEFT (1 << 9)
+
+ /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_CHANNEL_SIDE_RIGHT (1 << 10)
+
+ /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_CHANNEL_TOP (1 << 11)
+ //@}
+
+ /** \name Audio Feature Masks */
+ //@{
+ /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
+ #define AUDIO_FEATURE_MUTE (1 << 0)
+
+ /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
+ #define AUDIO_FEATURE_VOLUME (1 << 1)
+
+ /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
+ #define AUDIO_FEATURE_BASS (1 << 2)
+
+ /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
+ #define AUDIO_FEATURE_MID (1 << 3)
+
+ /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
+ #define AUDIO_FEATURE_TREBLE (1 << 4)
+
+ /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
+ #define AUDIO_FEATURE_GRAPHIC_EQUALIZER (1 << 5)
+
+ /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
+ #define AUDIO_FEATURE_AUTOMATIC_GAIN (1 << 6)
+
+ /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
+ #define AUDIO_FEATURE_DELAY (1 << 7)
+
+ /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
+ #define AUDIO_FEATURE_BASS_BOOST (1 << 8)
+
+ /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */
+ #define AUDIO_FEATURE_BASS_LOUDNESS (1 << 9)
+ //@}
+
+ /** \name Audio Terminal Types */
+ //@{
+ /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_TERMINAL_UNDEFINED 0x0100
+
+ /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_TERMINAL_STREAMING 0x0101
+
+ /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_TERMINAL_VENDOR 0x01FF
+
+ /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_TERMINAL_IN_UNDEFINED 0x0200
+
+ /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_TERMINAL_IN_MIC 0x0201
+
+ /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_TERMINAL_IN_DESKTOP_MIC 0x0202
+
+ /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_TERMINAL_IN_PERSONAL_MIC 0x0203
+
+ /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_TERMINAL_IN_OMNIDIR_MIC 0x0204
+
+ /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_TERMINAL_IN_MIC_ARRAY 0x0205
+
+ /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_TERMINAL_IN_PROCESSING_MIC 0x0206
+
+ /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_TERMINAL_IN_OUT_UNDEFINED 0x0300
+
+ /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_TERMINAL_OUT_SPEAKER 0x0301
+
+ /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_TERMINAL_OUT_HEADPHONES 0x0302
+
+ /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_TERMINAL_OUT_HEAD_MOUNTED 0x0303
+
+ /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_TERMINAL_OUT_DESKTOP 0x0304
+
+ /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_TERMINAL_OUT_ROOM 0x0305
+
+ /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_TERMINAL_OUT_COMMUNICATION 0x0306
+
+ /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */
+ #define AUDIO_TERMINAL_OUT_LOWFREQ 0x0307
+ //@}
+
+ /** Convenience macro to fill a 24-bit \ref USB_Audio_SampleFreq_t structure with the given sample rate as a 24-bit number.
+ *
+ * \param[in] freq Required audio sampling frequency in HZ
+ */
+ #define AUDIO_SAMPLE_FREQ(freq) {((uint32_t)freq & 0x00FFFF), (((uint32_t)freq >> 16) & 0x0000FF)}
+
+ /** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint
+ * accepts only filled endpoint packets of audio samples.
+ */
+ #define AUDIO_EP_FULL_PACKETS_ONLY (1 << 7)
+
+ /** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint
+ * will accept partially filled endpoint packets of audio samples.
+ */
+ #define AUDIO_EP_ACCEPTS_SMALL_PACKETS (0 << 7)
+
+ /* Enums: */
+ /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the Audio
+ * device class.
+ */
+ enum Audio_Descriptor_ClassSubclassProtocol_t
+ {
+ AUDIO_CSCP_AudioClass = 0x01, /**< Descriptor Class value indicating that the device or
+ * interface belongs to the USB Audio 1.0 class.
+ */
+ AUDIO_CSCP_ControlSubclass = 0x01, /**< Descriptor Subclass value indicating that the device or
+ * interface belongs to the Audio Control subclass.
+ */
+ AUDIO_CSCP_ControlProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or
+ * interface belongs to the Audio Control protocol.
+ */
+ AUDIO_CSCP_AudioStreamingSubclass = 0x02, /**< Descriptor Subclass value indicating that the device or
+ * interface belongs to the MIDI Streaming subclass.
+ */
+ AUDIO_CSCP_MIDIStreamingSubclass = 0x03, /**< Descriptor Subclass value indicating that the device or
+ * interface belongs to the Audio streaming subclass.
+ */
+ AUDIO_CSCP_StreamingProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or
+ * interface belongs to the Streaming Audio protocol.
+ */
+ };
+
+ /** Audio class specific interface description subtypes, for the Audio Control interface. */
+ enum Audio_CSInterface_AC_SubTypes_t
+ {
+ AUDIO_DSUBTYPE_CSInterface_Header = 0x01, /**< Audio class specific control interface header. */
+ AUDIO_DSUBTYPE_CSInterface_InputTerminal = 0x02, /**< Audio class specific control interface Input Terminal. */
+ AUDIO_DSUBTYPE_CSInterface_OutputTerminal = 0x03, /**< Audio class specific control interface Output Terminal. */
+ AUDIO_DSUBTYPE_CSInterface_Mixer = 0x04, /**< Audio class specific control interface Mixer Unit. */
+ AUDIO_DSUBTYPE_CSInterface_Selector = 0x05, /**< Audio class specific control interface Selector Unit. */
+ AUDIO_DSUBTYPE_CSInterface_Feature = 0x06, /**< Audio class specific control interface Feature Unit. */
+ AUDIO_DSUBTYPE_CSInterface_Processing = 0x07, /**< Audio class specific control interface Processing Unit. */
+ AUDIO_DSUBTYPE_CSInterface_Extension = 0x08, /**< Audio class specific control interface Extension Unit. */
+ };
+
+ /** Audio class specific interface description subtypes, for the Audio Streaming interface. */
+ enum Audio_CSInterface_AS_SubTypes_t
+ {
+ AUDIO_DSUBTYPE_CSInterface_General = 0x01, /**< Audio class specific streaming interface general descriptor. */
+ AUDIO_DSUBTYPE_CSInterface_FormatType = 0x02, /**< Audio class specific streaming interface format type descriptor. */
+ AUDIO_DSUBTYPE_CSInterface_FormatSpecific = 0x03, /**< Audio class specific streaming interface format information descriptor. */
+ };
+
+ /** Audio class specific endpoint description subtypes, for the Audio Streaming interface. */
+ enum Audio_CSEndpoint_SubTypes_t
+ {
+ AUDIO_DSUBTYPE_CSEndpoint_General = 0x01, /**< Audio class specific endpoint general descriptor. */
+ };
+
+ /* Type Defines: */
+ /** \brief Audio class-specific Input Terminal Descriptor (LUFA naming conventions).
+ *
+ * Type define for an Audio class-specific input terminal descriptor. This indicates to the host that the device
+ * contains an input audio source, either from a physical terminal on the device, or a logical terminal (for example,
+ * a USB endpoint). See the USB Audio specification for more details.
+ *
+ * \see \ref USB_Audio_StdDescriptor_InputTerminal_t for the version of this type with standard element names.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
+ uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
+ * must be \ref AUDIO_DSUBTYPE_CSInterface_InputTerminal.
+ */
+
+ uint8_t TerminalID; /**< ID value of this terminal unit - must be a unique value within the device. */
+ uint16_t TerminalType; /**< Type of terminal, a TERMINAL_* mask. */
+ uint8_t AssociatedOutputTerminal; /**< ID of associated output terminal, for physically grouped terminals
+ * such as the speaker and microphone of a phone handset.
+ */
+ uint8_t TotalChannels; /**< Total number of separate audio channels within this interface (right, left, etc.) */
+ uint16_t ChannelConfig; /**< CHANNEL_* masks indicating what channel layout is supported by this terminal. */
+
+ uint8_t ChannelStrIndex; /**< Index of a string descriptor describing this channel within the device. */
+ uint8_t TerminalStrIndex; /**< Index of a string descriptor describing this descriptor within the device. */
+ } USB_Audio_Descriptor_InputTerminal_t;
+
+ /** \brief Audio class-specific Input Terminal Descriptor (USB-IF naming conventions).
+ *
+ * Type define for an Audio class-specific input terminal descriptor. This indicates to the host that the device
+ * contains an input audio source, either from a physical terminal on the device, or a logical terminal (for example,
+ * a USB endpoint). See the USB Audio specification for more details.
+ *
+ * \see \ref USB_Audio_Descriptor_InputTerminal_t for the version of this type with non-standard LUFA specific
+ * element names.
+ */
+ typedef struct
+ {
+ uint8_t bLength; /**< Size of the descriptor, in bytes. */
+ uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
+ * given by the specific class.
+ */
+
+ uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
+ * must be \ref AUDIO_DSUBTYPE_CSInterface_InputTerminal.
+ */
+ uint8_t bTerminalID; /**< ID value of this terminal unit - must be a unique value within the device. */
+ uint16_t wTerminalType; /**< Type of terminal, a TERMINAL_* mask. */
+ uint8_t bAssocTerminal; /**< ID of associated output terminal, for physically grouped terminals
+ * such as the speaker and microphone of a phone handset.
+ */
+ uint8_t bNrChannels; /**< Total number of separate audio channels within this interface (right, left, etc.) */
+ uint16_t wChannelConfig; /**< CHANNEL_* masks indicating what channel layout is supported by this terminal. */
+
+ uint8_t iChannelNames; /**< Index of a string descriptor describing this channel within the device. */
+ uint8_t iTerminal; /**< Index of a string descriptor describing this descriptor within the device. */
+ } USB_Audio_StdDescriptor_InputTerminal_t;
+
+ /** \brief Audio class-specific Output Terminal Descriptor (LUFA naming conventions).
+ *
+ * Type define for an Audio class-specific output terminal descriptor. This indicates to the host that the device
+ * contains an output audio sink, either to a physical terminal on the device, or a logical terminal (for example,
+ * a USB endpoint). See the USB Audio specification for more details.
+ *
+ * \see \ref USB_Audio_StdDescriptor_OutputTerminal_t for the version of this type with standard element names.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
+ uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
+ * must be \ref AUDIO_DSUBTYPE_CSInterface_OutputTerminal.
+ */
+
+ uint8_t TerminalID; /**< ID value of this terminal unit - must be a unique value within the device. */
+ uint16_t TerminalType; /**< Type of terminal, a TERMINAL_* mask. */
+ uint8_t AssociatedInputTerminal; /**< ID of associated input terminal, for physically grouped terminals
+ * such as the speaker and microphone of a phone handset.
+ */
+ uint8_t SourceID; /**< ID value of the unit this terminal's audio is sourced from. */
+
+ uint8_t TerminalStrIndex; /**< Index of a string descriptor describing this descriptor within the device. */
+ } USB_Audio_Descriptor_OutputTerminal_t;
+
+ /** \brief Audio class-specific Output Terminal Descriptor (USB-IF naming conventions).
+ *
+ * Type define for an Audio class-specific output terminal descriptor. This indicates to the host that the device
+ * contains an output audio sink, either to a physical terminal on the device, or a logical terminal (for example,
+ * a USB endpoint). See the USB Audio specification for more details.
+ *
+ * \see \ref USB_Audio_Descriptor_OutputTerminal_t for the version of this type with non-standard LUFA specific
+ * element names.
+ */
+ typedef struct
+ {
+ uint8_t bLength; /**< Size of the descriptor, in bytes. */
+ uint8_t bDescriptorType; /**< Sub type value used to distinguish between audio class-specific descriptors,
+ * must be \ref AUDIO_DSUBTYPE_CSInterface_OutputTerminal.
+ */
+
+ uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
+ * a value from the \ref Audio_CSInterface_AC_SubTypes_t enum.
+ */
+ uint8_t bTerminalID; /**< ID value of this terminal unit - must be a unique value within the device. */
+ uint16_t wTerminalType; /**< Type of terminal, a TERMINAL_* mask. */
+ uint8_t bAssocTerminal; /**< ID of associated input terminal, for physically grouped terminals
+ * such as the speaker and microphone of a phone handset.
+ */
+ uint8_t bSourceID; /**< ID value of the unit this terminal's audio is sourced from. */
+
+ uint8_t iTerminal; /**< Index of a string descriptor describing this descriptor within the device. */
+ } USB_Audio_StdDescriptor_OutputTerminal_t;
+
+ /** \brief Audio class-specific Interface Descriptor (LUFA naming conventions).
+ *
+ * Type define for an Audio class-specific interface descriptor. This follows a regular interface descriptor to
+ * supply extra information about the audio device's layout to the host. See the USB Audio specification for more
+ * details.
+ *
+ * \see \ref USB_Audio_StdDescriptor_Interface_AC_t for the version of this type with standard element names.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
+ uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
+ * a value from the \ref Audio_CSInterface_AS_SubTypes_t enum.
+ */
+
+ uint16_t ACSpecification; /**< Binary coded decimal value, indicating the supported Audio Class specification version. */
+ uint16_t TotalLength; /**< Total length of the Audio class-specific descriptors, including this descriptor. */
+
+ uint8_t InCollection; /**< Total number of Audio Streaming interfaces linked to this Audio Control interface (must be 1). */
+ uint8_t InterfaceNumber; /**< Interface number of the associated Audio Streaming interface. */
+ } USB_Audio_Descriptor_Interface_AC_t;
+
+ /** \brief Audio class-specific Interface Descriptor (USB-IF naming conventions).
+ *
+ * Type define for an Audio class-specific interface descriptor. This follows a regular interface descriptor to
+ * supply extra information about the audio device's layout to the host. See the USB Audio specification for more
+ * details.
+ *
+ * \see \ref USB_Audio_Descriptor_Interface_AC_t for the version of this type with non-standard LUFA specific
+ * element names.
+ */
+ typedef struct
+ {
+ uint8_t bLength; /**< Size of the descriptor, in bytes. */
+ uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
+ * given by the specific class.
+ */
+
+ uint8_t bDescriptorSubtype;/**< Sub type value used to distinguish between audio class-specific descriptors,
+ * a value from the \ref Audio_CSInterface_AS_SubTypes_t enum.
+ */
+
+ uint16_t bcdADC; /**< Binary coded decimal value, indicating the supported Audio Class specification version. */
+ uint16_t wTotalLength; /**< Total length of the Audio class-specific descriptors, including this descriptor. */
+
+ uint8_t bInCollection; /**< Total number of Audio Streaming interfaces linked to this Audio Control interface (must be 1). */
+ uint8_t bInterfaceNumbers; /**< Interface number of the associated Audio Streaming interface. */
+ } USB_Audio_StdDescriptor_Interface_AC_t;
+
+ /** \brief Audio class-specific Feature Unit Descriptor (LUFA naming conventions).
+ *
+ * Type define for an Audio class-specific Feature Unit descriptor. This indicates to the host what features
+ * are present in the device's audio stream for basic control, such as per-channel volume. See the USB Audio
+ * specification for more details.
+ *
+ * \see \ref USB_Audio_StdDescriptor_FeatureUnit_t for the version of this type with standard element names.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
+ uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
+ * must be \ref AUDIO_DSUBTYPE_CSInterface_Feature.
+ */
+
+ uint8_t UnitID; /**< ID value of this feature unit - must be a unique value within the device. */
+ uint8_t SourceID; /**< Source ID value of the audio source input into this feature unit. */
+
+ uint8_t ControlSize; /**< Size of each element in the ChanelControlls array. */
+ uint8_t ChannelControls[3]; /**< Feature masks for the control channel, and each separate audio channel. */
+
+ uint8_t FeatureUnitStrIndex; /**< Index of a string descriptor describing this descriptor within the device. */
+ } USB_Audio_Descriptor_FeatureUnit_t;
+
+ /** \brief Audio class-specific Feature Unit Descriptor (USB-IF naming conventions).
+ *
+ * Type define for an Audio class-specific Feature Unit descriptor. This indicates to the host what features
+ * are present in the device's audio stream for basic control, such as per-channel volume. See the USB Audio
+ * specification for more details.
+ *
+ * \see \ref USB_Audio_Descriptor_FeatureUnit_t for the version of this type with non-standard LUFA specific
+ * element names.
+ */
+ typedef struct
+ {
+ uint8_t bLength; /**< Size of the descriptor, in bytes. */
+ uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
+ * given by the specific class.
+ */
+
+ uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
+ * must be \ref AUDIO_DSUBTYPE_CSInterface_Feature.
+ */
+
+ uint8_t bUnitID; /**< ID value of this feature unit - must be a unique value within the device. */
+ uint8_t bSourceID; /**< Source ID value of the audio source input into this feature unit. */
+
+ uint8_t bControlSize; /**< Size of each element in the ChanelControlls array. */
+ uint8_t bmaControls[3]; /**< Feature masks for the control channel, and each separate audio channel. */
+
+ uint8_t iFeature; /**< Index of a string descriptor describing this descriptor within the device. */
+ } USB_Audio_StdDescriptor_FeatureUnit_t;
+
+ /** \brief Audio class-specific Streaming Audio Interface Descriptor (LUFA naming conventions).
+ *
+ * Type define for an Audio class-specific streaming interface descriptor. This indicates to the host
+ * how audio streams within the device are formatted. See the USB Audio specification for more details.
+ *
+ * \see \ref USB_Audio_StdDescriptor_Interface_AS_t for the version of this type with standard element names.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
+ uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
+ * a value from the \ref Audio_CSInterface_AS_SubTypes_t enum.
+ */
+
+ uint8_t TerminalLink; /**< ID value of the output terminal this descriptor is describing. */
+
+ uint8_t FrameDelay; /**< Delay in frames resulting from the complete sample processing from input to output. */
+ uint16_t AudioFormat; /**< Format of the audio stream, see Audio Device Formats specification. */
+ } USB_Audio_Descriptor_Interface_AS_t;
+
+ /** \brief Audio class-specific Streaming Audio Interface Descriptor (USB-IF naming conventions).
+ *
+ * Type define for an Audio class-specific streaming interface descriptor. This indicates to the host
+ * how audio streams within the device are formatted. See the USB Audio specification for more details.
+ *
+ * \see \ref USB_Audio_Descriptor_Interface_AS_t for the version of this type with non-standard LUFA specific
+ * element names.
+ */
+ typedef struct
+ {
+ uint8_t bLength; /**< Size of the descriptor, in bytes. */
+ uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
+ * given by the specific class.
+ */
+
+ uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
+ * a value from the \ref Audio_CSInterface_AS_SubTypes_t enum.
+ */
+
+ uint8_t bTerminalLink; /**< ID value of the output terminal this descriptor is describing. */
+
+ uint8_t bDelay; /**< Delay in frames resulting from the complete sample processing from input to output. */
+ uint16_t wFormatTag; /**< Format of the audio stream, see Audio Device Formats specification. */
+ } USB_Audio_StdDescriptor_Interface_AS_t;
+
+ /** \brief 24-Bit Audio Frequency Structure.
+ *
+ * Type define for a 24bit audio sample frequency structure. GCC does not contain a built in 24bit datatype,
+ * this this structure is used to build up the value instead. Fill this structure with the \ref AUDIO_SAMPLE_FREQ() macro.
+ */
+ typedef struct
+ {
+ uint16_t LowWord; /**< Low 16 bits of the 24-bit value. */
+ uint8_t HighByte; /**< Upper 8 bits of the 24-bit value. */
+ } USB_Audio_SampleFreq_t;
+
+ /** \brief Audio class-specific Format Descriptor (LUFA naming conventions).
+ *
+ * Type define for an Audio class-specific audio format descriptor. This is used to give the host full details
+ * about the number of channels, the sample resolution, acceptable sample frequencies and encoding method used
+ * in the device's audio streams. See the USB Audio specification for more details.
+ *
+ * \see \ref USB_Audio_StdDescriptor_Format_t for the version of this type with standard element names.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
+ uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
+ * must be \ref AUDIO_DSUBTYPE_CSInterface_FormatType.
+ */
+
+ uint8_t FormatType; /**< Format of the audio stream, see Audio Device Formats specification. */
+ uint8_t Channels; /**< Total number of discrete channels in the stream. */
+
+ uint8_t SubFrameSize; /**< Size in bytes of each channel's sample data in the stream. */
+ uint8_t BitResolution; /**< Bits of resolution of each channel's samples in the stream. */
+
+ uint8_t SampleFrequencyType; /**< Total number of sample frequencies supported by the device. */
+ USB_Audio_SampleFreq_t SampleFrequencies[AUDIO_TOTAL_SAMPLE_RATES]; /**< Sample frequencies supported by the device (must be 24-bit). */
+ } USB_Audio_Descriptor_Format_t;
+
+ /** \brief Audio class-specific Format Descriptor (USB-IF naming conventions).
+ *
+ * Type define for an Audio class-specific audio format descriptor. This is used to give the host full details
+ * about the number of channels, the sample resolution, acceptable sample frequencies and encoding method used
+ * in the device's audio streams. See the USB Audio specification for more details.
+ *
+ * \see \ref USB_Audio_Descriptor_Format_t for the version of this type with non-standard LUFA specific
+ * element names.
+ */
+ typedef struct
+ {
+ uint8_t bLength; /**< Size of the descriptor, in bytes. */
+ uint8_t bDescriptorType; /**< Sub type value used to distinguish between audio class-specific descriptors,
+ * must be \ref AUDIO_DSUBTYPE_CSInterface_FormatType.
+ */
+
+ uint8_t bDescriptorSubtype;/**< Sub type value used to distinguish between audio class-specific descriptors,
+ * a value from the \ref Audio_CSInterface_AS_SubTypes_t enum.
+ */
+
+ uint8_t bFormatType; /**< Format of the audio stream, see Audio Device Formats specification. */
+ uint8_t bNrChannels; /**< Total number of discrete channels in the stream. */
+
+ uint8_t bSubFrameSize; /**< Size in bytes of each channel's sample data in the stream. */
+ uint8_t bBitResolution; /**< Bits of resolution of each channel's samples in the stream. */
+
+ uint8_t bSampleFrequencyType; /**< Total number of sample frequencies supported by the device. */
+ uint8_t SampleFrequencies[AUDIO_TOTAL_SAMPLE_RATES * 3]; /**< Sample frequencies supported by the device (must be 24-bit). */
+ } USB_Audio_StdDescriptor_Format_t;
+
+ /** \brief Audio class-specific Streaming Endpoint Descriptor (LUFA naming conventions).
+ *
+ * Type define for an Audio class-specific endpoint descriptor. This contains a regular endpoint
+ * descriptor with a few Audio-class-specific extensions. See the USB Audio specification for more details.
+ *
+ * \see \ref USB_Audio_StdDescriptor_StreamEndpoint_Std_t for the version of this type with standard element names.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Endpoint_t Endpoint; /**< Standard endpoint descriptor describing the audio endpoint. */
+
+ uint8_t Refresh; /**< Always set to zero for Audio class devices. */
+ uint8_t SyncEndpointNumber; /**< Endpoint address to send synchronization information to, if needed (zero otherwise). */
+ } USB_Audio_Descriptor_StreamEndpoint_Std_t;
+
+ /** \brief Audio class-specific Streaming Endpoint Descriptor (USB-IF naming conventions).
+ *
+ * Type define for an Audio class-specific endpoint descriptor. This contains a regular endpoint
+ * descriptor with a few Audio-class-specific extensions. See the USB Audio specification for more details.
+ *
+ * \see \ref USB_Audio_Descriptor_StreamEndpoint_Std_t for the version of this type with non-standard LUFA specific
+ * element names.
+ */
+ typedef struct
+ {
+ uint8_t bLength; /**< Size of the descriptor, in bytes. */
+ uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a
+ * value given by the specific class.
+ */
+ uint8_t bEndpointAddress; /**< Logical address of the endpoint within the device for the current
+ * configuration, including direction mask.
+ */
+ uint8_t bmAttributes; /**< Endpoint attributes, comprised of a mask of the endpoint type (EP_TYPE_*)
+ * and attributes (ENDPOINT_ATTR_*) masks.
+ */
+ uint16_t wMaxPacketSize; /**< Size of the endpoint bank, in bytes. This indicates the maximum packet size
+ * that the endpoint can receive at a time.
+ */
+ uint8_t bInterval; /**< Polling interval in milliseconds for the endpoint if it is an INTERRUPT or
+ * ISOCHRONOUS type.
+ */
+
+ uint8_t bRefresh; /**< Always set to zero for Audio class devices. */
+ uint8_t bSynchAddress; /**< Endpoint address to send synchronization information to, if needed (zero otherwise). */
+ } USB_Audio_StdDescriptor_StreamEndpoint_Std_t;
+
+ /** \brief Audio class-specific Extended Endpoint Descriptor (LUFA naming conventions).
+ *
+ * Type define for an Audio class-specific extended endpoint descriptor. This contains extra information
+ * on the usage of endpoints used to stream audio in and out of the USB Audio device, and follows an Audio
+ * class-specific extended endpoint descriptor. See the USB Audio specification for more details.
+ *
+ * \see \ref USB_Audio_StdDescriptor_StreamEndpoint_Spc_t for the version of this type with standard element names.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
+ uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
+ * a value from the \ref Audio_CSEndpoint_SubTypes_t enum.
+ */
+
+ uint8_t Attributes; /**< Audio class-specific endpoint attributes, such as ACCEPTS_SMALL_PACKETS. */
+
+ uint8_t LockDelayUnits; /**< Units used for the LockDelay field, see Audio class specification. */
+ uint16_t LockDelay; /**< Time required to internally lock endpoint's internal clock recovery circuitry. */
+ } USB_Audio_Descriptor_StreamEndpoint_Spc_t;
+
+ /** \brief Audio class-specific Extended Endpoint Descriptor (USB-IF naming conventions).
+ *
+ * Type define for an Audio class-specific extended endpoint descriptor. This contains extra information
+ * on the usage of endpoints used to stream audio in and out of the USB Audio device, and follows an Audio
+ * class-specific extended endpoint descriptor. See the USB Audio specification for more details.
+ *
+ * \see \ref USB_Audio_Descriptor_StreamEndpoint_Spc_t for the version of this type with non-standard LUFA specific
+ * element names.
+ */
+ typedef struct
+ {
+ uint8_t bLength; /**< Size of the descriptor, in bytes. */
+ uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
+ * given by the specific class.
+ */
+
+ uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors,
+ * a value from the \ref Audio_CSEndpoint_SubTypes_t enum.
+ */
+
+ uint8_t bmAttributes; /**< Audio class-specific endpoint attributes, such as ACCEPTS_SMALL_PACKETS. */
+
+ uint8_t bLockDelayUnits; /**< Units used for the LockDelay field, see Audio class specification. */
+ uint16_t wLockDelay; /**< Time required to internally lock endpoint's internal clock recovery circuitry. */
+ } USB_Audio_StdDescriptor_StreamEndpoint_Spc_t;
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Common/CDC.h b/firmware/LUFA/Drivers/USB/Class/Common/CDC.h
new file mode 100644
index 0000000..dabe438
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Common/CDC.h
@@ -0,0 +1,372 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Common definitions and declarations for the library USB CDC Class driver.
+ *
+ * Common definitions and declarations for the library USB CDC 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_USBClassCDC
+ * @defgroup Group_USBClassCDCCommon Common Class Definitions
+ *
+ * \section Module Description
+ * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
+ * CDC Class.
+ *
+ * @{
+ */
+
+#ifndef _CDC_CLASS_COMMON_H_
+#define _CDC_CLASS_COMMON_H_
+
+ /* Includes: */
+ #include "../../HighLevel/StdDescriptors.h"
+
+ #include <string.h>
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_CDC_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ /* Macros: */
+ /** \name Virtual Control Line Masks */
+ //@{
+ /** Mask for the DTR handshake line for use with the \ref CDC_REQ_SetControlLineState class-specific request
+ * from the host, to indicate that the DTR line state should be high.
+ */
+ #define CDC_CONTROL_LINE_OUT_DTR (1 << 0)
+
+ /** Mask for the RTS handshake line for use with the \ref CDC_REQ_SetControlLineState class-specific request
+ * from the host, to indicate that the RTS line state should be high.
+ */
+ #define CDC_CONTROL_LINE_OUT_RTS (1 << 1)
+
+ /** Mask for the DCD handshake line for use with the \ref CDC_NOTIF_SerialState class-specific notification
+ * from the device to the host, to indicate that the DCD line state is currently high.
+ */
+ #define CDC_CONTROL_LINE_IN_DCD (1 << 0)
+
+ /** Mask for the DSR handshake line for use with the \ref CDC_NOTIF_SerialState class-specific notification
+ * from the device to the host, to indicate that the DSR line state is currently high.
+ */
+ #define CDC_CONTROL_LINE_IN_DSR (1 << 1)
+
+ /** Mask for the BREAK handshake line for use with the \ref CDC_NOTIF_SerialState class-specific notification
+ * from the device to the host, to indicate that the BREAK line state is currently high.
+ */
+ #define CDC_CONTROL_LINE_IN_BREAK (1 << 2)
+
+ /** Mask for the RING handshake line for use with the \ref CDC_NOTIF_SerialState class-specific notification
+ * from the device to the host, to indicate that the RING line state is currently high.
+ */
+ #define CDC_CONTROL_LINE_IN_RING (1 << 3)
+
+ /** Mask for use with the \ref CDC_NOTIF_SerialState class-specific notification from the device to the host,
+ * to indicate that a framing error has occurred on the virtual serial port.
+ */
+ #define CDC_CONTROL_LINE_IN_FRAMEERROR (1 << 4)
+
+ /** Mask for use with the \ref CDC_NOTIF_SerialState class-specific notification from the device to the host,
+ * to indicate that a parity error has occurred on the virtual serial port.
+ */
+ #define CDC_CONTROL_LINE_IN_PARITYERROR (1 << 5)
+
+ /** Mask for use with the \ref CDC_NOTIF_SerialState class-specific notification from the device to the host,
+ * to indicate that a data overrun error has occurred on the virtual serial port.
+ */
+ #define CDC_CONTROL_LINE_IN_OVERRUNERROR (1 << 6)
+ //@}
+
+ /** Macro to define a CDC class-specific functional descriptor. CDC functional descriptors have a
+ * uniform structure but variable sized data payloads, thus cannot be represented accurately by
+ * a single typedef struct. A macro is used instead so that functional descriptors can be created
+ * easily by specifying the size of the payload. This allows sizeof() to work correctly.
+ *
+ * \param[in] DataSize Size in bytes of the CDC functional descriptor's data payload.
+ */
+ #define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \
+ struct \
+ { \
+ USB_Descriptor_Header_t Header; \
+ uint8_t SubType; \
+ uint8_t Data[DataSize]; \
+ }
+
+ /* Enums: */
+ /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the CDC
+ * device class.
+ */
+ enum CDC_Descriptor_ClassSubclassProtocol_t
+ {
+ CDC_CSCP_CDCClass = 0x02, /**< Descriptor Class value indicating that the device or interface
+ * belongs to the CDC class.
+ */
+ CDC_CSCP_NoSpecificSubclass = 0x00, /**< Descriptor Subclass value indicating that the device or interface
+ * belongs to no specific subclass of the CDC class.
+ */
+ CDC_CSCP_ACMSubclass = 0x02, /**< Descriptor Subclass value indicating that the device or interface
+ * belongs to the Abstract Control Model CDC subclass.
+ */
+ CDC_CSCP_ATCommandProtocol = 0x01, /**< Descriptor Protocol value indicating that the device or interface
+ * belongs to the AT Command protocol of the CDC class.
+ */
+ CDC_CSCP_NoSpecificProtocol = 0x00, /**< Descriptor Class value indicating that the device or interface
+ * belongs to no specific protocol of the CDC class.
+ */
+ CDC_CSCP_VendorSpecificProtocol = 0xFF, /**< Descriptor Class value indicating that the device or interface
+ * belongs to a vendor-specific protocol of the CDC class.
+ */
+ CDC_CSCP_CDCDataClass = 0x0A, /**< Descriptor Class value indicating that the device or interface
+ * belongs to the CDC Data class.
+ */
+ CDC_CSCP_NoDataSubclass = 0x00, /**< Descriptor Subclass value indicating that the device or interface
+ * belongs to no specific subclass of the CDC data class.
+ */
+ CDC_CSCP_NoDataProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or interface
+ * belongs to no specific protocol of the CDC data class.
+ */
+ };
+
+ /** Enum for the CDC class specific control requests that can be issued by the USB bus host. */
+ enum CDC_ClassRequests_t
+ {
+ CDC_REQ_SendEncapsulatedCommand = 0x00, /**< CDC class-specific request to send an encapsulated command to the device. */
+ CDC_REQ_GetEncapsulatedResponse = 0x01, /**< CDC class-specific request to retrieve an encapsulated command response from the device. */
+ CDC_REQ_SetLineEncoding = 0x20, /**< CDC class-specific request to set the current virtual serial port configuration settings. */
+ CDC_REQ_GetLineEncoding = 0x21, /**< CDC class-specific request to get the current virtual serial port configuration settings. */
+ CDC_REQ_SetControlLineState = 0x22, /**< CDC class-specific request to set the current virtual serial port handshake line states. */
+ CDC_REQ_SendBreak = 0x23, /**< CDC class-specific request to send a break to the receiver via the carrier channel. */
+ };
+
+ /** Enum for the CDC class specific notification requests that can be issued by a CDC device to a host. */
+ enum CDC_ClassNotifications_t
+ {
+ CDC_NOTIF_SerialState = 0x20, /**< Notification type constant for a change in the virtual serial port
+ * handshake line states, for use with a \ref USB_Request_Header_t
+ * notification structure when sent to the host via the CDC notification
+ * endpoint.
+ */
+ };
+
+ /** Enum for the CDC class specific interface descriptor subtypes. */
+ enum CDC_DescriptorSubtypes_t
+ {
+ CDC_DSUBTYPE_CSInterface_Header = 0x00, /**< CDC class-specific Header functional descriptor. */
+ CDC_DSUBTYPE_CSInterface_CallManagement = 0x01, /**< CDC class-specific Call Managment functional descriptor. */
+ CDC_DSUBTYPE_CSInterface_ACM = 0x02, /**< CDC class-specific Abstract Control Model functional descriptor. */
+ CDC_DSUBTYPE_CSInterface_DirectLine = 0x03, /**< CDC class-specific Direct Line functional descriptor. */
+ CDC_DSUBTYPE_CSInterface_TelephoneRinger = 0x04, /**< CDC class-specific Telephone Ringer functional descriptor. */
+ CDC_DSUBTYPE_CSInterface_TelephoneCall = 0x05, /**< CDC class-specific Telephone Call functional descriptor. */
+ CDC_DSUBTYPE_CSInterface_Union = 0x06, /**< CDC class-specific Union functional descriptor. */
+ CDC_DSUBTYPE_CSInterface_CountrySelection = 0x07, /**< CDC class-specific Country Selection functional descriptor. */
+ CDC_DSUBTYPE_CSInterface_TelephoneOpModes = 0x08, /**< CDC class-specific Telephone Operation Modes functional descriptor. */
+ CDC_DSUBTYPE_CSInterface_USBTerminal = 0x09, /**< CDC class-specific USB Terminal functional descriptor. */
+ CDC_DSUBTYPE_CSInterface_NetworkChannel = 0x0A, /**< CDC class-specific Network Channel functional descriptor. */
+ CDC_DSUBTYPE_CSInterface_ProtocolUnit = 0x0B, /**< CDC class-specific Protocol Unit functional descriptor. */
+ CDC_DSUBTYPE_CSInterface_ExtensionUnit = 0x0C, /**< CDC class-specific Extension Unit functional descriptor. */
+ CDC_DSUBTYPE_CSInterface_MultiChannel = 0x0D, /**< CDC class-specific Multi-Channel Management functional descriptor. */
+ CDC_DSUBTYPE_CSInterface_CAPI = 0x0E, /**< CDC class-specific Common ISDN API functional descriptor. */
+ CDC_DSUBTYPE_CSInterface_Ethernet = 0x0F, /**< CDC class-specific Ethernet functional descriptor. */
+ CDC_DSUBTYPE_CSInterface_ATM = 0x10, /**< CDC class-specific Asynchronous Transfer Mode functional descriptor. */
+ };
+
+ /** Enum for the possible line encoding formats of a virtual serial port. */
+ enum CDC_LineEncodingFormats_t
+ {
+ CDC_LINEENCODING_OneStopBit = 0, /**< Each frame contains one stop bit. */
+ CDC_LINEENCODING_OneAndAHalfStopBits = 1, /**< Each frame contains one and a half stop bits. */
+ CDC_LINEENCODING_TwoStopBits = 2, /**< Each frame contains two stop bits. */
+ };
+
+ /** Enum for the possible line encoding parity settings of a virtual serial port. */
+ enum CDC_LineEncodingParity_t
+ {
+ CDC_PARITY_None = 0, /**< No parity bit mode on each frame. */
+ CDC_PARITY_Odd = 1, /**< Odd parity bit mode on each frame. */
+ CDC_PARITY_Even = 2, /**< Even parity bit mode on each frame. */
+ CDC_PARITY_Mark = 3, /**< Mark parity bit mode on each frame. */
+ CDC_PARITY_Space = 4, /**< Space parity bit mode on each frame. */
+ };
+
+ /* Type Defines: */
+ /** \brief CDC class-specific Functional Header Descriptor (LUFA naming conventions).
+ *
+ * Type define for a CDC class-specific functional header descriptor. This indicates to the host that the device
+ * contains one or more CDC functional data descriptors, which give the CDC interface's capabilities and configuration.
+ * See the CDC class specification for more details.
+ *
+ * \see \ref USB_CDC_StdDescriptor_FunctionalHeader_t for the version of this type with standard element names.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
+ uint8_t Subtype; /**< Sub type value used to distinguish between CDC class-specific descriptors,
+ * must be \ref CDC_DSUBTYPE_CSInterface_Header.
+ */
+ uint16_t CDCSpecification; /**< Version number of the CDC specification implemented by the device,
+ * encoded in BCD format.
+ */
+ } USB_CDC_Descriptor_FunctionalHeader_t;
+
+ /** \brief CDC class-specific Functional Header Descriptor (USB-IF naming conventions).
+ *
+ * Type define for a CDC class-specific functional header descriptor. This indicates to the host that the device
+ * contains one or more CDC functional data descriptors, which give the CDC interface's capabilities and configuration.
+ * See the CDC class specification for more details.
+ *
+ * \see \ref USB_CDC_Descriptor_FunctionalHeader_t for the version of this type with non-standard LUFA specific
+ * element names.
+ */
+ typedef struct
+ {
+ uint8_t bFunctionLength; /**< Size of the descriptor, in bytes. */
+ uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
+ * given by the specific class.
+ */
+ uint8_t bDescriptorSubType; /**< Sub type value used to distinguish between CDC class-specific descriptors,
+ * must be \ref CDC_DSUBTYPE_CSInterface_Header.
+ */
+ uint16_t bcdCDC; /**< Version number of the CDC specification implemented by the device, encoded in BCD format. */
+ } USB_CDC_StdDescriptor_FunctionalHeader_t;
+
+ /** \brief CDC class-specific Functional ACM Descriptor (LUFA naming conventions).
+ *
+ * Type define for a CDC class-specific functional ACM descriptor. This indicates to the host that the CDC interface
+ * supports the CDC ACM subclass of the CDC specification. See the CDC class specification for more details.
+ *
+ * \see \ref USB_CDC_StdDescriptor_FunctionalACM_t for the version of this type with standard element names.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
+ uint8_t Subtype; /**< Sub type value used to distinguish between CDC class-specific descriptors,
+ * must be \ref CDC_DSUBTYPE_CSInterface_ACM.
+ */
+ uint8_t Capabilities; /**< Capabilities of the ACM interface, given as a bit mask. For most devices,
+ * this should be set to a fixed value of 0x06 - for other capabiltiies, refer
+ * to the CDC ACM specification.
+ */
+ } USB_CDC_Descriptor_FunctionalACM_t;
+
+ /** \brief CDC class-specific Functional ACM Descriptor (USB-IF naming conventions).
+ *
+ * Type define for a CDC class-specific functional ACM descriptor. This indicates to the host that the CDC interface
+ * supports the CDC ACM subclass of the CDC specification. See the CDC class specification for more details.
+ *
+ * \see \ref USB_CDC_Descriptor_FunctionalACM_t for the version of this type with non-standard LUFA specific
+ * element names.
+ */
+ typedef struct
+ {
+ uint8_t bFunctionLength; /**< Size of the descriptor, in bytes. */
+ uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
+ * given by the specific class.
+ */
+ uint8_t bDescriptorSubType; /**< Sub type value used to distinguish between CDC class-specific descriptors,
+ * must be \ref CDC_DSUBTYPE_CSInterface_ACM.
+ */
+ uint8_t bmCapabilities; /**< Capabilities of the ACM interface, given as a bit mask. For most devices,
+ * this should be set to a fixed value of 0x06 - for other capabiltiies, refer
+ * to the CDC ACM specification.
+ */
+ } USB_CDC_StdDescriptor_FunctionalACM_t;
+
+ /** \brief CDC class-specific Functional Union Descriptor (LUFA naming conventions).
+ *
+ * Type define for a CDC class-specific functional Union descriptor. This indicates to the host that specific
+ * CDC control and data interfaces are related. See the CDC class specification for more details.
+ *
+ * \see \ref USB_CDC_StdDescriptor_FunctionalUnion_t for the version of this type with standard element names.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
+ uint8_t Subtype; /**< Sub type value used to distinguish between CDC class-specific descriptors,
+ * must be \ref CDC_DSUBTYPE_CSInterface_Union.
+ */
+ uint8_t MasterInterfaceNumber; /**< Interface number of the CDC Control interface. */
+ uint8_t SlaveInterfaceNumber; /**< Interface number of the CDC Data interface. */
+ } USB_CDC_Descriptor_FunctionalUnion_t;
+
+ /** \brief CDC class-specific Functional Union Descriptor (USB-IF naming conventions).
+ *
+ * Type define for a CDC class-specific functional Union descriptor. This indicates to the host that specific
+ * CDC control and data interfaces are related. See the CDC class specification for more details.
+ *
+ * \see \ref USB_CDC_Descriptor_FunctionalUnion_t for the version of this type with non-standard LUFA specific
+ * element names.
+ */
+ typedef struct
+ {
+ uint8_t bFunctionLength; /**< Size of the descriptor, in bytes. */
+ uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
+ * given by the specific class.
+ */
+ uint8_t bDescriptorSubType; /**< Sub type value used to distinguish between CDC class-specific descriptors,
+ * must be \ref CDC_DSUBTYPE_CSInterface_Union.
+ */
+ uint8_t bMasterInterface; /**< Interface number of the CDC Control interface. */
+ uint8_t bSlaveInterface0; /**< Interface number of the CDC Data interface. */
+ } USB_CDC_StdDescriptor_FunctionalUnion_t;
+
+ /** Type define for a CDC Line Encoding structure, used to hold the various encoding parameters for a virtual
+ * serial port.
+ */
+ typedef struct
+ {
+ uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second. */
+ uint8_t CharFormat; /**< Character format of the virtual serial port, a value from the
+ * \ref CDC_LineEncodingFormats_t enum.
+ */
+ uint8_t ParityType; /**< Parity setting of the virtual serial port, a value from the
+ * \ref CDC_LineEncodingParity_t enum.
+ */
+ uint8_t DataBits; /**< Bits of data per character of the virtual serial port. */
+ } CDC_LineEncoding_t;
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Common/HID.h b/firmware/LUFA/Drivers/USB/Class/Common/HID.h
new file mode 100644
index 0000000..ca2212e
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Common/HID.h
@@ -0,0 +1,451 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Common definitions and declarations for the library USB HID Class driver.
+ *
+ * Common definitions and declarations for the library USB HID 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_USBClassHID
+ * @defgroup Group_USBClassHIDCommon Common Class Definitions
+ *
+ * \section Module Description
+ * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
+ * HID Class.
+ *
+ * @{
+ */
+
+#ifndef _HID_CLASS_COMMON_H_
+#define _HID_CLASS_COMMON_H_
+
+ /* Includes: */
+ #include "../../HighLevel/StdDescriptors.h"
+
+ #include <string.h>
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_HID_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ /* Macros: */
+ /** \name Keyboard Standard Report Modifier Masks */
+ //@{
+ /** Constant for a keyboard report modifier byte, indicating that the keyboard's left control key is currently pressed. */
+ #define HID_KEYBOARD_MODIFER_LEFTCTRL (1 << 0)
+
+ /** Constant for a keyboard report modifier byte, indicating that the keyboard's left shift key is currently pressed. */
+ #define HID_KEYBOARD_MODIFER_LEFTSHIFT (1 << 1)
+
+ /** Constant for a keyboard report modifier byte, indicating that the keyboard's left alt key is currently pressed. */
+ #define HID_KEYBOARD_MODIFER_LEFTALT (1 << 2)
+
+ /** Constant for a keyboard report modifier byte, indicating that the keyboard's left GUI key is currently pressed. */
+ #define HID_KEYBOARD_MODIFER_LEFTGUI (1 << 3)
+
+ /** Constant for a keyboard report modifier byte, indicating that the keyboard's right control key is currently pressed. */
+ #define HID_KEYBOARD_MODIFER_RIGHTCTRL (1 << 4)
+
+ /** Constant for a keyboard report modifier byte, indicating that the keyboard's right shift key is currently pressed. */
+ #define HID_KEYBOARD_MODIFER_RIGHTSHIFT (1 << 5)
+
+ /** Constant for a keyboard report modifier byte, indicating that the keyboard's right alt key is currently pressed. */
+ #define HID_KEYBOARD_MODIFER_RIGHTALT (1 << 6)
+
+ /** Constant for a keyboard report modifier byte, indicating that the keyboard's right GUI key is currently pressed. */
+ #define HID_KEYBOARD_MODIFER_RIGHTGUI (1 << 7)
+ //@}
+
+ /** \name Keyboard Standard Report LED Masks */
+ //@{
+ /** Constant for a keyboard output report LED byte, indicating that the host's NUM LOCK mode is currently set. */
+ #define HID_KEYBOARD_LED_NUMLOCK (1 << 0)
+
+ /** Constant for a keyboard output report LED byte, indicating that the host's CAPS LOCK mode is currently set. */
+ #define HID_KEYBOARD_LED_CAPSLOCK (1 << 1)
+
+ /** Constant for a keyboard output report LED byte, indicating that the host's SCROLL LOCK mode is currently set. */
+ #define HID_KEYBOARD_LED_SCROLLLOCK (1 << 2)
+
+ /** Constant for a keyboard output report LED byte, indicating that the host's KATANA mode is currently set. */
+ #define HID_KEYBOARD_LED_KATANA (1 << 3)
+ //@}
+
+ /** \name Keyboard Standard Report Key Scancodes */
+ //@{
+ #define HID_KEYBOARD_SC_ERROR_ROLLOVER 0x01
+ #define HID_KEYBOARD_SC_POST_FAIL 0x02
+ #define HID_KEYBOARD_SC_ERROR_UNDEFINED 0x03
+ #define HID_KEYBOARD_SC_A 0x04
+ #define HID_KEYBOARD_SC_B 0x05
+ #define HID_KEYBOARD_SC_C 0x06
+ #define HID_KEYBOARD_SC_D 0x04
+ #define HID_KEYBOARD_SC_E 0x08
+ #define HID_KEYBOARD_SC_F 0x09
+ #define HID_KEYBOARD_SC_G 0x0A
+ #define HID_KEYBOARD_SC_H 0x0B
+ #define HID_KEYBOARD_SC_I 0x0C
+ #define HID_KEYBOARD_SC_J 0x0D
+ #define HID_KEYBOARD_SC_K 0x0E
+ #define HID_KEYBOARD_SC_L 0x0F
+ #define HID_KEYBOARD_SC_M 0x10
+ #define HID_KEYBOARD_SC_N 0x11
+ #define HID_KEYBOARD_SC_O 0x12
+ #define HID_KEYBOARD_SC_P 0x13
+ #define HID_KEYBOARD_SC_Q 0x14
+ #define HID_KEYBOARD_SC_R 0x15
+ #define HID_KEYBOARD_SC_S 0x16
+ #define HID_KEYBOARD_SC_T 0x17
+ #define HID_KEYBOARD_SC_U 0x18
+ #define HID_KEYBOARD_SC_V 0x19
+ #define HID_KEYBOARD_SC_W 0x1A
+ #define HID_KEYBOARD_SC_X 0x1B
+ #define HID_KEYBOARD_SC_Y 0x1C
+ #define HID_KEYBOARD_SC_Z 0x1D
+ #define HID_KEYBOARD_SC_1_AND_EXCLAMATION 0x1E
+ #define HID_KEYBOARD_SC_2_AND_AT 0x1F
+ #define HID_KEYBOARD_SC_3_AND_HASHMARK 0x20
+ #define HID_KEYBOARD_SC_4_AND_DOLLAR 0x21
+ #define HID_KEYBOARD_SC_5_AND_PERCENTAGE 0x22
+ #define HID_KEYBOARD_SC_6_AND_CARET 0x23
+ #define HID_KEYBOARD_SC_7_AND_AND_AMPERSAND 0x24
+ #define HID_KEYBOARD_SC_8_AND_ASTERISK 0x25
+ #define HID_KEYBOARD_SC_9_AND_OPENING_PARENTHESIS 0x26
+ #define HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS 0x27
+ #define HID_KEYBOARD_SC_ENTER 0x28
+ #define HID_KEYBOARD_SC_ESCAPE 0x29
+ #define HID_KEYBOARD_SC_BACKSPACE 0x2A
+ #define HID_KEYBOARD_SC_TAB 0x2B
+ #define HID_KEYBOARD_SC_SPACE 0x2C
+ #define HID_KEYBOARD_SC_MINUS_AND_UNDERSCORE 0x2D
+ #define HID_KEYBOARD_SC_EQUAL_AND_PLUS 0x2E
+ #define HID_KEYBOARD_SC_OPENING_BRACKET_AND_OPENING_BRACE 0x2F
+ #define HID_KEYBOARD_SC_CLOSING_BRACKET_AND_CLOSING_BRACE 0x30
+ #define HID_KEYBOARD_SC_BACKSLASH_AND_PIPE 0x31
+ #define HID_KEYBOARD_SC_NON_US_HASHMARK_AND_TILDE 0x32
+ #define HID_KEYBOARD_SC_SEMICOLON_AND_COLON 0x33
+ #define HID_KEYBOARD_SC_APOSTROPHE_AND_QUOTE 0x34
+ #define HID_KEYBOARD_SC_GRAVE_ACCENT_AND_TILDE 0x35
+ #define HID_KEYBOARD_SC_COMMA_AND_LESS_THAN_SIGN 0x36
+ #define HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN 0x37
+ #define HID_KEYBOARD_SC_SLASH_AND_QUESTION_MARK 0x38
+ #define HID_KEYBOARD_SC_CAPS_LOCK 0x39
+ #define HID_KEYBOARD_SC_F1 0x3A
+ #define HID_KEYBOARD_SC_F2 0x3B
+ #define HID_KEYBOARD_SC_F3 0x3C
+ #define HID_KEYBOARD_SC_F4 0x3D
+ #define HID_KEYBOARD_SC_F5 0x3E
+ #define HID_KEYBOARD_SC_F6 0x3F
+ #define HID_KEYBOARD_SC_F7 0x40
+ #define HID_KEYBOARD_SC_F8 0x41
+ #define HID_KEYBOARD_SC_F9 0x42
+ #define HID_KEYBOARD_SC_F10 0x43
+ #define HID_KEYBOARD_SC_F11 0x44
+ #define HID_KEYBOARD_SC_F12 0x45
+ #define HID_KEYBOARD_SC_PRINT_SCREEN 0x46
+ #define HID_KEYBOARD_SC_SCROLL_LOCK 0x47
+ #define HID_KEYBOARD_SC_PAUSE 0x48
+ #define HID_KEYBOARD_SC_INSERT 0x49
+ #define HID_KEYBOARD_SC_HOME 0x4A
+ #define HID_KEYBOARD_SC_PAGE_UP 0x4B
+ #define HID_KEYBOARD_SC_DELETE 0x4C
+ #define HID_KEYBOARD_SC_END 0x4D
+ #define HID_KEYBOARD_SC_PAGE_DOWN 0x4E
+ #define HID_KEYBOARD_SC_RIGHT_ARROW 0xEF
+ #define HID_KEYBOARD_SC_LEFT_ARROW 0x50
+ #define HID_KEYBOARD_SC_DOWN_ARROW 0x51
+ #define HID_KEYBOARD_SC_UP_ARROW 0x52
+ #define HID_KEYBOARD_SC_NUM_LOCK 0x53
+ #define HID_KEYBOARD_SC_KEYPAD_SLASH 0x54
+ #define HID_KEYBOARD_SC_KEYPAD_ASTERISK 0x55
+ #define HID_KEYBOARD_SC_KEYPAD_MINUS 0x56
+ #define HID_KEYBOARD_SC_KEYPAD_PLUS 0x57
+ #define HID_KEYBOARD_SC_KEYPAD_ENTER 0x58
+ #define HID_KEYBOARD_SC_KEYPAD_1_AND_END 0x59
+ #define HID_KEYBOARD_SC_KEYPAD_2_AND_DOWN_ARROW 0x5A
+ #define HID_KEYBOARD_SC_KEYPAD_3_AND_PAGE_DOWN 0x5B
+ #define HID_KEYBOARD_SC_KEYPAD_4_AND_LEFT_ARROW 0x5C
+ #define HID_KEYBOARD_SC_KEYPAD_5 0x5D
+ #define HID_KEYBOARD_SC_KEYPAD_6_AND_RIGHT_ARROW 0x5E
+ #define HID_KEYBOARD_SC_KEYPAD_7_AND_HOME 0x5F
+ #define HID_KEYBOARD_SC_KEYPAD_8_AND_UP_ARROW 0x60
+ #define HID_KEYBOARD_SC_KEYPAD_9_AND_PAGE_UP 0x61
+ #define HID_KEYBOARD_SC_KEYPAD_0_AND_INSERT 0x62
+ #define HID_KEYBOARD_SC_KEYPAD_DOT_AND_DELETE 0x63
+ #define HID_KEYBOARD_SC_NON_US_BACKSLASH_AND_PIPE 0x64
+ #define HID_KEYBOARD_SC_EQUAL_SIGN 0x67
+ #define HID_KEYBOARD_SC_F13 0x68
+ #define HID_KEYBOARD_SC_F14 0x69
+ #define HID_KEYBOARD_SC_F15 0x6A
+ #define HID_KEYBOARD_SC_F16 0x6B
+ #define HID_KEYBOARD_SC_F17 0x6C
+ #define HID_KEYBOARD_SC_F18 0x6D
+ #define HID_KEYBOARD_SC_F19 0x6E
+ #define HID_KEYBOARD_SC_F20 0x6F
+ #define HID_KEYBOARD_SC_F21 0x70
+ #define HID_KEYBOARD_SC_F22 0x71
+ #define HID_KEYBOARD_SC_F23 0x72
+ #define HID_KEYBOARD_SC_F24 0x73
+ #define HID_KEYBOARD_SC_EXECUTE 0x74
+ #define HID_KEYBOARD_SC_HELP 0x75
+ #define HID_KEYBOARD_SC_MANU 0x76
+ #define HID_KEYBOARD_SC_SELECT 0x77
+ #define HID_KEYBOARD_SC_STOP 0x78
+ #define HID_KEYBOARD_SC_AGAIN 0x79
+ #define HID_KEYBOARD_SC_UNDO 0x7A
+ #define HID_KEYBOARD_SC_CUT 0x7B
+ #define HID_KEYBOARD_SC_COPY 0x7C
+ #define HID_KEYBOARD_SC_PASTE 0x7D
+ #define HID_KEYBOARD_SC_FIND 0x7E
+ #define HID_KEYBOARD_SC_MUTE 0x7F
+ #define HID_KEYBOARD_SC_VOLUME_UP 0x80
+ #define HID_KEYBOARD_SC_VOLUME_DOWN 0x81
+ #define HID_KEYBOARD_SC_LOCKING_CAPS_LOCK 0x82
+ #define HID_KEYBOARD_SC_LOCKING_NUM_LOCK 0x83
+ #define HID_KEYBOARD_SC_LOCKING_SCROLL_LOCK 0x84
+ #define HID_KEYBOARD_SC_KEYPAD_COMMA 0x85
+ #define HID_KEYBOARD_SC_KEYPAD_EQUAL_SIGN 0x86
+ #define HID_KEYBOARD_SC_INTERNATIONAL1 0x87
+ #define HID_KEYBOARD_SC_INTERNATIONAL2 0x88
+ #define HID_KEYBOARD_SC_INTERNATIONAL3 0x8A
+ #define HID_KEYBOARD_SC_INTERNATIONAL5 0x8B
+ #define HID_KEYBOARD_SC_INTERNATIONAL6 0x8C
+ #define HID_KEYBOARD_SC_INTERNATIONAL7 0x8D
+ #define HID_KEYBOARD_SC_INTERNATIONAL8 0x8E
+ #define HID_KEYBOARD_SC_INTERNATIONAL9 0x8F
+ #define HID_KEYBOARD_SC_LANG1 0x90
+ #define HID_KEYBOARD_SC_LANG2 0x91
+ #define HID_KEYBOARD_SC_LANG3 0x92
+ #define HID_KEYBOARD_SC_LANG4 0x93
+ #define HID_KEYBOARD_SC_LANG5 0x94
+ #define HID_KEYBOARD_SC_LANG6 0x95
+ #define HID_KEYBOARD_SC_LANG7 0x96
+ #define HID_KEYBOARD_SC_LANG8 0x97
+ #define HID_KEYBOARD_SC_LANG9 0x98
+ #define HID_KEYBOARD_SC_ALTERNATE_ERASE 0x99
+ #define HID_KEYBOARD_SC_SISREQ 0x9A
+ #define HID_KEYBOARD_SC_CANCEL 0x9B
+ #define HID_KEYBOARD_SC_CLEAR 0x9C
+ #define HID_KEYBOARD_SC_PRIOR 0x9D
+ #define HID_KEYBOARD_SC_RETURN 0x9E
+ #define HID_KEYBOARD_SC_SEPARATOR 0x9F
+ #define HID_KEYBOARD_SC_OUT 0xA0
+ #define HID_KEYBOARD_SC_OPER 0xA1
+ #define HID_KEYBOARD_SC_CLEAR_AND_AGAIN 0xA2
+ #define HID_KEYBOARD_SC_CRSEL_ANDPROPS 0xA3
+ #define HID_KEYBOARD_SC_EXSEL 0xA4
+ #define HID_KEYBOARD_SC_KEYPAD_00 0xB0
+ #define HID_KEYBOARD_SC_KEYPAD_000 0xB1
+ #define HID_KEYBOARD_SC_THOUSANDS_SEPARATOR 0xB2
+ #define HID_KEYBOARD_SC_DECIMAL_SEPARATOR 0xB3
+ #define HID_KEYBOARD_SC_CURRENCY_UNIT 0xB4
+ #define HID_KEYBOARD_SC_CURRENCY_SUB_UNIT 0xB5
+ #define HID_KEYBOARD_SC_KEYPAD_OPENING_PARENTHESIS 0xB6
+ #define HID_KEYBOARD_SC_KEYPAD_CLOSING_PARENTHESIS 0xB7
+ #define HID_KEYBOARD_SC_KEYPAD_OPENING_BRACE 0xB8
+ #define HID_KEYBOARD_SC_KEYPAD_CLOSING_BRACE 0xB9
+ #define HID_KEYBOARD_SC_KEYPAD_TAB 0xBA
+ #define HID_KEYBOARD_SC_KEYPAD_BACKSPACE 0xBB
+ #define HID_KEYBOARD_SC_KEYPAD_A 0xBC
+ #define HID_KEYBOARD_SC_KEYPAD_B 0xBD
+ #define HID_KEYBOARD_SC_KEYPAD_C 0xBE
+ #define HID_KEYBOARD_SC_KEYPAD_D 0xBF
+ #define HID_KEYBOARD_SC_KEYPAD_E 0xC0
+ #define HID_KEYBOARD_SC_KEYPAD_F 0xC1
+ #define HID_KEYBOARD_SC_KEYPAD_XOR 0xC2
+ #define HID_KEYBOARD_SC_KEYPAD_CARET 0xC3
+ #define HID_KEYBOARD_SC_KEYPAD_PERCENTAGE 0xC4
+ #define HID_KEYBOARD_SC_KEYPAD_LESS_THAN_SIGN 0xC5
+ #define HID_KEYBOARD_SC_KEYPAD_GREATER_THAN_SIGN 0xC6
+ #define HID_KEYBOARD_SC_KEYPAD_AMP 0xC7
+ #define HID_KEYBOARD_SC_KEYPAD_AMP_AMP 0xC8
+ #define HID_KEYBOARD_SC_KEYPAD_PIPE 0xC9
+ #define HID_KEYBOARD_SC_KEYPAD_PIPE_PIPE 0xCA
+ #define HID_KEYBOARD_SC_KEYPAD_COLON 0xCB
+ #define HID_KEYBOARD_SC_KEYPAD_HASHMARK 0xCC
+ #define HID_KEYBOARD_SC_KEYPAD_SPACE 0xCD
+ #define HID_KEYBOARD_SC_KEYPAD_AT 0xCE
+ #define HID_KEYBOARD_SC_KEYPAD_EXCLAMATION_SIGN 0xCF
+ #define HID_KEYBOARD_SC_KEYPAD_MEMORY_STORE 0xD0
+ #define HID_KEYBOARD_SC_KEYPAD_MEMORY_RECALL 0xD1
+ #define HID_KEYBOARD_SC_KEYPAD_MEMORY_CLEAR 0xD2
+ #define HID_KEYBOARD_SC_KEYPAD_MEMORY_ADD 0xD3
+ #define HID_KEYBOARD_SC_KEYPAD_MEMORY_SUBTRACT 0xD4
+ #define HID_KEYBOARD_SC_KEYPAD_MEMORY_MULTIPLY 0xD5
+ #define HID_KEYBOARD_SC_KEYPAD_MEMORY_DIVIDE 0xD6
+ #define HID_KEYBOARD_SC_KEYPAD_PLUS_AND_MINUS 0xD7
+ #define HID_KEYBOARD_SC_KEYPAD_CLEAR 0xD8
+ #define HID_KEYBOARD_SC_KEYPAD_CLEAR_ENTRY 0xD9
+ #define HID_KEYBOARD_SC_KEYPAD_BINARY 0xDA
+ #define HID_KEYBOARD_SC_KEYPAD_OCTAL 0xDB
+ #define HID_KEYBOARD_SC_KEYPAD_DECIMAL 0xDC
+ #define HID_KEYBOARD_SC_KEYPAD_HEXADECIMAL 0xDD
+ #define HID_KEYBOARD_SC_LEFT_CONTROL 0xE0
+ #define HID_KEYBOARD_SC_LEFT_SHIFT 0xE1
+ #define HID_KEYBOARD_SC_LEFT_ALT 0xE2
+ #define HID_KEYBOARD_SC_LEFT_GUI 0xE3
+ #define HID_KEYBOARD_SC_RIGHT_CONTROL 0xE4
+ #define HID_KEYBOARD_SC_RIGHT_SHIFT 0xE5
+ #define HID_KEYBOARD_SC_RIGHT_ALT 0xE6
+ #define HID_KEYBOARD_SC_RIGHT_GUI 0xE7
+ //@}
+
+ /* Type Defines: */
+ /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the HID
+ * device class.
+ */
+ enum HID_Descriptor_ClassSubclassProtocol_t
+ {
+ HID_CSCP_HIDClass = 0x03, /**< Descriptor Class value indicating that the device or interface
+ * belongs to the HID class.
+ */
+ HID_CSCP_NonBootSubclass = 0x00, /**< Descriptor Subclass value indicating that the device or interface
+ * does not implement a HID boot protocol.
+ */
+ HID_CSCP_BootSubclass = 0x01, /**< Descriptor Subclass value indicating that the device or interface
+ * implements a HID boot protocol.
+ */
+ HID_CSCP_NonBootProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or interface
+ * does not belong to a HID boot protocol.
+ */
+ HID_CSCP_KeyboardBootProtocol = 0x01, /**< Descriptor Protocol value indicating that the device or interface
+ * belongs to the Keyboard HID boot protocol.
+ */
+ HID_CSCP_MouseBootProtocol = 0x02, /**< Descriptor Protocol value indicating that the device or interface
+ * belongs to the Mouse HID boot protocol.
+ */
+ };
+
+ /** Enum for the HID class specific control requests that can be issued by the USB bus host. */
+ enum HID_ClassRequests_t
+ {
+ HID_REQ_GetReport = 0x01, /**< HID class-specific Request to get the current HID report from the device. */
+ HID_REQ_GetIdle = 0x02, /**< HID class-specific Request to get the current device idle count. */
+ HID_REQ_GetProtocol = 0x03, /**< HID class-specific Request to get the current HID report protocol mode. */
+ HID_REQ_SetReport = 0x09, /**< HID class-specific Request to set the current HID report to the device. */
+ HID_REQ_SetIdle = 0x0A, /**< HID class-specific Request to set the device's idle count. */
+ HID_REQ_SetProtocol = 0x0B, /**< HID class-specific Request to set the current HID report protocol mode. */
+ };
+
+ /** Enum for the HID class specific descriptor types. */
+ enum HID_DescriptorTypes_t
+ {
+ HID_DTYPE_HID = 0x21, /**< Descriptor header type value, to indicate a HID class HID descriptor. */
+ HID_DTYPE_Report = 0x22, /**< Descriptor header type value, to indicate a HID class HID report descriptor. */
+ };
+
+ /** Enum for the different types of HID reports. */
+ enum HID_ReportItemTypes_t
+ {
+ HID_REPORT_ITEM_In = 0, /**< Indicates that the item is an IN report type. */
+ HID_REPORT_ITEM_Out = 1, /**< Indicates that the item is an OUT report type. */
+ HID_REPORT_ITEM_Feature = 2, /**< Indicates that the item is a FEATURE report type. */
+ };
+
+ /** \brief HID class-specific HID Descriptor (LUFA naming conventions).
+ *
+ * Type define for the HID class-specific HID descriptor, to describe the HID device's specifications. Refer to the HID
+ * specification for details on the structure elements.
+ *
+ * \see \ref USB_HID_StdDescriptor_HID_t for the version of this type with standard element names.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
+
+ uint16_t HIDSpec; /**< BCD encoded version that the HID descriptor and device complies to. */
+ uint8_t CountryCode; /**< Country code of the localized device, or zero if universal. */
+
+ uint8_t TotalReportDescriptors; /**< Total number of HID report descriptors for the interface. */
+
+ uint8_t HIDReportType; /**< Type of HID report, set to \ref HID_DTYPE_Report. */
+ uint16_t HIDReportLength; /**< Length of the associated HID report descriptor, in bytes. */
+ } USB_HID_Descriptor_HID_t;
+
+ /** \brief HID class-specific HID Descriptor (USB-IF naming conventions).
+ *
+ * Type define for the HID class-specific HID descriptor, to describe the HID device's specifications. Refer to the HID
+ * specification for details on the structure elements.
+ *
+ * \see \ref USB_HID_Descriptor_HID_t for the version of this type with non-standard LUFA specific
+ * element names.
+ */
+ typedef struct
+ {
+ uint8_t bLength; /**< Size of the descriptor, in bytes. */
+ uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
+ * given by the specific class.
+ */
+
+ uint16_t bcdHID; /**< BCD encoded version that the HID descriptor and device complies to. */
+ uint8_t bCountryCode; /**< Country code of the localized device, or zero if universal. */
+
+ uint8_t bNumDescriptors; /**< Total number of HID report descriptors for the interface. */
+
+ uint8_t bDescriptorType2; /**< Type of HID report, set to \ref HID_DTYPE_Report. */
+ uint16_t wDescriptorLength; /**< Length of the associated HID report descriptor, in bytes. */
+ } USB_HID_StdDescriptor_HID_t;
+
+ /** \brief Standard HID Boot Protocol Mouse Report.
+ *
+ * Type define for a standard Boot Protocol Mouse report
+ */
+ typedef struct
+ {
+ uint8_t Button; /**< Button mask for currently pressed buttons in the mouse. */
+ int8_t X; /**< Current delta X movement of the mouse. */
+ int8_t Y; /**< Current delta Y movement on the mouse. */
+ } USB_MouseReport_Data_t;
+
+ /** \brief Standard HID Boot Protocol Keyboard Report.
+ *
+ * Type define for a standard Boot Protocol Keyboard report
+ */
+ typedef struct
+ {
+ uint8_t Modifier; /**< Keyboard modifier byte, indicating pressed modifier keys (a combination of
+ * HID_KEYBOARD_MODIFER_* masks).
+ */
+ uint8_t Reserved; /**< Reserved for OEM use, always set to 0. */
+ uint8_t KeyCode[6]; /**< Key codes of the currently pressed keys. */
+ } USB_KeyboardReport_Data_t;
+
+ /** Type define for the data type used to store HID report descriptor elements. */
+ typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Common/MIDI.h b/firmware/LUFA/Drivers/USB/Class/Common/MIDI.h
new file mode 100644
index 0000000..4a3be81
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Common/MIDI.h
@@ -0,0 +1,293 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Common definitions and declarations for the library USB MIDI Class driver.
+ *
+ * Common definitions and declarations for the library USB MIDI 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_USBClassMIDI
+ * @defgroup Group_USBClassMIDICommon Common Class Definitions
+ *
+ * \section Module Description
+ * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
+ * MIDI Class.
+ *
+ * @{
+ */
+
+#ifndef _MIDI_CLASS_COMMON_H_
+#define _MIDI_CLASS_COMMON_H_
+
+ /* Macros: */
+ #define __INCLUDE_FROM_AUDIO_DRIVER
+
+ /* Includes: */
+ #include "../../HighLevel/StdDescriptors.h"
+ #include "Audio.h"
+
+ #include <string.h>
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_MIDI_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ /* Macros: */
+ /** \name MIDI Command Values */
+ //@{
+ /** MIDI command for a note on (activation) event. */
+ #define MIDI_COMMAND_NOTE_ON 0x90
+
+ /** MIDI command for a note off (deactivation) event. */
+ #define MIDI_COMMAND_NOTE_OFF 0x80
+ //@}
+
+ /** Standard key press velocity value used for all note events. */
+ #define MIDI_STANDARD_VELOCITY 64
+
+ /** Convenience macro. MIDI channels are numbered from 1-10 (natural numbers) however the logical channel
+ * addresses are zero-indexed. This converts a natural MIDI channel number into the logical channel address.
+ *
+ * \param[in] channel MIDI channel number to address.
+ */
+ #define MIDI_CHANNEL(channel) ((channel) - 1)
+
+ /* Enums: */
+ /** Enum for the possible MIDI jack types in a MIDI device jack descriptor. */
+ enum MIDI_JackTypes_t
+ {
+ MIDI_JACKTYPE_Embedded = 0x01, /**< MIDI class descriptor jack type value for an embedded (logical) MIDI input or output jack. */
+ MIDI_JACKTYPE_External = 0x02, /**< MIDI class descriptor jack type value for an external (physical) MIDI input or output jack. */
+ };
+
+ /* Type Defines: */
+ /** \brief MIDI class-specific Streaming Interface Descriptor (LUFA naming conventions).
+ *
+ * Type define for an Audio class-specific MIDI streaming interface descriptor. This indicates to the host
+ * how MIDI the specification compliance of the device and the total length of the Audio class-specific descriptors.
+ * See the USB Audio specification for more details.
+ *
+ * \see \ref USB_MIDI_StdDescriptor_AudioInterface_AS_t for the version of this type with standard element names.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
+ uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */
+
+ uint16_t AudioSpecification; /**< Binary coded decimal value, indicating the supported Audio Class
+ * specification version.
+ */
+ uint16_t TotalLength; /**< Total length of the Audio class-specific descriptors, including this descriptor. */
+ } USB_MIDI_Descriptor_AudioInterface_AS_t;
+
+ /** \brief MIDI class-specific Streaming Interface Descriptor (USB-IF naming conventions).
+ *
+ * Type define for an Audio class-specific MIDI streaming interface descriptor. This indicates to the host
+ * how MIDI the specification compliance of the device and the total length of the Audio class-specific descriptors.
+ * See the USB Audio specification for more details.
+ *
+ * \see \ref USB_MIDI_Descriptor_AudioInterface_AS_t for the version of this type with non-standard LUFA specific
+ * element names.
+ */
+ typedef struct
+ {
+ uint8_t bLength; /**< Size of the descriptor, in bytes. */
+ uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
+ * given by the specific class.
+ */
+
+ uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */
+
+ uint16_t bcdMSC; /**< Binary coded decimal value, indicating the supported MIDI Class specification version. */
+ uint16_t wTotalLength; /**< Total length of the Audio class-specific descriptors, including this descriptor. */
+ } USB_MIDI_StdDescriptor_AudioInterface_AS_t;
+
+ /** \brief MIDI class-specific Input Jack Descriptor (LUFA naming conventions).
+ *
+ * Type define for an Audio class-specific MIDI IN jack. This gives information to the host on a MIDI input, either
+ * a physical input jack, or a logical jack (receiving input data internally, or from the host via an endpoint).
+ *
+ * \see \ref USB_MIDI_StdDescriptor_InputJack_t for the version of this type with standard element names.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
+ uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */
+
+ uint8_t JackType; /**< Type of jack, one of the JACKTYPE_* mask values. */
+ uint8_t JackID; /**< ID value of this jack - must be a unique value within the device. */
+
+ uint8_t JackStrIndex; /**< Index of a string descriptor describing this descriptor within the device. */
+ } USB_MIDI_Descriptor_InputJack_t;
+
+ /** \brief MIDI class-specific Input Jack Descriptor (USB-IF naming conventions).
+ *
+ * Type define for an Audio class-specific MIDI IN jack. This gives information to the host on a MIDI input, either
+ * a physical input jack, or a logical jack (receiving input data internally, or from the host via an endpoint).
+ *
+ * \see \ref USB_MIDI_Descriptor_InputJack_t for the version of this type with non-standard LUFA specific
+ * element names.
+ */
+ typedef struct
+ {
+ uint8_t bLength; /**< Size of the descriptor, in bytes. */
+ uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
+ * given by the specific class.
+ */
+
+ uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */
+
+ uint8_t bJackType; /**< Type of jack, one of the JACKTYPE_* mask values. */
+ uint8_t bJackID; /**< ID value of this jack - must be a unique value within the device. */
+
+ uint8_t iJack; /**< Index of a string descriptor describing this descriptor within the device. */
+ } USB_MIDI_StdDescriptor_InputJack_t;
+
+ /** \brief MIDI class-specific Output Jack Descriptor (LUFA naming conventions).
+ *
+ * Type define for an Audio class-specific MIDI OUT jack. This gives information to the host on a MIDI output, either
+ * a physical output jack, or a logical jack (sending output data internally, or to the host via an endpoint).
+ *
+ * \see \ref USB_MIDI_StdDescriptor_OutputJack_t for the version of this type with standard element names.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
+ uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */
+
+ uint8_t JackType; /**< Type of jack, one of the JACKTYPE_* mask values. */
+ uint8_t JackID; /**< ID value of this jack - must be a unique value within the device. */
+
+ uint8_t NumberOfPins; /**< Number of output channels within the jack, either physical or logical. */
+ uint8_t SourceJackID[1]; /**< ID of each output pin's source data jack. */
+ uint8_t SourcePinID[1]; /**< Pin number in the input jack of each output pin's source data. */
+
+ uint8_t JackStrIndex; /**< Index of a string descriptor describing this descriptor within the device. */
+ } USB_MIDI_Descriptor_OutputJack_t;
+
+ /** \brief MIDI class-specific Output Jack Descriptor (USB-IF naming conventions).
+ *
+ * Type define for an Audio class-specific MIDI OUT jack. This gives information to the host on a MIDI output, either
+ * a physical output jack, or a logical jack (sending output data internally, or to the host via an endpoint).
+ *
+ * \see \ref USB_MIDI_Descriptor_OutputJack_t for the version of this type with non-standard LUFA specific
+ * element names.
+ */
+ typedef struct
+ {
+ uint8_t bLength; /**< Size of the descriptor, in bytes. */
+ uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
+ * given by the specific class.
+ */
+
+ uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */
+
+ uint8_t bJackType; /**< Type of jack, one of the JACKTYPE_* mask values. */
+ uint8_t bJackID; /**< ID value of this jack - must be a unique value within the device. */
+
+ uint8_t bNrInputPins; /**< Number of output channels within the jack, either physical or logical. */
+ uint8_t baSourceID[1]; /**< ID of each output pin's source data jack. */
+ uint8_t baSourcePin[1]; /**< Pin number in the input jack of each output pin's source data. */
+
+ uint8_t iJack; /**< Index of a string descriptor describing this descriptor within the device. */
+ } USB_MIDI_StdDescriptor_OutputJack_t;
+
+ /** \brief Audio class-specific Jack Endpoint Descriptor (LUFA naming conventions).
+ *
+ * Type define for an Audio class-specific extended MIDI jack endpoint descriptor. This contains extra information
+ * on the usage of MIDI endpoints used to stream MIDI events in and out of the USB Audio device, and follows an Audio
+ * class-specific extended MIDI endpoint descriptor. See the USB Audio specification for more details.
+ *
+ * \see \ref USB_MIDI_StdDescriptor_Jack_Endpoint_t for the version of this type with standard element names.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */
+ uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */
+
+ uint8_t TotalEmbeddedJacks; /**< Total number of jacks inside this endpoint. */
+ uint8_t AssociatedJackID[1]; /**< IDs of each jack inside the endpoint. */
+ } USB_MIDI_Descriptor_Jack_Endpoint_t;
+
+ /** \brief Audio class-specific Jack Endpoint Descriptor (USB-IF naming conventions).
+ *
+ * Type define for an Audio class-specific extended MIDI jack endpoint descriptor. This contains extra information
+ * on the usage of MIDI endpoints used to stream MIDI events in and out of the USB Audio device, and follows an Audio
+ * class-specific extended MIDI endpoint descriptor. See the USB Audio specification for more details.
+ *
+ * \see \ref USB_MIDI_Descriptor_Jack_Endpoint_t for the version of this type with non-standard LUFA specific
+ * element names.
+ */
+ typedef struct
+ {
+ uint8_t bLength; /**< Size of the descriptor, in bytes. */
+ uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value
+ * given by the specific class.
+ */
+
+ uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */
+
+ uint8_t bNumEmbMIDIJack; /**< Total number of jacks inside this endpoint. */
+ uint8_t bAssocJackID[1]; /**< IDs of each jack inside the endpoint. */
+ } USB_MIDI_StdDescriptor_Jack_Endpoint_t;
+
+ /** \brief MIDI Class Driver Event Packet.
+ *
+ * Type define for a USB MIDI event packet, used to encapsulate sent and received MIDI messages from a USB MIDI interface.
+ */
+ typedef struct
+ {
+ unsigned char Command : 4; /**< Upper nibble of the MIDI command being sent or received in the event packet. */
+ unsigned char CableNumber : 4; /**< Virtual cable number of the event being sent or received in the given MIDI interface. */
+
+ uint8_t Data1; /**< First byte of data in the MIDI event. */
+ uint8_t Data2; /**< Second byte of data in the MIDI event. */
+ uint8_t Data3; /**< Third byte of data in the MIDI event. */
+ } MIDI_EventPacket_t;
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Common/MassStorage.h b/firmware/LUFA/Drivers/USB/Class/Common/MassStorage.h
new file mode 100644
index 0000000..fd24056
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Common/MassStorage.h
@@ -0,0 +1,362 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Common definitions and declarations for the library USB Mass Storage Class driver.
+ *
+ * Common definitions and declarations for the library USB Mass Storage 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_USBClassMS
+ * @defgroup Group_USBClassMSCommon Common Class Definitions
+ *
+ * \section Module Description
+ * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
+ * Mass Storage Class.
+ *
+ * @{
+ */
+
+#ifndef _MS_CLASS_COMMON_H_
+#define _MS_CLASS_COMMON_H_
+
+ /* Includes: */
+ #include "../../HighLevel/StdDescriptors.h"
+
+ #include <string.h>
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_MS_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ /* Macros: */
+ /** Magic signature for a Command Block Wrapper used in the Mass Storage Bulk-Only transport protocol. */
+ #define MS_CBW_SIGNATURE 0x43425355UL
+
+ /** Magic signature for a Command Status Wrapper used in the Mass Storage Bulk-Only transport protocol. */
+ #define MS_CSW_SIGNATURE 0x53425355UL
+
+ /** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from host-to-device. */
+ #define MS_COMMAND_DIR_DATA_OUT (0 << 7)
+
+ /** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from device-to-host. */
+ #define MS_COMMAND_DIR_DATA_IN (1 << 7)
+
+ /** \name SCSI Commands*/
+ //@{
+ /** SCSI Command Code for an INQUIRY command. */
+ #define SCSI_CMD_INQUIRY 0x12
+
+ /** SCSI Command Code for a REQUEST SENSE command. */
+ #define SCSI_CMD_REQUEST_SENSE 0x03
+
+ /** SCSI Command Code for a TEST UNIT READY command. */
+ #define SCSI_CMD_TEST_UNIT_READY 0x00
+
+ /** SCSI Command Code for a READ CAPACITY (10) command. */
+ #define SCSI_CMD_READ_CAPACITY_10 0x25
+
+ /** SCSI Command Code for a SEND DIAGNOSTIC command. */
+ #define SCSI_CMD_SEND_DIAGNOSTIC 0x1D
+
+ /** SCSI Command Code for a PREVENT ALLOW MEDIUM REMOVAL command. */
+ #define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E
+
+ /** SCSI Command Code for a WRITE (10) command. */
+ #define SCSI_CMD_WRITE_10 0x2A
+
+ /** SCSI Command Code for a READ (10) command. */
+ #define SCSI_CMD_READ_10 0x28
+
+ /** SCSI Command Code for a WRITE (6) command. */
+ #define SCSI_CMD_WRITE_6 0x0A
+
+ /** SCSI Command Code for a READ (6) command. */
+ #define SCSI_CMD_READ_6 0x08
+
+ /** SCSI Command Code for a VERIFY (10) command. */
+ #define SCSI_CMD_VERIFY_10 0x2F
+
+ /** SCSI Command Code for a MODE SENSE (6) command. */
+ #define SCSI_CMD_MODE_SENSE_6 0x1A
+
+ /** SCSI Command Code for a MODE SENSE (10) command. */
+ #define SCSI_CMD_MODE_SENSE_10 0x5A
+ //@}
+
+ /** \name SCSI Sense Key Values */
+ //@{
+ /** SCSI Sense Code to indicate no error has occurred. */
+ #define SCSI_SENSE_KEY_GOOD 0x00
+
+ /** SCSI Sense Code to indicate that the device has recovered from an error. */
+ #define SCSI_SENSE_KEY_RECOVERED_ERROR 0x01
+
+ /** SCSI Sense Code to indicate that the device is not ready for a new command. */
+ #define SCSI_SENSE_KEY_NOT_READY 0x02
+
+ /** SCSI Sense Code to indicate an error whilst accessing the medium. */
+ #define SCSI_SENSE_KEY_MEDIUM_ERROR 0x03
+
+ /** SCSI Sense Code to indicate a hardware has occurred. */
+ #define SCSI_SENSE_KEY_HARDWARE_ERROR 0x04
+
+ /** SCSI Sense Code to indicate that an illegal request has been issued. */
+ #define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05
+
+ /** SCSI Sense Code to indicate that the unit requires attention from the host to indicate
+ * a reset event, medium removal or other condition.
+ */
+ #define SCSI_SENSE_KEY_UNIT_ATTENTION 0x06
+
+ /** SCSI Sense Code to indicate that a write attempt on a protected block has been made. */
+ #define SCSI_SENSE_KEY_DATA_PROTECT 0x07
+
+ /** SCSI Sense Code to indicate an error while trying to write to a write-once medium. */
+ #define SCSI_SENSE_KEY_BLANK_CHECK 0x08
+
+ /** SCSI Sense Code to indicate a vendor specific error has occurred. */
+ #define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09
+
+ /** SCSI Sense Code to indicate that an EXTENDED COPY command has aborted due to an error. */
+ #define SCSI_SENSE_KEY_COPY_ABORTED 0x0A
+
+ /** SCSI Sense Code to indicate that the device has aborted the issued command. */
+ #define SCSI_SENSE_KEY_ABORTED_COMMAND 0x0B
+
+ /** SCSI Sense Code to indicate an attempt to write past the end of a partition has been made. */
+ #define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0D
+
+ /** SCSI Sense Code to indicate that the source data did not match the data read from the medium. */
+ #define SCSI_SENSE_KEY_MISCOMPARE 0x0E
+ //@}
+
+ /** \name SCSI Additional Sense Codes */
+ //@{
+ /** SCSI Additional Sense Code to indicate no additional sense information is available. */
+ #define SCSI_ASENSE_NO_ADDITIONAL_INFORMATION 0x00
+
+ /** SCSI Additional Sense Code to indicate that the logical unit (LUN) addressed is not ready. */
+ #define SCSI_ASENSE_LOGICAL_UNIT_NOT_READY 0x04
+
+ /** SCSI Additional Sense Code to indicate an invalid field was encountered while processing the issued command. */
+ #define SCSI_ASENSE_INVALID_FIELD_IN_CDB 0x24
+
+ /** SCSI Additional Sense Code to indicate that a medium that was previously indicated as not ready has now
+ * become ready for use.
+ */
+ #define SCSI_ASENSE_NOT_READY_TO_READY_CHANGE 0x28
+
+ /** SCSI Additional Sense Code to indicate that an attempt to write to a protected area was made. */
+ #define SCSI_ASENSE_WRITE_PROTECTED 0x27
+
+ /** SCSI Additional Sense Code to indicate an error whilst formatting the device medium. */
+ #define SCSI_ASENSE_FORMAT_ERROR 0x31
+
+ /** SCSI Additional Sense Code to indicate an invalid command was issued. */
+ #define SCSI_ASENSE_INVALID_COMMAND 0x20
+
+ /** SCSI Additional Sense Code to indicate a write to a block out outside of the medium's range was issued. */
+ #define SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21
+
+ /** SCSI Additional Sense Code to indicate that no removable medium is inserted into the device. */
+ #define SCSI_ASENSE_MEDIUM_NOT_PRESENT 0x3A
+ //@}
+
+ /** \name SCSI Additional Sense Key Code Qualifiers */
+ //@{
+ /** SCSI Additional Sense Qualifier Code to indicate no additional sense qualifier information is available. */
+ #define SCSI_ASENSEQ_NO_QUALIFIER 0x00
+
+ /** SCSI Additional Sense Qualifier Code to indicate that a medium format command failed to complete. */
+ #define SCSI_ASENSEQ_FORMAT_COMMAND_FAILED 0x01
+
+ /** SCSI Additional Sense Qualifier Code to indicate that an initializing command must be issued before the issued
+ * command can be executed.
+ */
+ #define SCSI_ASENSEQ_INITIALIZING_COMMAND_REQUIRED 0x02
+
+ /** SCSI Additional Sense Qualifier Code to indicate that an operation is currently in progress. */
+ #define SCSI_ASENSEQ_OPERATION_IN_PROGRESS 0x07
+ //@}
+
+ /* Enums: */
+ /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the Mass
+ * Storage device class.
+ */
+ enum MS_Descriptor_ClassSubclassProtocol_t
+ {
+ MS_CSCP_MassStorageClass = 0x08, /**< Descriptor Class value indicating that the device or interface
+ * belongs to the Mass Storage class.
+ */
+ MS_CSCP_SCSITransparentSubclass = 0x06, /**< Descriptor Subclass value indicating that the device or interface
+ * belongs to the SCSI Transparent Command Set subclass of the Mass
+ * storage class.
+ */
+ MS_CSCP_BulkOnlyTransportProtocol = 0x50, /**< Descriptor Protocol value indicating that the device or interface
+ * belongs to the Bulk Only Transport protocol of the Mass Storage class.
+ */
+ };
+
+ /** Enum for the Mass Storage class specific control requests that can be issued by the USB bus host. */
+ enum MS_ClassRequests_t
+ {
+ MS_REQ_GetMaxLUN = 0xFE, /**< Mass Storage class-specific request to retrieve the total number of Logical
+ * Units (drives) in the SCSI device.
+ */
+ MS_REQ_MassStorageReset = 0xFF, /**< Mass Storage class-specific request to reset the Mass Storage interface,
+ * ready for the next command.
+ */
+ };
+
+ /** Enum for the possible command status wrapper return status codes. */
+ enum MS_CommandStatusCodes_t
+ {
+ MS_SCSI_COMMAND_Pass = 0, /**< Command completed with no error */
+ MS_SCSI_COMMAND_Fail = 1, /**< Command failed to complete - host may check the exact error via a
+ * SCSI REQUEST SENSE command.
+ */
+ MS_SCSI_COMMAND_PhaseError = 2, /**< Command failed due to being invalid in the current phase. */
+ };
+
+ /* Type Defines: */
+ /** \brief Mass Storage Class Command Block Wrapper.
+ *
+ * Type define for a Command Block Wrapper, used in the Mass Storage Bulk-Only Transport protocol. */
+ typedef struct
+ {
+ uint32_t Signature; /**< Command block signature, must be CBW_SIGNATURE to indicate a valid Command Block. */
+ uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper. */
+ uint32_t DataTransferLength; /**< Length of the optional data portion of the issued command, in bytes. */
+ uint8_t Flags; /**< Command block flags, indicating command data direction. */
+ uint8_t LUN; /**< Logical Unit number this command is issued to. */
+ uint8_t SCSICommandLength; /**< Length of the issued SCSI command within the SCSI command data array. */
+ uint8_t SCSICommandData[16]; /**< Issued SCSI command in the Command Block. */
+ } MS_CommandBlockWrapper_t;
+
+ /** \brief Mass Storage Class Command Status Wrapper.
+ *
+ * Type define for a Command Status Wrapper, used in the Mass Storage Bulk-Only Transport protocol.
+ */
+ typedef struct
+ {
+ uint32_t Signature; /**< Status block signature, must be CSW_SIGNATURE to indicate a valid Command Status. */
+ uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper. */
+ uint32_t DataTransferResidue; /**< Number of bytes of data not processed in the SCSI command. */
+ uint8_t Status; /**< Status code of the issued command - a value from the \ref MS_CommandStatusCodes_t enum. */
+ } MS_CommandStatusWrapper_t;
+
+ /** \brief Mass Storage Class SCSI Sense Structure
+ *
+ * Type define for a SCSI Sense structure. Structures of this type are filled out by the
+ * device via the \ref MS_Host_RequestSense() function, indicating the current sense data of the
+ * device (giving explicit error codes for the last issued command). For details of the
+ * structure contents, refer to the SCSI specifications.
+ */
+ typedef struct
+ {
+ uint8_t ResponseCode;
+
+ uint8_t SegmentNumber;
+
+ unsigned char SenseKey : 4;
+ unsigned char Reserved : 1;
+ unsigned char ILI : 1;
+ unsigned char EOM : 1;
+ unsigned char FileMark : 1;
+
+ uint8_t Information[4];
+ uint8_t AdditionalLength;
+ uint8_t CmdSpecificInformation[4];
+ uint8_t AdditionalSenseCode;
+ uint8_t AdditionalSenseQualifier;
+ uint8_t FieldReplaceableUnitCode;
+ uint8_t SenseKeySpecific[3];
+ } SCSI_Request_Sense_Response_t;
+
+ /** \brief Mass Storage Class SCSI Inquiry Structure.
+ *
+ * Type define for a SCSI Inquiry structure. Structures of this type are filled out by the
+ * device via the \ref MS_Host_GetInquiryData() function, retrieving the attached device's
+ * information.
+ *
+ * For details of the structure contents, refer to the SCSI specifications.
+ */
+ typedef struct
+ {
+ unsigned char DeviceType : 5;
+ unsigned char PeripheralQualifier : 3;
+
+ unsigned char Reserved : 7;
+ unsigned char Removable : 1;
+
+ uint8_t Version;
+
+ unsigned char ResponseDataFormat : 4;
+ unsigned char Reserved2 : 1;
+ unsigned char NormACA : 1;
+ unsigned char TrmTsk : 1;
+ unsigned char AERC : 1;
+
+ uint8_t AdditionalLength;
+ uint8_t Reserved3[2];
+
+ unsigned char SoftReset : 1;
+ unsigned char CmdQue : 1;
+ unsigned char Reserved4 : 1;
+ unsigned char Linked : 1;
+ unsigned char Sync : 1;
+ unsigned char WideBus16Bit : 1;
+ unsigned char WideBus32Bit : 1;
+ unsigned char RelAddr : 1;
+
+ uint8_t VendorID[8];
+ uint8_t ProductID[16];
+ uint8_t RevisionID[4];
+ } SCSI_Inquiry_Response_t;
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Common/Printer.h b/firmware/LUFA/Drivers/USB/Class/Common/Printer.h
new file mode 100644
index 0000000..47a7909
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Common/Printer.h
@@ -0,0 +1,121 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Common definitions and declarations for the library USB Printer Class driver.
+ *
+ * Common definitions and declarations for the library USB Printer 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_USBClassPrinter
+ * @defgroup Group_USBClassPrinterCommon Common Class Definitions
+ *
+ * \section Module Description
+ * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
+ * Printer Class.
+ *
+ * @{
+ */
+
+#ifndef _PRINTER_CLASS_COMMON_H_
+#define _PRINTER_CLASS_COMMON_H_
+
+ /* Includes: */
+ #include "../../HighLevel/StdDescriptors.h"
+
+ #include <string.h>
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_PRINTER_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ /* Macros: */
+ /** \name Virtual Printer Status Line Masks */
+ //@{
+ /** Port status mask for a printer device, indicating that an error has *not* occurred. */
+ #define PRNT_PORTSTATUS_NOTERROR (1 << 3)
+
+ /** Port status mask for a printer device, indicating that the device is currently selected. */
+ #define PRNT_PORTSTATUS_SELECT (1 << 4)
+
+ /** Port status mask for a printer device, indicating that the device is currently out of paper. */
+ #define PRNT_PORTSTATUS_PAPEREMPTY (1 << 5)
+ //@}
+
+ /* Enums: */
+ /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the Printer
+ * device class.
+ */
+ enum PRNT_Descriptor_ClassSubclassProtocol_t
+ {
+ PRNT_CSCP_PrinterClass = 0x07, /**< Descriptor Class value indicating that the device or interface
+ * belongs to the Printer class.
+ */
+ PRNT_CSCP_PrinterSubclass = 0x01, /**< Descriptor Subclass value indicating that the device or interface
+ * belongs to the Printer subclass.
+ */
+ PRNT_CSCP_BidirectionalProtocol = 0x02, /**< Descriptor Protocol value indicating that the device or interface
+ * belongs to the Bidirectional protocol of the Printer class.
+ */
+ };
+
+ /** Enum for the Printer class specific control requests that can be issued by the USB bus host. */
+ enum PRNT_ClassRequests_t
+ {
+ PRNT_REQ_GetDeviceID = 0x00, /**< Printer class-specific request to retrieve the Unicode ID
+ * string of the device, containing the device's name, manufacturer
+ * and supported printer languages.
+ */
+ PRNT_REQ_GetPortStatus = 0x01, /**< Printer class-specific request to get the current status of the
+ * virtual printer port, for device selection and ready states.
+ */
+ PRNT_REQ_SoftReset = 0x02, /**< Printer class-specific request to reset the device, ready for new
+ * printer commands.
+ */
+ };
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Common/RNDIS.h b/firmware/LUFA/Drivers/USB/Class/Common/RNDIS.h
new file mode 100644
index 0000000..b4fb114
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Common/RNDIS.h
@@ -0,0 +1,399 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Common definitions and declarations for the library USB RNDIS Class driver.
+ *
+ * Common definitions and declarations for the library USB RNDIS 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_USBClassRNDIS
+ * @defgroup Group_USBClassRNDISCommon Common Class Definitions
+ *
+ * \section Module Description
+ * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
+ * RNDIS Class.
+ *
+ * @{
+ */
+
+#ifndef _RNDIS_CLASS_COMMON_H_
+#define _RNDIS_CLASS_COMMON_H_
+
+ /* Macros: */
+ #define __INCLUDE_FROM_CDC_DRIVER
+
+ /* Includes: */
+ #include "../../HighLevel/StdDescriptors.h"
+ #include "CDC.h"
+
+ #include <string.h>
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_RNDIS_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ /* Macros: */
+ /** Implemented RNDIS Version Major. */
+ #define REMOTE_NDIS_VERSION_MAJOR 0x01
+
+ /** Implemented RNDIS Version Minor. */
+ #define REMOTE_NDIS_VERSION_MINOR 0x00
+
+ /** \name RNDIS Message Values */
+ //@{
+ #define REMOTE_NDIS_PACKET_MSG 0x00000001UL
+ #define REMOTE_NDIS_INITIALIZE_MSG 0x00000002UL
+ #define REMOTE_NDIS_HALT_MSG 0x00000003UL
+ #define REMOTE_NDIS_QUERY_MSG 0x00000004UL
+ #define REMOTE_NDIS_SET_MSG 0x00000005UL
+ #define REMOTE_NDIS_RESET_MSG 0x00000006UL
+ #define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007UL
+ #define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008UL
+ //@}
+
+ /** \name RNDIS Response Values */
+ //@{
+ #define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002UL
+ #define REMOTE_NDIS_QUERY_CMPLT 0x80000004UL
+ #define REMOTE_NDIS_SET_CMPLT 0x80000005UL
+ #define REMOTE_NDIS_RESET_CMPLT 0x80000006UL
+ #define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008UL
+ //@}
+
+ /** \name RNDIS Status Values */
+ //@{
+ #define REMOTE_NDIS_STATUS_SUCCESS 0x00000000UL
+ #define REMOTE_NDIS_STATUS_FAILURE 0xC0000001UL
+ #define REMOTE_NDIS_STATUS_INVALID_DATA 0xC0010015UL
+ #define REMOTE_NDIS_STATUS_NOT_SUPPORTED 0xC00000BBUL
+ #define REMOTE_NDIS_STATUS_MEDIA_CONNECT 0x4001000BUL
+ #define REMOTE_NDIS_STATUS_MEDIA_DISCONNECT 0x4001000CUL
+ //@}
+
+ /** \name RNDIS Media States */
+ //@{
+ #define REMOTE_NDIS_MEDIA_STATE_CONNECTED 0x00000000UL
+ #define REMOTE_NDIS_MEDIA_STATE_DISCONNECTED 0x00000001UL
+ //@}
+
+ #define REMOTE_NDIS_MEDIUM_802_3 0x00000000UL
+
+ /** \name RNDIS Connection Types */
+ //@{
+ #define REMOTE_NDIS_DF_CONNECTIONLESS 0x00000001UL
+ #define REMOTE_NDIS_DF_CONNECTION_ORIENTED 0x00000002UL
+ //@}
+
+ /** \name RNDIS Packet Types */
+ //@{
+ #define REMOTE_NDIS_PACKET_DIRECTED 0x00000001UL
+ #define REMOTE_NDIS_PACKET_MULTICAST 0x00000002UL
+ #define REMOTE_NDIS_PACKET_ALL_MULTICAST 0x00000004UL
+ #define REMOTE_NDIS_PACKET_BROADCAST 0x00000008UL
+ #define REMOTE_NDIS_PACKET_SOURCE_ROUTING 0x00000010UL
+ #define REMOTE_NDIS_PACKET_PROMISCUOUS 0x00000020UL
+ #define REMOTE_NDIS_PACKET_SMT 0x00000040UL
+ #define REMOTE_NDIS_PACKET_ALL_LOCAL 0x00000080UL
+ #define REMOTE_NDIS_PACKET_GROUP 0x00001000UL
+ #define REMOTE_NDIS_PACKET_ALL_FUNCTIONAL 0x00002000UL
+ #define REMOTE_NDIS_PACKET_FUNCTIONAL 0x00004000UL
+ #define REMOTE_NDIS_PACKET_MAC_FRAME 0x00008000UL
+ //@}
+
+ /** \name RNDIS OID Values */
+ //@{
+ #define OID_GEN_SUPPORTED_LIST 0x00010101UL
+ #define OID_GEN_HARDWARE_STATUS 0x00010102UL
+ #define OID_GEN_MEDIA_SUPPORTED 0x00010103UL
+ #define OID_GEN_MEDIA_IN_USE 0x00010104UL
+ #define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106UL
+ #define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL
+ #define OID_GEN_LINK_SPEED 0x00010107UL
+ #define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010AUL
+ #define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010BUL
+ #define OID_GEN_VENDOR_ID 0x0001010CUL
+ #define OID_GEN_VENDOR_DESCRIPTION 0x0001010DUL
+ #define OID_GEN_CURRENT_PACKET_FILTER 0x0001010EUL
+ #define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL
+ #define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114UL
+ #define OID_GEN_PHYSICAL_MEDIUM 0x00010202UL
+ #define OID_GEN_XMIT_OK 0x00020101UL
+ #define OID_GEN_RCV_OK 0x00020102UL
+ #define OID_GEN_XMIT_ERROR 0x00020103UL
+ #define OID_GEN_RCV_ERROR 0x00020104UL
+ #define OID_GEN_RCV_NO_BUFFER 0x00020105UL
+ #define OID_802_3_PERMANENT_ADDRESS 0x01010101UL
+ #define OID_802_3_CURRENT_ADDRESS 0x01010102UL
+ #define OID_802_3_MULTICAST_LIST 0x01010103UL
+ #define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104UL
+ #define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101UL
+ #define OID_802_3_XMIT_ONE_COLLISION 0x01020102UL
+ #define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103UL
+ //@}
+
+ /** Maximum size in bytes of a RNDIS control message which can be sent or received. */
+ #define RNDIS_MESSAGE_BUFFER_SIZE 128
+
+ /** Maximum size in bytes of an Ethernet frame according to the Ethernet standard. */
+ #define ETHERNET_FRAME_SIZE_MAX 1500
+
+ /* Enums: */
+ /** Enum for the RNDIS class specific control requests that can be issued by the USB bus host. */
+ enum RNDIS_ClassRequests_t
+ {
+ RNDIS_REQ_SendEncapsulatedCommand = 0x00, /**< RNDIS request to issue a host-to-device NDIS command. */
+ RNDIS_REQ_GetEncapsulatedResponse = 0x01, /**< RNDIS request to issue a device-to-host NDIS response. */
+ };
+
+ /** Enum for the possible NDIS adapter states. */
+ enum RNDIS_States_t
+ {
+ RNDIS_Uninitialized = 0, /**< Adapter currently uninitialized. */
+ RNDIS_Initialized = 1, /**< Adapter currently initialized but not ready for data transfers. */
+ RNDIS_Data_Initialized = 2, /**< Adapter currently initialized and ready for data transfers. */
+ };
+
+ /** Enum for the RNDIS class specific notification requests that can be issued by a RNDIS device to a host. */
+ enum RNDIS_ClassNotifications_t
+ {
+ RNDIS_NOTIF_ResponseAvailable = 0x01, /**< Notification request value for a RNDIS Response Available notification. */
+ };
+
+ /** Enum for the NDIS hardware states. */
+ enum NDIS_Hardware_Status_t
+ {
+ NDIS_HardwareStatus_Ready, /**< Hardware Ready to accept commands from the host. */
+ NDIS_HardwareStatus_Initializing, /**< Hardware busy initializing. */
+ NDIS_HardwareStatus_Reset, /**< Hardware reset. */
+ NDIS_HardwareStatus_Closing, /**< Hardware currently closing. */
+ NDIS_HardwareStatus_NotReady /**< Hardware not ready to accept commands from the host. */
+ };
+
+ /* Type Defines: */
+ /** \brief MAC Address Structure.
+ *
+ * Type define for a physical MAC address of a device on a network.
+ */
+ typedef struct
+ {
+ uint8_t Octets[6]; /**< Individual bytes of a MAC address */
+ } MAC_Address_t;
+
+ /** \brief RNDIS Ethernet Frame Packet Information Structure.
+ *
+ * Type define for an Ethernet frame buffer data and information structure.
+ */
+ typedef struct
+ {
+ uint8_t FrameData[ETHERNET_FRAME_SIZE_MAX]; /**< Ethernet frame contents. */
+ uint16_t FrameLength; /**< Length in bytes of the Ethernet frame stored in the buffer. */
+ bool FrameInBuffer; /**< Indicates if a frame is currently stored in the buffer. */
+ } Ethernet_Frame_Info_t;
+
+ /** \brief RNDIS Common Message Header Structure.
+ *
+ * Type define for a RNDIS message header, sent before RNDIS messages.
+ */
+ typedef struct
+ {
+ uint32_t MessageType; /**< RNDIS message type, a REMOTE_NDIS_*_MSG constant */
+ uint32_t MessageLength; /**< Total length of the RNDIS message, in bytes */
+ } RNDIS_Message_Header_t;
+
+ /** \brief RNDIS Message Structure.
+ *
+ * Type define for a RNDIS packet message, used to encapsulate Ethernet packets sent to and from the adapter.
+ */
+ typedef struct
+ {
+ uint32_t MessageType;
+ uint32_t MessageLength;
+ uint32_t DataOffset;
+ uint32_t DataLength;
+ uint32_t OOBDataOffset;
+ uint32_t OOBDataLength;
+ uint32_t NumOOBDataElements;
+ uint32_t PerPacketInfoOffset;
+ uint32_t PerPacketInfoLength;
+ uint32_t VcHandle;
+ uint32_t Reserved;
+ } RNDIS_Packet_Message_t;
+
+ /** \brief RNDIS Initialization Message Structure.
+ *
+ * Type define for a RNDIS Initialize command message.
+ */
+ typedef struct
+ {
+ uint32_t MessageType;
+ uint32_t MessageLength;
+ uint32_t RequestId;
+
+ uint32_t MajorVersion;
+ uint32_t MinorVersion;
+ uint32_t MaxTransferSize;
+ } RNDIS_Initialize_Message_t;
+
+ /** \brief RNDIS Initialize Complete Message Structure.
+ *
+ * Type define for a RNDIS Initialize Complete response message.
+ */
+ typedef struct
+ {
+ uint32_t MessageType;
+ uint32_t MessageLength;
+ uint32_t RequestId;
+ uint32_t Status;
+
+ uint32_t MajorVersion;
+ uint32_t MinorVersion;
+ uint32_t DeviceFlags;
+ uint32_t Medium;
+ uint32_t MaxPacketsPerTransfer;
+ uint32_t MaxTransferSize;
+ uint32_t PacketAlignmentFactor;
+ uint32_t AFListOffset;
+ uint32_t AFListSize;
+ } RNDIS_Initialize_Complete_t;
+
+ /** \brief RNDIS Keep Alive Message Structure.
+ *
+ * Type define for a RNDIS Keep Alive command message.
+ */
+ typedef struct
+ {
+ uint32_t MessageType;
+ uint32_t MessageLength;
+ uint32_t RequestId;
+ } RNDIS_KeepAlive_Message_t;
+
+ /** \brief RNDIS Keep Alive Complete Message Structure.
+ *
+ * Type define for a RNDIS Keep Alive Complete response message.
+ */
+ typedef struct
+ {
+ uint32_t MessageType;
+ uint32_t MessageLength;
+ uint32_t RequestId;
+ uint32_t Status;
+ } RNDIS_KeepAlive_Complete_t;
+
+ /** \brief RNDIS Reset Complete Message Structure.
+ *
+ * Type define for a RNDIS Reset Complete response message.
+ */
+ typedef struct
+ {
+ uint32_t MessageType;
+ uint32_t MessageLength;
+ uint32_t Status;
+
+ uint32_t AddressingReset;
+ } RNDIS_Reset_Complete_t;
+
+ /** \brief RNDIS OID Property Set Message Structure.
+ *
+ * Type define for a RNDIS OID Property Set command message.
+ */
+ typedef struct
+ {
+ uint32_t MessageType;
+ uint32_t MessageLength;
+ uint32_t RequestId;
+
+ uint32_t Oid;
+ uint32_t InformationBufferLength;
+ uint32_t InformationBufferOffset;
+ uint32_t DeviceVcHandle;
+ } RNDIS_Set_Message_t;
+
+ /** \brief RNDIS OID Property Set Complete Message Structure.
+ *
+ * Type define for a RNDIS OID Property Set Complete response message.
+ */
+ typedef struct
+ {
+ uint32_t MessageType;
+ uint32_t MessageLength;
+ uint32_t RequestId;
+ uint32_t Status;
+ } RNDIS_Set_Complete_t;
+
+ /** \brief RNDIS OID Property Query Message Structure.
+ *
+ * Type define for a RNDIS OID Property Query command message.
+ */
+ typedef struct
+ {
+ uint32_t MessageType;
+ uint32_t MessageLength;
+ uint32_t RequestId;
+
+ uint32_t Oid;
+ uint32_t InformationBufferLength;
+ uint32_t InformationBufferOffset;
+ uint32_t DeviceVcHandle;
+ } RNDIS_Query_Message_t;
+
+ /** \brief RNDIS OID Property Query Complete Message Structure.
+ *
+ * Type define for a RNDIS OID Property Query Complete response message.
+ */
+ typedef struct
+ {
+ uint32_t MessageType;
+ uint32_t MessageLength;
+ uint32_t RequestId;
+ uint32_t Status;
+
+ uint32_t InformationBufferLength;
+ uint32_t InformationBufferOffset;
+ } RNDIS_Query_Complete_t;
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Common/StillImage.h b/firmware/LUFA/Drivers/USB/Class/Common/StillImage.h
new file mode 100644
index 0000000..6347d59
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Common/StillImage.h
@@ -0,0 +1,161 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Common definitions and declarations for the library USB Still Image Class driver.
+ *
+ * Common definitions and declarations for the library USB Still Image 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_USBClassSI
+ * @defgroup Group_USBClassSICommon Common Class Definitions
+ *
+ * \section Module Description
+ * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB
+ * Still Image Class.
+ *
+ * @{
+ */
+
+#ifndef _SI_CLASS_COMMON_H_
+#define _SI_CLASS_COMMON_H_
+
+ /* Includes: */
+ #include "../../HighLevel/StdDescriptors.h"
+
+ #include <string.h>
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_SI_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ /* Macros: */
+ /** Length in bytes of a given Unicode string's character length.
+ *
+ * \param[in] Chars Total number of Unicode characters in the string.
+ *
+ * \return Number of bytes of the given unicode string.
+ */
+ #define UNICODE_STRING_LENGTH(Chars) ((Chars) << 1)
+
+ /** Used in the DataLength field of a PIMA container, to give the total container size in bytes for
+ * a command container.
+ *
+ * \param[in] Params Number of parameters which are to be sent in the Param field of the container.
+ */
+ #define PIMA_COMMAND_SIZE(Params) ((sizeof(PIMA_Container_t) - 12) + ((Params) * sizeof(uint32_t)))
+
+ /** Used in the DataLength field of a PIMA container, to give the total container size in bytes for
+ * a data container.
+ *
+ * \param[in] DataLen Length in bytes of the data in the container.
+ */
+ #define PIMA_DATA_SIZE(DataLen) ((sizeof(PIMA_Container_t) - 12) + (DataLen))
+
+ /* Enums: */
+ /** Enum for the possible PIMA contains types. */
+ enum PIMA_Container_Types_t
+ {
+ PIMA_CONTAINER_Undefined = 0, /**< Undefined container type. */
+ PIMA_CONTAINER_CommandBlock = 1, /**< Command Block container type. */
+ PIMA_CONTAINER_DataBlock = 2, /**< Data Block container type. */
+ PIMA_CONTAINER_ResponseBlock = 3, /**< Response container type. */
+ PIMA_CONTAINER_EventBlock = 4, /**< Event Block container type. */
+ };
+
+ /* Enums: */
+ /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the
+ * Still Image device class.
+ */
+ enum SI_Descriptor_ClassSubclassProtocol_t
+ {
+ SI_CSCP_StillImageClass = 0x06, /**< Descriptor Class value indicating that the device or interface
+ * belongs to the Still Image class.
+ */
+ SI_CSCP_StillImageSubclass = 0x01, /**< Descriptor Subclass value indicating that the device or interface
+ * belongs to the Still Image subclass.
+ */
+ SI_CSCP_BulkOnlyProtocol = 0x01, /**< Descriptor Protocol value indicating that the device or interface
+ * belongs to the Bulk Only Transport protocol of the Still Image class.
+ */
+ };
+
+ /** Enums for the possible status codes of a returned Response Block from an attached PIMA compliant Still Image device. */
+ enum PIMA_ResponseCodes_t
+ {
+ PIMA_RESPONSE_OK = 1, /**< Response code indicating no error in the issued command. */
+ PIMA_RESPONSE_GeneralError = 2, /**< Response code indicating a general error while processing the
+ * issued command.
+ */
+ PIMA_RESPONSE_SessionNotOpen = 3, /**< Response code indicating that the sent command requires an open
+ * session before being issued.
+ */
+ PIMA_RESPONSE_InvalidTransaction = 4, /**< Response code indicating an invalid transaction occurred. */
+ PIMA_RESPONSE_OperationNotSupported = 5, /**< Response code indicating that the issued command is not supported
+ * by the attached device.
+ */
+ PIMA_RESPONSE_ParameterNotSupported = 6, /**< Response code indicating that one or more of the issued command's
+ * parameters are not supported by the device.
+ */
+ };
+
+ /* Type Defines: */
+ /** \brief PIMA Still Image Device Command/Response Container.
+ *
+ * Type define for a PIMA container, use to send commands and receive responses to and from an
+ * attached Still Image device.
+ */
+ typedef struct
+ {
+ uint32_t DataLength; /**< Length of the container and data, in bytes. */
+ uint16_t Type; /**< Container type, a value from the \ref PIMA_Container_Types_t enum. */
+ uint16_t Code; /**< Command, event or response code of the container. */
+ uint32_t TransactionID; /**< Unique container ID to link blocks together. */
+ uint32_t Params[3]; /**< Block parameters to be issued along with the block code (command blocks only). */
+ } PIMA_Container_t;
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/Audio.c b/firmware/LUFA/Drivers/USB/Class/Device/Audio.c
new file mode 100644
index 0000000..cc847e5
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/Audio.c
@@ -0,0 +1,98 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define __INCLUDE_FROM_USB_DRIVER
+#include "../../HighLevel/USBMode.h"
+#if defined(USB_CAN_BE_DEVICE)
+
+#define __INCLUDE_FROM_AUDIO_DRIVER
+#define __INCLUDE_FROM_AUDIO_DEVICE_C
+#include "Audio.h"
+
+void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
+{
+ if (!(Endpoint_IsSETUPReceived()))
+ return;
+
+ if (USB_ControlRequest.wIndex != AudioInterfaceInfo->Config.StreamingInterfaceNumber)
+ return;
+
+ switch (USB_ControlRequest.bRequest)
+ {
+ case REQ_SetInterface:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+ Endpoint_ClearStatusStage();
+
+ AudioInterfaceInfo->State.InterfaceEnabled = ((USB_ControlRequest.wValue & 0xFF) != 0);
+ }
+
+ break;
+ }
+}
+
+bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
+{
+ memset(&AudioInterfaceInfo->State, 0x00, sizeof(AudioInterfaceInfo->State));
+
+ for (uint8_t EndpointNum = 1; EndpointNum < ENDPOINT_TOTAL_ENDPOINTS; EndpointNum++)
+ {
+ uint16_t Size;
+ uint8_t Type;
+ uint8_t Direction;
+
+ if (EndpointNum == AudioInterfaceInfo->Config.DataINEndpointNumber)
+ {
+ Size = AudioInterfaceInfo->Config.DataINEndpointSize;
+ Direction = ENDPOINT_DIR_IN;
+ Type = EP_TYPE_ISOCHRONOUS;
+ }
+ else if (EndpointNum == AudioInterfaceInfo->Config.DataOUTEndpointNumber)
+ {
+ Size = AudioInterfaceInfo->Config.DataOUTEndpointSize;
+ Direction = ENDPOINT_DIR_OUT;
+ Type = EP_TYPE_ISOCHRONOUS;
+ }
+ else
+ {
+ continue;
+ }
+
+ if (!(Endpoint_ConfigureEndpoint(EndpointNum, Type, Direction, Size, ENDPOINT_BANK_DOUBLE)))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+#endif
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/Audio.h b/firmware/LUFA/Drivers/USB/Class/Device/Audio.h
new file mode 100644
index 0000000..5ba688a
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/Audio.h
@@ -0,0 +1,336 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Device mode driver for the library USB Audio 1.0 Class driver.
+ *
+ * Device mode driver for the library USB Audio 1.0 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_USBClassAudio
+ * @defgroup Group_USBClassAudioDevice Audio Class Device 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/Device/Audio.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ *
+ * \section Module Description
+ * Device Mode USB Class driver framework interface, for the Audio 1.0 USB Class driver.
+ *
+ * @{
+ */
+
+#ifndef _AUDIO_CLASS_DEVICE_H_
+#define _AUDIO_CLASS_DEVICE_H_
+
+ /* Includes: */
+ #include "../../USB.h"
+ #include "../Common/Audio.h"
+
+ #include <string.h>
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_AUDIO_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ #if defined(__INCLUDE_FROM_AUDIO_DEVICE_C) && defined(NO_STREAM_CALLBACKS)
+ #error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
+ #endif
+
+ /* Public Interface - May be used in end-application: */
+ /* Type Defines: */
+ /** \brief Audio Class Device Mode Configuration and State Structure.
+ *
+ * Class state structure. An instance of this structure should be made for each Audio interface
+ * within the user application, and passed to each of the Audio class driver functions as the
+ * AudioInterfaceInfo parameter. This stores each Audio interface's configuration and state information.
+ */
+ typedef struct
+ {
+ const struct
+ {
+ uint8_t StreamingInterfaceNumber; /**< Index of the Audio Streaming interface within the device this
+ * structure controls.
+ */
+
+ uint8_t DataINEndpointNumber; /**< Endpoint number of the incoming Audio Streaming data, if available
+ * (zero if unused).
+ */
+ uint16_t DataINEndpointSize; /**< Size in bytes of the incoming Audio Streaming data endpoint, if available
+ * (zero if unused).
+ */
+
+ uint8_t DataOUTEndpointNumber; /**< Endpoint number of the outgoing Audio Streaming data, if available
+ * (zero if unused).
+ */
+ uint16_t DataOUTEndpointSize; /**< Size in bytes of the outgoing Audio Streaming data endpoint, if available
+ * (zero if unused).
+ */
+ } Config; /**< Config data for the USB class interface within the device. All elements in this section
+ * <b>must</b> be set or the interface will fail to enumerate and operate correctly.
+ */
+ struct
+ {
+ bool InterfaceEnabled; /**< Set and cleared by the class driver to indicate if the host has enabled the streaming endpoints
+ * of the Audio Streaming interface.
+ */
+ } State; /**< State data for the USB class interface within the device. All elements in this section
+ * are reset to their defaults when the interface is enumerated.
+ */
+ } USB_ClassInfo_Audio_Device_t;
+
+ /* Function Prototypes: */
+ /** Configures the endpoints of a given Audio interface, ready for use. This should be linked to the library
+ * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing the
+ * given Audio interface is selected.
+ *
+ * \note The endpoint index numbers as given in the interface's configuration structure must not overlap with any other
+ * interface, or endpoint bank corruption will occur. Gaps in the allocated endpoint numbers or non-sequential indexes
+ * within a single interface is allowed, but no two interfaces of any type have have interleaved endpoint indexes.
+ *
+ * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
+ *
+ * \return Boolean true if the endpoints were successfully configured, false otherwise.
+ */
+ bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Processes incoming control requests from the host, that are directed to the given Audio class interface. This should be
+ * linked to the library \ref EVENT_USB_Device_ControlRequest() event.
+ *
+ * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
+ */
+ void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /* Inline Functions: */
+ /** General management task for a given Audio 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] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
+ */
+ static inline void Audio_Device_USBTask(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
+ ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
+ static inline void Audio_Device_USBTask(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
+ {
+ (void)AudioInterfaceInfo;
+ }
+
+ /** Determines if the given audio interface is ready for a sample to be read from it, and selects the streaming
+ * OUT endpoint ready for reading.
+ *
+ * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
+ * the call will fail.
+ *
+ * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
+ *
+ * \return Boolean true if the given Audio interface has a sample to be read, false otherwise.
+ */
+ static inline bool Audio_Device_IsSampleReceived(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
+ ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
+ static inline bool Audio_Device_IsSampleReceived(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
+ {
+ if ((USB_DeviceState != DEVICE_STATE_Configured) || !(AudioInterfaceInfo->State.InterfaceEnabled))
+ return false;
+
+ Endpoint_SelectEndpoint(AudioInterfaceInfo->Config.DataOUTEndpointNumber);
+ return Endpoint_IsOUTReceived();
+ }
+
+ /** Determines if the given audio interface is ready to accept the next sample to be written to it, and selects
+ * the streaming IN endpoint ready for writing.
+ *
+ * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
+ * the call will fail.
+ *
+ * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
+ *
+ * \return Boolean true if the given Audio interface is ready to accept the next sample, false otherwise.
+ */
+ static inline bool Audio_Device_IsReadyForNextSample(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
+ ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
+ static inline bool Audio_Device_IsReadyForNextSample(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
+ {
+ if ((USB_DeviceState != DEVICE_STATE_Configured) || !(AudioInterfaceInfo->State.InterfaceEnabled))
+ return false;
+
+ Endpoint_SelectEndpoint(AudioInterfaceInfo->Config.DataINEndpointNumber);
+ return Endpoint_IsINReady();
+ }
+
+ /** Reads the next 8-bit audio sample from the current audio interface.
+ *
+ * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsSampleReceived() function to ensure
+ * ensure the correct endpoint is selected and ready for data.
+ *
+ * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
+ *
+ * \return Signed 8-bit audio sample from the audio interface.
+ */
+ static inline int8_t Audio_Device_ReadSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
+ ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
+ static inline int8_t Audio_Device_ReadSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
+ {
+ int8_t Sample;
+
+ (void)AudioInterfaceInfo;
+
+ Sample = Endpoint_Read_Byte();
+
+ if (!(Endpoint_BytesInEndpoint()))
+ Endpoint_ClearOUT();
+
+ return Sample;
+ }
+
+ /** Reads the next 16-bit audio sample from the current audio interface.
+ *
+ * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsSampleReceived() function to ensure
+ * that the correct endpoint is selected and ready for data.
+ *
+ * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
+ *
+ * \return Signed 16-bit audio sample from the audio interface.
+ */
+ static inline int16_t Audio_Device_ReadSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
+ ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
+ static inline int16_t Audio_Device_ReadSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
+ {
+ int16_t Sample;
+
+ (void)AudioInterfaceInfo;
+
+ Sample = (int16_t)Endpoint_Read_Word_LE();
+
+ if (!(Endpoint_BytesInEndpoint()))
+ Endpoint_ClearOUT();
+
+ return Sample;
+ }
+
+ /** Reads the next 24-bit audio sample from the current audio interface.
+ *
+ * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsSampleReceived() function to ensure
+ * that the correct endpoint is selected and ready for data.
+ *
+ * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
+ *
+ * \return Signed 24-bit audio sample from the audio interface.
+ */
+ static inline int32_t Audio_Device_ReadSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
+ ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
+ static inline int32_t Audio_Device_ReadSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
+ {
+ int32_t Sample;
+
+ (void)AudioInterfaceInfo;
+
+ Sample = (((uint32_t)Endpoint_Read_Byte() << 16) | Endpoint_Read_Word_LE());
+
+ if (!(Endpoint_BytesInEndpoint()))
+ Endpoint_ClearOUT();
+
+ return Sample;
+ }
+
+ /** Writes the next 8-bit audio sample to the current audio interface.
+ *
+ * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsReadyForNextSample() function to
+ * ensure that the correct endpoint is selected and ready for data.
+ *
+ * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
+ * \param[in] Sample Signed 8-bit audio sample.
+ */
+ static inline void Audio_Device_WriteSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
+ const int8_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
+ static inline void Audio_Device_WriteSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
+ const int8_t Sample)
+ {
+ Endpoint_Write_Byte(Sample);
+
+ if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpointSize)
+ Endpoint_ClearIN();
+ }
+
+ /** Writes the next 16-bit audio sample to the current audio interface.
+ *
+ * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsReadyForNextSample() function to
+ * ensure that the correct endpoint is selected and ready for data.
+ *
+ * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
+ * \param[in] Sample Signed 16-bit audio sample.
+ */
+ static inline void Audio_Device_WriteSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
+ const int16_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
+ static inline void Audio_Device_WriteSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
+ const int16_t Sample)
+ {
+ Endpoint_Write_Word_LE(Sample);
+
+ if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpointSize)
+ Endpoint_ClearIN();
+ }
+
+ /** Writes the next 24-bit audio sample to the current audio interface.
+ *
+ * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsReadyForNextSample() function to
+ * ensure that the correct endpoint is selected and ready for data.
+ *
+ * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
+ * \param[in] Sample Signed 24-bit audio sample.
+ */
+ static inline void Audio_Device_WriteSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
+ const int32_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
+ static inline void Audio_Device_WriteSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
+ const int32_t Sample)
+ {
+ Endpoint_Write_Byte(Sample >> 16);
+ Endpoint_Write_Word_LE(Sample);
+
+ if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpointSize)
+ Endpoint_ClearIN();
+ }
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/Audio.lst b/firmware/LUFA/Drivers/USB/Class/Device/Audio.lst
new file mode 100644
index 0000000..711e651
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/Audio.lst
@@ -0,0 +1,184 @@
+ 1 .file "Audio.c"
+ 2 __SREG__ = 0x3f
+ 3 __SP_H__ = 0x3e
+ 4 __SP_L__ = 0x3d
+ 5 __CCP__ = 0x34
+ 6 __tmp_reg__ = 0
+ 7 __zero_reg__ = 1
+ 15 .Ltext0:
+ 16 .section .text.Audio_Device_ConfigureEndpoints,"ax",@progbits
+ 17 .global Audio_Device_ConfigureEndpoints
+ 19 Audio_Device_ConfigureEndpoints:
+ 20 .LFB82:
+ 21 .LSM0:
+ 22 .LVL0:
+ 23 0000 1F93 push r17
+ 24 0002 CF93 push r28
+ 25 0004 DF93 push r29
+ 26 /* prologue: function */
+ 27 /* frame size = 0 */
+ 28 0006 EC01 movw r28,r24
+ 29 .LSM1:
+ 30 0008 1F82 std Y+7,__zero_reg__
+ 31 000a 11E0 ldi r17,lo8(1)
+ 32 .LVL1:
+ 33 .L8:
+ 34 .LBB14:
+ 35 .LBB15:
+ 36 .LSM2:
+ 37 000c 8981 ldd r24,Y+1
+ 38 000e 1817 cp r17,r24
+ 39 0010 01F4 brne .L2
+ 40 .LSM3:
+ 41 0012 2A81 ldd r18,Y+2
+ 42 0014 3B81 ldd r19,Y+3
+ 43 .LVL2:
+ 44 0016 61E0 ldi r22,lo8(1)
+ 45 .LVL3:
+ 46 0018 00C0 rjmp .L3
+ 47 .LVL4:
+ 48 .L2:
+ 49 .LSM4:
+ 50 001a 8C81 ldd r24,Y+4
+ 51 001c 1817 cp r17,r24
+ 52 001e 01F4 brne .L4
+ 53 .LSM5:
+ 54 0020 2D81 ldd r18,Y+5
+ 55 0022 3E81 ldd r19,Y+6
+ 56 .LVL5:
+ 57 0024 60E0 ldi r22,lo8(0)
+ 58 .LVL6:
+ 59 .L3:
+ 60 0026 40E0 ldi r20,lo8(0)
+ 61 .LVL7:
+ 62 0028 88E0 ldi r24,lo8(8)
+ 63 002a 90E0 ldi r25,hi8(8)
+ 64 .LVL8:
+ 65 002c 00C0 rjmp .L5
+ 66 .L6:
+ 67 .LBB16:
+ 68 .LBB17:
+ 69 .LBB18:
+ 70 .LBB19:
+ 71 .LSM6:
+ 72 002e 4F5F subi r20,lo8(-(1))
+ 73 .LSM7:
+ 74 0030 880F lsl r24
+ 75 0032 991F rol r25
+ 76 .L5:
+ 77 .LSM8:
+ 78 0034 8217 cp r24,r18
+ 79 0036 9307 cpc r25,r19
+ 80 0038 00F0 brlo .L6
+ 81 .LBE19:
+ 82 .LBE18:
+ 83 .LBE17:
+ 84 .LSM9:
+ 85 003a 6064 ori r22,lo8(64)
+ 86 003c 4295 swap r20
+ 87 003e 407F andi r20,lo8(-16)
+ 88 0040 4660 ori r20,lo8(6)
+ 89 0042 812F mov r24,r17
+ 90 .LVL9:
+ 91 0044 0E94 0000 call Endpoint_ConfigureEndpoint_Prv
+ 92 .LVL10:
+ 93 .LBE16:
+ 94 .LSM10:
+ 95 0048 8823 tst r24
+ 96 004a 01F0 breq .L7
+ 97 .L4:
+ 98 .LBE15:
+ 99 .LSM11:
+ 100 004c 1F5F subi r17,lo8(-(1))
+ 101 004e 1530 cpi r17,lo8(5)
+ 102 0050 01F4 brne .L8
+ 103 0052 81E0 ldi r24,lo8(1)
+ 104 .L7:
+ 105 /* epilogue start */
+ 106 .LBE14:
+ 107 .LSM12:
+ 108 0054 DF91 pop r29
+ 109 0056 CF91 pop r28
+ 110 .LVL11:
+ 111 0058 1F91 pop r17
+ 112 .LVL12:
+ 113 005a 0895 ret
+ 114 .LFE82:
+ 116 .section .text.Audio_Device_ProcessControlRequest,"ax",@progbits
+ 117 .global Audio_Device_ProcessControlRequest
+ 119 Audio_Device_ProcessControlRequest:
+ 120 .LFB81:
+ 121 .LSM13:
+ 122 .LVL13:
+ 123 0000 CF93 push r28
+ 124 0002 DF93 push r29
+ 125 /* prologue: function */
+ 126 /* frame size = 0 */
+ 127 0004 EC01 movw r28,r24
+ 128 .LBB20:
+ 129 .LBB21:
+ 130 .LSM14:
+ 131 0006 8091 E800 lds r24,232
+ 132 .LVL14:
+ 133 .LBE21:
+ 134 .LBE20:
+ 135 .LSM15:
+ 136 000a 83FF sbrs r24,3
+ 137 000c 00C0 rjmp .L15
+ 138 .LSM16:
+ 139 000e 8881 ld r24,Y
+ 140 0010 90E0 ldi r25,lo8(0)
+ 141 0012 2091 0000 lds r18,USB_ControlRequest+4
+ 142 0016 3091 0000 lds r19,(USB_ControlRequest+4)+1
+ 143 001a 2817 cp r18,r24
+ 144 001c 3907 cpc r19,r25
+ 145 001e 01F4 brne .L15
+ 146 .LSM17:
+ 147 0020 8091 0000 lds r24,USB_ControlRequest+1
+ 148 0024 8B30 cpi r24,lo8(11)
+ 149 0026 01F4 brne .L15
+ 150 .LSM18:
+ 151 0028 8091 0000 lds r24,USB_ControlRequest
+ 152 002c 8130 cpi r24,lo8(1)
+ 153 002e 01F4 brne .L15
+ 154 .LBB22:
+ 155 .LBB23:
+ 156 .LSM19:
+ 157 0030 8091 E800 lds r24,232
+ 158 0034 877F andi r24,lo8(-9)
+ 159 0036 8093 E800 sts 232,r24
+ 160 .LBE23:
+ 161 .LBE22:
+ 162 .LSM20:
+ 163 003a 0E94 0000 call Endpoint_ClearStatusStage
+ 164 .LSM21:
+ 165 003e 90E0 ldi r25,lo8(0)
+ 166 0040 8091 0000 lds r24,USB_ControlRequest+2
+ 167 0044 8111 cpse r24,__zero_reg__
+ 168 0046 91E0 ldi r25,lo8(1)
+ 169 .L14:
+ 170 0048 9F83 std Y+7,r25
+ 171 .L15:
+ 172 /* epilogue start */
+ 173 .LSM22:
+ 174 004a DF91 pop r29
+ 175 004c CF91 pop r28
+ 176 .LVL15:
+ 177 004e 0895 ret
+ 178 .LFE81:
+ 212 .Letext0:
+DEFINED SYMBOLS
+ *ABS*:0000000000000000 Audio.c
+ /tmp/ccVOq125.s:2 *ABS*:000000000000003f __SREG__
+ /tmp/ccVOq125.s:3 *ABS*:000000000000003e __SP_H__
+ /tmp/ccVOq125.s:4 *ABS*:000000000000003d __SP_L__
+ /tmp/ccVOq125.s:5 *ABS*:0000000000000034 __CCP__
+ /tmp/ccVOq125.s:6 *ABS*:0000000000000000 __tmp_reg__
+ /tmp/ccVOq125.s:7 *ABS*:0000000000000001 __zero_reg__
+ /tmp/ccVOq125.s:19 .text.Audio_Device_ConfigureEndpoints:0000000000000000 Audio_Device_ConfigureEndpoints
+ /tmp/ccVOq125.s:119 .text.Audio_Device_ProcessControlRequest:0000000000000000 Audio_Device_ProcessControlRequest
+
+UNDEFINED SYMBOLS
+Endpoint_ConfigureEndpoint_Prv
+USB_ControlRequest
+Endpoint_ClearStatusStage
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/Audio.o b/firmware/LUFA/Drivers/USB/Class/Device/Audio.o
new file mode 100644
index 0000000..6658370
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/Audio.o
Binary files differ
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/CDC.c b/firmware/LUFA/Drivers/USB/Class/Device/CDC.c
new file mode 100644
index 0000000..0da5cc6
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/CDC.c
@@ -0,0 +1,332 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define __INCLUDE_FROM_USB_DRIVER
+#include "../../HighLevel/USBMode.h"
+#if defined(USB_CAN_BE_DEVICE)
+
+#define __INCLUDE_FROM_CDC_DRIVER
+#define __INCLUDE_FROM_CDC_DEVICE_C
+#include "CDC.h"
+
+void CDC_Device_Event_Stub(void)
+{
+
+}
+
+void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
+{
+ if (!(Endpoint_IsSETUPReceived()))
+ return;
+
+ if (USB_ControlRequest.wIndex != CDCInterfaceInfo->Config.ControlInterfaceNumber)
+ return;
+
+ switch (USB_ControlRequest.bRequest)
+ {
+ case CDC_REQ_GetLineEncoding:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+ Endpoint_Write_Control_Stream_LE(&CDCInterfaceInfo->State.LineEncoding, sizeof(CDCInterfaceInfo->State.LineEncoding));
+ Endpoint_ClearOUT();
+ }
+
+ break;
+ case CDC_REQ_SetLineEncoding:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+ Endpoint_Read_Control_Stream_LE(&CDCInterfaceInfo->State.LineEncoding, sizeof(CDCInterfaceInfo->State.LineEncoding));
+ Endpoint_ClearIN();
+
+ EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo);
+ }
+
+ break;
+ case CDC_REQ_SetControlLineState:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+ Endpoint_ClearStatusStage();
+
+ CDCInterfaceInfo->State.ControlLineStates.HostToDevice = USB_ControlRequest.wValue;
+
+ EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo);
+ }
+
+ break;
+ case CDC_REQ_SendBreak:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+ Endpoint_ClearStatusStage();
+
+ EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue);
+ }
+
+ break;
+ }
+}
+
+bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
+{
+ memset(&CDCInterfaceInfo->State, 0x00, sizeof(CDCInterfaceInfo->State));
+
+ for (uint8_t EndpointNum = 1; EndpointNum < ENDPOINT_TOTAL_ENDPOINTS; EndpointNum++)
+ {
+ uint16_t Size;
+ uint8_t Type;
+ uint8_t Direction;
+ bool DoubleBanked;
+
+ if (EndpointNum == CDCInterfaceInfo->Config.DataINEndpointNumber)
+ {
+ Size = CDCInterfaceInfo->Config.DataINEndpointSize;
+ Direction = ENDPOINT_DIR_IN;
+ Type = EP_TYPE_BULK;
+ DoubleBanked = CDCInterfaceInfo->Config.DataINEndpointDoubleBank;
+ }
+ else if (EndpointNum == CDCInterfaceInfo->Config.DataOUTEndpointNumber)
+ {
+ Size = CDCInterfaceInfo->Config.DataOUTEndpointSize;
+ Direction = ENDPOINT_DIR_OUT;
+ Type = EP_TYPE_BULK;
+ DoubleBanked = CDCInterfaceInfo->Config.DataOUTEndpointDoubleBank;
+ }
+ else if (EndpointNum == CDCInterfaceInfo->Config.NotificationEndpointNumber)
+ {
+ Size = CDCInterfaceInfo->Config.NotificationEndpointSize;
+ Direction = ENDPOINT_DIR_IN;
+ Type = EP_TYPE_INTERRUPT;
+ DoubleBanked = CDCInterfaceInfo->Config.NotificationEndpointDoubleBank;
+ }
+ else
+ {
+ continue;
+ }
+
+ if (!(Endpoint_ConfigureEndpoint(EndpointNum, Type, Direction, Size,
+ DoubleBanked ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
+{
+ if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
+ return;
+
+ #if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
+ CDC_Device_Flush(CDCInterfaceInfo);
+ #endif
+}
+
+uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
+ const char* const Data,
+ const uint16_t Length)
+{
+ if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
+ return ENDPOINT_RWSTREAM_DeviceDisconnected;
+
+ Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber);
+ return Endpoint_Write_Stream_LE(Data, Length, NO_STREAM_CALLBACK);
+}
+
+uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
+ const uint8_t Data)
+{
+ if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
+ return ENDPOINT_RWSTREAM_DeviceDisconnected;
+
+ Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber);
+
+ if (!(Endpoint_IsReadWriteAllowed()))
+ {
+ Endpoint_ClearIN();
+
+ uint8_t ErrorCode;
+
+ if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
+ return ErrorCode;
+ }
+
+ Endpoint_Write_Byte(Data);
+ return ENDPOINT_READYWAIT_NoError;
+}
+
+uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
+{
+ if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
+ return ENDPOINT_RWSTREAM_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber);
+
+ if (!(Endpoint_BytesInEndpoint()))
+ return ENDPOINT_READYWAIT_NoError;
+
+ bool BankFull = !(Endpoint_IsReadWriteAllowed());
+
+ Endpoint_ClearIN();
+
+ if (BankFull)
+ {
+ if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
+ return ErrorCode;
+
+ Endpoint_ClearIN();
+ }
+
+ return ENDPOINT_READYWAIT_NoError;
+}
+
+uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
+{
+ if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
+ return 0;
+
+ Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpointNumber);
+
+ if (Endpoint_IsOUTReceived())
+ {
+ if (!(Endpoint_BytesInEndpoint()))
+ {
+ Endpoint_ClearOUT();
+ return 0;
+ }
+ else
+ {
+ return Endpoint_BytesInEndpoint();
+ }
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+int16_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
+{
+ if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
+ return -1;
+
+ int16_t ReceivedByte = -1;
+
+ Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpointNumber);
+
+ if (Endpoint_IsOUTReceived())
+ {
+ if (Endpoint_BytesInEndpoint())
+ ReceivedByte = Endpoint_Read_Byte();
+
+ if (!(Endpoint_BytesInEndpoint()))
+ Endpoint_ClearOUT();
+ }
+
+ return ReceivedByte;
+}
+
+void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
+{
+ if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
+ return;
+
+ Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.NotificationEndpointNumber);
+
+ USB_Request_Header_t Notification = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = CDC_NOTIF_SerialState,
+ .wValue = 0,
+ .wIndex = 0,
+ .wLength = sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost),
+ };
+
+ Endpoint_Write_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NO_STREAM_CALLBACK);
+ Endpoint_Write_Stream_LE(&CDCInterfaceInfo->State.ControlLineStates.DeviceToHost,
+ sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost),
+ NO_STREAM_CALLBACK);
+ Endpoint_ClearIN();
+}
+
+void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
+ FILE* const Stream)
+{
+ *Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar, _FDEV_SETUP_RW);
+ fdev_set_udata(Stream, CDCInterfaceInfo);
+}
+
+void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
+ FILE* const Stream)
+{
+ *Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar_Blocking, _FDEV_SETUP_RW);
+ fdev_set_udata(Stream, CDCInterfaceInfo);
+}
+
+static int CDC_Device_putchar(char c,
+ FILE* Stream)
+{
+ return CDC_Device_SendByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0;
+}
+
+static int CDC_Device_getchar(FILE* Stream)
+{
+ int16_t ReceivedByte = CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream));
+
+ if (ReceivedByte < 0)
+ return _FDEV_EOF;
+
+ return ReceivedByte;
+}
+
+static int CDC_Device_getchar_Blocking(FILE* Stream)
+{
+ int16_t ReceivedByte;
+
+ while ((ReceivedByte = CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream))) < 0)
+ {
+ if (USB_DeviceState == DEVICE_STATE_Unattached)
+ return _FDEV_EOF;
+
+ CDC_Device_USBTask((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream));
+ USB_USBTask();
+ }
+
+ return ReceivedByte;
+}
+
+#endif
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/CDC.h b/firmware/LUFA/Drivers/USB/Class/Device/CDC.h
new file mode 100644
index 0000000..4fa823a
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/CDC.h
@@ -0,0 +1,342 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Device mode driver for the library USB CDC Class driver.
+ *
+ * Device mode driver for the library USB CDC 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_USBClassCDC
+ * @defgroup Group_USBClassCDCDevice CDC Class Device 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/Device/CDC.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ *
+ * \section Module Description
+ * Device Mode USB Class driver framework interface, for the CDC USB Class driver.
+ *
+ * \note There are several major drawbacks to the CDC-ACM standard USB class, however
+ * it is very standardized and thus usually available as a built-in driver on
+ * most platforms, and so is a better choice than a proprietary serial class.
+ *
+ * One major issue with CDC-ACM is that it requires two Interface descriptors,
+ * which will upset most hosts when part of a multi-function "Composite" USB
+ * device, as each interface will be loaded into a separate driver instance. To
+ * combat this, you should use the "Interface Association Descriptor" addendum to
+ * the USB standard which is available on most OSes when creating Composite devices.
+ *
+ * Another major oversight is that there is no mechanism for the host to notify the
+ * device that there is a data sink on the host side ready to accept data. This
+ * means that the device may try to send data while the host isn't listening, causing
+ * lengthy blocking timeouts in the transmission routines. To combat this, it is
+ * recommended that the virtual serial line DTR (Data Terminal Ready) be used where
+ * possible to determine if a host application is ready for data.
+ *
+ * @{
+ */
+
+#ifndef _CDC_CLASS_DEVICE_H_
+#define _CDC_CLASS_DEVICE_H_
+
+ /* Includes: */
+ #include "../../USB.h"
+ #include "../Common/CDC.h"
+
+ #include <stdio.h>
+ #include <string.h>
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_CDC_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ #if defined(__INCLUDE_FROM_CDC_DEVICE_C) && defined(NO_STREAM_CALLBACKS)
+ #error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
+ #endif
+
+ /* Public Interface - May be used in end-application: */
+ /* Type Defines: */
+ /** \brief CDC Class Device Mode Configuration and State Structure.
+ *
+ * Class state structure. An instance of this structure should be made for each CDC interface
+ * within the user application, and passed to each of the CDC class driver functions as the
+ * CDCInterfaceInfo parameter. This stores each CDC interface's configuration and state information.
+ */
+ typedef struct
+ {
+ const struct
+ {
+ uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device. */
+
+ uint8_t DataINEndpointNumber; /**< Endpoint number of the CDC interface's IN data endpoint. */
+ uint16_t DataINEndpointSize; /**< Size in bytes of the CDC interface's IN data endpoint. */
+ bool DataINEndpointDoubleBank; /**< Indicates if the CDC interface's IN data endpoint should use double banking. */
+
+ uint8_t DataOUTEndpointNumber; /**< Endpoint number of the CDC interface's OUT data endpoint. */
+ uint16_t DataOUTEndpointSize; /**< Size in bytes of the CDC interface's OUT data endpoint. */
+ bool DataOUTEndpointDoubleBank; /**< Indicates if the CDC interface's OUT data endpoint should use double banking. */
+
+ uint8_t NotificationEndpointNumber; /**< Endpoint number of the CDC interface's IN notification endpoint, if used. */
+ uint16_t NotificationEndpointSize; /**< Size in bytes of the CDC interface's IN notification endpoint, if used. */
+ bool NotificationEndpointDoubleBank; /**< Indicates if the CDC interface's notification endpoint should use double banking. */
+ } Config; /**< Config data for the USB class interface within the device. All elements in this section
+ * <b>must</b> be set or the interface will fail to enumerate and operate correctly.
+ */
+ struct
+ {
+ struct
+ {
+ uint8_t HostToDevice; /**< Control line states from the host to device, as a set of CDC_CONTROL_LINE_OUT_*
+ * masks. This value is updated each time \ref CDC_Device_USBTask() is called.
+ */
+ uint8_t DeviceToHost; /**< Control line states from the device to host, as a set of CDC_CONTROL_LINE_IN_*
+ * masks - to notify the host of changes to these values, call the
+ * \ref CDC_Device_SendControlLineStateChange() function.
+ */
+ } ControlLineStates; /**< Current states of the virtual serial port's control lines between the device and host. */
+
+ CDC_LineEncoding_t LineEncoding; /** Line encoding used in the virtual serial port, for the device's information.
+ * This is generally only used if the virtual serial port data is to be
+ * reconstructed on a physical UART.
+ */
+ } State; /**< State data for the USB class interface within the device. All elements in this section
+ * are reset to their defaults when the interface is enumerated.
+ */
+ } USB_ClassInfo_CDC_Device_t;
+
+ /* Function Prototypes: */
+ /** Configures the endpoints of a given CDC interface, ready for use. This should be linked to the library
+ * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing
+ * the given CDC interface is selected.
+ *
+ * \note The endpoint index numbers as given in the interface's configuration structure must not overlap with any other
+ * interface, or endpoint bank corruption will occur. Gaps in the allocated endpoint numbers or non-sequential indexes
+ * within a single interface is allowed, but no two interfaces of any type have have interleaved endpoint indexes.
+ *
+ * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
+ *
+ * \return Boolean true if the endpoints were successfully configured, false otherwise.
+ */
+ bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Processes incoming control requests from the host, that are directed to the given CDC class interface. This should be
+ * linked to the library \ref EVENT_USB_Device_ControlRequest() event.
+ *
+ * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
+ */
+ void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** General management task for a given CDC 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] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
+ */
+ void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** CDC class driver event for a line encoding change on a CDC interface. This event fires each time the host requests a
+ * line encoding change (containing the serial parity, baud and other configuration information) and may be hooked in the
+ * user program by declaring a handler function with the same name and parameters listed here. The new line encoding
+ * settings are available in the LineEncoding structure inside the CDC interface structure passed as a parameter.
+ *
+ * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
+ */
+ void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** CDC class driver event for a control line state change on a CDC interface. This event fires each time the host requests a
+ * control line state change (containing the virtual serial control line states, such as DTR) 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
+ * are available in the ControlLineStates.HostToDevice value inside the CDC interface structure passed as a parameter, set as
+ * a mask of CDC_CONTROL_LINE_OUT_* masks.
+ *
+ * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
+ */
+ void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** CDC class driver event for a send break request sent to the device from the host. This is generally used to separate
+ * data or to indicate a special condition to the receiving device.
+ *
+ * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
+ * \param[in] Duration Duration of the break that has been sent by the host, in milliseconds.
+ */
+ void EVENT_CDC_Device_BreakSent(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
+ const uint8_t Duration) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Sends a given string to the attached USB host, if connected. If a host is not connected when the function is called, the
+ * string is discarded. Bytes will be queued for transmission to the host until either the endpoint bank becomes full, or the
+ * \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be
+ * packed into a single endpoint packet, increasing data throughput.
+ *
+ * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
+ * the call will fail.
+ *
+ * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
+ * \param[in] Data Pointer to the string to send to the host.
+ * \param[in] Length Size in bytes of the string to send to the host.
+ *
+ * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
+ const char* const Data,
+ const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+
+ /** Sends a given byte to the attached USB host, if connected. If a host is not connected when the function is called, the
+ * byte is discarded. Bytes will be queued for transmission to the host until either the endpoint bank becomes full, or the
+ * \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be
+ * packed into a single endpoint packet, increasing data throughput.
+ *
+ * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
+ * the call will fail.
+ *
+ * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
+ * \param[in] Data Byte of data to send to the host.
+ *
+ * \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum.
+ */
+ uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
+ const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Determines the number of bytes received by the CDC interface from the host, waiting to be read. This indicates the number
+ * of bytes in the OUT endpoint bank only, and thus the number of calls to \ref CDC_Device_ReceiveByte() which are guaranteed to
+ * succeed immediately. If multiple bytes are to be received, they should be buffered by the user application, as the endpoint
+ * bank will not be released back to the USB controller until all bytes are read.
+ *
+ * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
+ * the call will fail.
+ *
+ * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
+ *
+ * \return Total number of buffered bytes received from the host.
+ */
+ uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Reads a byte of data from the host. If no data is waiting to be read of if a USB host is not connected, the function
+ * returns a negative value. The \ref CDC_Device_BytesReceived() function may be queried in advance to determine how many
+ * bytes are currently buffered in the CDC interface's data receive endpoint bank, and thus how many repeated calls to this
+ * function which are guaranteed to succeed.
+ *
+ * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
+ * the call will fail.
+ *
+ * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
+ *
+ * \return Next received byte from the host, or a negative value if no data received.
+ */
+ int16_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) 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 Device state machine is in the \ref DEVICE_STATE_Configured state or
+ * the call will fail.
+ *
+ * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
+ *
+ * \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum.
+ */
+ uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Sends a Serial Control Line State Change notification to the host. This should be called when the virtual serial
+ * control lines (DCD, DSR, etc.) have changed states, or to give BREAK notifications to the host. Line states persist
+ * until they are cleared via a second notification. This should be called each time the CDC class driver's
+ * ControlLineStates.DeviceToHost value is updated to push the new states to the USB host.
+ *
+ * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
+ * the call will fail.
+ *
+ * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
+ */
+ void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Creates a standard character stream for the given CDC Device instance so that it can be used with all the regular
+ * functions in the avr-libc <stdio.h> library that accept a FILE stream as a destination (e.g. 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 getc()) or when the user application will implement its own
+ * line buffering.
+ *
+ * \note The created stream can be given as stdout if desired to direct the standard output from all <stdio.h> functions
+ * to the given CDC interface.
+ *
+ * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
+ * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed.
+ */
+ void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
+ FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+
+ /** Identical to CDC_Device_CreateStream(), except that reads are blocking until the calling stream function terminates
+ * the transfer. While blocking, the USB and CDC service tasks are called repeatedly to maintain USB communications.
+ *
+ * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
+ * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed.
+ */
+ 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);
+
+ /* Private Interface - For use in library only: */
+ #if !defined(__DOXYGEN__)
+ /* Function Prototypes: */
+ #if defined(__INCLUDE_FROM_CDC_DEVICE_C)
+ static int CDC_Device_putchar(char c,
+ FILE* Stream) ATTR_NON_NULL_PTR_ARG(2);
+ static int CDC_Device_getchar(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1);
+ static int CDC_Device_getchar_Blocking(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1);
+
+ void CDC_Device_Event_Stub(void);
+ void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
+ ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Device_Event_Stub);
+ void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
+ ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Device_Event_Stub);
+ void EVENT_CDC_Device_BreakSent(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
+ const uint8_t Duration) ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1)
+ ATTR_ALIAS(CDC_Device_Event_Stub);
+ #endif
+
+ #endif
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/CDC.lst b/firmware/LUFA/Drivers/USB/Class/Device/CDC.lst
new file mode 100644
index 0000000..ceb9593
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/CDC.lst
@@ -0,0 +1,1059 @@
+ 1 .file "CDC.c"
+ 2 __SREG__ = 0x3f
+ 3 __SP_H__ = 0x3e
+ 4 __SP_L__ = 0x3d
+ 5 __CCP__ = 0x34
+ 6 __tmp_reg__ = 0
+ 7 __zero_reg__ = 1
+ 15 .Ltext0:
+ 16 .section .text.CDC_Device_Event_Stub,"ax",@progbits
+ 17 .global CDC_Device_Event_Stub
+ 19 CDC_Device_Event_Stub:
+ 20 .LFB81:
+ 21 .LSM0:
+ 22 /* prologue: function */
+ 23 /* frame size = 0 */
+ 24 /* epilogue start */
+ 25 .LSM1:
+ 26 0000 0895 ret
+ 27 .LFE81:
+ 29 .section .text.CDC_Device_BytesReceived,"ax",@progbits
+ 30 .global CDC_Device_BytesReceived
+ 32 CDC_Device_BytesReceived:
+ 33 .LFB88:
+ 34 .LSM2:
+ 35 .LVL0:
+ 36 /* prologue: function */
+ 37 /* frame size = 0 */
+ 38 0000 FC01 movw r30,r24
+ 39 .LSM3:
+ 40 0002 8091 0000 lds r24,USB_DeviceState
+ 41 .LVL1:
+ 42 0006 8430 cpi r24,lo8(4)
+ 43 0008 01F4 brne .L4
+ 44 000a 8785 ldd r24,Z+15
+ 45 000c 9089 ldd r25,Z+16
+ 46 000e A189 ldd r26,Z+17
+ 47 0010 B289 ldd r27,Z+18
+ 48 0012 0097 sbiw r24,0
+ 49 0014 A105 cpc r26,__zero_reg__
+ 50 0016 B105 cpc r27,__zero_reg__
+ 51 0018 01F0 breq .L4
+ 52 .LSM4:
+ 53 001a 8581 ldd r24,Z+5
+ 54 .LBB71:
+ 55 .LBB72:
+ 56 .LSM5:
+ 57 001c 8093 E900 sts 233,r24
+ 58 .LBE72:
+ 59 .LBE71:
+ 60 .LBB73:
+ 61 .LBB74:
+ 62 .LSM6:
+ 63 0020 8091 E800 lds r24,232
+ 64 .LBE74:
+ 65 .LBE73:
+ 66 .LSM7:
+ 67 0024 82FF sbrs r24,2
+ 68 0026 00C0 rjmp .L4
+ 69 .LBB75:
+ 70 .LBB76:
+ 71 .LSM8:
+ 72 0028 8091 F200 lds r24,242
+ 73 .LBE76:
+ 74 .LBE75:
+ 75 .LSM9:
+ 76 002c 8823 tst r24
+ 77 002e 01F4 brne .L5
+ 78 .LBB77:
+ 79 .LBB78:
+ 80 .LSM10:
+ 81 0030 8091 E800 lds r24,232
+ 82 0034 8B77 andi r24,lo8(123)
+ 83 0036 8093 E800 sts 232,r24
+ 84 003a 00C0 rjmp .L4
+ 85 .L5:
+ 86 .LBE78:
+ 87 .LBE77:
+ 88 .LBB79:
+ 89 .LBB80:
+ 90 .LSM11:
+ 91 003c 8091 F200 lds r24,242
+ 92 0040 282F mov r18,r24
+ 93 0042 30E0 ldi r19,lo8(0)
+ 94 0044 00C0 rjmp .L6
+ 95 .L4:
+ 96 .LSM12:
+ 97 0046 20E0 ldi r18,lo8(0)
+ 98 0048 30E0 ldi r19,hi8(0)
+ 99 .L6:
+ 100 .LBE80:
+ 101 .LBE79:
+ 102 .LSM13:
+ 103 004a C901 movw r24,r18
+ 104 /* epilogue start */
+ 105 004c 0895 ret
+ 106 .LFE88:
+ 108 .section .text.CDC_Device_ReceiveByte,"ax",@progbits
+ 109 .global CDC_Device_ReceiveByte
+ 111 CDC_Device_ReceiveByte:
+ 112 .LFB89:
+ 113 .LSM14:
+ 114 .LVL2:
+ 115 /* prologue: function */
+ 116 /* frame size = 0 */
+ 117 0000 FC01 movw r30,r24
+ 118 .LSM15:
+ 119 0002 8091 0000 lds r24,USB_DeviceState
+ 120 .LVL3:
+ 121 0006 8430 cpi r24,lo8(4)
+ 122 0008 01F4 brne .L9
+ 123 000a 8785 ldd r24,Z+15
+ 124 000c 9089 ldd r25,Z+16
+ 125 000e A189 ldd r26,Z+17
+ 126 0010 B289 ldd r27,Z+18
+ 127 0012 0097 sbiw r24,0
+ 128 0014 A105 cpc r26,__zero_reg__
+ 129 0016 B105 cpc r27,__zero_reg__
+ 130 0018 01F0 breq .L9
+ 131 .LSM16:
+ 132 001a 8581 ldd r24,Z+5
+ 133 .LBB81:
+ 134 .LBB82:
+ 135 .LSM17:
+ 136 001c 8093 E900 sts 233,r24
+ 137 .LBE82:
+ 138 .LBE81:
+ 139 .LBB83:
+ 140 .LBB84:
+ 141 .LSM18:
+ 142 0020 8091 E800 lds r24,232
+ 143 .LBE84:
+ 144 .LBE83:
+ 145 .LSM19:
+ 146 0024 82FF sbrs r24,2
+ 147 0026 00C0 rjmp .L9
+ 148 .L10:
+ 149 .LBB85:
+ 150 .LBB86:
+ 151 .LSM20:
+ 152 0028 8091 F200 lds r24,242
+ 153 .LBE86:
+ 154 .LBE85:
+ 155 .LSM21:
+ 156 002c 8823 tst r24
+ 157 002e 01F4 brne .L12
+ 158 0030 2FEF ldi r18,lo8(-1)
+ 159 0032 3FEF ldi r19,hi8(-1)
+ 160 .LVL4:
+ 161 0034 00C0 rjmp .L13
+ 162 .LVL5:
+ 163 .L12:
+ 164 .LBB87:
+ 165 .LBB88:
+ 166 .LSM22:
+ 167 0036 8091 F100 lds r24,241
+ 168 .LBE88:
+ 169 .LBE87:
+ 170 .LSM23:
+ 171 003a 282F mov r18,r24
+ 172 .LVL6:
+ 173 003c 30E0 ldi r19,lo8(0)
+ 174 .LVL7:
+ 175 .L13:
+ 176 .LBB89:
+ 177 .LBB90:
+ 178 .LSM24:
+ 179 003e 8091 F200 lds r24,242
+ 180 .LBE90:
+ 181 .LBE89:
+ 182 .LSM25:
+ 183 0042 8823 tst r24
+ 184 0044 01F4 brne .L11
+ 185 .LBB91:
+ 186 .LBB92:
+ 187 .LSM26:
+ 188 0046 8091 E800 lds r24,232
+ 189 004a 8B77 andi r24,lo8(123)
+ 190 004c 8093 E800 sts 232,r24
+ 191 0050 00C0 rjmp .L11
+ 192 .LVL8:
+ 193 .L9:
+ 194 0052 2FEF ldi r18,lo8(-1)
+ 195 0054 3FEF ldi r19,hi8(-1)
+ 196 .LVL9:
+ 197 .L11:
+ 198 .LBE92:
+ 199 .LBE91:
+ 200 .LSM27:
+ 201 0056 C901 movw r24,r18
+ 202 .LVL10:
+ 203 /* epilogue start */
+ 204 0058 0895 ret
+ 205 .LFE89:
+ 207 .section .text.CDC_Device_CreateStream,"ax",@progbits
+ 208 .global CDC_Device_CreateStream
+ 210 CDC_Device_CreateStream:
+ 211 .LFB91:
+ 212 .LSM28:
+ 213 .LVL11:
+ 214 /* prologue: function */
+ 215 /* frame size = 0 */
+ 216 0000 FB01 movw r30,r22
+ 217 .LSM29:
+ 218 0002 2EE0 ldi r18,lo8(14)
+ 219 0004 DB01 movw r26,r22
+ 220 0006 1D92 st X+,__zero_reg__
+ 221 0008 2A95 dec r18
+ 222 000a 01F4 brne .-6
+ 223 000c 23E0 ldi r18,lo8(3)
+ 224 000e 2383 std Z+3,r18
+ 225 0010 20E0 ldi r18,lo8(gs(CDC_Device_putchar))
+ 226 0012 30E0 ldi r19,hi8(gs(CDC_Device_putchar))
+ 227 0014 3187 std Z+9,r19
+ 228 0016 2087 std Z+8,r18
+ 229 0018 20E0 ldi r18,lo8(gs(CDC_Device_getchar))
+ 230 001a 30E0 ldi r19,hi8(gs(CDC_Device_getchar))
+ 231 001c 3387 std Z+11,r19
+ 232 001e 2287 std Z+10,r18
+ 233 .LSM30:
+ 234 0020 9587 std Z+13,r25
+ 235 0022 8487 std Z+12,r24
+ 236 /* epilogue start */
+ 237 .LSM31:
+ 238 0024 0895 ret
+ 239 .LFE91:
+ 241 .section .text.CDC_Device_CreateBlockingStream,"ax",@progbits
+ 242 .global CDC_Device_CreateBlockingStream
+ 244 CDC_Device_CreateBlockingStream:
+ 245 .LFB92:
+ 246 .LSM32:
+ 247 .LVL12:
+ 248 /* prologue: function */
+ 249 /* frame size = 0 */
+ 250 0000 FB01 movw r30,r22
+ 251 .LSM33:
+ 252 0002 2EE0 ldi r18,lo8(14)
+ 253 0004 DB01 movw r26,r22
+ 254 0006 1D92 st X+,__zero_reg__
+ 255 0008 2A95 dec r18
+ 256 000a 01F4 brne .-6
+ 257 000c 23E0 ldi r18,lo8(3)
+ 258 000e 2383 std Z+3,r18
+ 259 0010 20E0 ldi r18,lo8(gs(CDC_Device_putchar))
+ 260 0012 30E0 ldi r19,hi8(gs(CDC_Device_putchar))
+ 261 0014 3187 std Z+9,r19
+ 262 0016 2087 std Z+8,r18
+ 263 0018 20E0 ldi r18,lo8(gs(CDC_Device_getchar_Blocking))
+ 264 001a 30E0 ldi r19,hi8(gs(CDC_Device_getchar_Blocking))
+ 265 001c 3387 std Z+11,r19
+ 266 001e 2287 std Z+10,r18
+ 267 .LSM34:
+ 268 0020 9587 std Z+13,r25
+ 269 0022 8487 std Z+12,r24
+ 270 /* epilogue start */
+ 271 .LSM35:
+ 272 0024 0895 ret
+ 273 .LFE92:
+ 275 .section .text.CDC_Device_getchar,"ax",@progbits
+ 277 CDC_Device_getchar:
+ 278 .LFB94:
+ 279 .LSM36:
+ 280 .LVL13:
+ 281 /* prologue: function */
+ 282 /* frame size = 0 */
+ 283 .LSM37:
+ 284 0000 FC01 movw r30,r24
+ 285 0002 8485 ldd r24,Z+12
+ 286 0004 9585 ldd r25,Z+13
+ 287 .LVL14:
+ 288 0006 0E94 0000 call CDC_Device_ReceiveByte
+ 289 000a 9C01 movw r18,r24
+ 290 .LVL15:
+ 291 .LSM38:
+ 292 000c 97FF sbrs r25,7
+ 293 000e 00C0 rjmp .L20
+ 294 .LVL16:
+ 295 0010 2EEF ldi r18,lo8(-2)
+ 296 0012 3FEF ldi r19,hi8(-2)
+ 297 .LVL17:
+ 298 .L20:
+ 299 .LSM39:
+ 300 0014 C901 movw r24,r18
+ 301 .LVL18:
+ 302 /* epilogue start */
+ 303 0016 0895 ret
+ 304 .LFE94:
+ 306 .section .text.CDC_Device_SendControlLineStateChange,"ax",@progbits
+ 307 .global CDC_Device_SendControlLineStateChange
+ 309 CDC_Device_SendControlLineStateChange:
+ 310 .LFB90:
+ 311 .LSM40:
+ 312 .LVL19:
+ 313 0000 0F93 push r16
+ 314 0002 1F93 push r17
+ 315 0004 DF93 push r29
+ 316 0006 CF93 push r28
+ 317 0008 CDB7 in r28,__SP_L__
+ 318 000a DEB7 in r29,__SP_H__
+ 319 000c 2897 sbiw r28,8
+ 320 000e 0FB6 in __tmp_reg__,__SREG__
+ 321 0010 F894 cli
+ 322 0012 DEBF out __SP_H__,r29
+ 323 0014 0FBE out __SREG__,__tmp_reg__
+ 324 0016 CDBF out __SP_L__,r28
+ 325 /* prologue: function */
+ 326 /* frame size = 8 */
+ 327 0018 8C01 movw r16,r24
+ 328 .LSM41:
+ 329 001a 8091 0000 lds r24,USB_DeviceState
+ 330 .LVL20:
+ 331 001e 8430 cpi r24,lo8(4)
+ 332 0020 01F4 brne .L25
+ 333 0022 F801 movw r30,r16
+ 334 0024 8785 ldd r24,Z+15
+ 335 0026 9089 ldd r25,Z+16
+ 336 0028 A189 ldd r26,Z+17
+ 337 002a B289 ldd r27,Z+18
+ 338 002c 0097 sbiw r24,0
+ 339 002e A105 cpc r26,__zero_reg__
+ 340 0030 B105 cpc r27,__zero_reg__
+ 341 0032 01F0 breq .L25
+ 342 .LSM42:
+ 343 0034 8185 ldd r24,Z+9
+ 344 .LBB93:
+ 345 .LBB94:
+ 346 .LSM43:
+ 347 0036 8093 E900 sts 233,r24
+ 348 .LBE94:
+ 349 .LBE93:
+ 350 .LSM44:
+ 351 003a DE01 movw r26,r28
+ 352 003c 1196 adiw r26,1
+ 353 003e E0E0 ldi r30,lo8(C.17.3562)
+ 354 0040 F0E0 ldi r31,hi8(C.17.3562)
+ 355 0042 88E0 ldi r24,lo8(8)
+ 356 .L24:
+ 357 0044 0190 ld r0,Z+
+ 358 0046 0D92 st X+,r0
+ 359 0048 8150 subi r24,lo8(-(-1))
+ 360 004a 01F4 brne .L24
+ 361 .LSM45:
+ 362 004c CE01 movw r24,r28
+ 363 004e 0196 adiw r24,1
+ 364 0050 68E0 ldi r22,lo8(8)
+ 365 0052 70E0 ldi r23,hi8(8)
+ 366 0054 40E0 ldi r20,lo8(0)
+ 367 0056 50E0 ldi r21,hi8(0)
+ 368 0058 0E94 0000 call Endpoint_Write_Stream_LE
+ 369 .LSM46:
+ 370 005c C801 movw r24,r16
+ 371 005e 0E96 adiw r24,14
+ 372 0060 61E0 ldi r22,lo8(1)
+ 373 0062 70E0 ldi r23,hi8(1)
+ 374 0064 40E0 ldi r20,lo8(0)
+ 375 0066 50E0 ldi r21,hi8(0)
+ 376 0068 0E94 0000 call Endpoint_Write_Stream_LE
+ 377 .LBB95:
+ 378 .LBB96:
+ 379 .LSM47:
+ 380 006c 8091 E800 lds r24,232
+ 381 0070 8E77 andi r24,lo8(126)
+ 382 0072 8093 E800 sts 232,r24
+ 383 .L25:
+ 384 /* epilogue start */
+ 385 .LBE96:
+ 386 .LBE95:
+ 387 .LSM48:
+ 388 0076 2896 adiw r28,8
+ 389 0078 0FB6 in __tmp_reg__,__SREG__
+ 390 007a F894 cli
+ 391 007c DEBF out __SP_H__,r29
+ 392 007e 0FBE out __SREG__,__tmp_reg__
+ 393 0080 CDBF out __SP_L__,r28
+ 394 0082 CF91 pop r28
+ 395 0084 DF91 pop r29
+ 396 0086 1F91 pop r17
+ 397 0088 0F91 pop r16
+ 398 .LVL21:
+ 399 008a 0895 ret
+ 400 .LFE90:
+ 402 .section .text.CDC_Device_SendString,"ax",@progbits
+ 403 .global CDC_Device_SendString
+ 405 CDC_Device_SendString:
+ 406 .LFB85:
+ 407 .LSM49:
+ 408 .LVL22:
+ 409 /* prologue: function */
+ 410 /* frame size = 0 */
+ 411 0000 FC01 movw r30,r24
+ 412 .LSM50:
+ 413 0002 8091 0000 lds r24,USB_DeviceState
+ 414 .LVL23:
+ 415 0006 8430 cpi r24,lo8(4)
+ 416 0008 01F4 brne .L28
+ 417 000a 8785 ldd r24,Z+15
+ 418 000c 9089 ldd r25,Z+16
+ 419 000e A189 ldd r26,Z+17
+ 420 0010 B289 ldd r27,Z+18
+ 421 0012 0097 sbiw r24,0
+ 422 0014 A105 cpc r26,__zero_reg__
+ 423 0016 B105 cpc r27,__zero_reg__
+ 424 0018 01F0 breq .L28
+ 425 .LSM51:
+ 426 001a 8181 ldd r24,Z+1
+ 427 .LBB97:
+ 428 .LBB98:
+ 429 .LSM52:
+ 430 001c 8093 E900 sts 233,r24
+ 431 .LBE98:
+ 432 .LBE97:
+ 433 .LSM53:
+ 434 0020 CB01 movw r24,r22
+ 435 0022 BA01 movw r22,r20
+ 436 .LVL24:
+ 437 0024 40E0 ldi r20,lo8(0)
+ 438 0026 50E0 ldi r21,hi8(0)
+ 439 .LVL25:
+ 440 0028 0E94 0000 call Endpoint_Write_Stream_LE
+ 441 .LVL26:
+ 442 002c 0895 ret
+ 443 .LVL27:
+ 444 .L28:
+ 445 002e 82E0 ldi r24,lo8(2)
+ 446 .LSM54:
+ 447 0030 0895 ret
+ 448 .LFE85:
+ 450 .section .text.CDC_Device_Flush,"ax",@progbits
+ 451 .global CDC_Device_Flush
+ 453 CDC_Device_Flush:
+ 454 .LFB87:
+ 455 .LSM55:
+ 456 .LVL28:
+ 457 /* prologue: function */
+ 458 /* frame size = 0 */
+ 459 0000 FC01 movw r30,r24
+ 460 .LSM56:
+ 461 0002 8091 0000 lds r24,USB_DeviceState
+ 462 .LVL29:
+ 463 0006 8430 cpi r24,lo8(4)
+ 464 0008 01F4 brne .L32
+ 465 000a 8785 ldd r24,Z+15
+ 466 000c 9089 ldd r25,Z+16
+ 467 000e A189 ldd r26,Z+17
+ 468 0010 B289 ldd r27,Z+18
+ 469 0012 0097 sbiw r24,0
+ 470 0014 A105 cpc r26,__zero_reg__
+ 471 0016 B105 cpc r27,__zero_reg__
+ 472 0018 01F0 breq .L32
+ 473 .LSM57:
+ 474 001a 8181 ldd r24,Z+1
+ 475 .LBB99:
+ 476 .LBB100:
+ 477 .LSM58:
+ 478 001c 8093 E900 sts 233,r24
+ 479 .LBE100:
+ 480 .LBE99:
+ 481 .LBB101:
+ 482 .LBB102:
+ 483 .LSM59:
+ 484 0020 8091 F200 lds r24,242
+ 485 .LBE102:
+ 486 .LBE101:
+ 487 .LSM60:
+ 488 0024 8823 tst r24
+ 489 0026 01F0 breq .L33
+ 490 .LBB103:
+ 491 .LBB104:
+ 492 .LSM61:
+ 493 0028 9091 E800 lds r25,232
+ 494 .LBE104:
+ 495 .LBE103:
+ 496 .LBB105:
+ 497 .LBB106:
+ 498 .LSM62:
+ 499 002c 8091 E800 lds r24,232
+ 500 0030 8E77 andi r24,lo8(126)
+ 501 0032 8093 E800 sts 232,r24
+ 502 .LBE106:
+ 503 .LBE105:
+ 504 .LSM63:
+ 505 0036 95FD sbrc r25,5
+ 506 0038 00C0 rjmp .L33
+ 507 .LSM64:
+ 508 003a 0E94 0000 call Endpoint_WaitUntilReady
+ 509 .LVL30:
+ 510 003e 982F mov r25,r24
+ 511 .LVL31:
+ 512 0040 8823 tst r24
+ 513 0042 01F4 brne .L34
+ 514 .LVL32:
+ 515 .LBB107:
+ 516 .LBB108:
+ 517 .LSM65:
+ 518 0044 8091 E800 lds r24,232
+ 519 .LVL33:
+ 520 0048 8E77 andi r24,lo8(126)
+ 521 004a 8093 E800 sts 232,r24
+ 522 004e 00C0 rjmp .L34
+ 523 .LVL34:
+ 524 .L32:
+ 525 0050 92E0 ldi r25,lo8(2)
+ 526 .LVL35:
+ 527 0052 00C0 rjmp .L34
+ 528 .LVL36:
+ 529 .L33:
+ 530 0054 90E0 ldi r25,lo8(0)
+ 531 .LVL37:
+ 532 .L34:
+ 533 .LBE108:
+ 534 .LBE107:
+ 535 .LSM66:
+ 536 0056 892F mov r24,r25
+ 537 /* epilogue start */
+ 538 0058 0895 ret
+ 539 .LFE87:
+ 541 .section .text.CDC_Device_USBTask,"ax",@progbits
+ 542 .global CDC_Device_USBTask
+ 544 CDC_Device_USBTask:
+ 545 .LFB84:
+ 546 .LSM67:
+ 547 .LVL38:
+ 548 /* prologue: function */
+ 549 /* frame size = 0 */
+ 550 0000 FC01 movw r30,r24
+ 551 .LSM68:
+ 552 0002 8091 0000 lds r24,USB_DeviceState
+ 553 .LVL39:
+ 554 0006 8430 cpi r24,lo8(4)
+ 555 0008 01F4 brne .L38
+ 556 000a 8785 ldd r24,Z+15
+ 557 000c 9089 ldd r25,Z+16
+ 558 000e A189 ldd r26,Z+17
+ 559 0010 B289 ldd r27,Z+18
+ 560 0012 0097 sbiw r24,0
+ 561 0014 A105 cpc r26,__zero_reg__
+ 562 0016 B105 cpc r27,__zero_reg__
+ 563 0018 01F0 breq .L38
+ 564 .LSM69:
+ 565 001a CF01 movw r24,r30
+ 566 001c 0E94 0000 call CDC_Device_Flush
+ 567 .LVL40:
+ 568 .L38:
+ 569 0020 0895 ret
+ 570 .LFE84:
+ 572 .section .text.CDC_Device_getchar_Blocking,"ax",@progbits
+ 574 CDC_Device_getchar_Blocking:
+ 575 .LFB95:
+ 576 .LSM70:
+ 577 .LVL41:
+ 578 0000 CF93 push r28
+ 579 0002 DF93 push r29
+ 580 /* prologue: function */
+ 581 /* frame size = 0 */
+ 582 0004 EC01 movw r28,r24
+ 583 0006 00C0 rjmp .L40
+ 584 .LVL42:
+ 585 .L43:
+ 586 .LSM71:
+ 587 0008 8091 0000 lds r24,USB_DeviceState
+ 588 .LVL43:
+ 589 000c 8823 tst r24
+ 590 000e 01F4 brne .L41
+ 591 0010 2EEF ldi r18,lo8(-2)
+ 592 0012 3FEF ldi r19,hi8(-2)
+ 593 0014 00C0 rjmp .L42
+ 594 .L41:
+ 595 .LSM72:
+ 596 0016 8C85 ldd r24,Y+12
+ 597 0018 9D85 ldd r25,Y+13
+ 598 001a 0E94 0000 call CDC_Device_USBTask
+ 599 .LVL44:
+ 600 .LSM73:
+ 601 001e 0E94 0000 call USB_USBTask
+ 602 .LVL45:
+ 603 .L40:
+ 604 .LSM74:
+ 605 0022 8C85 ldd r24,Y+12
+ 606 0024 9D85 ldd r25,Y+13
+ 607 0026 0E94 0000 call CDC_Device_ReceiveByte
+ 608 002a 9C01 movw r18,r24
+ 609 .LVL46:
+ 610 002c 97FD sbrc r25,7
+ 611 002e 00C0 rjmp .L43
+ 612 .L42:
+ 613 .LSM75:
+ 614 0030 C901 movw r24,r18
+ 615 .LVL47:
+ 616 /* epilogue start */
+ 617 0032 DF91 pop r29
+ 618 0034 CF91 pop r28
+ 619 .LVL48:
+ 620 0036 0895 ret
+ 621 .LFE95:
+ 623 .section .text.CDC_Device_SendByte,"ax",@progbits
+ 624 .global CDC_Device_SendByte
+ 626 CDC_Device_SendByte:
+ 627 .LFB86:
+ 628 .LSM76:
+ 629 .LVL49:
+ 630 0000 1F93 push r17
+ 631 /* prologue: function */
+ 632 /* frame size = 0 */
+ 633 0002 FC01 movw r30,r24
+ 634 0004 162F mov r17,r22
+ 635 .LSM77:
+ 636 0006 8091 0000 lds r24,USB_DeviceState
+ 637 .LVL50:
+ 638 000a 8430 cpi r24,lo8(4)
+ 639 000c 01F4 brne .L46
+ 640 .LVL51:
+ 641 000e 8785 ldd r24,Z+15
+ 642 0010 9089 ldd r25,Z+16
+ 643 0012 A189 ldd r26,Z+17
+ 644 0014 B289 ldd r27,Z+18
+ 645 0016 0097 sbiw r24,0
+ 646 0018 A105 cpc r26,__zero_reg__
+ 647 001a B105 cpc r27,__zero_reg__
+ 648 001c 01F0 breq .L46
+ 649 .LSM78:
+ 650 001e 8181 ldd r24,Z+1
+ 651 .LBB109:
+ 652 .LBB110:
+ 653 .LSM79:
+ 654 0020 8093 E900 sts 233,r24
+ 655 .LBE110:
+ 656 .LBE109:
+ 657 .LBB111:
+ 658 .LBB112:
+ 659 .LSM80:
+ 660 0024 8091 E800 lds r24,232
+ 661 .LBE112:
+ 662 .LBE111:
+ 663 .LSM81:
+ 664 0028 85FD sbrc r24,5
+ 665 002a 00C0 rjmp .L47
+ 666 .LBB113:
+ 667 .LBB114:
+ 668 .LBB115:
+ 669 .LSM82:
+ 670 002c 8091 E800 lds r24,232
+ 671 0030 8E77 andi r24,lo8(126)
+ 672 0032 8093 E800 sts 232,r24
+ 673 .LBE115:
+ 674 .LBE114:
+ 675 .LSM83:
+ 676 0036 0E94 0000 call Endpoint_WaitUntilReady
+ 677 .LVL52:
+ 678 003a 8823 tst r24
+ 679 .LVL53:
+ 680 003c 01F4 brne .L48
+ 681 .LVL54:
+ 682 .L47:
+ 683 .LBE113:
+ 684 .LBB116:
+ 685 .LBB117:
+ 686 .LSM84:
+ 687 003e 1093 F100 sts 241,r17
+ 688 0042 80E0 ldi r24,lo8(0)
+ 689 0044 00C0 rjmp .L48
+ 690 .LVL55:
+ 691 .L46:
+ 692 .LSM85:
+ 693 0046 82E0 ldi r24,lo8(2)
+ 694 .LVL56:
+ 695 .L48:
+ 696 .LVL57:
+ 697 /* epilogue start */
+ 698 .LBE117:
+ 699 .LBE116:
+ 700 .LSM86:
+ 701 0048 1F91 pop r17
+ 702 .LVL58:
+ 703 004a 0895 ret
+ 704 .LFE86:
+ 706 .section .text.CDC_Device_putchar,"ax",@progbits
+ 708 CDC_Device_putchar:
+ 709 .LFB93:
+ 710 .LSM87:
+ 711 .LVL59:
+ 712 /* prologue: function */
+ 713 /* frame size = 0 */
+ 714 0000 282F mov r18,r24
+ 715 0002 FB01 movw r30,r22
+ 716 .LSM88:
+ 717 0004 8485 ldd r24,Z+12
+ 718 0006 9585 ldd r25,Z+13
+ 719 .LVL60:
+ 720 0008 622F mov r22,r18
+ 721 .LVL61:
+ 722 000a 0E94 0000 call CDC_Device_SendByte
+ 723 .LVL62:
+ 724 000e 8823 tst r24
+ 725 0010 01F4 brne .L51
+ 726 0012 20E0 ldi r18,lo8(0)
+ 727 0014 30E0 ldi r19,hi8(0)
+ 728 0016 00C0 rjmp .L52
+ 729 .L51:
+ 730 0018 2FEF ldi r18,lo8(-1)
+ 731 001a 3FEF ldi r19,hi8(-1)
+ 732 .L52:
+ 733 .LSM89:
+ 734 001c C901 movw r24,r18
+ 735 /* epilogue start */
+ 736 001e 0895 ret
+ 737 .LFE93:
+ 739 .section .text.CDC_Device_ConfigureEndpoints,"ax",@progbits
+ 740 .global CDC_Device_ConfigureEndpoints
+ 742 CDC_Device_ConfigureEndpoints:
+ 743 .LFB83:
+ 744 .LSM90:
+ 745 .LVL63:
+ 746 0000 1F93 push r17
+ 747 0002 CF93 push r28
+ 748 0004 DF93 push r29
+ 749 /* prologue: function */
+ 750 /* frame size = 0 */
+ 751 0006 EC01 movw r28,r24
+ 752 .LSM91:
+ 753 0008 0D96 adiw r24,13
+ 754 .LVL64:
+ 755 000a FC01 movw r30,r24
+ 756 000c 89E0 ldi r24,lo8(9)
+ 757 000e DF01 movw r26,r30
+ 758 0010 1D92 st X+,__zero_reg__
+ 759 0012 8A95 dec r24
+ 760 0014 01F4 brne .-6
+ 761 0016 11E0 ldi r17,lo8(1)
+ 762 .LVL65:
+ 763 .L64:
+ 764 .LBB118:
+ 765 .LBB119:
+ 766 .LSM92:
+ 767 0018 8981 ldd r24,Y+1
+ 768 001a 1817 cp r17,r24
+ 769 001c 01F4 brne .L55
+ 770 .LSM93:
+ 771 001e EA81 ldd r30,Y+2
+ 772 0020 FB81 ldd r31,Y+3
+ 773 .LVL66:
+ 774 .LSM94:
+ 775 0022 8C81 ldd r24,Y+4
+ 776 .LVL67:
+ 777 0024 62E0 ldi r22,lo8(2)
+ 778 .LVL68:
+ 779 0026 00C0 rjmp .L67
+ 780 .LVL69:
+ 781 .L55:
+ 782 .LSM95:
+ 783 0028 8D81 ldd r24,Y+5
+ 784 002a 1817 cp r17,r24
+ 785 002c 01F4 brne .L57
+ 786 .LSM96:
+ 787 002e EE81 ldd r30,Y+6
+ 788 0030 FF81 ldd r31,Y+7
+ 789 .LVL70:
+ 790 .LSM97:
+ 791 0032 8885 ldd r24,Y+8
+ 792 .LVL71:
+ 793 0034 62E0 ldi r22,lo8(2)
+ 794 .LVL72:
+ 795 0036 30E0 ldi r19,lo8(0)
+ 796 .LVL73:
+ 797 0038 00C0 rjmp .L56
+ 798 .LVL74:
+ 799 .L57:
+ 800 .LSM98:
+ 801 003a 8985 ldd r24,Y+9
+ 802 003c 1817 cp r17,r24
+ 803 003e 01F4 brne .L58
+ 804 .LSM99:
+ 805 0040 EA85 ldd r30,Y+10
+ 806 0042 FB85 ldd r31,Y+11
+ 807 .LVL75:
+ 808 .LSM100:
+ 809 0044 8C85 ldd r24,Y+12
+ 810 .LVL76:
+ 811 0046 63E0 ldi r22,lo8(3)
+ 812 .LVL77:
+ 813 .L67:
+ 814 0048 31E0 ldi r19,lo8(1)
+ 815 .LVL78:
+ 816 .L56:
+ 817 .LSM101:
+ 818 004a 8823 tst r24
+ 819 004c 01F4 brne .L59
+ 820 004e 40E0 ldi r20,lo8(0)
+ 821 0050 00C0 rjmp .L60
+ 822 .L59:
+ 823 0052 44E0 ldi r20,lo8(4)
+ 824 .L60:
+ 825 0054 20E0 ldi r18,lo8(0)
+ 826 .LVL79:
+ 827 0056 88E0 ldi r24,lo8(8)
+ 828 0058 90E0 ldi r25,hi8(8)
+ 829 .LVL80:
+ 830 005a 00C0 rjmp .L61
+ 831 .L62:
+ 832 .LBB120:
+ 833 .LBB121:
+ 834 .LBB122:
+ 835 .LBB123:
+ 836 .LSM102:
+ 837 005c 2F5F subi r18,lo8(-(1))
+ 838 .LSM103:
+ 839 005e 880F lsl r24
+ 840 0060 991F rol r25
+ 841 .L61:
+ 842 .LSM104:
+ 843 0062 8E17 cp r24,r30
+ 844 0064 9F07 cpc r25,r31
+ 845 0066 00F0 brlo .L62
+ 846 .LBE123:
+ 847 .LBE122:
+ 848 .LBE121:
+ 849 .LSM105:
+ 850 0068 6295 swap r22
+ 851 006a 660F lsl r22
+ 852 006c 660F lsl r22
+ 853 006e 607C andi r22,lo8(-64)
+ 854 0070 632B or r22,r19
+ 855 0072 4260 ori r20,lo8(2)
+ 856 0074 2295 swap r18
+ 857 0076 207F andi r18,lo8(-16)
+ 858 0078 422B or r20,r18
+ 859 007a 812F mov r24,r17
+ 860 .LVL81:
+ 861 007c 0E94 0000 call Endpoint_ConfigureEndpoint_Prv
+ 862 .LVL82:
+ 863 .LBE120:
+ 864 .LSM106:
+ 865 0080 8823 tst r24
+ 866 0082 01F0 breq .L63
+ 867 .L58:
+ 868 .LBE119:
+ 869 .LSM107:
+ 870 0084 1F5F subi r17,lo8(-(1))
+ 871 0086 1530 cpi r17,lo8(5)
+ 872 0088 01F4 brne .L64
+ 873 008a 81E0 ldi r24,lo8(1)
+ 874 .L63:
+ 875 /* epilogue start */
+ 876 .LBE118:
+ 877 .LSM108:
+ 878 008c DF91 pop r29
+ 879 008e CF91 pop r28
+ 880 .LVL83:
+ 881 0090 1F91 pop r17
+ 882 .LVL84:
+ 883 0092 0895 ret
+ 884 .LFE83:
+ 886 .section .text.CDC_Device_ProcessControlRequest,"ax",@progbits
+ 887 .global CDC_Device_ProcessControlRequest
+ 889 CDC_Device_ProcessControlRequest:
+ 890 .LFB82:
+ 891 .LSM109:
+ 892 .LVL85:
+ 893 0000 CF93 push r28
+ 894 0002 DF93 push r29
+ 895 /* prologue: function */
+ 896 /* frame size = 0 */
+ 897 0004 EC01 movw r28,r24
+ 898 .LBB124:
+ 899 .LBB125:
+ 900 .LSM110:
+ 901 0006 8091 E800 lds r24,232
+ 902 .LVL86:
+ 903 .LBE125:
+ 904 .LBE124:
+ 905 .LSM111:
+ 906 000a 83FF sbrs r24,3
+ 907 000c 00C0 rjmp .L75
+ 908 .LSM112:
+ 909 000e 8881 ld r24,Y
+ 910 0010 90E0 ldi r25,lo8(0)
+ 911 0012 2091 0000 lds r18,USB_ControlRequest+4
+ 912 0016 3091 0000 lds r19,(USB_ControlRequest+4)+1
+ 913 001a 2817 cp r18,r24
+ 914 001c 3907 cpc r19,r25
+ 915 001e 01F0 breq .+2
+ 916 0020 00C0 rjmp .L75
+ 917 .LSM113:
+ 918 0022 8091 0000 lds r24,USB_ControlRequest+1
+ 919 0026 8132 cpi r24,lo8(33)
+ 920 0028 01F0 breq .L71
+ 921 002a 8232 cpi r24,lo8(34)
+ 922 002c 00F4 brsh .L74
+ 923 002e 8032 cpi r24,lo8(32)
+ 924 0030 01F0 breq .+2
+ 925 0032 00C0 rjmp .L75
+ 926 0034 00C0 rjmp .L76
+ 927 .L74:
+ 928 0036 8232 cpi r24,lo8(34)
+ 929 0038 01F0 breq .L72
+ 930 003a 8332 cpi r24,lo8(35)
+ 931 003c 01F0 breq .+2
+ 932 003e 00C0 rjmp .L75
+ 933 0040 00C0 rjmp .L77
+ 934 .L71:
+ 935 .LSM114:
+ 936 0042 8091 0000 lds r24,USB_ControlRequest
+ 937 0046 813A cpi r24,lo8(-95)
+ 938 0048 01F0 breq .+2
+ 939 004a 00C0 rjmp .L75
+ 940 .LBB126:
+ 941 .LBB127:
+ 942 .LSM115:
+ 943 004c 8091 E800 lds r24,232
+ 944 0050 877F andi r24,lo8(-9)
+ 945 0052 8093 E800 sts 232,r24
+ 946 .LBE127:
+ 947 .LBE126:
+ 948 .LSM116:
+ 949 0056 CE01 movw r24,r28
+ 950 0058 0F96 adiw r24,15
+ 951 005a 67E0 ldi r22,lo8(7)
+ 952 005c 70E0 ldi r23,hi8(7)
+ 953 005e 0E94 0000 call Endpoint_Write_Control_Stream_LE
+ 954 .LBB128:
+ 955 .LBB129:
+ 956 .LSM117:
+ 957 0062 8091 E800 lds r24,232
+ 958 0066 8B77 andi r24,lo8(123)
+ 959 0068 8093 E800 sts 232,r24
+ 960 006c 00C0 rjmp .L75
+ 961 .L76:
+ 962 .LBE129:
+ 963 .LBE128:
+ 964 .LSM118:
+ 965 006e 8091 0000 lds r24,USB_ControlRequest
+ 966 0072 8132 cpi r24,lo8(33)
+ 967 0074 01F4 brne .L75
+ 968 .LBB130:
+ 969 .LBB131:
+ 970 .LSM119:
+ 971 0076 8091 E800 lds r24,232
+ 972 007a 877F andi r24,lo8(-9)
+ 973 007c 8093 E800 sts 232,r24
+ 974 .LBE131:
+ 975 .LBE130:
+ 976 .LSM120:
+ 977 0080 CE01 movw r24,r28
+ 978 0082 0F96 adiw r24,15
+ 979 0084 67E0 ldi r22,lo8(7)
+ 980 0086 70E0 ldi r23,hi8(7)
+ 981 0088 0E94 0000 call Endpoint_Read_Control_Stream_LE
+ 982 .LBB132:
+ 983 .LBB133:
+ 984 .LSM121:
+ 985 008c 8091 E800 lds r24,232
+ 986 0090 8E77 andi r24,lo8(126)
+ 987 0092 8093 E800 sts 232,r24
+ 988 .LBE133:
+ 989 .LBE132:
+ 990 .LSM122:
+ 991 0096 CE01 movw r24,r28
+ 992 0098 0E94 0000 call EVENT_CDC_Device_LineEncodingChanged
+ 993 009c 00C0 rjmp .L75
+ 994 .L72:
+ 995 .LSM123:
+ 996 009e 8091 0000 lds r24,USB_ControlRequest
+ 997 00a2 8132 cpi r24,lo8(33)
+ 998 00a4 01F4 brne .L75
+ 999 .LBB134:
+ 1000 .LBB135:
+ 1001 .LSM124:
+ 1002 00a6 8091 E800 lds r24,232
+ 1003 00aa 877F andi r24,lo8(-9)
+ 1004 00ac 8093 E800 sts 232,r24
+ 1005 .LBE135:
+ 1006 .LBE134:
+ 1007 .LSM125:
+ 1008 00b0 0E94 0000 call Endpoint_ClearStatusStage
+ 1009 .LSM126:
+ 1010 00b4 8091 0000 lds r24,USB_ControlRequest+2
+ 1011 00b8 8D87 std Y+13,r24
+ 1012 .LSM127:
+ 1013 00ba CE01 movw r24,r28
+ 1014 00bc 0E94 0000 call EVENT_CDC_Device_ControLineStateChanged
+ 1015 00c0 00C0 rjmp .L75
+ 1016 .L77:
+ 1017 .LSM128:
+ 1018 00c2 8091 0000 lds r24,USB_ControlRequest
+ 1019 00c6 8132 cpi r24,lo8(33)
+ 1020 00c8 01F4 brne .L75
+ 1021 .LBB136:
+ 1022 .LBB137:
+ 1023 .LSM129:
+ 1024 00ca 8091 E800 lds r24,232
+ 1025 00ce 877F andi r24,lo8(-9)
+ 1026 00d0 8093 E800 sts 232,r24
+ 1027 .LBE137:
+ 1028 .LBE136:
+ 1029 .LSM130:
+ 1030 00d4 0E94 0000 call Endpoint_ClearStatusStage
+ 1031 .LSM131:
+ 1032 00d8 CE01 movw r24,r28
+ 1033 00da 6091 0000 lds r22,USB_ControlRequest+2
+ 1034 00de 0E94 0000 call EVENT_CDC_Device_BreakSent
+ 1035 .L75:
+ 1036 /* epilogue start */
+ 1037 .LSM132:
+ 1038 00e2 DF91 pop r29
+ 1039 00e4 CF91 pop r28
+ 1040 .LVL87:
+ 1041 00e6 0895 ret
+ 1042 .LFE82:
+ 1044 .data
+ 1047 C.17.3562:
+ 1048 0000 A1 .byte -95
+ 1049 0001 20 .byte 32
+ 1050 0002 0000 .word 0
+ 1051 0004 0000 .word 0
+ 1052 0006 0100 .word 1
+ 1053 .weak EVENT_CDC_Device_LineEncodingChanged
+ 1054 .set EVENT_CDC_Device_LineEncodingChanged,CDC_Device_Event_Stub
+ 1055 .weak EVENT_CDC_Device_ControLineStateChanged
+ 1056 .set EVENT_CDC_Device_ControLineStateChanged,CDC_Device_Event_Stub
+ 1057 .weak EVENT_CDC_Device_BreakSent
+ 1058 .set EVENT_CDC_Device_BreakSent,CDC_Device_Event_Stub
+ 1195 .Letext0:
+DEFINED SYMBOLS
+ *ABS*:0000000000000000 CDC.c
+ /tmp/cc6wpRq4.s:2 *ABS*:000000000000003f __SREG__
+ /tmp/cc6wpRq4.s:3 *ABS*:000000000000003e __SP_H__
+ /tmp/cc6wpRq4.s:4 *ABS*:000000000000003d __SP_L__
+ /tmp/cc6wpRq4.s:5 *ABS*:0000000000000034 __CCP__
+ /tmp/cc6wpRq4.s:6 *ABS*:0000000000000000 __tmp_reg__
+ /tmp/cc6wpRq4.s:7 *ABS*:0000000000000001 __zero_reg__
+ /tmp/cc6wpRq4.s:19 .text.CDC_Device_Event_Stub:0000000000000000 CDC_Device_Event_Stub
+ /tmp/cc6wpRq4.s:32 .text.CDC_Device_BytesReceived:0000000000000000 CDC_Device_BytesReceived
+ /tmp/cc6wpRq4.s:111 .text.CDC_Device_ReceiveByte:0000000000000000 CDC_Device_ReceiveByte
+ /tmp/cc6wpRq4.s:210 .text.CDC_Device_CreateStream:0000000000000000 CDC_Device_CreateStream
+ /tmp/cc6wpRq4.s:708 .text.CDC_Device_putchar:0000000000000000 CDC_Device_putchar
+ /tmp/cc6wpRq4.s:277 .text.CDC_Device_getchar:0000000000000000 CDC_Device_getchar
+ /tmp/cc6wpRq4.s:244 .text.CDC_Device_CreateBlockingStream:0000000000000000 CDC_Device_CreateBlockingStream
+ /tmp/cc6wpRq4.s:574 .text.CDC_Device_getchar_Blocking:0000000000000000 CDC_Device_getchar_Blocking
+ /tmp/cc6wpRq4.s:309 .text.CDC_Device_SendControlLineStateChange:0000000000000000 CDC_Device_SendControlLineStateChange
+ /tmp/cc6wpRq4.s:1047 .data:0000000000000000 C.17.3562
+ /tmp/cc6wpRq4.s:405 .text.CDC_Device_SendString:0000000000000000 CDC_Device_SendString
+ /tmp/cc6wpRq4.s:453 .text.CDC_Device_Flush:0000000000000000 CDC_Device_Flush
+ /tmp/cc6wpRq4.s:544 .text.CDC_Device_USBTask:0000000000000000 CDC_Device_USBTask
+ /tmp/cc6wpRq4.s:626 .text.CDC_Device_SendByte:0000000000000000 CDC_Device_SendByte
+ /tmp/cc6wpRq4.s:742 .text.CDC_Device_ConfigureEndpoints:0000000000000000 CDC_Device_ConfigureEndpoints
+ /tmp/cc6wpRq4.s:889 .text.CDC_Device_ProcessControlRequest:0000000000000000 CDC_Device_ProcessControlRequest
+ /tmp/cc6wpRq4.s:19 .text.CDC_Device_Event_Stub:0000000000000000 EVENT_CDC_Device_LineEncodingChanged
+ /tmp/cc6wpRq4.s:19 .text.CDC_Device_Event_Stub:0000000000000000 EVENT_CDC_Device_ControLineStateChanged
+ /tmp/cc6wpRq4.s:19 .text.CDC_Device_Event_Stub:0000000000000000 EVENT_CDC_Device_BreakSent
+
+UNDEFINED SYMBOLS
+USB_DeviceState
+Endpoint_Write_Stream_LE
+Endpoint_WaitUntilReady
+USB_USBTask
+Endpoint_ConfigureEndpoint_Prv
+USB_ControlRequest
+Endpoint_Write_Control_Stream_LE
+Endpoint_Read_Control_Stream_LE
+Endpoint_ClearStatusStage
+__do_copy_data
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/CDC.o b/firmware/LUFA/Drivers/USB/Class/Device/CDC.o
new file mode 100644
index 0000000..4e47b49
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/CDC.o
Binary files differ
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/HID.c b/firmware/LUFA/Drivers/USB/Class/Device/HID.c
new file mode 100644
index 0000000..f538610
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/HID.c
@@ -0,0 +1,190 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define __INCLUDE_FROM_USB_DRIVER
+#include "../../HighLevel/USBMode.h"
+#if defined(USB_CAN_BE_DEVICE)
+
+#define __INCLUDE_FROM_HID_DRIVER
+#define __INCLUDE_FROM_HID_DEVICE_C
+#include "HID.h"
+
+void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
+{
+ if (!(Endpoint_IsSETUPReceived()))
+ return;
+
+ if (USB_ControlRequest.wIndex != HIDInterfaceInfo->Config.InterfaceNumber)
+ return;
+
+ switch (USB_ControlRequest.bRequest)
+ {
+ case HID_REQ_GetReport:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ uint16_t ReportSize = 0;
+ uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF);
+ uint8_t ReportType = (USB_ControlRequest.wValue >> 8) - 1;
+ uint8_t ReportData[HIDInterfaceInfo->Config.PrevReportINBufferSize];
+
+ memset(ReportData, 0, sizeof(ReportData));
+
+ CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, ReportType, ReportData, &ReportSize);
+
+ if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL)
+ memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportData, HIDInterfaceInfo->Config.PrevReportINBufferSize);
+
+ Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
+
+ Endpoint_ClearSETUP();
+ Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
+ Endpoint_ClearOUT();
+ }
+
+ break;
+ case HID_REQ_SetReport:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ uint16_t ReportSize = USB_ControlRequest.wLength;
+ uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF);
+ uint8_t ReportType = (USB_ControlRequest.wValue >> 8) - 1;
+ uint8_t ReportData[ReportSize];
+
+ Endpoint_ClearSETUP();
+ Endpoint_Read_Control_Stream_LE(ReportData, ReportSize);
+ Endpoint_ClearIN();
+
+ CALLBACK_HID_Device_ProcessHIDReport(HIDInterfaceInfo, ReportID, ReportType, ReportData, ReportSize);
+ }
+
+ break;
+ case HID_REQ_GetProtocol:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+ Endpoint_Write_Byte(HIDInterfaceInfo->State.UsingReportProtocol);
+ Endpoint_ClearIN();
+ Endpoint_ClearStatusStage();
+ }
+
+ break;
+ case HID_REQ_SetProtocol:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+ Endpoint_ClearStatusStage();
+
+ HIDInterfaceInfo->State.UsingReportProtocol = ((USB_ControlRequest.wValue & 0xFF) != 0x00);
+ }
+
+ break;
+ case HID_REQ_SetIdle:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+ Endpoint_ClearStatusStage();
+
+ HIDInterfaceInfo->State.IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6);
+ }
+
+ break;
+ case HID_REQ_GetIdle:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+ Endpoint_Write_Byte(HIDInterfaceInfo->State.IdleCount >> 2);
+ Endpoint_ClearIN();
+ Endpoint_ClearStatusStage();
+ }
+
+ break;
+ }
+}
+
+bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
+{
+ memset(&HIDInterfaceInfo->State, 0x00, sizeof(HIDInterfaceInfo->State));
+ HIDInterfaceInfo->State.UsingReportProtocol = true;
+ HIDInterfaceInfo->State.IdleCount = 500;
+
+ if (!(Endpoint_ConfigureEndpoint(HIDInterfaceInfo->Config.ReportINEndpointNumber, EP_TYPE_INTERRUPT,
+ ENDPOINT_DIR_IN, HIDInterfaceInfo->Config.ReportINEndpointSize,
+ HIDInterfaceInfo->Config.ReportINEndpointDoubleBank ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
+{
+ if (USB_DeviceState != DEVICE_STATE_Configured)
+ return;
+
+ Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpointNumber);
+
+ if (Endpoint_IsReadWriteAllowed())
+ {
+ uint8_t ReportINData[HIDInterfaceInfo->Config.PrevReportINBufferSize];
+ uint8_t ReportID = 0;
+ uint16_t ReportINSize = 0;
+
+ memset(ReportINData, 0, sizeof(ReportINData));
+
+ bool ForceSend = CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, HID_REPORT_ITEM_In,
+ ReportINData, &ReportINSize);
+ bool StatesChanged = false;
+ bool IdlePeriodElapsed = (HIDInterfaceInfo->State.IdleCount && !(HIDInterfaceInfo->State.IdleMSRemaining));
+
+ if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL)
+ {
+ StatesChanged = (memcmp(ReportINData, HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINSize) != 0);
+ memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINData, HIDInterfaceInfo->Config.PrevReportINBufferSize);
+ }
+
+ if (ReportINSize && (ForceSend || StatesChanged || IdlePeriodElapsed))
+ {
+ HIDInterfaceInfo->State.IdleMSRemaining = HIDInterfaceInfo->State.IdleCount;
+
+ Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpointNumber);
+
+ if (ReportID)
+ Endpoint_Write_Byte(ReportID);
+
+ Endpoint_Write_Stream_LE(ReportINData, ReportINSize, NO_STREAM_CALLBACK);
+
+ Endpoint_ClearIN();
+ }
+ }
+}
+
+#endif
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/HID.h b/firmware/LUFA/Drivers/USB/Class/Device/HID.h
new file mode 100644
index 0000000..49358f5
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/HID.h
@@ -0,0 +1,222 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Device mode driver for the library USB HID Class driver.
+ *
+ * Device mode driver for the library USB HID 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_USBClassHID
+ * @defgroup Group_USBClassHIDDevice HID Class Device 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/Device/HID.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ *
+ * \section Module Description
+ * Device Mode USB Class driver framework interface, for the HID USB Class driver.
+ *
+ * @{
+ */
+
+#ifndef _HID_CLASS_DEVICE_H_
+#define _HID_CLASS_DEVICE_H_
+
+ /* Includes: */
+ #include "../../USB.h"
+ #include "../Common/HID.h"
+
+ #include <string.h>
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_HID_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ #if defined(__INCLUDE_FROM_HID_DEVICE_C) && defined(NO_STREAM_CALLBACKS)
+ #error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
+ #endif
+
+
+ /* Public Interface - May be used in end-application: */
+ /* Type Defines: */
+ /** \brief HID Class Device Mode Configuration and State Structure.
+ *
+ * Class state structure. An instance of this structure should be made for each HID interface
+ * within the user application, and passed to each of the HID class driver functions as the
+ * HIDInterfaceInfo parameter. This stores each HID interface's configuration and state information.
+ *
+ * \note Due to technical limitations, the HID device class driver does not utilize a separate OUT
+ * endpoint for host->device communications. Instead, the host->device data (if any) is sent to
+ * the device via the control endpoint.
+ */
+ typedef struct
+ {
+ const struct
+ {
+ uint8_t InterfaceNumber; /**< Interface number of the HID interface within the device. */
+
+ uint8_t ReportINEndpointNumber; /**< Endpoint number of the HID interface's IN report endpoint. */
+ uint16_t ReportINEndpointSize; /**< Size in bytes of the HID interface's IN report endpoint. */
+ bool ReportINEndpointDoubleBank; /**< Indicates if the HID interface's IN report endpoint should use double banking. */
+
+ void* PrevReportINBuffer; /**< Pointer to a buffer where the previously created HID input report can be
+ * stored by the driver, for comparison purposes to detect report changes that
+ * must be sent immediately to the host. This should point to a buffer big enough
+ * to hold the largest HID input report sent from the HID interface. If this is set
+ * to NULL, it is up to the user to force transfers when needed in the
+ * \ref CALLBACK_HID_Device_CreateHIDReport() callback function.
+ *
+ * \note Due to the single buffer, the internal driver can only correctly compare
+ * subsequent reports with identical report IDs. In multiple report devices,
+ * this buffer should be set to NULL and the decision to send reports made
+ * by the user application instead.
+ */
+ uint8_t PrevReportINBufferSize; /**< Size in bytes of the given input report buffer. This is used to create a
+ * second buffer of the same size within the driver so that subsequent reports
+ * can be compared. If the user app is to determine when reports are to be sent
+ * exclusively (i.e. \ref PrevReportINBuffer is NULL) this value must still be
+ * set to the size of the largest report the device can issue to the host.
+ */
+ } Config; /**< Config data for the USB class interface within the device. All elements in this section
+ * <b>must</b> be set or the interface will fail to enumerate and operate correctly.
+ */
+ struct
+ {
+ bool UsingReportProtocol; /**< Indicates if the HID interface is set to Boot or Report protocol mode. */
+ uint16_t IdleCount; /**< Report idle period, in milliseconds, set by the host. */
+ uint16_t IdleMSRemaining; /**< Total number of milliseconds remaining before the idle period elapsed - this
+ * should be decremented by the user application if non-zero each millisecond. */
+ } State; /**< State data for the USB class interface within the device. All elements in this section
+ * are reset to their defaults when the interface is enumerated.
+ */
+ } USB_ClassInfo_HID_Device_t;
+
+ /* Function Prototypes: */
+ /** Configures the endpoints of a given HID interface, ready for use. This should be linked to the library
+ * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
+ * containing the given HID interface is selected.
+ *
+ * \note The endpoint index numbers as given in the interface's configuration structure must not overlap with any other
+ * interface, or endpoint bank corruption will occur. Gaps in the allocated endpoint numbers or non-sequential indexes
+ * within a single interface is allowed, but no two interfaces of any type have have interleaved endpoint indexes.
+ *
+ * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
+ *
+ * \return Boolean true if the endpoints were successfully configured, false otherwise.
+ */
+ bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Processes incoming control requests from the host, that are directed to the given HID class interface. This should be
+ * linked to the library \ref EVENT_USB_Device_ControlRequest() event.
+ *
+ * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
+ */
+ void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** General management task for a given HID 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] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
+ */
+ void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** HID class driver callback for the user creation of a HID IN report. This callback may fire in response to either
+ * HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback the
+ * user is responsible for the creation of the next HID input report to be sent to the host.
+ *
+ * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
+ * \param[in,out] ReportID If preset to a non-zero value, this is the report ID being requested by the host. If zero,
+ * this should be set to the report ID of the generated HID input report (if any). If multiple
+ * reports are not sent via the given HID interface, this parameter should be ignored.
+ * \param[in] ReportType Type of HID report to generate, either \ref HID_REPORT_ITEM_In or \ref HID_REPORT_ITEM_Feature.
+ * \param[out] ReportData Pointer to a buffer where the generated HID report should be stored.
+ * \param[out] ReportSize Number of bytes in the generated input report, or zero if no report is to be sent.
+ *
+ * \return Boolean true to force the sending of the report even if it is identical to the previous report and still within
+ * the idle period (useful for devices which report relative movement), false otherwise.
+ */
+ bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
+ uint8_t* const ReportID,
+ const uint8_t ReportType,
+ void* ReportData,
+ uint16_t* const ReportSize) ATTR_NON_NULL_PTR_ARG(1)
+ ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(4) ATTR_NON_NULL_PTR_ARG(5);
+
+ /** HID class driver callback for the user processing of a received HID OUT report. This callback may fire in response to
+ * either HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback
+ * the user is responsible for the processing of the received HID output report from the host.
+ *
+ * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
+ * \param[in] ReportID Report ID of the received output report. If multiple reports are not received via the given HID
+ * interface, this parameter should be ignored.
+ * \param[in] ReportType Type of received HID report, either \ref HID_REPORT_ITEM_Out or \ref HID_REPORT_ITEM_Feature.
+ * \param[in] ReportData Pointer to a buffer where the received HID report is stored.
+ * \param[in] ReportSize Size in bytes of the received report from the host.
+ */
+ void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
+ const uint8_t ReportID,
+ const uint8_t ReportType,
+ const void* ReportData,
+ const uint16_t ReportSize) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(4);
+
+ /* Inline Functions: */
+ /** Indicates that a millisecond of idle time has elapsed on the given HID interface, and the interface's idle count should be
+ * decremented. This should be called once per millisecond so that hardware key-repeats function correctly. It is recommended
+ * that this be called by the \ref EVENT_USB_Device_StartOfFrame() event, once SOF events have been enabled via
+ * \ref USB_Device_EnableSOFEvents().
+ *
+ * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
+ */
+ static inline void HID_Device_MillisecondElapsed(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_ALWAYS_INLINE ATTR_NON_NULL_PTR_ARG(1);
+ static inline void HID_Device_MillisecondElapsed(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
+ {
+ if (HIDInterfaceInfo->State.IdleMSRemaining)
+ HIDInterfaceInfo->State.IdleMSRemaining--;
+ }
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/HID.lst b/firmware/LUFA/Drivers/USB/Class/Device/HID.lst
new file mode 100644
index 0000000..46fb481
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/HID.lst
@@ -0,0 +1,769 @@
+ 1 .file "HID.c"
+ 2 __SREG__ = 0x3f
+ 3 __SP_H__ = 0x3e
+ 4 __SP_L__ = 0x3d
+ 5 __CCP__ = 0x34
+ 6 __tmp_reg__ = 0
+ 7 __zero_reg__ = 1
+ 15 .Ltext0:
+ 16 .section .text.HID_Device_USBTask,"ax",@progbits
+ 17 .global HID_Device_USBTask
+ 19 HID_Device_USBTask:
+ 20 .LFB83:
+ 21 .LSM0:
+ 22 .LVL0:
+ 23 0000 4F92 push r4
+ 24 0002 5F92 push r5
+ 25 0004 6F92 push r6
+ 26 0006 7F92 push r7
+ 27 0008 8F92 push r8
+ 28 000a 9F92 push r9
+ 29 000c AF92 push r10
+ 30 000e BF92 push r11
+ 31 0010 CF92 push r12
+ 32 0012 DF92 push r13
+ 33 0014 EF92 push r14
+ 34 0016 FF92 push r15
+ 35 0018 0F93 push r16
+ 36 001a 1F93 push r17
+ 37 001c DF93 push r29
+ 38 001e CF93 push r28
+ 39 0020 00D0 rcall .
+ 40 0022 0F92 push __tmp_reg__
+ 41 0024 CDB7 in r28,__SP_L__
+ 42 0026 DEB7 in r29,__SP_H__
+ 43 /* prologue: function */
+ 44 /* frame size = 3 */
+ 45 0028 7C01 movw r14,r24
+ 46 .LSM1:
+ 47 002a 6DB6 in r6,__SP_L__
+ 48 002c 7EB6 in r7,__SP_H__
+ 49 .LSM2:
+ 50 002e 8091 0000 lds r24,USB_DeviceState
+ 51 .LVL1:
+ 52 0032 8430 cpi r24,lo8(4)
+ 53 0034 01F0 breq .+2
+ 54 0036 00C0 rjmp .L13
+ 55 .LSM3:
+ 56 0038 F701 movw r30,r14
+ 57 003a 8181 ldd r24,Z+1
+ 58 .LBB49:
+ 59 .LBB50:
+ 60 .LSM4:
+ 61 003c 8093 E900 sts 233,r24
+ 62 .LBE50:
+ 63 .LBE49:
+ 64 .LBB51:
+ 65 .LBB52:
+ 66 .LSM5:
+ 67 0040 8091 E800 lds r24,232
+ 68 .LBE52:
+ 69 .LBE51:
+ 70 .LSM6:
+ 71 0044 85FF sbrs r24,5
+ 72 0046 00C0 rjmp .L13
+ 73 0048 5DB6 in r5,__SP_L__
+ 74 004a 4EB6 in r4,__SP_H__
+ 75 .LBB53:
+ 76 .LSM7:
+ 77 004c 4781 ldd r20,Z+7
+ 78 004e 8DB7 in r24,__SP_L__
+ 79 0050 9EB7 in r25,__SP_H__
+ 80 0052 841B sub r24,r20
+ 81 0054 9109 sbc r25,__zero_reg__
+ 82 0056 0FB6 in __tmp_reg__,__SREG__
+ 83 0058 F894 cli
+ 84 005a 9EBF out __SP_H__,r25
+ 85 005c 0FBE out __SREG__,__tmp_reg__
+ 86 005e 8DBF out __SP_L__,r24
+ 87 0060 0DB7 in r16,__SP_L__
+ 88 0062 1EB7 in r17,__SP_H__
+ 89 0064 0F5F subi r16,lo8(-(1))
+ 90 0066 1F4F sbci r17,hi8(-(1))
+ 91 .LSM8:
+ 92 0068 1982 std Y+1,__zero_reg__
+ 93 .LVL2:
+ 94 .LSM9:
+ 95 006a 1B82 std Y+3,__zero_reg__
+ 96 006c 1A82 std Y+2,__zero_reg__
+ 97 .LVL3:
+ 98 .LSM10:
+ 99 006e C02E mov r12,r16
+ 100 0070 912E mov r9,r17
+ 101 0072 C801 movw r24,r16
+ 102 0074 60E0 ldi r22,lo8(0)
+ 103 0076 70E0 ldi r23,hi8(0)
+ 104 0078 50E0 ldi r21,lo8(0)
+ 105 007a 0E94 0000 call memset
+ 106 .LSM11:
+ 107 007e C701 movw r24,r14
+ 108 0080 BE01 movw r22,r28
+ 109 0082 6F5F subi r22,lo8(-(1))
+ 110 0084 7F4F sbci r23,hi8(-(1))
+ 111 0086 40E0 ldi r20,lo8(0)
+ 112 0088 9801 movw r18,r16
+ 113 008a 8E01 movw r16,r28
+ 114 008c 0E5F subi r16,lo8(-(2))
+ 115 008e 1F4F sbci r17,hi8(-(2))
+ 116 0090 0E94 0000 call CALLBACK_HID_Device_CreateHIDReport
+ 117 0094 882E mov r8,r24
+ 118 .LVL4:
+ 119 .LSM12:
+ 120 0096 F701 movw r30,r14
+ 121 0098 8185 ldd r24,Z+9
+ 122 009a 9285 ldd r25,Z+10
+ 123 009c 892B or r24,r25
+ 124 009e 01F4 brne .L3
+ 125 00a0 AA24 clr r10
+ 126 00a2 BB24 clr r11
+ 127 00a4 00C0 rjmp .L4
+ 128 .L3:
+ 129 00a6 20E0 ldi r18,lo8(0)
+ 130 00a8 F701 movw r30,r14
+ 131 00aa 8385 ldd r24,Z+11
+ 132 00ac 9485 ldd r25,Z+12
+ 133 00ae 892B or r24,r25
+ 134 00b0 01F0 breq .L5
+ 135 00b2 21E0 ldi r18,lo8(1)
+ 136 .L5:
+ 137 00b4 81E0 ldi r24,lo8(1)
+ 138 00b6 2827 eor r18,r24
+ 139 00b8 A22E mov r10,r18
+ 140 00ba BB24 clr r11
+ 141 .L4:
+ 142 .LSM13:
+ 143 00bc F701 movw r30,r14
+ 144 00be 0581 ldd r16,Z+5
+ 145 00c0 1681 ldd r17,Z+6
+ 146 00c2 0115 cp r16,__zero_reg__
+ 147 00c4 1105 cpc r17,__zero_reg__
+ 148 00c6 01F4 brne .L6
+ 149 00c8 DD24 clr r13
+ 150 .LVL5:
+ 151 00ca 00C0 rjmp .L7
+ 152 .LVL6:
+ 153 .L6:
+ 154 .LSM14:
+ 155 00cc 4A81 ldd r20,Y+2
+ 156 00ce 5B81 ldd r21,Y+3
+ 157 00d0 8C2D mov r24,r12
+ 158 00d2 992D mov r25,r9
+ 159 00d4 B801 movw r22,r16
+ 160 00d6 0E94 0000 call memcmp
+ 161 00da DD24 clr r13
+ 162 .LVL7:
+ 163 00dc 0097 sbiw r24,0
+ 164 00de 01F0 breq .L8
+ 165 00e0 DD24 clr r13
+ 166 00e2 D394 inc r13
+ 167 .L8:
+ 168 .LSM15:
+ 169 00e4 F701 movw r30,r14
+ 170 00e6 4781 ldd r20,Z+7
+ 171 00e8 C801 movw r24,r16
+ 172 00ea 6C2D mov r22,r12
+ 173 00ec 792D mov r23,r9
+ 174 00ee 50E0 ldi r21,lo8(0)
+ 175 00f0 0E94 0000 call memcpy
+ 176 .L7:
+ 177 .LSM16:
+ 178 00f4 8A81 ldd r24,Y+2
+ 179 00f6 9B81 ldd r25,Y+3
+ 180 00f8 892B or r24,r25
+ 181 00fa 01F0 breq .L10
+ 182 .LVL8:
+ 183 00fc 8820 tst r8
+ 184 00fe 01F4 brne .L11
+ 185 0100 DD20 tst r13
+ 186 0102 01F4 brne .L11
+ 187 0104 AB28 or r10,r11
+ 188 0106 01F0 breq .L10
+ 189 .L11:
+ 190 .LSM17:
+ 191 0108 F701 movw r30,r14
+ 192 010a 8185 ldd r24,Z+9
+ 193 010c 9285 ldd r25,Z+10
+ 194 .LVL9:
+ 195 010e 9487 std Z+12,r25
+ 196 0110 8387 std Z+11,r24
+ 197 .LSM18:
+ 198 0112 8181 ldd r24,Z+1
+ 199 .LBB54:
+ 200 .LBB55:
+ 201 .LSM19:
+ 202 0114 8093 E900 sts 233,r24
+ 203 .LBE55:
+ 204 .LBE54:
+ 205 .LSM20:
+ 206 0118 8981 ldd r24,Y+1
+ 207 011a 8823 tst r24
+ 208 011c 01F0 breq .L12
+ 209 .LBB56:
+ 210 .LBB57:
+ 211 .LSM21:
+ 212 011e 8093 F100 sts 241,r24
+ 213 .L12:
+ 214 .LBE57:
+ 215 .LBE56:
+ 216 .LSM22:
+ 217 0122 6A81 ldd r22,Y+2
+ 218 0124 7B81 ldd r23,Y+3
+ 219 0126 8C2D mov r24,r12
+ 220 0128 992D mov r25,r9
+ 221 012a 40E0 ldi r20,lo8(0)
+ 222 012c 50E0 ldi r21,hi8(0)
+ 223 012e 0E94 0000 call Endpoint_Write_Stream_LE
+ 224 .LBB58:
+ 225 .LBB59:
+ 226 .LSM23:
+ 227 0132 8091 E800 lds r24,232
+ 228 0136 8E77 andi r24,lo8(126)
+ 229 0138 8093 E800 sts 232,r24
+ 230 .LVL10:
+ 231 .L10:
+ 232 013c 852D mov r24,r5
+ 233 013e 942D mov r25,r4
+ 234 0140 9C01 movw r18,r24
+ 235 0142 0FB6 in __tmp_reg__,__SREG__
+ 236 0144 F894 cli
+ 237 0146 3EBF out __SP_H__,r19
+ 238 0148 0FBE out __SREG__,__tmp_reg__
+ 239 014a 2DBF out __SP_L__,r18
+ 240 .L13:
+ 241 .LBE59:
+ 242 .LBE58:
+ 243 .LBE53:
+ 244 .LSM24:
+ 245 014c 0FB6 in __tmp_reg__,__SREG__
+ 246 014e F894 cli
+ 247 0150 7EBE out __SP_H__,r7
+ 248 0152 0FBE out __SREG__,__tmp_reg__
+ 249 0154 6DBE out __SP_L__,r6
+ 250 /* epilogue start */
+ 251 0156 0F90 pop __tmp_reg__
+ 252 0158 0F90 pop __tmp_reg__
+ 253 015a 0F90 pop __tmp_reg__
+ 254 015c CF91 pop r28
+ 255 015e DF91 pop r29
+ 256 0160 1F91 pop r17
+ 257 0162 0F91 pop r16
+ 258 0164 FF90 pop r15
+ 259 0166 EF90 pop r14
+ 260 .LVL11:
+ 261 0168 DF90 pop r13
+ 262 .LVL12:
+ 263 016a CF90 pop r12
+ 264 016c BF90 pop r11
+ 265 016e AF90 pop r10
+ 266 0170 9F90 pop r9
+ 267 0172 8F90 pop r8
+ 268 .LVL13:
+ 269 0174 7F90 pop r7
+ 270 0176 6F90 pop r6
+ 271 0178 5F90 pop r5
+ 272 017a 4F90 pop r4
+ 273 017c 0895 ret
+ 274 .LFE83:
+ 276 .section .text.HID_Device_ConfigureEndpoints,"ax",@progbits
+ 277 .global HID_Device_ConfigureEndpoints
+ 279 HID_Device_ConfigureEndpoints:
+ 280 .LFB82:
+ 281 .LSM25:
+ 282 .LVL14:
+ 283 0000 CF93 push r28
+ 284 0002 DF93 push r29
+ 285 /* prologue: function */
+ 286 /* frame size = 0 */
+ 287 0004 DC01 movw r26,r24
+ 288 .LSM26:
+ 289 0006 0896 adiw r24,8
+ 290 .LVL15:
+ 291 0008 FC01 movw r30,r24
+ 292 000a 85E0 ldi r24,lo8(5)
+ 293 000c EF01 movw r28,r30
+ 294 000e 1992 st Y+,__zero_reg__
+ 295 0010 8A95 dec r24
+ 296 0012 01F4 brne .-6
+ 297 .LSM27:
+ 298 0014 81E0 ldi r24,lo8(1)
+ 299 0016 1896 adiw r26,8
+ 300 0018 8C93 st X,r24
+ 301 001a 1897 sbiw r26,8
+ 302 .LSM28:
+ 303 001c 84EF ldi r24,lo8(500)
+ 304 001e 91E0 ldi r25,hi8(500)
+ 305 0020 1A96 adiw r26,9+1
+ 306 0022 9C93 st X,r25
+ 307 0024 8E93 st -X,r24
+ 308 0026 1997 sbiw r26,9
+ 309 .LSM29:
+ 310 0028 1196 adiw r26,1
+ 311 002a 3C91 ld r19,X
+ 312 002c 1197 sbiw r26,1
+ 313 002e 1296 adiw r26,2
+ 314 0030 6D91 ld r22,X+
+ 315 0032 7C91 ld r23,X
+ 316 0034 1397 sbiw r26,2+1
+ 317 0036 1496 adiw r26,4
+ 318 0038 8C91 ld r24,X
+ 319 003a 8823 tst r24
+ 320 003c 01F4 brne .L15
+ 321 003e 40E0 ldi r20,lo8(0)
+ 322 0040 00C0 rjmp .L16
+ 323 .L15:
+ 324 0042 44E0 ldi r20,lo8(4)
+ 325 .L16:
+ 326 0044 20E0 ldi r18,lo8(0)
+ 327 .LVL16:
+ 328 0046 88E0 ldi r24,lo8(8)
+ 329 0048 90E0 ldi r25,hi8(8)
+ 330 .LVL17:
+ 331 004a 00C0 rjmp .L17
+ 332 .L18:
+ 333 .LBB60:
+ 334 .LBB61:
+ 335 .LBB62:
+ 336 .LBB63:
+ 337 .LSM30:
+ 338 004c 2F5F subi r18,lo8(-(1))
+ 339 .LSM31:
+ 340 004e 880F lsl r24
+ 341 0050 991F rol r25
+ 342 .L17:
+ 343 .LSM32:
+ 344 0052 8617 cp r24,r22
+ 345 0054 9707 cpc r25,r23
+ 346 0056 00F0 brlo .L18
+ 347 .LBE63:
+ 348 .LBE62:
+ 349 .LBE61:
+ 350 .LSM33:
+ 351 0058 4260 ori r20,lo8(2)
+ 352 005a 2295 swap r18
+ 353 005c 207F andi r18,lo8(-16)
+ 354 005e 422B or r20,r18
+ 355 0060 832F mov r24,r19
+ 356 .LVL18:
+ 357 0062 61EC ldi r22,lo8(-63)
+ 358 0064 0E94 0000 call Endpoint_ConfigureEndpoint_Prv
+ 359 .LVL19:
+ 360 0068 8111 cpse r24,__zero_reg__
+ 361 006a 81E0 ldi r24,lo8(1)
+ 362 .L19:
+ 363 /* epilogue start */
+ 364 .LBE60:
+ 365 .LSM34:
+ 366 006c DF91 pop r29
+ 367 006e CF91 pop r28
+ 368 0070 0895 ret
+ 369 .LFE82:
+ 371 .section .text.HID_Device_ProcessControlRequest,"ax",@progbits
+ 372 .global HID_Device_ProcessControlRequest
+ 374 HID_Device_ProcessControlRequest:
+ 375 .LFB81:
+ 376 .LSM35:
+ 377 .LVL20:
+ 378 0000 6F92 push r6
+ 379 0002 7F92 push r7
+ 380 0004 8F92 push r8
+ 381 0006 9F92 push r9
+ 382 0008 AF92 push r10
+ 383 000a BF92 push r11
+ 384 000c CF92 push r12
+ 385 000e DF92 push r13
+ 386 0010 EF92 push r14
+ 387 0012 FF92 push r15
+ 388 0014 0F93 push r16
+ 389 0016 1F93 push r17
+ 390 0018 DF93 push r29
+ 391 001a CF93 push r28
+ 392 001c 00D0 rcall .
+ 393 001e 0F92 push __tmp_reg__
+ 394 0020 CDB7 in r28,__SP_L__
+ 395 0022 DEB7 in r29,__SP_H__
+ 396 /* prologue: function */
+ 397 /* frame size = 3 */
+ 398 0024 4C01 movw r8,r24
+ 399 .LSM36:
+ 400 0026 6DB6 in r6,__SP_L__
+ 401 0028 7EB6 in r7,__SP_H__
+ 402 .LBB64:
+ 403 .LBB65:
+ 404 .LSM37:
+ 405 002a 8091 E800 lds r24,232
+ 406 .LVL21:
+ 407 .LBE65:
+ 408 .LBE64:
+ 409 .LSM38:
+ 410 002e 83FF sbrs r24,3
+ 411 0030 00C0 rjmp .L33
+ 412 .LSM39:
+ 413 0032 F401 movw r30,r8
+ 414 0034 8081 ld r24,Z
+ 415 0036 90E0 ldi r25,lo8(0)
+ 416 0038 2091 0000 lds r18,USB_ControlRequest+4
+ 417 003c 3091 0000 lds r19,(USB_ControlRequest+4)+1
+ 418 0040 2817 cp r18,r24
+ 419 0042 3907 cpc r19,r25
+ 420 0044 01F0 breq .+2
+ 421 0046 00C0 rjmp .L33
+ 422 .LSM40:
+ 423 0048 8091 0000 lds r24,USB_ControlRequest+1
+ 424 004c 8330 cpi r24,lo8(3)
+ 425 004e 01F4 brne .+2
+ 426 0050 00C0 rjmp .L25
+ 427 0052 8430 cpi r24,lo8(4)
+ 428 0054 00F4 brsh .L29
+ 429 0056 8130 cpi r24,lo8(1)
+ 430 0058 01F0 breq .L23
+ 431 005a 8230 cpi r24,lo8(2)
+ 432 005c 01F0 breq .+2
+ 433 005e 00C0 rjmp .L33
+ 434 0060 00C0 rjmp .L36
+ 435 .L29:
+ 436 0062 8A30 cpi r24,lo8(10)
+ 437 0064 01F4 brne .+2
+ 438 0066 00C0 rjmp .L27
+ 439 0068 8B30 cpi r24,lo8(11)
+ 440 006a 01F4 brne .+2
+ 441 006c 00C0 rjmp .L28
+ 442 006e 8930 cpi r24,lo8(9)
+ 443 0070 01F0 breq .+2
+ 444 0072 00C0 rjmp .L33
+ 445 0074 00C0 rjmp .L37
+ 446 .L23:
+ 447 .LSM41:
+ 448 0076 8091 0000 lds r24,USB_ControlRequest
+ 449 007a 813A cpi r24,lo8(-95)
+ 450 007c 01F0 breq .+2
+ 451 007e 00C0 rjmp .L33
+ 452 0080 ADB6 in r10,__SP_L__
+ 453 0082 FEB6 in r15,__SP_H__
+ 454 .LBB66:
+ 455 .LSM42:
+ 456 0084 1B82 std Y+3,__zero_reg__
+ 457 0086 1A82 std Y+2,__zero_reg__
+ 458 .LVL22:
+ 459 .LSM43:
+ 460 0088 8091 0000 lds r24,USB_ControlRequest+2
+ 461 008c 1091 0000 lds r17,USB_ControlRequest+3
+ 462 0090 8983 std Y+1,r24
+ 463 .LVL23:
+ 464 .LSM44:
+ 465 0092 F401 movw r30,r8
+ 466 0094 4781 ldd r20,Z+7
+ 467 0096 8DB7 in r24,__SP_L__
+ 468 0098 9EB7 in r25,__SP_H__
+ 469 009a 841B sub r24,r20
+ 470 009c 9109 sbc r25,__zero_reg__
+ 471 009e 0FB6 in __tmp_reg__,__SREG__
+ 472 00a0 F894 cli
+ 473 00a2 9EBF out __SP_H__,r25
+ 474 00a4 0FBE out __SREG__,__tmp_reg__
+ 475 00a6 8DBF out __SP_L__,r24
+ 476 00a8 CDB6 in r12,__SP_L__
+ 477 00aa DEB6 in r13,__SP_H__
+ 478 00ac 0894 sec
+ 479 00ae C11C adc r12,__zero_reg__
+ 480 00b0 D11C adc r13,__zero_reg__
+ 481 .LSM45:
+ 482 00b2 EC2C mov r14,r12
+ 483 00b4 BD2C mov r11,r13
+ 484 00b6 C601 movw r24,r12
+ 485 00b8 60E0 ldi r22,lo8(0)
+ 486 00ba 70E0 ldi r23,hi8(0)
+ 487 00bc 50E0 ldi r21,lo8(0)
+ 488 00be 0E94 0000 call memset
+ 489 .LSM46:
+ 490 00c2 1150 subi r17,lo8(-(-1))
+ 491 00c4 C401 movw r24,r8
+ 492 00c6 BE01 movw r22,r28
+ 493 00c8 6F5F subi r22,lo8(-(1))
+ 494 00ca 7F4F sbci r23,hi8(-(1))
+ 495 00cc 412F mov r20,r17
+ 496 00ce 9601 movw r18,r12
+ 497 00d0 8E01 movw r16,r28
+ 498 00d2 0E5F subi r16,lo8(-(2))
+ 499 00d4 1F4F sbci r17,hi8(-(2))
+ 500 00d6 0E94 0000 call CALLBACK_HID_Device_CreateHIDReport
+ 501 .LSM47:
+ 502 00da F401 movw r30,r8
+ 503 00dc 2581 ldd r18,Z+5
+ 504 00de 3681 ldd r19,Z+6
+ 505 00e0 2115 cp r18,__zero_reg__
+ 506 00e2 3105 cpc r19,__zero_reg__
+ 507 00e4 01F0 breq .L30
+ 508 .LSM48:
+ 509 00e6 4781 ldd r20,Z+7
+ 510 00e8 C901 movw r24,r18
+ 511 00ea B601 movw r22,r12
+ 512 00ec 50E0 ldi r21,lo8(0)
+ 513 00ee 0E94 0000 call memcpy
+ 514 .L30:
+ 515 .LBB67:
+ 516 .LBB68:
+ 517 .LSM49:
+ 518 00f2 1092 E900 sts 233,__zero_reg__
+ 519 .LBE68:
+ 520 .LBE67:
+ 521 .LBB69:
+ 522 .LBB70:
+ 523 .LSM50:
+ 524 00f6 8091 E800 lds r24,232
+ 525 00fa 877F andi r24,lo8(-9)
+ 526 00fc 8093 E800 sts 232,r24
+ 527 .LBE70:
+ 528 .LBE69:
+ 529 .LSM51:
+ 530 0100 6A81 ldd r22,Y+2
+ 531 0102 7B81 ldd r23,Y+3
+ 532 0104 8E2D mov r24,r14
+ 533 0106 9B2D mov r25,r11
+ 534 0108 0E94 0000 call Endpoint_Write_Control_Stream_LE
+ 535 .LBB71:
+ 536 .LBB72:
+ 537 .LSM52:
+ 538 010c 8091 E800 lds r24,232
+ 539 0110 8B77 andi r24,lo8(123)
+ 540 0112 8093 E800 sts 232,r24
+ 541 0116 2A2D mov r18,r10
+ 542 0118 3F2D mov r19,r15
+ 543 011a 00C0 rjmp .L34
+ 544 .LVL24:
+ 545 .L37:
+ 546 .LBE72:
+ 547 .LBE71:
+ 548 .LBE66:
+ 549 .LSM53:
+ 550 011c 8091 0000 lds r24,USB_ControlRequest
+ 551 0120 8132 cpi r24,lo8(33)
+ 552 0122 01F0 breq .+2
+ 553 0124 00C0 rjmp .L33
+ 554 0126 AEB6 in r10,__SP_H__
+ 555 .LBB73:
+ 556 .LSM54:
+ 557 0128 0091 0000 lds r16,USB_ControlRequest+6
+ 558 012c 1091 0000 lds r17,(USB_ControlRequest+6)+1
+ 559 .LVL25:
+ 560 .LSM55:
+ 561 0130 C090 0000 lds r12,USB_ControlRequest+2
+ 562 0134 D090 0000 lds r13,USB_ControlRequest+3
+ 563 .LSM56:
+ 564 0138 8DB7 in r24,__SP_L__
+ 565 013a 9EB7 in r25,__SP_H__
+ 566 013c 801B sub r24,r16
+ 567 013e 910B sbc r25,r17
+ 568 0140 0FB6 in __tmp_reg__,__SREG__
+ 569 0142 F894 cli
+ 570 0144 9EBF out __SP_H__,r25
+ 571 0146 0FBE out __SREG__,__tmp_reg__
+ 572 0148 8DBF out __SP_L__,r24
+ 573 014a EDB6 in r14,__SP_L__
+ 574 014c FEB6 in r15,__SP_H__
+ 575 014e 0894 sec
+ 576 0150 E11C adc r14,__zero_reg__
+ 577 0152 F11C adc r15,__zero_reg__
+ 578 .LBB74:
+ 579 .LBB75:
+ 580 .LSM57:
+ 581 0154 8091 E800 lds r24,232
+ 582 0158 877F andi r24,lo8(-9)
+ 583 015a 8093 E800 sts 232,r24
+ 584 .LBE75:
+ 585 .LBE74:
+ 586 .LSM58:
+ 587 015e C701 movw r24,r14
+ 588 0160 B801 movw r22,r16
+ 589 0162 0E94 0000 call Endpoint_Read_Control_Stream_LE
+ 590 .LBB76:
+ 591 .LBB77:
+ 592 .LSM59:
+ 593 0166 8091 E800 lds r24,232
+ 594 016a 8E77 andi r24,lo8(126)
+ 595 016c 8093 E800 sts 232,r24
+ 596 .LBE77:
+ 597 .LBE76:
+ 598 .LSM60:
+ 599 0170 DA94 dec r13
+ 600 0172 C401 movw r24,r8
+ 601 0174 6C2D mov r22,r12
+ 602 0176 4D2D mov r20,r13
+ 603 0178 9701 movw r18,r14
+ 604 017a 0E94 0000 call CALLBACK_HID_Device_ProcessHIDReport
+ 605 017e 262D mov r18,r6
+ 606 0180 3A2D mov r19,r10
+ 607 .LVL26:
+ 608 .L34:
+ 609 0182 0FB6 in __tmp_reg__,__SREG__
+ 610 0184 F894 cli
+ 611 0186 3EBF out __SP_H__,r19
+ 612 0188 0FBE out __SREG__,__tmp_reg__
+ 613 018a 2DBF out __SP_L__,r18
+ 614 018c 00C0 rjmp .L33
+ 615 .LVL27:
+ 616 .L25:
+ 617 .LBE73:
+ 618 .LSM61:
+ 619 018e 8091 0000 lds r24,USB_ControlRequest
+ 620 0192 813A cpi r24,lo8(-95)
+ 621 0194 01F0 breq .+2
+ 622 0196 00C0 rjmp .L33
+ 623 .LBB78:
+ 624 .LBB79:
+ 625 .LSM62:
+ 626 0198 8091 E800 lds r24,232
+ 627 019c 877F andi r24,lo8(-9)
+ 628 019e 8093 E800 sts 232,r24
+ 629 .LBE79:
+ 630 .LBE78:
+ 631 .LSM63:
+ 632 01a2 F401 movw r30,r8
+ 633 01a4 8085 ldd r24,Z+8
+ 634 01a6 00C0 rjmp .L35
+ 635 .L28:
+ 636 .LSM64:
+ 637 01a8 8091 0000 lds r24,USB_ControlRequest
+ 638 01ac 8132 cpi r24,lo8(33)
+ 639 01ae 01F0 breq .+2
+ 640 01b0 00C0 rjmp .L33
+ 641 .LBB80:
+ 642 .LBB81:
+ 643 .LSM65:
+ 644 01b2 8091 E800 lds r24,232
+ 645 01b6 877F andi r24,lo8(-9)
+ 646 01b8 8093 E800 sts 232,r24
+ 647 .LBE81:
+ 648 .LBE80:
+ 649 .LSM66:
+ 650 01bc 0E94 0000 call Endpoint_ClearStatusStage
+ 651 .LSM67:
+ 652 01c0 90E0 ldi r25,lo8(0)
+ 653 01c2 8091 0000 lds r24,USB_ControlRequest+2
+ 654 01c6 8111 cpse r24,__zero_reg__
+ 655 01c8 91E0 ldi r25,lo8(1)
+ 656 .L32:
+ 657 01ca F401 movw r30,r8
+ 658 01cc 9087 std Z+8,r25
+ 659 01ce 00C0 rjmp .L33
+ 660 .L27:
+ 661 .LSM68:
+ 662 01d0 8091 0000 lds r24,USB_ControlRequest
+ 663 01d4 8132 cpi r24,lo8(33)
+ 664 01d6 01F4 brne .L33
+ 665 .LBB82:
+ 666 .LBB83:
+ 667 .LSM69:
+ 668 01d8 8091 E800 lds r24,232
+ 669 01dc 877F andi r24,lo8(-9)
+ 670 01de 8093 E800 sts 232,r24
+ 671 .LBE83:
+ 672 .LBE82:
+ 673 .LSM70:
+ 674 01e2 0E94 0000 call Endpoint_ClearStatusStage
+ 675 .LSM71:
+ 676 01e6 8091 0000 lds r24,USB_ControlRequest+2
+ 677 01ea 9091 0000 lds r25,(USB_ControlRequest+2)+1
+ 678 01ee 8070 andi r24,lo8(-256)
+ 679 01f0 76E0 ldi r23,6
+ 680 01f2 9695 1: lsr r25
+ 681 01f4 8795 ror r24
+ 682 01f6 7A95 dec r23
+ 683 01f8 01F4 brne 1b
+ 684 01fa F401 movw r30,r8
+ 685 01fc 9287 std Z+10,r25
+ 686 01fe 8187 std Z+9,r24
+ 687 0200 00C0 rjmp .L33
+ 688 .L36:
+ 689 .LSM72:
+ 690 0202 8091 0000 lds r24,USB_ControlRequest
+ 691 0206 813A cpi r24,lo8(-95)
+ 692 0208 01F4 brne .L33
+ 693 .LBB84:
+ 694 .LBB85:
+ 695 .LSM73:
+ 696 020a 8091 E800 lds r24,232
+ 697 020e 877F andi r24,lo8(-9)
+ 698 0210 8093 E800 sts 232,r24
+ 699 .LBE85:
+ 700 .LBE84:
+ 701 .LSM74:
+ 702 0214 F401 movw r30,r8
+ 703 0216 8185 ldd r24,Z+9
+ 704 0218 9285 ldd r25,Z+10
+ 705 021a 9695 lsr r25
+ 706 021c 8795 ror r24
+ 707 021e 9695 lsr r25
+ 708 0220 8795 ror r24
+ 709 .L35:
+ 710 .LBB86:
+ 711 .LBB87:
+ 712 .LSM75:
+ 713 0222 8093 F100 sts 241,r24
+ 714 .LBE87:
+ 715 .LBE86:
+ 716 .LBB88:
+ 717 .LBB89:
+ 718 .LSM76:
+ 719 0226 8091 E800 lds r24,232
+ 720 022a 8E77 andi r24,lo8(126)
+ 721 022c 8093 E800 sts 232,r24
+ 722 .LBE89:
+ 723 .LBE88:
+ 724 .LSM77:
+ 725 0230 0E94 0000 call Endpoint_ClearStatusStage
+ 726 .LVL28:
+ 727 .L33:
+ 728 .LSM78:
+ 729 0234 0FB6 in __tmp_reg__,__SREG__
+ 730 0236 F894 cli
+ 731 0238 7EBE out __SP_H__,r7
+ 732 023a 0FBE out __SREG__,__tmp_reg__
+ 733 023c 6DBE out __SP_L__,r6
+ 734 /* epilogue start */
+ 735 023e 0F90 pop __tmp_reg__
+ 736 0240 0F90 pop __tmp_reg__
+ 737 0242 0F90 pop __tmp_reg__
+ 738 0244 CF91 pop r28
+ 739 0246 DF91 pop r29
+ 740 0248 1F91 pop r17
+ 741 024a 0F91 pop r16
+ 742 .LVL29:
+ 743 024c FF90 pop r15
+ 744 024e EF90 pop r14
+ 745 0250 DF90 pop r13
+ 746 0252 CF90 pop r12
+ 747 0254 BF90 pop r11
+ 748 0256 AF90 pop r10
+ 749 0258 9F90 pop r9
+ 750 025a 8F90 pop r8
+ 751 .LVL30:
+ 752 025c 7F90 pop r7
+ 753 025e 6F90 pop r6
+ 754 0260 0895 ret
+ 755 .LFE81:
+ 797 .Letext0:
+DEFINED SYMBOLS
+ *ABS*:0000000000000000 HID.c
+ /tmp/ccYdlTY9.s:2 *ABS*:000000000000003f __SREG__
+ /tmp/ccYdlTY9.s:3 *ABS*:000000000000003e __SP_H__
+ /tmp/ccYdlTY9.s:4 *ABS*:000000000000003d __SP_L__
+ /tmp/ccYdlTY9.s:5 *ABS*:0000000000000034 __CCP__
+ /tmp/ccYdlTY9.s:6 *ABS*:0000000000000000 __tmp_reg__
+ /tmp/ccYdlTY9.s:7 *ABS*:0000000000000001 __zero_reg__
+ /tmp/ccYdlTY9.s:19 .text.HID_Device_USBTask:0000000000000000 HID_Device_USBTask
+ /tmp/ccYdlTY9.s:279 .text.HID_Device_ConfigureEndpoints:0000000000000000 HID_Device_ConfigureEndpoints
+ /tmp/ccYdlTY9.s:374 .text.HID_Device_ProcessControlRequest:0000000000000000 HID_Device_ProcessControlRequest
+
+UNDEFINED SYMBOLS
+USB_DeviceState
+memset
+CALLBACK_HID_Device_CreateHIDReport
+memcmp
+memcpy
+Endpoint_Write_Stream_LE
+Endpoint_ConfigureEndpoint_Prv
+USB_ControlRequest
+Endpoint_Write_Control_Stream_LE
+Endpoint_Read_Control_Stream_LE
+CALLBACK_HID_Device_ProcessHIDReport
+Endpoint_ClearStatusStage
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/HID.o b/firmware/LUFA/Drivers/USB/Class/Device/HID.o
new file mode 100644
index 0000000..d3f9f75
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/HID.o
Binary files differ
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/MIDI.c b/firmware/LUFA/Drivers/USB/Class/Device/MIDI.c
new file mode 100644
index 0000000..9d2a1a8
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/MIDI.c
@@ -0,0 +1,148 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define __INCLUDE_FROM_USB_DRIVER
+#include "../../HighLevel/USBMode.h"
+#if defined(USB_CAN_BE_DEVICE)
+
+#define __INCLUDE_FROM_MIDI_DRIVER
+#define __INCLUDE_FROM_MIDI_DEVICE_C
+#include "MIDI.h"
+
+bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
+{
+ memset(&MIDIInterfaceInfo->State, 0x00, sizeof(MIDIInterfaceInfo->State));
+
+ for (uint8_t EndpointNum = 1; EndpointNum < ENDPOINT_TOTAL_ENDPOINTS; EndpointNum++)
+ {
+ uint16_t Size;
+ uint8_t Type;
+ uint8_t Direction;
+ bool DoubleBanked;
+
+ if (EndpointNum == MIDIInterfaceInfo->Config.DataINEndpointNumber)
+ {
+ Size = MIDIInterfaceInfo->Config.DataINEndpointSize;
+ Direction = ENDPOINT_DIR_IN;
+ Type = EP_TYPE_BULK;
+ DoubleBanked = MIDIInterfaceInfo->Config.DataINEndpointDoubleBank;
+ }
+ else if (EndpointNum == MIDIInterfaceInfo->Config.DataOUTEndpointNumber)
+ {
+ Size = MIDIInterfaceInfo->Config.DataOUTEndpointSize;
+ Direction = ENDPOINT_DIR_OUT;
+ Type = EP_TYPE_BULK;
+ DoubleBanked = MIDIInterfaceInfo->Config.DataOUTEndpointDoubleBank;
+ }
+ else
+ {
+ continue;
+ }
+
+ if (!(Endpoint_ConfigureEndpoint(EndpointNum, Type, Direction, Size,
+ DoubleBanked ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
+{
+ if (USB_DeviceState != DEVICE_STATE_Configured)
+ return;
+
+ #if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
+ MIDI_Device_Flush(MIDIInterfaceInfo);
+ #endif
+}
+
+uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
+ const MIDI_EventPacket_t* const Event)
+{
+ if (USB_DeviceState != DEVICE_STATE_Configured)
+ return ENDPOINT_RWSTREAM_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpointNumber);
+
+ if ((ErrorCode = Endpoint_Write_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NO_STREAM_CALLBACK)) != ENDPOINT_RWSTREAM_NoError)
+ return ErrorCode;
+
+ if (!(Endpoint_IsReadWriteAllowed()))
+ Endpoint_ClearIN();
+
+ return ENDPOINT_RWSTREAM_NoError;
+}
+
+uint8_t MIDI_Device_Flush(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
+{
+ if (USB_DeviceState != DEVICE_STATE_Configured)
+ return ENDPOINT_RWSTREAM_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpointNumber);
+
+ if (Endpoint_BytesInEndpoint())
+ {
+ Endpoint_ClearIN();
+
+ if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
+ return ErrorCode;
+ }
+
+ return ENDPOINT_READYWAIT_NoError;
+}
+
+bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
+ MIDI_EventPacket_t* const Event)
+{
+ if (USB_DeviceState != DEVICE_STATE_Configured)
+ return false;
+
+ Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataOUTEndpointNumber);
+
+ if (!(Endpoint_IsReadWriteAllowed()))
+ return false;
+
+ Endpoint_Read_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NO_STREAM_CALLBACK);
+
+ if (!(Endpoint_IsReadWriteAllowed()))
+ Endpoint_ClearOUT();
+
+ return true;
+}
+
+#endif
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/MIDI.h b/firmware/LUFA/Drivers/USB/Class/Device/MIDI.h
new file mode 100644
index 0000000..8ac7146
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/MIDI.h
@@ -0,0 +1,189 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Device mode driver for the library USB MIDI Class driver.
+ *
+ * Device mode driver for the library USB MIDI 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_USBClassMIDI
+ * @defgroup Group_USBClassMIDIDevice MIDI Class Device 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/Device/MIDI.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ *
+ * \section Module Description
+ * Device Mode USB Class driver framework interface, for the MIDI USB Class driver.
+ *
+ * @{
+ */
+
+#ifndef _MIDI_CLASS_DEVICE_H_
+#define _MIDI_CLASS_DEVICE_H_
+
+ /* Includes: */
+ #include "../../USB.h"
+ #include "../Common/MIDI.h"
+
+ #include <string.h>
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_MIDI_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ #if defined(__INCLUDE_FROM_MIDI_DEVICE_C) && defined(NO_STREAM_CALLBACKS)
+ #error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
+ #endif
+
+ /* Public Interface - May be used in end-application: */
+ /* Type Define: */
+ /** \brief MIDI Class Device Mode Configuration and State Structure.
+ *
+ * Class state structure. An instance of this structure should be made for each MIDI interface
+ * within the user application, and passed to each of the MIDI class driver functions as the
+ * MIDIInterfaceInfo parameter. This stores each MIDI interface's configuration and state information.
+ */
+ typedef struct
+ {
+ const struct
+ {
+ uint8_t StreamingInterfaceNumber; /**< Index of the Audio Streaming interface within the device this structure controls. */
+
+ uint8_t DataINEndpointNumber; /**< Endpoint number of the incoming MIDI data, if available (zero if unused). */
+ uint16_t DataINEndpointSize; /**< Size in bytes of the incoming MIDI data endpoint, if available (zero if unused). */
+ bool DataINEndpointDoubleBank; /**< Indicates if the MIDI interface's IN data endpoint should use double banking. */
+
+ uint8_t DataOUTEndpointNumber; /**< Endpoint number of the outgoing MIDI data, if available (zero if unused). */
+ uint16_t DataOUTEndpointSize; /**< Size in bytes of the outgoing MIDI data endpoint, if available (zero if unused). */
+ bool DataOUTEndpointDoubleBank; /**< Indicates if the MIDI interface's IN data endpoint should use double banking. */
+ } Config; /**< Config data for the USB class interface within the device. All elements in this section
+ * <b>must</b> be set or the interface will fail to enumerate and operate correctly.
+ */
+ struct
+ {
+ // No state information for this class
+ } State; /**< State data for the USB class interface within the device. All elements in this section
+ * are reset to their defaults when the interface is enumerated.
+ */
+ } USB_ClassInfo_MIDI_Device_t;
+
+ /* Function Prototypes: */
+ /** Configures the endpoints of a given MIDI interface, ready for use. This should be linked to the library
+ * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
+ * containing the given MIDI interface is selected.
+ *
+ * \note The endpoint index numbers as given in the interface's configuration structure must not overlap with any other
+ * interface, or endpoint bank corruption will occur. Gaps in the allocated endpoint numbers or non-sequential indexes
+ * within a single interface is allowed, but no two interfaces of any type have have interleaved endpoint indexes.
+ *
+ * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
+ *
+ * \return Boolean true if the endpoints were successfully configured, false otherwise.
+ */
+ bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** General management task for a given MIDI 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] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
+ */
+ void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Sends a MIDI event packet to the host. If no host is connected, the event packet is discarded. Events are queued into the
+ * endpoint bank until either the endpoint bank is full, or \ref MIDI_Device_Flush() is called. This allows for multiple
+ * MIDI events to be packed into a single endpoint 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] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
+ * \param[in] Event Pointer to a populated \ref MIDI_EventPacket_t structure containing the MIDI event to send.
+ *
+ * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
+ const 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 host. This should be called to override the
+ * \ref MIDI_Device_SendEventPacket() function's packing behaviour, to flush queued events.
+ *
+ * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
+ *
+ * \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum.
+ */
+ uint8_t MIDI_Device_Flush(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Receives a MIDI event packet from the host. Events are unpacked from the endpoint, thus if the endpoint bank contains
+ * multiple MIDI events from the host in the one packet, multiple calls to this function will return each individual event.
+ *
+ * \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] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
+ * \param[out] Event Pointer to a USB_MIDI_EventPacket_t structure where the received MIDI event is to be placed.
+ *
+ * \return Boolean true if a MIDI event packet was received, false otherwise.
+ */
+ bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
+ MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+
+ /* Inline Functions: */
+ /** Processes incoming control requests from the host, that are directed to the given MIDI class interface. This should be
+ * linked to the library \ref EVENT_USB_Device_ControlRequest() event.
+ *
+ * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
+ */
+ static inline void MIDI_Device_ProcessControlRequest(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+ static inline void MIDI_Device_ProcessControlRequest(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
+ {
+ (void)MIDIInterfaceInfo;
+ }
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/MIDI.lst b/firmware/LUFA/Drivers/USB/Class/Device/MIDI.lst
new file mode 100644
index 0000000..cb878a0
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/MIDI.lst
@@ -0,0 +1,346 @@
+ 1 .file "MIDI.c"
+ 2 __SREG__ = 0x3f
+ 3 __SP_H__ = 0x3e
+ 4 __SP_L__ = 0x3d
+ 5 __CCP__ = 0x34
+ 6 __tmp_reg__ = 0
+ 7 __zero_reg__ = 1
+ 15 .Ltext0:
+ 16 .section .text.MIDI_Device_ReceiveEventPacket,"ax",@progbits
+ 17 .global MIDI_Device_ReceiveEventPacket
+ 19 MIDI_Device_ReceiveEventPacket:
+ 20 .LFB85:
+ 21 .LSM0:
+ 22 .LVL0:
+ 23 /* prologue: function */
+ 24 /* frame size = 0 */
+ 25 0000 FC01 movw r30,r24
+ 26 .LSM1:
+ 27 0002 8091 0000 lds r24,USB_DeviceState
+ 28 .LVL1:
+ 29 0006 8430 cpi r24,lo8(4)
+ 30 0008 01F4 brne .L2
+ 31 .LSM2:
+ 32 000a 8581 ldd r24,Z+5
+ 33 .LBB30:
+ 34 .LBB31:
+ 35 .LSM3:
+ 36 000c 8093 E900 sts 233,r24
+ 37 .LBE31:
+ 38 .LBE30:
+ 39 .LBB32:
+ 40 .LBB33:
+ 41 .LSM4:
+ 42 0010 8091 E800 lds r24,232
+ 43 .LBE33:
+ 44 .LBE32:
+ 45 .LSM5:
+ 46 0014 85FF sbrs r24,5
+ 47 0016 00C0 rjmp .L2
+ 48 .LSM6:
+ 49 0018 CB01 movw r24,r22
+ 50 001a 64E0 ldi r22,lo8(4)
+ 51 001c 70E0 ldi r23,hi8(4)
+ 52 .LVL2:
+ 53 001e 40E0 ldi r20,lo8(0)
+ 54 0020 50E0 ldi r21,hi8(0)
+ 55 0022 0E94 0000 call Endpoint_Read_Stream_LE
+ 56 .LVL3:
+ 57 .LBB34:
+ 58 .LBB35:
+ 59 .LSM7:
+ 60 0026 8091 E800 lds r24,232
+ 61 .LBE35:
+ 62 .LBE34:
+ 63 .LSM8:
+ 64 002a 85FD sbrc r24,5
+ 65 002c 00C0 rjmp .L6
+ 66 .L3:
+ 67 .LBB36:
+ 68 .LBB37:
+ 69 .LSM9:
+ 70 002e 8091 E800 lds r24,232
+ 71 0032 8B77 andi r24,lo8(123)
+ 72 0034 8093 E800 sts 232,r24
+ 73 .L6:
+ 74 0038 81E0 ldi r24,lo8(1)
+ 75 003a 0895 ret
+ 76 .LVL4:
+ 77 .L2:
+ 78 003c 80E0 ldi r24,lo8(0)
+ 79 .LBE37:
+ 80 .LBE36:
+ 81 .LSM10:
+ 82 003e 0895 ret
+ 83 .LFE85:
+ 85 .section .text.MIDI_Device_Flush,"ax",@progbits
+ 86 .global MIDI_Device_Flush
+ 88 MIDI_Device_Flush:
+ 89 .LFB84:
+ 90 .LSM11:
+ 91 .LVL5:
+ 92 /* prologue: function */
+ 93 /* frame size = 0 */
+ 94 0000 FC01 movw r30,r24
+ 95 .LSM12:
+ 96 0002 8091 0000 lds r24,USB_DeviceState
+ 97 .LVL6:
+ 98 0006 8430 cpi r24,lo8(4)
+ 99 0008 01F0 breq .L8
+ 100 000a 82E0 ldi r24,lo8(2)
+ 101 .LVL7:
+ 102 000c 0895 ret
+ 103 .LVL8:
+ 104 .L8:
+ 105 .LSM13:
+ 106 000e 8181 ldd r24,Z+1
+ 107 .LBB38:
+ 108 .LBB39:
+ 109 .LSM14:
+ 110 0010 8093 E900 sts 233,r24
+ 111 .LBE39:
+ 112 .LBE38:
+ 113 .LBB40:
+ 114 .LBB41:
+ 115 .LSM15:
+ 116 0014 8091 F200 lds r24,242
+ 117 .LBE41:
+ 118 .LBE40:
+ 119 .LSM16:
+ 120 0018 8823 tst r24
+ 121 001a 01F0 breq .L9
+ 122 .LBB42:
+ 123 .LBB43:
+ 124 .LSM17:
+ 125 001c 8091 E800 lds r24,232
+ 126 0020 8E77 andi r24,lo8(126)
+ 127 0022 8093 E800 sts 232,r24
+ 128 .LBE43:
+ 129 .LBE42:
+ 130 .LSM18:
+ 131 0026 0E94 0000 call Endpoint_WaitUntilReady
+ 132 .LVL9:
+ 133 .L9:
+ 134 .LSM19:
+ 135 002a 0895 ret
+ 136 .LFE84:
+ 138 .section .text.MIDI_Device_USBTask,"ax",@progbits
+ 139 .global MIDI_Device_USBTask
+ 141 MIDI_Device_USBTask:
+ 142 .LFB82:
+ 143 .LSM20:
+ 144 .LVL10:
+ 145 /* prologue: function */
+ 146 /* frame size = 0 */
+ 147 0000 9C01 movw r18,r24
+ 148 .LSM21:
+ 149 0002 8091 0000 lds r24,USB_DeviceState
+ 150 .LVL11:
+ 151 0006 8430 cpi r24,lo8(4)
+ 152 0008 01F4 brne .L14
+ 153 .LSM22:
+ 154 000a C901 movw r24,r18
+ 155 000c 0E94 0000 call MIDI_Device_Flush
+ 156 .LVL12:
+ 157 .L14:
+ 158 0010 0895 ret
+ 159 .LFE82:
+ 161 .section .text.MIDI_Device_SendEventPacket,"ax",@progbits
+ 162 .global MIDI_Device_SendEventPacket
+ 164 MIDI_Device_SendEventPacket:
+ 165 .LFB83:
+ 166 .LSM23:
+ 167 .LVL13:
+ 168 /* prologue: function */
+ 169 /* frame size = 0 */
+ 170 0000 FC01 movw r30,r24
+ 171 .LSM24:
+ 172 0002 8091 0000 lds r24,USB_DeviceState
+ 173 .LVL14:
+ 174 0006 8430 cpi r24,lo8(4)
+ 175 0008 01F0 breq .L16
+ 176 000a 92E0 ldi r25,lo8(2)
+ 177 .LVL15:
+ 178 000c 00C0 rjmp .L17
+ 179 .LVL16:
+ 180 .L16:
+ 181 .LSM25:
+ 182 000e 8181 ldd r24,Z+1
+ 183 .LBB44:
+ 184 .LBB45:
+ 185 .LSM26:
+ 186 0010 8093 E900 sts 233,r24
+ 187 .LBE45:
+ 188 .LBE44:
+ 189 .LSM27:
+ 190 0014 CB01 movw r24,r22
+ 191 0016 64E0 ldi r22,lo8(4)
+ 192 0018 70E0 ldi r23,hi8(4)
+ 193 .LVL17:
+ 194 001a 40E0 ldi r20,lo8(0)
+ 195 001c 50E0 ldi r21,hi8(0)
+ 196 001e 0E94 0000 call Endpoint_Write_Stream_LE
+ 197 .LVL18:
+ 198 0022 982F mov r25,r24
+ 199 .LVL19:
+ 200 0024 8823 tst r24
+ 201 0026 01F4 brne .L17
+ 202 .LVL20:
+ 203 .LBB46:
+ 204 .LBB47:
+ 205 .LSM28:
+ 206 0028 8091 E800 lds r24,232
+ 207 .LVL21:
+ 208 .LBE47:
+ 209 .LBE46:
+ 210 .LSM29:
+ 211 002c 85FD sbrc r24,5
+ 212 002e 00C0 rjmp .L17
+ 213 .LBB48:
+ 214 .LBB49:
+ 215 .LSM30:
+ 216 0030 8091 E800 lds r24,232
+ 217 0034 8E77 andi r24,lo8(126)
+ 218 0036 8093 E800 sts 232,r24
+ 219 .LVL22:
+ 220 .L17:
+ 221 .LBE49:
+ 222 .LBE48:
+ 223 .LSM31:
+ 224 003a 892F mov r24,r25
+ 225 /* epilogue start */
+ 226 003c 0895 ret
+ 227 .LFE83:
+ 229 .section .text.MIDI_Device_ConfigureEndpoints,"ax",@progbits
+ 230 .global MIDI_Device_ConfigureEndpoints
+ 232 MIDI_Device_ConfigureEndpoints:
+ 233 .LFB81:
+ 234 .LSM32:
+ 235 .LVL23:
+ 236 0000 1F93 push r17
+ 237 0002 CF93 push r28
+ 238 0004 DF93 push r29
+ 239 /* prologue: function */
+ 240 /* frame size = 0 */
+ 241 0006 EC01 movw r28,r24
+ 242 .LSM33:
+ 243 0008 11E0 ldi r17,lo8(1)
+ 244 .LVL24:
+ 245 .L28:
+ 246 .LBB50:
+ 247 .LBB51:
+ 248 .LSM34:
+ 249 000a 8981 ldd r24,Y+1
+ 250 000c 1817 cp r17,r24
+ 251 000e 01F4 brne .L20
+ 252 .LSM35:
+ 253 0010 EA81 ldd r30,Y+2
+ 254 0012 FB81 ldd r31,Y+3
+ 255 .LVL25:
+ 256 .LSM36:
+ 257 0014 8C81 ldd r24,Y+4
+ 258 .LVL26:
+ 259 0016 61E0 ldi r22,lo8(1)
+ 260 .LVL27:
+ 261 0018 00C0 rjmp .L21
+ 262 .LVL28:
+ 263 .L20:
+ 264 .LSM37:
+ 265 001a 8D81 ldd r24,Y+5
+ 266 001c 1817 cp r17,r24
+ 267 001e 01F4 brne .L22
+ 268 .LSM38:
+ 269 0020 EE81 ldd r30,Y+6
+ 270 0022 FF81 ldd r31,Y+7
+ 271 .LVL29:
+ 272 .LSM39:
+ 273 0024 8885 ldd r24,Y+8
+ 274 .LVL30:
+ 275 0026 60E0 ldi r22,lo8(0)
+ 276 .LVL31:
+ 277 .L21:
+ 278 .LSM40:
+ 279 0028 8823 tst r24
+ 280 002a 01F4 brne .L23
+ 281 002c 40E0 ldi r20,lo8(0)
+ 282 002e 00C0 rjmp .L24
+ 283 .L23:
+ 284 0030 44E0 ldi r20,lo8(4)
+ 285 .L24:
+ 286 0032 20E0 ldi r18,lo8(0)
+ 287 .LVL32:
+ 288 0034 88E0 ldi r24,lo8(8)
+ 289 0036 90E0 ldi r25,hi8(8)
+ 290 .LVL33:
+ 291 0038 00C0 rjmp .L25
+ 292 .L26:
+ 293 .LBB52:
+ 294 .LBB53:
+ 295 .LBB54:
+ 296 .LBB55:
+ 297 .LSM41:
+ 298 003a 2F5F subi r18,lo8(-(1))
+ 299 .LSM42:
+ 300 003c 880F lsl r24
+ 301 003e 991F rol r25
+ 302 .L25:
+ 303 .LSM43:
+ 304 0040 8E17 cp r24,r30
+ 305 0042 9F07 cpc r25,r31
+ 306 0044 00F0 brlo .L26
+ 307 .LBE55:
+ 308 .LBE54:
+ 309 .LBE53:
+ 310 .LSM44:
+ 311 0046 6068 ori r22,lo8(-128)
+ 312 0048 4260 ori r20,lo8(2)
+ 313 004a 2295 swap r18
+ 314 004c 207F andi r18,lo8(-16)
+ 315 004e 422B or r20,r18
+ 316 0050 812F mov r24,r17
+ 317 .LVL34:
+ 318 0052 0E94 0000 call Endpoint_ConfigureEndpoint_Prv
+ 319 .LVL35:
+ 320 .LBE52:
+ 321 .LSM45:
+ 322 0056 8823 tst r24
+ 323 0058 01F0 breq .L27
+ 324 .L22:
+ 325 .LBE51:
+ 326 .LSM46:
+ 327 005a 1F5F subi r17,lo8(-(1))
+ 328 005c 1530 cpi r17,lo8(5)
+ 329 005e 01F4 brne .L28
+ 330 0060 81E0 ldi r24,lo8(1)
+ 331 .L27:
+ 332 /* epilogue start */
+ 333 .LBE50:
+ 334 .LSM47:
+ 335 0062 DF91 pop r29
+ 336 0064 CF91 pop r28
+ 337 .LVL36:
+ 338 0066 1F91 pop r17
+ 339 .LVL37:
+ 340 0068 0895 ret
+ 341 .LFE81:
+ 399 .Letext0:
+DEFINED SYMBOLS
+ *ABS*:0000000000000000 MIDI.c
+ /tmp/cc3Ze3Jq.s:2 *ABS*:000000000000003f __SREG__
+ /tmp/cc3Ze3Jq.s:3 *ABS*:000000000000003e __SP_H__
+ /tmp/cc3Ze3Jq.s:4 *ABS*:000000000000003d __SP_L__
+ /tmp/cc3Ze3Jq.s:5 *ABS*:0000000000000034 __CCP__
+ /tmp/cc3Ze3Jq.s:6 *ABS*:0000000000000000 __tmp_reg__
+ /tmp/cc3Ze3Jq.s:7 *ABS*:0000000000000001 __zero_reg__
+ /tmp/cc3Ze3Jq.s:19 .text.MIDI_Device_ReceiveEventPacket:0000000000000000 MIDI_Device_ReceiveEventPacket
+ /tmp/cc3Ze3Jq.s:88 .text.MIDI_Device_Flush:0000000000000000 MIDI_Device_Flush
+ /tmp/cc3Ze3Jq.s:141 .text.MIDI_Device_USBTask:0000000000000000 MIDI_Device_USBTask
+ /tmp/cc3Ze3Jq.s:164 .text.MIDI_Device_SendEventPacket:0000000000000000 MIDI_Device_SendEventPacket
+ /tmp/cc3Ze3Jq.s:232 .text.MIDI_Device_ConfigureEndpoints:0000000000000000 MIDI_Device_ConfigureEndpoints
+
+UNDEFINED SYMBOLS
+USB_DeviceState
+Endpoint_Read_Stream_LE
+Endpoint_WaitUntilReady
+Endpoint_Write_Stream_LE
+Endpoint_ConfigureEndpoint_Prv
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/MIDI.o b/firmware/LUFA/Drivers/USB/Class/Device/MIDI.o
new file mode 100644
index 0000000..80100ad
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/MIDI.o
Binary files differ
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/MassStorage.c b/firmware/LUFA/Drivers/USB/Class/Device/MassStorage.c
new file mode 100644
index 0000000..64d61df
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/MassStorage.c
@@ -0,0 +1,247 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define __INCLUDE_FROM_USB_DRIVER
+#include "../../HighLevel/USBMode.h"
+#if defined(USB_CAN_BE_DEVICE)
+
+#define __INCLUDE_FROM_MS_DRIVER
+#define __INCLUDE_FROM_MASSSTORAGE_DEVICE_C
+#include "MassStorage.h"
+
+static volatile bool* CallbackIsResetSource;
+
+void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
+{
+ if (!(Endpoint_IsSETUPReceived()))
+ return;
+
+ if (USB_ControlRequest.wIndex != MSInterfaceInfo->Config.InterfaceNumber)
+ return;
+
+ switch (USB_ControlRequest.bRequest)
+ {
+ case MS_REQ_MassStorageReset:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+ Endpoint_ClearStatusStage();
+
+ MSInterfaceInfo->State.IsMassStoreReset = true;
+ }
+
+ break;
+ case MS_REQ_GetMaxLUN:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+ Endpoint_Write_Byte(MSInterfaceInfo->Config.TotalLUNs - 1);
+ Endpoint_ClearIN();
+ Endpoint_ClearStatusStage();
+ }
+
+ break;
+ }
+}
+
+bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
+{
+ memset(&MSInterfaceInfo->State, 0x00, sizeof(MSInterfaceInfo->State));
+
+ for (uint8_t EndpointNum = 1; EndpointNum < ENDPOINT_TOTAL_ENDPOINTS; EndpointNum++)
+ {
+ uint16_t Size;
+ uint8_t Type;
+ uint8_t Direction;
+ bool DoubleBanked;
+
+ if (EndpointNum == MSInterfaceInfo->Config.DataINEndpointNumber)
+ {
+ Size = MSInterfaceInfo->Config.DataINEndpointSize;
+ Direction = ENDPOINT_DIR_IN;
+ Type = EP_TYPE_BULK;
+ DoubleBanked = MSInterfaceInfo->Config.DataINEndpointDoubleBank;
+ }
+ else if (EndpointNum == MSInterfaceInfo->Config.DataOUTEndpointNumber)
+ {
+ Size = MSInterfaceInfo->Config.DataOUTEndpointSize;
+ Direction = ENDPOINT_DIR_OUT;
+ Type = EP_TYPE_BULK;
+ DoubleBanked = MSInterfaceInfo->Config.DataOUTEndpointDoubleBank;
+ }
+ else
+ {
+ continue;
+ }
+
+ if (!(Endpoint_ConfigureEndpoint(EndpointNum, Type, Direction, Size,
+ DoubleBanked ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
+{
+ if (USB_DeviceState != DEVICE_STATE_Configured)
+ return;
+
+ Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);
+
+ if (Endpoint_IsReadWriteAllowed())
+ {
+ if (MS_Device_ReadInCommandBlock(MSInterfaceInfo))
+ {
+ if (MSInterfaceInfo->State.CommandBlock.Flags & MS_COMMAND_DIR_DATA_IN)
+ Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);
+
+ MSInterfaceInfo->State.CommandStatus.Status = CALLBACK_MS_Device_SCSICommandReceived(MSInterfaceInfo) ?
+ MS_SCSI_COMMAND_Pass : MS_SCSI_COMMAND_Fail;
+ MSInterfaceInfo->State.CommandStatus.Signature = MS_CSW_SIGNATURE;
+ MSInterfaceInfo->State.CommandStatus.Tag = MSInterfaceInfo->State.CommandBlock.Tag;
+ MSInterfaceInfo->State.CommandStatus.DataTransferResidue = MSInterfaceInfo->State.CommandBlock.DataTransferLength;
+
+ if ((MSInterfaceInfo->State.CommandStatus.Status == MS_SCSI_COMMAND_Fail) &&
+ (MSInterfaceInfo->State.CommandStatus.DataTransferResidue))
+ {
+ Endpoint_StallTransaction();
+ }
+
+ MS_Device_ReturnCommandStatus(MSInterfaceInfo);
+ }
+ }
+
+ if (MSInterfaceInfo->State.IsMassStoreReset)
+ {
+ Endpoint_ResetFIFO(MSInterfaceInfo->Config.DataOUTEndpointNumber);
+ Endpoint_ResetFIFO(MSInterfaceInfo->Config.DataINEndpointNumber);
+
+ Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);
+ Endpoint_ClearStall();
+ Endpoint_ResetDataToggle();
+ Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);
+ Endpoint_ClearStall();
+ Endpoint_ResetDataToggle();
+
+ MSInterfaceInfo->State.IsMassStoreReset = false;
+ }
+}
+
+static bool MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
+{
+ Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);
+
+ CallbackIsResetSource = &MSInterfaceInfo->State.IsMassStoreReset;
+ if (Endpoint_Read_Stream_LE(&MSInterfaceInfo->State.CommandBlock,
+ (sizeof(MS_CommandBlockWrapper_t) - 16),
+ StreamCallback_MS_Device_AbortOnMassStoreReset))
+ {
+ return false;
+ }
+
+ if ((MSInterfaceInfo->State.CommandBlock.Signature != MS_CBW_SIGNATURE) ||
+ (MSInterfaceInfo->State.CommandBlock.LUN >= MSInterfaceInfo->Config.TotalLUNs) ||
+ (MSInterfaceInfo->State.CommandBlock.Flags & 0x1F) ||
+ (MSInterfaceInfo->State.CommandBlock.SCSICommandLength == 0) ||
+ (MSInterfaceInfo->State.CommandBlock.SCSICommandLength > 16))
+ {
+ Endpoint_StallTransaction();
+ Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);
+ Endpoint_StallTransaction();
+
+ return false;
+ }
+
+ CallbackIsResetSource = &MSInterfaceInfo->State.IsMassStoreReset;
+ if (Endpoint_Read_Stream_LE(&MSInterfaceInfo->State.CommandBlock.SCSICommandData,
+ MSInterfaceInfo->State.CommandBlock.SCSICommandLength,
+ StreamCallback_MS_Device_AbortOnMassStoreReset))
+ {
+ return false;
+ }
+
+ Endpoint_ClearOUT();
+
+ return true;
+}
+
+static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
+{
+ Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);
+
+ while (Endpoint_IsStalled())
+ {
+ #if !defined(INTERRUPT_CONTROL_ENDPOINT)
+ USB_USBTask();
+ #endif
+
+ if (MSInterfaceInfo->State.IsMassStoreReset)
+ return;
+ }
+
+ Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);
+
+ while (Endpoint_IsStalled())
+ {
+ #if !defined(INTERRUPT_CONTROL_ENDPOINT)
+ USB_USBTask();
+ #endif
+
+ if (MSInterfaceInfo->State.IsMassStoreReset)
+ return;
+ }
+
+ CallbackIsResetSource = &MSInterfaceInfo->State.IsMassStoreReset;
+ if (Endpoint_Write_Stream_LE(&MSInterfaceInfo->State.CommandStatus, sizeof(MS_CommandStatusWrapper_t),
+ StreamCallback_MS_Device_AbortOnMassStoreReset))
+ {
+ return;
+ }
+
+ Endpoint_ClearIN();
+}
+
+static uint8_t StreamCallback_MS_Device_AbortOnMassStoreReset(void)
+{
+ #if !defined(INTERRUPT_CONTROL_ENDPOINT)
+ USB_USBTask();
+ #endif
+
+ if (*CallbackIsResetSource)
+ return STREAMCALLBACK_Abort;
+ else
+ return STREAMCALLBACK_Continue;
+}
+
+#endif
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/MassStorage.h b/firmware/LUFA/Drivers/USB/Class/Device/MassStorage.h
new file mode 100644
index 0000000..31d3ba9
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/MassStorage.h
@@ -0,0 +1,177 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Device mode driver for the library USB Mass Storage Class driver.
+ *
+ * Device mode driver for the library USB Mass Storage 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_USBClassMS
+ * @defgroup Group_USBClassMSDevice Mass Storage Class Device 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/Device/MassStorage.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ *
+ * \section Module Description
+ * Device Mode USB Class driver framework interface, for the Mass Storage USB Class driver.
+ *
+ * @{
+ */
+
+#ifndef _MS_CLASS_DEVICE_H_
+#define _MS_CLASS_DEVICE_H_
+
+ /* Includes: */
+ #include "../../USB.h"
+ #include "../Common/MassStorage.h"
+
+ #include <string.h>
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_MS_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ #if defined(__INCLUDE_FROM_MASSSTORAGE_DEVICE_C) && defined(NO_STREAM_CALLBACKS)
+ #error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
+ #endif
+
+ /* Public Interface - May be used in end-application: */
+ /* Type Defines: */
+ /** \brief Mass Storage Class Device Mode Configuration and State Structure.
+ *
+ * Class state structure. An instance of this structure should be made for each Mass Storage interface
+ * within the user application, and passed to each of the Mass Storage class driver functions as the
+ * MSInterfaceInfo parameter. This stores each Mass Storage interface's configuration and state information.
+ */
+ typedef struct
+ {
+ const struct
+ {
+ uint8_t InterfaceNumber; /**< Interface number of the Mass Storage interface within the device. */
+
+ uint8_t DataINEndpointNumber; /**< Endpoint number of the Mass Storage interface's IN data endpoint. */
+ uint16_t DataINEndpointSize; /**< Size in bytes of the Mass Storage interface's IN data endpoint. */
+ bool DataINEndpointDoubleBank; /**< Indicates if the Mass Storage interface's IN data endpoint should use double banking. */
+
+ uint8_t DataOUTEndpointNumber; /**< Endpoint number of the Mass Storage interface's OUT data endpoint. */
+ uint16_t DataOUTEndpointSize; /**< Size in bytes of the Mass Storage interface's OUT data endpoint. */
+ bool DataOUTEndpointDoubleBank; /**< Indicates if the Mass Storage interface's OUT data endpoint should use double banking. */
+
+ uint8_t TotalLUNs; /**< Total number of logical drives in the Mass Storage interface. */
+ } Config; /**< Config data for the USB class interface within the device. All elements in this section
+ * <b>must</b> be set or the interface will fail to enumerate and operate correctly.
+ */
+ struct
+ {
+ MS_CommandBlockWrapper_t CommandBlock; /**< Mass Storage class command block structure, stores the received SCSI
+ * command from the host which is to be processed.
+ */
+ MS_CommandStatusWrapper_t CommandStatus; /**< Mass Storage class command status structure, set elements to indicate
+ * the issued command's success or failure to the host.
+ */
+ volatile bool IsMassStoreReset; /**< Flag indicating that the host has requested that the Mass Storage interface be reset
+ * and that all current Mass Storage operations should immediately abort.
+ */
+ } State; /**< State data for the USB class interface within the device. All elements in this section
+ * are reset to their defaults when the interface is enumerated.
+ */
+ } USB_ClassInfo_MS_Device_t;
+
+ /* Function Prototypes: */
+ /** Configures the endpoints of a given Mass Storage interface, ready for use. This should be linked to the library
+ * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
+ * containing the given Mass Storage interface is selected.
+ *
+ * \note The endpoint index numbers as given in the interface's configuration structure must not overlap with any other
+ * interface, or endpoint bank corruption will occur. Gaps in the allocated endpoint numbers or non-sequential indexes
+ * within a single interface is allowed, but no two interfaces of any type have have interleaved endpoint indexes.
+ *
+ * \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state.
+ *
+ * \return Boolean true if the endpoints were successfully configured, false otherwise.
+ */
+ bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Processes incoming control requests from the host, that are directed to the given Mass Storage class interface. This should be
+ * linked to the library \ref EVENT_USB_Device_ControlRequest() event.
+ *
+ * \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state.
+ */
+ void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** General management task for a given Mass Storage 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] MSInterfaceInfo Pointer to a structure containing a Mass Storage configuration and state.
+ */
+ void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Mass Storage class driver callback for the user processing of a received SCSI command. This callback will fire each time the
+ * host sends a SCSI command which requires processing by the user application. Inside this callback the user is responsible
+ * for the processing of the received SCSI command from the host. The SCSI command is available in the CommandBlock structure
+ * inside the Mass Storage class state structure passed as a parameter to the callback function.
+ *
+ * \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state.
+ *
+ * \return Boolean true if the SCSI command was successfully processed, false otherwise.
+ */
+ bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /* Private Interface - For use in library only: */
+ #if !defined(__DOXYGEN__)
+ /* Function Prototypes: */
+ #if defined(__INCLUDE_FROM_MASSSTORAGE_DEVICE_C)
+ static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+ static bool MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+ static uint8_t StreamCallback_MS_Device_AbortOnMassStoreReset(void);
+ #endif
+
+ #endif
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/MassStorage.lst b/firmware/LUFA/Drivers/USB/Class/Device/MassStorage.lst
new file mode 100644
index 0000000..12dc787
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/MassStorage.lst
@@ -0,0 +1,643 @@
+ 1 .file "MassStorage.c"
+ 2 __SREG__ = 0x3f
+ 3 __SP_H__ = 0x3e
+ 4 __SP_L__ = 0x3d
+ 5 __CCP__ = 0x34
+ 6 __tmp_reg__ = 0
+ 7 __zero_reg__ = 1
+ 15 .Ltext0:
+ 16 .section .text.StreamCallback_MS_Device_AbortOnMassStoreReset,"ax",@progbits
+ 18 StreamCallback_MS_Device_AbortOnMassStoreReset:
+ 19 .LFB86:
+ 20 .LSM0:
+ 21 /* prologue: function */
+ 22 /* frame size = 0 */
+ 23 .LSM1:
+ 24 0000 0E94 0000 call USB_USBTask
+ 25 .LSM2:
+ 26 0004 E091 0000 lds r30,CallbackIsResetSource
+ 27 0008 F091 0000 lds r31,(CallbackIsResetSource)+1
+ 28 000c 8081 ld r24,Z
+ 29 /* epilogue start */
+ 30 .LSM3:
+ 31 000e 0895 ret
+ 32 .LFE86:
+ 34 .section .text.MS_Device_USBTask,"ax",@progbits
+ 35 .global MS_Device_USBTask
+ 37 MS_Device_USBTask:
+ 38 .LFB83:
+ 39 .LSM4:
+ 40 .LVL0:
+ 41 0000 0F93 push r16
+ 42 0002 1F93 push r17
+ 43 0004 CF93 push r28
+ 44 0006 DF93 push r29
+ 45 /* prologue: function */
+ 46 /* frame size = 0 */
+ 47 0008 EC01 movw r28,r24
+ 48 .LSM5:
+ 49 000a 8091 0000 lds r24,USB_DeviceState
+ 50 .LVL1:
+ 51 000e 8430 cpi r24,lo8(4)
+ 52 0010 01F0 breq .+2
+ 53 0012 00C0 rjmp .L14
+ 54 .LSM6:
+ 55 0014 9D81 ldd r25,Y+5
+ 56 .LBB112:
+ 57 .LBB113:
+ 58 .LSM7:
+ 59 0016 9093 E900 sts 233,r25
+ 60 .LBE113:
+ 61 .LBE112:
+ 62 .LBB114:
+ 63 .LBB115:
+ 64 .LSM8:
+ 65 001a 8091 E800 lds r24,232
+ 66 .LBE115:
+ 67 .LBE114:
+ 68 .LSM9:
+ 69 001e 85FF sbrs r24,5
+ 70 0020 00C0 rjmp .L5
+ 71 .LBB116:
+ 72 .LBB117:
+ 73 .LBB124:
+ 74 .LBB125:
+ 75 .LSM10:
+ 76 0022 9093 E900 sts 233,r25
+ 77 .LBE125:
+ 78 .LBE124:
+ 79 .LSM11:
+ 80 0026 8E01 movw r16,r28
+ 81 0028 0A5C subi r16,lo8(-(54))
+ 82 002a 1F4F sbci r17,hi8(-(54))
+ 83 002c 1093 0000 sts (CallbackIsResetSource)+1,r17
+ 84 0030 0093 0000 sts CallbackIsResetSource,r16
+ 85 .LBE117:
+ 86 .LSM12:
+ 87 0034 CE01 movw r24,r28
+ 88 0036 0A96 adiw r24,10
+ 89 0038 6FE0 ldi r22,lo8(15)
+ 90 003a 70E0 ldi r23,hi8(15)
+ 91 003c 40E0 ldi r20,lo8(gs(StreamCallback_MS_Device_AbortOnMassStoreReset))
+ 92 003e 50E0 ldi r21,hi8(gs(StreamCallback_MS_Device_AbortOnMassStoreReset))
+ 93 0040 0E94 0000 call Endpoint_Read_Stream_LE
+ 94 .LBB128:
+ 95 0044 8823 tst r24
+ 96 0046 01F0 breq .+2
+ 97 0048 00C0 rjmp .L5
+ 98 .LSM13:
+ 99 004a 8A85 ldd r24,Y+10
+ 100 004c 9B85 ldd r25,Y+11
+ 101 004e AC85 ldd r26,Y+12
+ 102 0050 BD85 ldd r27,Y+13
+ 103 0052 8555 subi r24,lo8(1128420181)
+ 104 0054 9345 sbci r25,hi8(1128420181)
+ 105 0056 A244 sbci r26,hlo8(1128420181)
+ 106 0058 B344 sbci r27,hhi8(1128420181)
+ 107 005a 01F4 brne .L6
+ 108 005c 9F89 ldd r25,Y+23
+ 109 005e 8985 ldd r24,Y+9
+ 110 0060 9817 cp r25,r24
+ 111 0062 00F4 brsh .L6
+ 112 0064 8E89 ldd r24,Y+22
+ 113 0066 90E0 ldi r25,lo8(0)
+ 114 0068 8F71 andi r24,lo8(31)
+ 115 006a 9070 andi r25,hi8(31)
+ 116 006c 892B or r24,r25
+ 117 006e 01F4 brne .L6
+ 118 0070 688D ldd r22,Y+24
+ 119 0072 6623 tst r22
+ 120 0074 01F0 breq .L6
+ 121 0076 6131 cpi r22,lo8(17)
+ 122 0078 00F0 brlo .L7
+ 123 .L6:
+ 124 .LBB122:
+ 125 .LBB123:
+ 126 .LSM14:
+ 127 007a 8091 EB00 lds r24,235
+ 128 007e 8062 ori r24,lo8(32)
+ 129 0080 8093 EB00 sts 235,r24
+ 130 .LBE123:
+ 131 .LBE122:
+ 132 .LSM15:
+ 133 0084 8981 ldd r24,Y+1
+ 134 .LBB120:
+ 135 .LBB121:
+ 136 .LSM16:
+ 137 0086 8093 E900 sts 233,r24
+ 138 .LBE121:
+ 139 .LBE120:
+ 140 .LBB118:
+ 141 .LBB119:
+ 142 .LSM17:
+ 143 008a 8091 EB00 lds r24,235
+ 144 008e 8062 ori r24,lo8(32)
+ 145 0090 8093 EB00 sts 235,r24
+ 146 0094 00C0 rjmp .L5
+ 147 .L7:
+ 148 .LBE119:
+ 149 .LBE118:
+ 150 .LSM18:
+ 151 0096 1093 0000 sts (CallbackIsResetSource)+1,r17
+ 152 009a 0093 0000 sts CallbackIsResetSource,r16
+ 153 .LBE128:
+ 154 .LSM19:
+ 155 009e CE01 movw r24,r28
+ 156 00a0 4996 adiw r24,25
+ 157 00a2 70E0 ldi r23,lo8(0)
+ 158 00a4 40E0 ldi r20,lo8(gs(StreamCallback_MS_Device_AbortOnMassStoreReset))
+ 159 00a6 50E0 ldi r21,hi8(gs(StreamCallback_MS_Device_AbortOnMassStoreReset))
+ 160 00a8 0E94 0000 call Endpoint_Read_Stream_LE
+ 161 .LBB129:
+ 162 00ac 8823 tst r24
+ 163 00ae 01F0 breq .+2
+ 164 00b0 00C0 rjmp .L5
+ 165 .LBB126:
+ 166 .LBB127:
+ 167 .LSM20:
+ 168 00b2 8091 E800 lds r24,232
+ 169 00b6 8B77 andi r24,lo8(123)
+ 170 00b8 8093 E800 sts 232,r24
+ 171 .LBE127:
+ 172 .LBE126:
+ 173 .LBE129:
+ 174 .LBE116:
+ 175 .LSM21:
+ 176 00bc 8E89 ldd r24,Y+22
+ 177 00be 87FF sbrs r24,7
+ 178 00c0 00C0 rjmp .L8
+ 179 .LSM22:
+ 180 00c2 8981 ldd r24,Y+1
+ 181 .LBB130:
+ 182 .LBB131:
+ 183 .LSM23:
+ 184 00c4 8093 E900 sts 233,r24
+ 185 .L8:
+ 186 .LBE131:
+ 187 .LBE130:
+ 188 .LSM24:
+ 189 00c8 CE01 movw r24,r28
+ 190 00ca 0E94 0000 call CALLBACK_MS_Device_SCSICommandReceived
+ 191 00ce 91E0 ldi r25,lo8(1)
+ 192 00d0 9827 eor r25,r24
+ 193 00d2 9DAB std Y+53,r25
+ 194 .LSM25:
+ 195 00d4 25E5 ldi r18,lo8(1396855637)
+ 196 00d6 33E5 ldi r19,hi8(1396855637)
+ 197 00d8 42E4 ldi r20,hlo8(1396855637)
+ 198 00da 53E5 ldi r21,hhi8(1396855637)
+ 199 00dc 29A7 std Y+41,r18
+ 200 00de 3AA7 std Y+42,r19
+ 201 00e0 4BA7 std Y+43,r20
+ 202 00e2 5CA7 std Y+44,r21
+ 203 .LSM26:
+ 204 00e4 2E85 ldd r18,Y+14
+ 205 00e6 3F85 ldd r19,Y+15
+ 206 00e8 4889 ldd r20,Y+16
+ 207 00ea 5989 ldd r21,Y+17
+ 208 00ec 2DA7 std Y+45,r18
+ 209 00ee 3EA7 std Y+46,r19
+ 210 00f0 4FA7 std Y+47,r20
+ 211 00f2 58AB std Y+48,r21
+ 212 .LSM27:
+ 213 00f4 2A89 ldd r18,Y+18
+ 214 00f6 3B89 ldd r19,Y+19
+ 215 00f8 4C89 ldd r20,Y+20
+ 216 00fa 5D89 ldd r21,Y+21
+ 217 00fc 29AB std Y+49,r18
+ 218 00fe 3AAB std Y+50,r19
+ 219 0100 4BAB std Y+51,r20
+ 220 0102 5CAB std Y+52,r21
+ 221 .LSM28:
+ 222 0104 9130 cpi r25,lo8(1)
+ 223 0106 01F4 brne .L9
+ 224 0108 2115 cp r18,__zero_reg__
+ 225 010a 3105 cpc r19,__zero_reg__
+ 226 010c 4105 cpc r20,__zero_reg__
+ 227 010e 5105 cpc r21,__zero_reg__
+ 228 0110 01F0 breq .L9
+ 229 .LBB132:
+ 230 .LBB133:
+ 231 .LSM29:
+ 232 0112 8091 EB00 lds r24,235
+ 233 0116 8062 ori r24,lo8(32)
+ 234 0118 8093 EB00 sts 235,r24
+ 235 .L9:
+ 236 .LBE133:
+ 237 .LBE132:
+ 238 .LBB134:
+ 239 .LBB135:
+ 240 .LSM30:
+ 241 011c 8D81 ldd r24,Y+5
+ 242 .LBB142:
+ 243 .LBB143:
+ 244 .LSM31:
+ 245 011e 8093 E900 sts 233,r24
+ 246 0122 00C0 rjmp .L10
+ 247 .L11:
+ 248 .LBE143:
+ 249 .LBE142:
+ 250 .LSM32:
+ 251 0124 0E94 0000 call USB_USBTask
+ 252 .LSM33:
+ 253 0128 8EA9 ldd r24,Y+54
+ 254 012a 8823 tst r24
+ 255 012c 01F4 brne .L5
+ 256 .L10:
+ 257 .LBB140:
+ 258 .LBB141:
+ 259 .LSM34:
+ 260 012e 8091 EB00 lds r24,235
+ 261 .LBE141:
+ 262 .LBE140:
+ 263 .LSM35:
+ 264 0132 85FD sbrc r24,5
+ 265 0134 00C0 rjmp .L11
+ 266 .LSM36:
+ 267 0136 8981 ldd r24,Y+1
+ 268 .LBB138:
+ 269 .LBB139:
+ 270 .LSM37:
+ 271 0138 8093 E900 sts 233,r24
+ 272 013c 00C0 rjmp .L12
+ 273 .L13:
+ 274 .LBE139:
+ 275 .LBE138:
+ 276 .LSM38:
+ 277 013e 0E94 0000 call USB_USBTask
+ 278 .LSM39:
+ 279 0142 8EA9 ldd r24,Y+54
+ 280 0144 8823 tst r24
+ 281 0146 01F4 brne .L5
+ 282 .L12:
+ 283 .LBB136:
+ 284 .LBB137:
+ 285 .LSM40:
+ 286 0148 8091 EB00 lds r24,235
+ 287 .LBE137:
+ 288 .LBE136:
+ 289 .LSM41:
+ 290 014c 85FD sbrc r24,5
+ 291 014e 00C0 rjmp .L13
+ 292 .LSM42:
+ 293 0150 E696 adiw r28,54
+ 294 0152 D093 0000 sts (CallbackIsResetSource)+1,r29
+ 295 0156 C093 0000 sts CallbackIsResetSource,r28
+ 296 015a E697 sbiw r28,54
+ 297 .LBE135:
+ 298 .LSM43:
+ 299 015c CE01 movw r24,r28
+ 300 015e 8996 adiw r24,41
+ 301 0160 6DE0 ldi r22,lo8(13)
+ 302 0162 70E0 ldi r23,hi8(13)
+ 303 0164 40E0 ldi r20,lo8(gs(StreamCallback_MS_Device_AbortOnMassStoreReset))
+ 304 0166 50E0 ldi r21,hi8(gs(StreamCallback_MS_Device_AbortOnMassStoreReset))
+ 305 0168 0E94 0000 call Endpoint_Write_Stream_LE
+ 306 .LBB146:
+ 307 016c 8823 tst r24
+ 308 016e 01F4 brne .L5
+ 309 .LBB144:
+ 310 .LBB145:
+ 311 .LSM44:
+ 312 0170 8091 E800 lds r24,232
+ 313 0174 8E77 andi r24,lo8(126)
+ 314 0176 8093 E800 sts 232,r24
+ 315 .L5:
+ 316 .LBE145:
+ 317 .LBE144:
+ 318 .LBE146:
+ 319 .LBE134:
+ 320 .LSM45:
+ 321 017a 8EA9 ldd r24,Y+54
+ 322 017c 8823 tst r24
+ 323 017e 01F0 breq .L14
+ 324 .LSM46:
+ 325 0180 4D81 ldd r20,Y+5
+ 326 .LBB147:
+ 327 .LBB148:
+ 328 .LSM47:
+ 329 0182 21E0 ldi r18,lo8(1)
+ 330 0184 30E0 ldi r19,hi8(1)
+ 331 0186 C901 movw r24,r18
+ 332 0188 042E mov r0,r20
+ 333 018a 00C0 rjmp 2f
+ 334 018c 880F 1: lsl r24
+ 335 018e 991F rol r25
+ 336 0190 0A94 2: dec r0
+ 337 0192 02F4 brpl 1b
+ 338 0194 8093 EA00 sts 234,r24
+ 339 .LSM48:
+ 340 0198 1092 EA00 sts 234,__zero_reg__
+ 341 .LBE148:
+ 342 .LBE147:
+ 343 .LSM49:
+ 344 019c 9981 ldd r25,Y+1
+ 345 .LBB149:
+ 346 .LBB150:
+ 347 .LSM50:
+ 348 019e 092E mov r0,r25
+ 349 01a0 00C0 rjmp 2f
+ 350 01a2 220F 1: lsl r18
+ 351 01a4 331F rol r19
+ 352 01a6 0A94 2: dec r0
+ 353 01a8 02F4 brpl 1b
+ 354 01aa 2093 EA00 sts 234,r18
+ 355 .LSM51:
+ 356 01ae 1092 EA00 sts 234,__zero_reg__
+ 357 .LBE150:
+ 358 .LBE149:
+ 359 .LBB151:
+ 360 .LBB152:
+ 361 .LSM52:
+ 362 01b2 4093 E900 sts 233,r20
+ 363 .LBE152:
+ 364 .LBE151:
+ 365 .LBB153:
+ 366 .LBB154:
+ 367 .LSM53:
+ 368 01b6 8091 EB00 lds r24,235
+ 369 01ba 8061 ori r24,lo8(16)
+ 370 01bc 8093 EB00 sts 235,r24
+ 371 .LBE154:
+ 372 .LBE153:
+ 373 .LBB155:
+ 374 .LBB156:
+ 375 .LSM54:
+ 376 01c0 8091 EB00 lds r24,235
+ 377 01c4 8860 ori r24,lo8(8)
+ 378 01c6 8093 EB00 sts 235,r24
+ 379 .LBE156:
+ 380 .LBE155:
+ 381 .LBB157:
+ 382 .LBB158:
+ 383 .LSM55:
+ 384 01ca 9093 E900 sts 233,r25
+ 385 .LBE158:
+ 386 .LBE157:
+ 387 .LBB159:
+ 388 .LBB160:
+ 389 .LSM56:
+ 390 01ce 8091 EB00 lds r24,235
+ 391 01d2 8061 ori r24,lo8(16)
+ 392 01d4 8093 EB00 sts 235,r24
+ 393 .LBE160:
+ 394 .LBE159:
+ 395 .LBB161:
+ 396 .LBB162:
+ 397 .LSM57:
+ 398 01d8 8091 EB00 lds r24,235
+ 399 01dc 8860 ori r24,lo8(8)
+ 400 01de 8093 EB00 sts 235,r24
+ 401 .LBE162:
+ 402 .LBE161:
+ 403 .LSM58:
+ 404 01e2 1EAA std Y+54,__zero_reg__
+ 405 .L14:
+ 406 /* epilogue start */
+ 407 .LSM59:
+ 408 01e4 DF91 pop r29
+ 409 01e6 CF91 pop r28
+ 410 .LVL2:
+ 411 01e8 1F91 pop r17
+ 412 01ea 0F91 pop r16
+ 413 01ec 0895 ret
+ 414 .LFE83:
+ 416 .section .text.MS_Device_ConfigureEndpoints,"ax",@progbits
+ 417 .global MS_Device_ConfigureEndpoints
+ 419 MS_Device_ConfigureEndpoints:
+ 420 .LFB82:
+ 421 .LSM60:
+ 422 .LVL3:
+ 423 0000 1F93 push r17
+ 424 0002 CF93 push r28
+ 425 0004 DF93 push r29
+ 426 /* prologue: function */
+ 427 /* frame size = 0 */
+ 428 0006 EC01 movw r28,r24
+ 429 .LSM61:
+ 430 0008 0A96 adiw r24,10
+ 431 .LVL4:
+ 432 000a FC01 movw r30,r24
+ 433 000c 8DE2 ldi r24,lo8(45)
+ 434 000e DF01 movw r26,r30
+ 435 0010 1D92 st X+,__zero_reg__
+ 436 0012 8A95 dec r24
+ 437 0014 01F4 brne .-6
+ 438 0016 11E0 ldi r17,lo8(1)
+ 439 .LVL5:
+ 440 .L24:
+ 441 .LBB163:
+ 442 .LBB164:
+ 443 .LSM62:
+ 444 0018 8981 ldd r24,Y+1
+ 445 001a 1817 cp r17,r24
+ 446 001c 01F4 brne .L16
+ 447 .LSM63:
+ 448 001e EA81 ldd r30,Y+2
+ 449 0020 FB81 ldd r31,Y+3
+ 450 .LVL6:
+ 451 .LSM64:
+ 452 0022 8C81 ldd r24,Y+4
+ 453 .LVL7:
+ 454 0024 61E0 ldi r22,lo8(1)
+ 455 .LVL8:
+ 456 0026 00C0 rjmp .L17
+ 457 .LVL9:
+ 458 .L16:
+ 459 .LSM65:
+ 460 0028 8D81 ldd r24,Y+5
+ 461 002a 1817 cp r17,r24
+ 462 002c 01F4 brne .L18
+ 463 .LSM66:
+ 464 002e EE81 ldd r30,Y+6
+ 465 0030 FF81 ldd r31,Y+7
+ 466 .LVL10:
+ 467 .LSM67:
+ 468 0032 8885 ldd r24,Y+8
+ 469 .LVL11:
+ 470 0034 60E0 ldi r22,lo8(0)
+ 471 .LVL12:
+ 472 .L17:
+ 473 .LSM68:
+ 474 0036 8823 tst r24
+ 475 0038 01F4 brne .L19
+ 476 003a 40E0 ldi r20,lo8(0)
+ 477 003c 00C0 rjmp .L20
+ 478 .L19:
+ 479 003e 44E0 ldi r20,lo8(4)
+ 480 .L20:
+ 481 0040 20E0 ldi r18,lo8(0)
+ 482 .LVL13:
+ 483 0042 88E0 ldi r24,lo8(8)
+ 484 0044 90E0 ldi r25,hi8(8)
+ 485 .LVL14:
+ 486 0046 00C0 rjmp .L21
+ 487 .L22:
+ 488 .LBB165:
+ 489 .LBB166:
+ 490 .LBB167:
+ 491 .LBB168:
+ 492 .LSM69:
+ 493 0048 2F5F subi r18,lo8(-(1))
+ 494 .LSM70:
+ 495 004a 880F lsl r24
+ 496 004c 991F rol r25
+ 497 .L21:
+ 498 .LSM71:
+ 499 004e 8E17 cp r24,r30
+ 500 0050 9F07 cpc r25,r31
+ 501 0052 00F0 brlo .L22
+ 502 .LBE168:
+ 503 .LBE167:
+ 504 .LBE166:
+ 505 .LSM72:
+ 506 0054 6068 ori r22,lo8(-128)
+ 507 0056 4260 ori r20,lo8(2)
+ 508 0058 2295 swap r18
+ 509 005a 207F andi r18,lo8(-16)
+ 510 005c 422B or r20,r18
+ 511 005e 812F mov r24,r17
+ 512 .LVL15:
+ 513 0060 0E94 0000 call Endpoint_ConfigureEndpoint_Prv
+ 514 .LVL16:
+ 515 .LBE165:
+ 516 .LSM73:
+ 517 0064 8823 tst r24
+ 518 0066 01F0 breq .L23
+ 519 .L18:
+ 520 .LBE164:
+ 521 .LSM74:
+ 522 0068 1F5F subi r17,lo8(-(1))
+ 523 006a 1530 cpi r17,lo8(5)
+ 524 006c 01F4 brne .L24
+ 525 006e 81E0 ldi r24,lo8(1)
+ 526 .L23:
+ 527 /* epilogue start */
+ 528 .LBE163:
+ 529 .LSM75:
+ 530 0070 DF91 pop r29
+ 531 0072 CF91 pop r28
+ 532 .LVL17:
+ 533 0074 1F91 pop r17
+ 534 .LVL18:
+ 535 0076 0895 ret
+ 536 .LFE82:
+ 538 .section .text.MS_Device_ProcessControlRequest,"ax",@progbits
+ 539 .global MS_Device_ProcessControlRequest
+ 541 MS_Device_ProcessControlRequest:
+ 542 .LFB81:
+ 543 .LSM76:
+ 544 .LVL19:
+ 545 0000 CF93 push r28
+ 546 0002 DF93 push r29
+ 547 /* prologue: function */
+ 548 /* frame size = 0 */
+ 549 0004 EC01 movw r28,r24
+ 550 .LBB169:
+ 551 .LBB170:
+ 552 .LSM77:
+ 553 0006 8091 E800 lds r24,232
+ 554 .LVL20:
+ 555 .LBE170:
+ 556 .LBE169:
+ 557 .LSM78:
+ 558 000a 83FF sbrs r24,3
+ 559 000c 00C0 rjmp .L31
+ 560 .LSM79:
+ 561 000e 8881 ld r24,Y
+ 562 0010 90E0 ldi r25,lo8(0)
+ 563 0012 2091 0000 lds r18,USB_ControlRequest+4
+ 564 0016 3091 0000 lds r19,(USB_ControlRequest+4)+1
+ 565 001a 2817 cp r18,r24
+ 566 001c 3907 cpc r19,r25
+ 567 001e 01F4 brne .L31
+ 568 .LSM80:
+ 569 0020 8091 0000 lds r24,USB_ControlRequest+1
+ 570 0024 8E3F cpi r24,lo8(-2)
+ 571 0026 01F0 breq .L29
+ 572 0028 8F3F cpi r24,lo8(-1)
+ 573 002a 01F4 brne .L31
+ 574 .LSM81:
+ 575 002c 8091 0000 lds r24,USB_ControlRequest
+ 576 0030 8132 cpi r24,lo8(33)
+ 577 0032 01F4 brne .L31
+ 578 .LBB171:
+ 579 .LBB172:
+ 580 .LSM82:
+ 581 0034 8091 E800 lds r24,232
+ 582 0038 877F andi r24,lo8(-9)
+ 583 003a 8093 E800 sts 232,r24
+ 584 .LBE172:
+ 585 .LBE171:
+ 586 .LSM83:
+ 587 003e 0E94 0000 call Endpoint_ClearStatusStage
+ 588 .LSM84:
+ 589 0042 81E0 ldi r24,lo8(1)
+ 590 0044 8EAB std Y+54,r24
+ 591 0046 00C0 rjmp .L31
+ 592 .L29:
+ 593 .LSM85:
+ 594 0048 8091 0000 lds r24,USB_ControlRequest
+ 595 004c 813A cpi r24,lo8(-95)
+ 596 004e 01F4 brne .L31
+ 597 .LBB173:
+ 598 .LBB174:
+ 599 .LSM86:
+ 600 0050 8091 E800 lds r24,232
+ 601 0054 877F andi r24,lo8(-9)
+ 602 0056 8093 E800 sts 232,r24
+ 603 .LBE174:
+ 604 .LBE173:
+ 605 .LSM87:
+ 606 005a 8985 ldd r24,Y+9
+ 607 005c 8150 subi r24,lo8(-(-1))
+ 608 .LBB175:
+ 609 .LBB176:
+ 610 .LSM88:
+ 611 005e 8093 F100 sts 241,r24
+ 612 .LBE176:
+ 613 .LBE175:
+ 614 .LBB177:
+ 615 .LBB178:
+ 616 .LSM89:
+ 617 0062 8091 E800 lds r24,232
+ 618 0066 8E77 andi r24,lo8(126)
+ 619 0068 8093 E800 sts 232,r24
+ 620 .LBE178:
+ 621 .LBE177:
+ 622 .LSM90:
+ 623 006c 0E94 0000 call Endpoint_ClearStatusStage
+ 624 .L31:
+ 625 /* epilogue start */
+ 626 .LSM91:
+ 627 0070 DF91 pop r29
+ 628 0072 CF91 pop r28
+ 629 .LVL21:
+ 630 0074 0895 ret
+ 631 .LFE81:
+ 633 .lcomm CallbackIsResetSource,2
+ 682 .Letext0:
+DEFINED SYMBOLS
+ *ABS*:0000000000000000 MassStorage.c
+ /tmp/ccHFx5pp.s:2 *ABS*:000000000000003f __SREG__
+ /tmp/ccHFx5pp.s:3 *ABS*:000000000000003e __SP_H__
+ /tmp/ccHFx5pp.s:4 *ABS*:000000000000003d __SP_L__
+ /tmp/ccHFx5pp.s:5 *ABS*:0000000000000034 __CCP__
+ /tmp/ccHFx5pp.s:6 *ABS*:0000000000000000 __tmp_reg__
+ /tmp/ccHFx5pp.s:7 *ABS*:0000000000000001 __zero_reg__
+ /tmp/ccHFx5pp.s:18 .text.StreamCallback_MS_Device_AbortOnMassStoreReset:0000000000000000 StreamCallback_MS_Device_AbortOnMassStoreReset
+ .bss:0000000000000000 CallbackIsResetSource
+ /tmp/ccHFx5pp.s:37 .text.MS_Device_USBTask:0000000000000000 MS_Device_USBTask
+ /tmp/ccHFx5pp.s:419 .text.MS_Device_ConfigureEndpoints:0000000000000000 MS_Device_ConfigureEndpoints
+ /tmp/ccHFx5pp.s:541 .text.MS_Device_ProcessControlRequest:0000000000000000 MS_Device_ProcessControlRequest
+
+UNDEFINED SYMBOLS
+USB_USBTask
+USB_DeviceState
+Endpoint_Read_Stream_LE
+CALLBACK_MS_Device_SCSICommandReceived
+Endpoint_Write_Stream_LE
+Endpoint_ConfigureEndpoint_Prv
+USB_ControlRequest
+Endpoint_ClearStatusStage
+__do_clear_bss
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/MassStorage.o b/firmware/LUFA/Drivers/USB/Class/Device/MassStorage.o
new file mode 100644
index 0000000..2dbf5cd
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/MassStorage.o
Binary files differ
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/RNDIS.c b/firmware/LUFA/Drivers/USB/Class/Device/RNDIS.c
new file mode 100644
index 0000000..c6de9e5
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/RNDIS.c
@@ -0,0 +1,496 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define __INCLUDE_FROM_USB_DRIVER
+#include "../../HighLevel/USBMode.h"
+#if defined(USB_CAN_BE_DEVICE)
+
+#define __INCLUDE_FROM_RNDIS_DRIVER
+#define __INCLUDE_FROM_RNDIS_DEVICE_C
+#include "RNDIS.h"
+
+static const uint32_t PROGMEM AdapterSupportedOIDList[] =
+ {
+ OID_GEN_SUPPORTED_LIST,
+ OID_GEN_PHYSICAL_MEDIUM,
+ OID_GEN_HARDWARE_STATUS,
+ OID_GEN_MEDIA_SUPPORTED,
+ OID_GEN_MEDIA_IN_USE,
+ OID_GEN_MAXIMUM_FRAME_SIZE,
+ OID_GEN_MAXIMUM_TOTAL_SIZE,
+ OID_GEN_LINK_SPEED,
+ OID_GEN_TRANSMIT_BLOCK_SIZE,
+ OID_GEN_RECEIVE_BLOCK_SIZE,
+ OID_GEN_VENDOR_ID,
+ OID_GEN_VENDOR_DESCRIPTION,
+ OID_GEN_CURRENT_PACKET_FILTER,
+ OID_GEN_MAXIMUM_TOTAL_SIZE,
+ OID_GEN_MEDIA_CONNECT_STATUS,
+ OID_GEN_XMIT_OK,
+ OID_GEN_RCV_OK,
+ OID_GEN_XMIT_ERROR,
+ OID_GEN_RCV_ERROR,
+ OID_GEN_RCV_NO_BUFFER,
+ OID_802_3_PERMANENT_ADDRESS,
+ OID_802_3_CURRENT_ADDRESS,
+ OID_802_3_MULTICAST_LIST,
+ OID_802_3_MAXIMUM_LIST_SIZE,
+ OID_802_3_RCV_ERROR_ALIGNMENT,
+ OID_802_3_XMIT_ONE_COLLISION,
+ OID_802_3_XMIT_MORE_COLLISIONS,
+ };
+
+void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
+{
+ if (!(Endpoint_IsSETUPReceived()))
+ return;
+
+ if (USB_ControlRequest.wIndex != RNDISInterfaceInfo->Config.ControlInterfaceNumber)
+ return;
+
+ switch (USB_ControlRequest.bRequest)
+ {
+ case RNDIS_REQ_SendEncapsulatedCommand:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+ Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->State.RNDISMessageBuffer, USB_ControlRequest.wLength);
+ Endpoint_ClearIN();
+
+ RNDIS_Device_ProcessRNDISControlMessage(RNDISInterfaceInfo);
+ }
+
+ break;
+ case RNDIS_REQ_GetEncapsulatedResponse:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
+
+ if (!(MessageHeader->MessageLength))
+ {
+ RNDISInterfaceInfo->State.RNDISMessageBuffer[0] = 0;
+ MessageHeader->MessageLength = 1;
+ }
+
+ Endpoint_ClearSETUP();
+ Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->State.RNDISMessageBuffer, MessageHeader->MessageLength);
+ Endpoint_ClearOUT();
+
+ MessageHeader->MessageLength = 0;
+ }
+
+ break;
+ }
+}
+
+bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
+{
+ memset(&RNDISInterfaceInfo->State, 0x00, sizeof(RNDISInterfaceInfo->State));
+
+ for (uint8_t EndpointNum = 1; EndpointNum < ENDPOINT_TOTAL_ENDPOINTS; EndpointNum++)
+ {
+ uint16_t Size;
+ uint8_t Type;
+ uint8_t Direction;
+ bool DoubleBanked;
+
+ if (EndpointNum == RNDISInterfaceInfo->Config.DataINEndpointNumber)
+ {
+ Size = RNDISInterfaceInfo->Config.DataINEndpointSize;
+ Direction = ENDPOINT_DIR_IN;
+ Type = EP_TYPE_BULK;
+ DoubleBanked = RNDISInterfaceInfo->Config.DataINEndpointDoubleBank;
+ }
+ else if (EndpointNum == RNDISInterfaceInfo->Config.DataOUTEndpointNumber)
+ {
+ Size = RNDISInterfaceInfo->Config.DataOUTEndpointSize;
+ Direction = ENDPOINT_DIR_OUT;
+ Type = EP_TYPE_BULK;
+ DoubleBanked = RNDISInterfaceInfo->Config.DataOUTEndpointDoubleBank;
+ }
+ else if (EndpointNum == RNDISInterfaceInfo->Config.NotificationEndpointNumber)
+ {
+ Size = RNDISInterfaceInfo->Config.NotificationEndpointSize;
+ Direction = ENDPOINT_DIR_IN;
+ Type = EP_TYPE_INTERRUPT;
+ DoubleBanked = RNDISInterfaceInfo->Config.NotificationEndpointDoubleBank;
+ }
+ else
+ {
+ continue;
+ }
+
+ if (!(Endpoint_ConfigureEndpoint(EndpointNum, Type, Direction, Size,
+ DoubleBanked ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
+{
+ if (USB_DeviceState != DEVICE_STATE_Configured)
+ return;
+
+ RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
+
+ Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.NotificationEndpointNumber);
+
+ if (Endpoint_IsINReady() && RNDISInterfaceInfo->State.ResponseReady)
+ {
+ USB_Request_Header_t Notification = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = RNDIS_NOTIF_ResponseAvailable,
+ .wValue = 0,
+ .wIndex = 0,
+ .wLength = 0,
+ };
+
+ Endpoint_Write_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NO_STREAM_CALLBACK);
+
+ Endpoint_ClearIN();
+
+ RNDISInterfaceInfo->State.ResponseReady = false;
+ }
+
+ if ((RNDISInterfaceInfo->State.CurrRNDISState == RNDIS_Data_Initialized) && !(MessageHeader->MessageLength))
+ {
+ RNDIS_Packet_Message_t RNDISPacketHeader;
+
+ Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpointNumber);
+
+ if (Endpoint_IsOUTReceived() && !(RNDISInterfaceInfo->State.FrameIN.FrameInBuffer))
+ {
+ Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NO_STREAM_CALLBACK);
+
+ if (RNDISPacketHeader.DataLength > ETHERNET_FRAME_SIZE_MAX)
+ {
+ Endpoint_StallTransaction();
+ return;
+ }
+
+ Endpoint_Read_Stream_LE(RNDISInterfaceInfo->State.FrameIN.FrameData, RNDISPacketHeader.DataLength, NO_STREAM_CALLBACK);
+
+ Endpoint_ClearOUT();
+
+ RNDISInterfaceInfo->State.FrameIN.FrameLength = RNDISPacketHeader.DataLength;
+
+ RNDISInterfaceInfo->State.FrameIN.FrameInBuffer = true;
+ }
+
+ Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataINEndpointNumber);
+
+ if (Endpoint_IsINReady() && RNDISInterfaceInfo->State.FrameOUT.FrameInBuffer)
+ {
+ memset(&RNDISPacketHeader, 0, sizeof(RNDIS_Packet_Message_t));
+
+ RNDISPacketHeader.MessageType = REMOTE_NDIS_PACKET_MSG;
+ RNDISPacketHeader.MessageLength = (sizeof(RNDIS_Packet_Message_t) + RNDISInterfaceInfo->State.FrameOUT.FrameLength);
+ RNDISPacketHeader.DataOffset = (sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t));
+ RNDISPacketHeader.DataLength = RNDISInterfaceInfo->State.FrameOUT.FrameLength;
+
+ Endpoint_Write_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NO_STREAM_CALLBACK);
+ Endpoint_Write_Stream_LE(RNDISInterfaceInfo->State.FrameOUT.FrameData, RNDISPacketHeader.DataLength, NO_STREAM_CALLBACK);
+ Endpoint_ClearIN();
+
+ RNDISInterfaceInfo->State.FrameOUT.FrameInBuffer = false;
+ }
+ }
+}
+
+void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
+{
+ /* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of
+ this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */
+
+ RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
+
+ switch (MessageHeader->MessageType)
+ {
+ case REMOTE_NDIS_INITIALIZE_MSG:
+ RNDISInterfaceInfo->State.ResponseReady = true;
+
+ RNDIS_Initialize_Message_t* INITIALIZE_Message =
+ (RNDIS_Initialize_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
+ RNDIS_Initialize_Complete_t* INITIALIZE_Response =
+ (RNDIS_Initialize_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
+
+ INITIALIZE_Response->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
+ INITIALIZE_Response->MessageLength = sizeof(RNDIS_Initialize_Complete_t);
+ INITIALIZE_Response->RequestId = INITIALIZE_Message->RequestId;
+ INITIALIZE_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
+
+ INITIALIZE_Response->MajorVersion = REMOTE_NDIS_VERSION_MAJOR;
+ INITIALIZE_Response->MinorVersion = REMOTE_NDIS_VERSION_MINOR;
+ INITIALIZE_Response->DeviceFlags = REMOTE_NDIS_DF_CONNECTIONLESS;
+ INITIALIZE_Response->Medium = REMOTE_NDIS_MEDIUM_802_3;
+ INITIALIZE_Response->MaxPacketsPerTransfer = 1;
+ INITIALIZE_Response->MaxTransferSize = (sizeof(RNDIS_Packet_Message_t) + ETHERNET_FRAME_SIZE_MAX);
+ INITIALIZE_Response->PacketAlignmentFactor = 0;
+ INITIALIZE_Response->AFListOffset = 0;
+ INITIALIZE_Response->AFListSize = 0;
+
+ RNDISInterfaceInfo->State.CurrRNDISState = RNDIS_Initialized;
+
+ break;
+ case REMOTE_NDIS_HALT_MSG:
+ RNDISInterfaceInfo->State.ResponseReady = false;
+ MessageHeader->MessageLength = 0;
+
+ RNDISInterfaceInfo->State.CurrRNDISState = RNDIS_Uninitialized;
+
+ break;
+ case REMOTE_NDIS_QUERY_MSG:
+ RNDISInterfaceInfo->State.ResponseReady = true;
+
+ RNDIS_Query_Message_t* QUERY_Message = (RNDIS_Query_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
+ RNDIS_Query_Complete_t* QUERY_Response = (RNDIS_Query_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
+ uint32_t Query_Oid = QUERY_Message->Oid;
+
+ void* QueryData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
+ QUERY_Message->InformationBufferOffset];
+ void* ResponseData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Query_Complete_t)];
+ uint16_t ResponseSize;
+
+ QUERY_Response->MessageType = REMOTE_NDIS_QUERY_CMPLT;
+ QUERY_Response->MessageLength = sizeof(RNDIS_Query_Complete_t);
+
+ if (RNDIS_Device_ProcessNDISQuery(RNDISInterfaceInfo, Query_Oid, QueryData, QUERY_Message->InformationBufferLength,
+ ResponseData, &ResponseSize))
+ {
+ QUERY_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
+ QUERY_Response->MessageLength += ResponseSize;
+
+ QUERY_Response->InformationBufferLength = ResponseSize;
+ QUERY_Response->InformationBufferOffset = (sizeof(RNDIS_Query_Complete_t) - sizeof(RNDIS_Message_Header_t));
+ }
+ else
+ {
+ QUERY_Response->Status = REMOTE_NDIS_STATUS_NOT_SUPPORTED;
+
+ QUERY_Response->InformationBufferLength = 0;
+ QUERY_Response->InformationBufferOffset = 0;
+ }
+
+ break;
+ case REMOTE_NDIS_SET_MSG:
+ RNDISInterfaceInfo->State.ResponseReady = true;
+
+ RNDIS_Set_Message_t* SET_Message = (RNDIS_Set_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
+ RNDIS_Set_Complete_t* SET_Response = (RNDIS_Set_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
+ uint32_t SET_Oid = SET_Message->Oid;
+
+ SET_Response->MessageType = REMOTE_NDIS_SET_CMPLT;
+ SET_Response->MessageLength = sizeof(RNDIS_Set_Complete_t);
+ SET_Response->RequestId = SET_Message->RequestId;
+
+ void* SetData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
+ SET_Message->InformationBufferOffset];
+
+ SET_Response->Status = RNDIS_Device_ProcessNDISSet(RNDISInterfaceInfo, SET_Oid, SetData,
+ SET_Message->InformationBufferLength) ?
+ REMOTE_NDIS_STATUS_SUCCESS : REMOTE_NDIS_STATUS_NOT_SUPPORTED;
+ break;
+ case REMOTE_NDIS_RESET_MSG:
+ RNDISInterfaceInfo->State.ResponseReady = true;
+
+ RNDIS_Reset_Complete_t* RESET_Response = (RNDIS_Reset_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
+
+ RESET_Response->MessageType = REMOTE_NDIS_RESET_CMPLT;
+ RESET_Response->MessageLength = sizeof(RNDIS_Reset_Complete_t);
+ RESET_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
+ RESET_Response->AddressingReset = 0;
+
+ break;
+ case REMOTE_NDIS_KEEPALIVE_MSG:
+ RNDISInterfaceInfo->State.ResponseReady = true;
+
+ RNDIS_KeepAlive_Message_t* KEEPALIVE_Message =
+ (RNDIS_KeepAlive_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
+ RNDIS_KeepAlive_Complete_t* KEEPALIVE_Response =
+ (RNDIS_KeepAlive_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
+
+ KEEPALIVE_Response->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
+ KEEPALIVE_Response->MessageLength = sizeof(RNDIS_KeepAlive_Complete_t);
+ KEEPALIVE_Response->RequestId = KEEPALIVE_Message->RequestId;
+ KEEPALIVE_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
+
+ break;
+ }
+}
+
+static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
+ const uint32_t OId,
+ void* const QueryData,
+ const uint16_t QuerySize,
+ void* ResponseData,
+ uint16_t* const ResponseSize)
+{
+ (void)QueryData;
+ (void)QuerySize;
+
+ switch (OId)
+ {
+ case OID_GEN_SUPPORTED_LIST:
+ *ResponseSize = sizeof(AdapterSupportedOIDList);
+
+ memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList));
+
+ return true;
+ case OID_GEN_PHYSICAL_MEDIUM:
+ *ResponseSize = sizeof(uint32_t);
+
+ /* Indicate that the device is a true ethernet link */
+ *((uint32_t*)ResponseData) = 0;
+
+ return true;
+ case OID_GEN_HARDWARE_STATUS:
+ *ResponseSize = sizeof(uint32_t);
+
+ *((uint32_t*)ResponseData) = NDIS_HardwareStatus_Ready;
+
+ return true;
+ case OID_GEN_MEDIA_SUPPORTED:
+ case OID_GEN_MEDIA_IN_USE:
+ *ResponseSize = sizeof(uint32_t);
+
+ *((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIUM_802_3;
+
+ return true;
+ case OID_GEN_VENDOR_ID:
+ *ResponseSize = sizeof(uint32_t);
+
+ /* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */
+ *((uint32_t*)ResponseData) = 0x00FFFFFF;
+
+ return true;
+ case OID_GEN_MAXIMUM_FRAME_SIZE:
+ case OID_GEN_TRANSMIT_BLOCK_SIZE:
+ case OID_GEN_RECEIVE_BLOCK_SIZE:
+ *ResponseSize = sizeof(uint32_t);
+
+ *((uint32_t*)ResponseData) = ETHERNET_FRAME_SIZE_MAX;
+
+ return true;
+ case OID_GEN_VENDOR_DESCRIPTION:
+ *ResponseSize = (strlen(RNDISInterfaceInfo->Config.AdapterVendorDescription) + 1);
+
+ memcpy(ResponseData, RNDISInterfaceInfo->Config.AdapterVendorDescription, *ResponseSize);
+
+ return true;
+ case OID_GEN_MEDIA_CONNECT_STATUS:
+ *ResponseSize = sizeof(uint32_t);
+
+ *((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIA_STATE_CONNECTED;
+
+ return true;
+ case OID_GEN_LINK_SPEED:
+ *ResponseSize = sizeof(uint32_t);
+
+ /* Indicate 10Mb/s link speed */
+ *((uint32_t*)ResponseData) = 100000;
+
+ return true;
+ case OID_802_3_PERMANENT_ADDRESS:
+ case OID_802_3_CURRENT_ADDRESS:
+ *ResponseSize = sizeof(MAC_Address_t);
+
+ memcpy(ResponseData, &RNDISInterfaceInfo->Config.AdapterMACAddress, sizeof(MAC_Address_t));
+
+ return true;
+ case OID_802_3_MAXIMUM_LIST_SIZE:
+ *ResponseSize = sizeof(uint32_t);
+
+ /* Indicate only one multicast address supported */
+ *((uint32_t*)ResponseData) = 1;
+
+ return true;
+ case OID_GEN_CURRENT_PACKET_FILTER:
+ *ResponseSize = sizeof(uint32_t);
+
+ *((uint32_t*)ResponseData) = RNDISInterfaceInfo->State.CurrPacketFilter;
+
+ return true;
+ case OID_GEN_XMIT_OK:
+ case OID_GEN_RCV_OK:
+ case OID_GEN_XMIT_ERROR:
+ case OID_GEN_RCV_ERROR:
+ case OID_GEN_RCV_NO_BUFFER:
+ case OID_802_3_RCV_ERROR_ALIGNMENT:
+ case OID_802_3_XMIT_ONE_COLLISION:
+ case OID_802_3_XMIT_MORE_COLLISIONS:
+ *ResponseSize = sizeof(uint32_t);
+
+ /* Unused statistic OIDs - always return 0 for each */
+ *((uint32_t*)ResponseData) = 0;
+
+ return true;
+ case OID_GEN_MAXIMUM_TOTAL_SIZE:
+ *ResponseSize = sizeof(uint32_t);
+
+ /* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */
+ *((uint32_t*)ResponseData) = (RNDIS_MESSAGE_BUFFER_SIZE + ETHERNET_FRAME_SIZE_MAX);
+
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
+ const uint32_t OId,
+ const void* SetData,
+ const uint16_t SetSize)
+{
+ (void)SetSize;
+
+ switch (OId)
+ {
+ case OID_GEN_CURRENT_PACKET_FILTER:
+ RNDISInterfaceInfo->State.CurrPacketFilter = *((uint32_t*)SetData);
+ RNDISInterfaceInfo->State.CurrRNDISState = ((RNDISInterfaceInfo->State.CurrPacketFilter) ?
+ RNDIS_Data_Initialized : RNDIS_Data_Initialized);
+
+ return true;
+ case OID_802_3_MULTICAST_LIST:
+ /* Do nothing - throw away the value from the host as it is unused */
+
+ return true;
+ default:
+ return false;
+ }
+}
+
+#endif
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/RNDIS.h b/firmware/LUFA/Drivers/USB/Class/Device/RNDIS.h
new file mode 100644
index 0000000..9f24f29
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/RNDIS.h
@@ -0,0 +1,186 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Device mode driver for the library USB RNDIS Class driver.
+ *
+ * Device mode driver for the library USB RNDIS 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_USBClassRNDIS
+ * @defgroup Group_USBClassRNDISDevice RNDIS Class Device 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/Device/RNDIS.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ *
+ * \section Module Description
+ * Device Mode USB Class driver framework interface, for the RNDIS USB Class driver.
+ *
+ * @{
+ */
+
+#ifndef _RNDIS_CLASS_DEVICE_H_
+#define _RNDIS_CLASS_DEVICE_H_
+
+ /* Includes: */
+ #include "../../USB.h"
+ #include "../Common/RNDIS.h"
+
+ #include <string.h>
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_RNDIS_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ #if defined(__INCLUDE_FROM_RNDIS_DEVICE_C) && defined(NO_STREAM_CALLBACKS)
+ #error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
+ #endif
+
+
+ /* Public Interface - May be used in end-application: */
+ /* Type Defines: */
+ /** \brief RNDIS Class Device Mode Configuration and State Structure.
+ *
+ * Class state structure. An instance of this structure should be made for each RNDIS interface
+ * within the user application, and passed to each of the RNDIS class driver functions as the
+ * RNDISInterfaceInfo parameter. This stores each RNDIS interface's configuration and state information.
+ */
+ typedef struct
+ {
+ const struct
+ {
+ uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device. */
+
+ uint8_t DataINEndpointNumber; /**< Endpoint number of the CDC interface's IN data endpoint. */
+ uint16_t DataINEndpointSize; /**< Size in bytes of the CDC interface's IN data endpoint. */
+ bool DataINEndpointDoubleBank; /**< Indicates if the RNDIS interface's IN data endpoint should use double banking. */
+
+ uint8_t DataOUTEndpointNumber; /**< Endpoint number of the CDC interface's OUT data endpoint. */
+ uint16_t DataOUTEndpointSize; /**< Size in bytes of the CDC interface's OUT data endpoint. */
+ bool DataOUTEndpointDoubleBank; /**< Indicates if the RNDIS interface's OUT data endpoint should use double banking. */
+
+ uint8_t NotificationEndpointNumber; /**< Endpoint number of the CDC interface's IN notification endpoint, if used. */
+ uint16_t NotificationEndpointSize; /**< Size in bytes of the CDC interface's IN notification endpoint, if used. */
+ bool NotificationEndpointDoubleBank; /**< Indicates if the RNDIS interface's notification endpoint should use double banking. */
+
+ char* AdapterVendorDescription; /**< String description of the adapter vendor. */
+ MAC_Address_t AdapterMACAddress; /**< MAC address of the adapter. */
+ } Config; /**< Config data for the USB class interface within the device. All elements in this section.
+ * <b>must</b> be set or the interface will fail to enumerate and operate correctly.
+ */
+ struct
+ {
+ uint8_t RNDISMessageBuffer[RNDIS_MESSAGE_BUFFER_SIZE]; /**< Buffer to hold RNDIS messages to and from the host,
+ * managed by the class driver.
+ */
+ bool ResponseReady; /**< Internal flag indicating if a RNDIS message is waiting to be returned to the host. */
+ uint8_t CurrRNDISState; /**< Current RNDIS state of the adapter, a value from the \ref RNDIS_States_t enum. */
+ uint32_t CurrPacketFilter; /**< Current packet filter mode, used internally by the class driver. */
+ Ethernet_Frame_Info_t FrameIN; /**< Structure holding the last received Ethernet frame from the host, for user
+ * processing.
+ */
+ Ethernet_Frame_Info_t FrameOUT; /**< Structure holding the next Ethernet frame to send to the host, populated by the
+ * user application.
+ */
+ } State; /**< State data for the USB class interface within the device. All elements in this section
+ * are reset to their defaults when the interface is enumerated.
+ */
+ } USB_ClassInfo_RNDIS_Device_t;
+
+ /* Function Prototypes: */
+ /** Configures the endpoints of a given RNDIS interface, ready for use. This should be linked to the library
+ * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
+ * containing the given HID interface is selected.
+ *
+ * \note The endpoint index numbers as given in the interface's configuration structure must not overlap with any other
+ * interface, or endpoint bank corruption will occur. Gaps in the allocated endpoint numbers or non-sequential indexes
+ * within a single interface is allowed, but no two interfaces of any type have have interleaved endpoint indexes.
+ *
+ * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state.
+ *
+ * \return Boolean true if the endpoints were successfully configured, false otherwise.
+ */
+ bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Processes incoming control requests from the host, that are directed to the given RNDIS class interface. This should be
+ * linked to the library \ref EVENT_USB_Device_ControlRequest() event.
+ *
+ * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state.
+ */
+ void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** General management task for a given HID 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] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state.
+ */
+ void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /* Private Interface - For use in library only: */
+ #if !defined(__DOXYGEN__)
+ /* Function Prototypes: */
+ #if defined(__INCLUDE_FROM_RNDIS_DEVICE_C)
+ static void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
+ ATTR_NON_NULL_PTR_ARG(1);
+ static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
+ const uint32_t OId,
+ void* const QueryData,
+ const uint16_t QuerySize,
+ void* ResponseData,
+ uint16_t* const ResponseSize) ATTR_NON_NULL_PTR_ARG(1)
+ ATTR_NON_NULL_PTR_ARG(5) ATTR_NON_NULL_PTR_ARG(6);
+ static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
+ const uint32_t OId,
+ const void* SetData,
+ const uint16_t SetSize) ATTR_NON_NULL_PTR_ARG(1)
+ ATTR_NON_NULL_PTR_ARG(3);
+ #endif
+
+ #endif
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/RNDIS.lst b/firmware/LUFA/Drivers/USB/Class/Device/RNDIS.lst
new file mode 100644
index 0000000..3ae93a2
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/RNDIS.lst
@@ -0,0 +1,1519 @@
+ 1 .file "RNDIS.c"
+ 2 __SREG__ = 0x3f
+ 3 __SP_H__ = 0x3e
+ 4 __SP_L__ = 0x3d
+ 5 __CCP__ = 0x34
+ 6 __tmp_reg__ = 0
+ 7 __zero_reg__ = 1
+ 15 .Ltext0:
+ 16 .section .text.RNDIS_Device_USBTask,"ax",@progbits
+ 17 .global RNDIS_Device_USBTask
+ 19 RNDIS_Device_USBTask:
+ 20 .LFB83:
+ 21 .LSM0:
+ 22 .LVL0:
+ 23 0000 EF92 push r14
+ 24 0002 FF92 push r15
+ 25 0004 0F93 push r16
+ 26 0006 1F93 push r17
+ 27 0008 DF93 push r29
+ 28 000a CF93 push r28
+ 29 000c CDB7 in r28,__SP_L__
+ 30 000e DEB7 in r29,__SP_H__
+ 31 0010 AC97 sbiw r28,44
+ 32 0012 0FB6 in __tmp_reg__,__SREG__
+ 33 0014 F894 cli
+ 34 0016 DEBF out __SP_H__,r29
+ 35 0018 0FBE out __SREG__,__tmp_reg__
+ 36 001a CDBF out __SP_L__,r28
+ 37 /* prologue: function */
+ 38 /* frame size = 44 */
+ 39 001c 8C01 movw r16,r24
+ 40 .LSM1:
+ 41 001e 8091 0000 lds r24,USB_DeviceState
+ 42 .LVL1:
+ 43 0022 8430 cpi r24,lo8(4)
+ 44 0024 01F0 breq .+2
+ 45 0026 00C0 rjmp .L7
+ 46 .LSM2:
+ 47 0028 D801 movw r26,r16
+ 48 002a 1996 adiw r26,9
+ 49 002c 8C91 ld r24,X
+ 50 .LBB43:
+ 51 .LBB44:
+ 52 .LSM3:
+ 53 002e 8093 E900 sts 233,r24
+ 54 .LBE44:
+ 55 .LBE43:
+ 56 .LBB45:
+ 57 .LBB46:
+ 58 .LSM4:
+ 59 0032 8091 E800 lds r24,232
+ 60 .LBE46:
+ 61 .LBE45:
+ 62 .LSM5:
+ 63 0036 80FF sbrs r24,0
+ 64 0038 00C0 rjmp .L3
+ 65 003a 0B56 subi r16,lo8(-(149))
+ 66 003c 1F4F sbci r17,hi8(-(149))
+ 67 003e F801 movw r30,r16
+ 68 0040 8081 ld r24,Z
+ 69 0042 0559 subi r16,lo8(-(-149))
+ 70 0044 1040 sbci r17,hi8(-(-149))
+ 71 0046 8823 tst r24
+ 72 0048 01F0 breq .L3
+ 73 .LBB47:
+ 74 .LSM6:
+ 75 004a DE01 movw r26,r28
+ 76 004c 1196 adiw r26,1
+ 77 004e E0E0 ldi r30,lo8(C.9.3485)
+ 78 0050 F0E0 ldi r31,hi8(C.9.3485)
+ 79 0052 88E0 ldi r24,lo8(8)
+ 80 .L4:
+ 81 0054 0190 ld r0,Z+
+ 82 0056 0D92 st X+,r0
+ 83 0058 8150 subi r24,lo8(-(-1))
+ 84 005a 01F4 brne .L4
+ 85 .LSM7:
+ 86 005c CE01 movw r24,r28
+ 87 005e 0196 adiw r24,1
+ 88 0060 68E0 ldi r22,lo8(8)
+ 89 0062 70E0 ldi r23,hi8(8)
+ 90 0064 40E0 ldi r20,lo8(0)
+ 91 0066 50E0 ldi r21,hi8(0)
+ 92 0068 0E94 0000 call Endpoint_Write_Stream_LE
+ 93 .LBB48:
+ 94 .LBB49:
+ 95 .LSM8:
+ 96 006c 8091 E800 lds r24,232
+ 97 0070 8E77 andi r24,lo8(126)
+ 98 0072 8093 E800 sts 232,r24
+ 99 .LBE49:
+ 100 .LBE48:
+ 101 .LSM9:
+ 102 0076 0B56 subi r16,lo8(-(149))
+ 103 0078 1F4F sbci r17,hi8(-(149))
+ 104 007a D801 movw r26,r16
+ 105 007c 1C92 st X,__zero_reg__
+ 106 007e 0559 subi r16,lo8(-(-149))
+ 107 0080 1040 sbci r17,hi8(-(-149))
+ 108 .L3:
+ 109 .LBE47:
+ 110 .LSM10:
+ 111 0082 0A56 subi r16,lo8(-(150))
+ 112 0084 1F4F sbci r17,hi8(-(150))
+ 113 0086 F801 movw r30,r16
+ 114 0088 8081 ld r24,Z
+ 115 008a 0659 subi r16,lo8(-(-150))
+ 116 008c 1040 sbci r17,hi8(-(-150))
+ 117 008e 8230 cpi r24,lo8(2)
+ 118 0090 01F0 breq .+2
+ 119 0092 00C0 rjmp .L7
+ 120 0094 F801 movw r30,r16
+ 121 0096 818D ldd r24,Z+25
+ 122 0098 928D ldd r25,Z+26
+ 123 009a A38D ldd r26,Z+27
+ 124 009c B48D ldd r27,Z+28
+ 125 009e 0097 sbiw r24,0
+ 126 00a0 A105 cpc r26,__zero_reg__
+ 127 00a2 B105 cpc r27,__zero_reg__
+ 128 00a4 01F0 breq .+2
+ 129 00a6 00C0 rjmp .L7
+ 130 .LBB50:
+ 131 .LSM11:
+ 132 00a8 8581 ldd r24,Z+5
+ 133 .LBB51:
+ 134 .LBB52:
+ 135 .LSM12:
+ 136 00aa 8093 E900 sts 233,r24
+ 137 .LBE52:
+ 138 .LBE51:
+ 139 .LBB53:
+ 140 .LBB54:
+ 141 .LSM13:
+ 142 00ae 8091 E800 lds r24,232
+ 143 .LBE54:
+ 144 .LBE53:
+ 145 .LSM14:
+ 146 00b2 82FF sbrs r24,2
+ 147 00b4 00C0 rjmp .L5
+ 148 00b6 99E7 ldi r25,lo8(1657)
+ 149 00b8 E92E mov r14,r25
+ 150 00ba 96E0 ldi r25,hi8(1657)
+ 151 00bc F92E mov r15,r25
+ 152 00be E00E add r14,r16
+ 153 00c0 F11E adc r15,r17
+ 154 00c2 D701 movw r26,r14
+ 155 00c4 8C91 ld r24,X
+ 156 00c6 8823 tst r24
+ 157 00c8 01F4 brne .L5
+ 158 .LSM15:
+ 159 00ca CE01 movw r24,r28
+ 160 00cc 0196 adiw r24,1
+ 161 00ce 6CE2 ldi r22,lo8(44)
+ 162 00d0 70E0 ldi r23,hi8(44)
+ 163 00d2 40E0 ldi r20,lo8(0)
+ 164 00d4 50E0 ldi r21,hi8(0)
+ 165 00d6 0E94 0000 call Endpoint_Read_Stream_LE
+ 166 .LSM16:
+ 167 00da 2D85 ldd r18,Y+13
+ 168 00dc 3E85 ldd r19,Y+14
+ 169 00de 4F85 ldd r20,Y+15
+ 170 00e0 5889 ldd r21,Y+16
+ 171 00e2 2D3D cpi r18,lo8(1501)
+ 172 00e4 B5E0 ldi r27,hi8(1501)
+ 173 00e6 3B07 cpc r19,r27
+ 174 00e8 B0E0 ldi r27,hlo8(1501)
+ 175 00ea 4B07 cpc r20,r27
+ 176 00ec B0E0 ldi r27,hhi8(1501)
+ 177 00ee 5B07 cpc r21,r27
+ 178 00f0 00F0 brlo .L6
+ 179 .LBB55:
+ 180 .LBB56:
+ 181 .LSM17:
+ 182 00f2 8091 EB00 lds r24,235
+ 183 00f6 8062 ori r24,lo8(32)
+ 184 00f8 8093 EB00 sts 235,r24
+ 185 00fc 00C0 rjmp .L7
+ 186 .L6:
+ 187 .LBE56:
+ 188 .LBE55:
+ 189 .LSM18:
+ 190 00fe C801 movw r24,r16
+ 191 0100 8556 subi r24,lo8(-(155))
+ 192 0102 9F4F sbci r25,hi8(-(155))
+ 193 0104 B901 movw r22,r18
+ 194 0106 40E0 ldi r20,lo8(0)
+ 195 0108 50E0 ldi r21,hi8(0)
+ 196 010a 0E94 0000 call Endpoint_Read_Stream_LE
+ 197 .LBB57:
+ 198 .LBB58:
+ 199 .LSM19:
+ 200 010e 8091 E800 lds r24,232
+ 201 0112 8B77 andi r24,lo8(123)
+ 202 0114 8093 E800 sts 232,r24
+ 203 .LBE58:
+ 204 .LBE57:
+ 205 .LSM20:
+ 206 0118 0958 subi r16,lo8(-(1655))
+ 207 011a 194F sbci r17,hi8(-(1655))
+ 208 011c 8D85 ldd r24,Y+13
+ 209 011e 9E85 ldd r25,Y+14
+ 210 0120 F801 movw r30,r16
+ 211 0122 9183 std Z+1,r25
+ 212 0124 8083 st Z,r24
+ 213 0126 0757 subi r16,lo8(-(-1655))
+ 214 0128 1640 sbci r17,hi8(-(-1655))
+ 215 .LSM21:
+ 216 012a 81E0 ldi r24,lo8(1)
+ 217 012c D701 movw r26,r14
+ 218 012e 8C93 st X,r24
+ 219 .L5:
+ 220 .LSM22:
+ 221 0130 F801 movw r30,r16
+ 222 0132 8181 ldd r24,Z+1
+ 223 .LBB59:
+ 224 .LBB60:
+ 225 .LSM23:
+ 226 0134 8093 E900 sts 233,r24
+ 227 .LBE60:
+ 228 .LBE59:
+ 229 .LBB61:
+ 230 .LBB62:
+ 231 .LSM24:
+ 232 0138 8091 E800 lds r24,232
+ 233 .LBE62:
+ 234 .LBE61:
+ 235 .LSM25:
+ 236 013c 80FF sbrs r24,0
+ 237 013e 00C0 rjmp .L7
+ 238 0140 88E5 ldi r24,lo8(3160)
+ 239 0142 E82E mov r14,r24
+ 240 0144 8CE0 ldi r24,hi8(3160)
+ 241 0146 F82E mov r15,r24
+ 242 0148 E00E add r14,r16
+ 243 014a F11E adc r15,r17
+ 244 014c D701 movw r26,r14
+ 245 014e 8C91 ld r24,X
+ 246 0150 8823 tst r24
+ 247 0152 01F4 brne .+2
+ 248 0154 00C0 rjmp .L7
+ 249 .LSM26:
+ 250 0156 FE01 movw r30,r28
+ 251 0158 3196 adiw r30,1
+ 252 015a 8CE2 ldi r24,lo8(44)
+ 253 015c DF01 movw r26,r30
+ 254 015e 1D92 st X+,__zero_reg__
+ 255 0160 8A95 dec r24
+ 256 0162 01F4 brne .-6
+ 257 .LSM27:
+ 258 0164 81E0 ldi r24,lo8(1)
+ 259 0166 90E0 ldi r25,hi8(1)
+ 260 0168 A0E0 ldi r26,hlo8(1)
+ 261 016a B0E0 ldi r27,hhi8(1)
+ 262 016c 8983 std Y+1,r24
+ 263 016e 9A83 std Y+2,r25
+ 264 0170 AB83 std Y+3,r26
+ 265 0172 BC83 std Y+4,r27
+ 266 .LSM28:
+ 267 0174 0A5A subi r16,lo8(-(3158))
+ 268 0176 134F sbci r17,hi8(-(3158))
+ 269 0178 D801 movw r26,r16
+ 270 017a 8D91 ld r24,X+
+ 271 017c 9C91 ld r25,X
+ 272 017e 8C96 adiw r24,44
+ 273 0180 9C01 movw r18,r24
+ 274 0182 40E0 ldi r20,lo8(0)
+ 275 0184 50E0 ldi r21,hi8(0)
+ 276 0186 8C97 sbiw r24,44
+ 277 0188 2D83 std Y+5,r18
+ 278 018a 3E83 std Y+6,r19
+ 279 018c 4F83 std Y+7,r20
+ 280 018e 5887 std Y+8,r21
+ 281 .LSM29:
+ 282 0190 24E2 ldi r18,lo8(36)
+ 283 0192 30E0 ldi r19,hi8(36)
+ 284 0194 40E0 ldi r20,hlo8(36)
+ 285 0196 50E0 ldi r21,hhi8(36)
+ 286 0198 2987 std Y+9,r18
+ 287 019a 3A87 std Y+10,r19
+ 288 019c 4B87 std Y+11,r20
+ 289 019e 5C87 std Y+12,r21
+ 290 .LSM30:
+ 291 01a0 A0E0 ldi r26,lo8(0)
+ 292 01a2 B0E0 ldi r27,hi8(0)
+ 293 01a4 8D87 std Y+13,r24
+ 294 01a6 9E87 std Y+14,r25
+ 295 01a8 AF87 std Y+15,r26
+ 296 01aa B88B std Y+16,r27
+ 297 .LSM31:
+ 298 01ac CF01 movw r24,r30
+ 299 01ae 6CE2 ldi r22,lo8(44)
+ 300 01b0 70E0 ldi r23,hi8(44)
+ 301 01b2 40E0 ldi r20,lo8(0)
+ 302 01b4 50E0 ldi r21,hi8(0)
+ 303 01b6 0E94 0000 call Endpoint_Write_Stream_LE
+ 304 .LSM32:
+ 305 01ba 6D85 ldd r22,Y+13
+ 306 01bc 7E85 ldd r23,Y+14
+ 307 01be C801 movw r24,r16
+ 308 01c0 8C5D subi r24,lo8(-(-1500))
+ 309 01c2 9540 sbci r25,hi8(-(-1500))
+ 310 01c4 40E0 ldi r20,lo8(0)
+ 311 01c6 50E0 ldi r21,hi8(0)
+ 312 01c8 0E94 0000 call Endpoint_Write_Stream_LE
+ 313 .LBB63:
+ 314 .LBB64:
+ 315 .LSM33:
+ 316 01cc 8091 E800 lds r24,232
+ 317 01d0 8E77 andi r24,lo8(126)
+ 318 01d2 8093 E800 sts 232,r24
+ 319 .LBE64:
+ 320 .LBE63:
+ 321 .LSM34:
+ 322 01d6 F701 movw r30,r14
+ 323 01d8 1082 st Z,__zero_reg__
+ 324 .L7:
+ 325 /* epilogue start */
+ 326 .LBE50:
+ 327 .LSM35:
+ 328 01da AC96 adiw r28,44
+ 329 01dc 0FB6 in __tmp_reg__,__SREG__
+ 330 01de F894 cli
+ 331 01e0 DEBF out __SP_H__,r29
+ 332 01e2 0FBE out __SREG__,__tmp_reg__
+ 333 01e4 CDBF out __SP_L__,r28
+ 334 01e6 CF91 pop r28
+ 335 01e8 DF91 pop r29
+ 336 01ea 1F91 pop r17
+ 337 01ec 0F91 pop r16
+ 338 .LVL2:
+ 339 01ee FF90 pop r15
+ 340 01f0 EF90 pop r14
+ 341 01f2 0895 ret
+ 342 .LFE83:
+ 344 .section .text.RNDIS_Device_ConfigureEndpoints,"ax",@progbits
+ 345 .global RNDIS_Device_ConfigureEndpoints
+ 347 RNDIS_Device_ConfigureEndpoints:
+ 348 .LFB82:
+ 349 .LSM36:
+ 350 .LVL3:
+ 351 0000 1F93 push r17
+ 352 0002 CF93 push r28
+ 353 0004 DF93 push r29
+ 354 /* prologue: function */
+ 355 /* frame size = 0 */
+ 356 0006 EC01 movw r28,r24
+ 357 .LSM37:
+ 358 0008 4596 adiw r24,21
+ 359 .LVL4:
+ 360 000a FC01 movw r30,r24
+ 361 000c 84E4 ldi r24,lo8(3140)
+ 362 000e 9CE0 ldi r25,hi8(3140)
+ 363 0010 DF01 movw r26,r30
+ 364 0012 9C01 movw r18,r24
+ 365 0014 1D92 st X+,__zero_reg__
+ 366 0016 2150 subi r18,1
+ 367 0018 3040 sbci r19,0
+ 368 001a 01F4 brne .-8
+ 369 001c 11E0 ldi r17,lo8(1)
+ 370 .LVL5:
+ 371 .L19:
+ 372 .LBB65:
+ 373 .LBB66:
+ 374 .LSM38:
+ 375 001e 8981 ldd r24,Y+1
+ 376 0020 1817 cp r17,r24
+ 377 0022 01F4 brne .L10
+ 378 .LSM39:
+ 379 0024 EA81 ldd r30,Y+2
+ 380 0026 FB81 ldd r31,Y+3
+ 381 .LVL6:
+ 382 .LSM40:
+ 383 0028 8C81 ldd r24,Y+4
+ 384 .LVL7:
+ 385 002a 62E0 ldi r22,lo8(2)
+ 386 .LVL8:
+ 387 002c 00C0 rjmp .L22
+ 388 .LVL9:
+ 389 .L10:
+ 390 .LSM41:
+ 391 002e 8D81 ldd r24,Y+5
+ 392 0030 1817 cp r17,r24
+ 393 0032 01F4 brne .L12
+ 394 .LSM42:
+ 395 0034 EE81 ldd r30,Y+6
+ 396 0036 FF81 ldd r31,Y+7
+ 397 .LVL10:
+ 398 .LSM43:
+ 399 0038 8885 ldd r24,Y+8
+ 400 .LVL11:
+ 401 003a 62E0 ldi r22,lo8(2)
+ 402 .LVL12:
+ 403 003c 30E0 ldi r19,lo8(0)
+ 404 .LVL13:
+ 405 003e 00C0 rjmp .L11
+ 406 .LVL14:
+ 407 .L12:
+ 408 .LSM44:
+ 409 0040 8985 ldd r24,Y+9
+ 410 0042 1817 cp r17,r24
+ 411 0044 01F4 brne .L13
+ 412 .LSM45:
+ 413 0046 EA85 ldd r30,Y+10
+ 414 0048 FB85 ldd r31,Y+11
+ 415 .LVL15:
+ 416 .LSM46:
+ 417 004a 8C85 ldd r24,Y+12
+ 418 .LVL16:
+ 419 004c 63E0 ldi r22,lo8(3)
+ 420 .LVL17:
+ 421 .L22:
+ 422 004e 31E0 ldi r19,lo8(1)
+ 423 .LVL18:
+ 424 .L11:
+ 425 .LSM47:
+ 426 0050 8823 tst r24
+ 427 0052 01F4 brne .L14
+ 428 0054 40E0 ldi r20,lo8(0)
+ 429 0056 00C0 rjmp .L15
+ 430 .L14:
+ 431 0058 44E0 ldi r20,lo8(4)
+ 432 .L15:
+ 433 005a 20E0 ldi r18,lo8(0)
+ 434 .LVL19:
+ 435 005c 88E0 ldi r24,lo8(8)
+ 436 005e 90E0 ldi r25,hi8(8)
+ 437 .LVL20:
+ 438 0060 00C0 rjmp .L16
+ 439 .L17:
+ 440 .LBB67:
+ 441 .LBB68:
+ 442 .LBB69:
+ 443 .LBB70:
+ 444 .LSM48:
+ 445 0062 2F5F subi r18,lo8(-(1))
+ 446 .LSM49:
+ 447 0064 880F lsl r24
+ 448 0066 991F rol r25
+ 449 .L16:
+ 450 .LSM50:
+ 451 0068 8E17 cp r24,r30
+ 452 006a 9F07 cpc r25,r31
+ 453 006c 00F0 brlo .L17
+ 454 .LBE70:
+ 455 .LBE69:
+ 456 .LBE68:
+ 457 .LSM51:
+ 458 006e 6295 swap r22
+ 459 0070 660F lsl r22
+ 460 0072 660F lsl r22
+ 461 0074 607C andi r22,lo8(-64)
+ 462 0076 632B or r22,r19
+ 463 0078 4260 ori r20,lo8(2)
+ 464 007a 2295 swap r18
+ 465 007c 207F andi r18,lo8(-16)
+ 466 007e 422B or r20,r18
+ 467 0080 812F mov r24,r17
+ 468 .LVL21:
+ 469 0082 0E94 0000 call Endpoint_ConfigureEndpoint_Prv
+ 470 .LVL22:
+ 471 .LBE67:
+ 472 .LSM52:
+ 473 0086 8823 tst r24
+ 474 0088 01F0 breq .L18
+ 475 .L13:
+ 476 .LBE66:
+ 477 .LSM53:
+ 478 008a 1F5F subi r17,lo8(-(1))
+ 479 008c 1530 cpi r17,lo8(5)
+ 480 008e 01F4 brne .L19
+ 481 0090 81E0 ldi r24,lo8(1)
+ 482 .L18:
+ 483 /* epilogue start */
+ 484 .LBE65:
+ 485 .LSM54:
+ 486 0092 DF91 pop r29
+ 487 0094 CF91 pop r28
+ 488 .LVL23:
+ 489 0096 1F91 pop r17
+ 490 .LVL24:
+ 491 0098 0895 ret
+ 492 .LFE82:
+ 494 .section .text.RNDIS_Device_ProcessControlRequest,"ax",@progbits
+ 495 .global RNDIS_Device_ProcessControlRequest
+ 497 RNDIS_Device_ProcessControlRequest:
+ 498 .LFB81:
+ 499 .LSM55:
+ 500 .LVL25:
+ 501 0000 EF92 push r14
+ 502 0002 FF92 push r15
+ 503 0004 0F93 push r16
+ 504 0006 1F93 push r17
+ 505 0008 CF93 push r28
+ 506 000a DF93 push r29
+ 507 /* prologue: function */
+ 508 /* frame size = 0 */
+ 509 000c EC01 movw r28,r24
+ 510 .LBB89:
+ 511 .LBB90:
+ 512 .LSM56:
+ 513 000e 8091 E800 lds r24,232
+ 514 .LVL26:
+ 515 .LBE90:
+ 516 .LBE89:
+ 517 .LSM57:
+ 518 0012 83FF sbrs r24,3
+ 519 0014 00C0 rjmp .L63
+ 520 .LSM58:
+ 521 0016 8881 ld r24,Y
+ 522 0018 90E0 ldi r25,lo8(0)
+ 523 001a 2091 0000 lds r18,USB_ControlRequest+4
+ 524 001e 3091 0000 lds r19,(USB_ControlRequest+4)+1
+ 525 0022 2817 cp r18,r24
+ 526 0024 3907 cpc r19,r25
+ 527 0026 01F0 breq .+2
+ 528 0028 00C0 rjmp .L63
+ 529 .LSM59:
+ 530 002a 8091 0000 lds r24,USB_ControlRequest+1
+ 531 002e 8823 tst r24
+ 532 0030 01F0 breq .L25
+ 533 0032 8130 cpi r24,lo8(1)
+ 534 0034 01F0 breq .+2
+ 535 0036 00C0 rjmp .L63
+ 536 0038 00C0 rjmp .L71
+ 537 .L25:
+ 538 .LSM60:
+ 539 003a 8091 0000 lds r24,USB_ControlRequest
+ 540 003e 8132 cpi r24,lo8(33)
+ 541 0040 01F0 breq .+2
+ 542 0042 00C0 rjmp .L63
+ 543 .LBB91:
+ 544 .LBB92:
+ 545 .LSM61:
+ 546 0044 8091 E800 lds r24,232
+ 547 0048 877F andi r24,lo8(-9)
+ 548 004a 8093 E800 sts 232,r24
+ 549 .LBE92:
+ 550 .LBE91:
+ 551 .LSM62:
+ 552 004e 8E01 movw r16,r28
+ 553 0050 0B5E subi r16,lo8(-(21))
+ 554 0052 1F4F sbci r17,hi8(-(21))
+ 555 0054 6091 0000 lds r22,USB_ControlRequest+6
+ 556 0058 7091 0000 lds r23,(USB_ControlRequest+6)+1
+ 557 005c C801 movw r24,r16
+ 558 005e 0E94 0000 call Endpoint_Read_Control_Stream_LE
+ 559 .LBB93:
+ 560 .LBB94:
+ 561 .LSM63:
+ 562 0062 8091 E800 lds r24,232
+ 563 0066 8E77 andi r24,lo8(126)
+ 564 0068 8093 E800 sts 232,r24
+ 565 .LBE94:
+ 566 .LBE93:
+ 567 .LBB95:
+ 568 .LBB96:
+ 569 .LSM64:
+ 570 006c 8D89 ldd r24,Y+21
+ 571 006e 9E89 ldd r25,Y+22
+ 572 0070 AF89 ldd r26,Y+23
+ 573 0072 B88D ldd r27,Y+24
+ 574 0074 8430 cpi r24,lo8(4)
+ 575 0076 9105 cpc r25,__zero_reg__
+ 576 0078 A105 cpc r26,__zero_reg__
+ 577 007a B105 cpc r27,__zero_reg__
+ 578 007c 01F4 brne .+2
+ 579 007e 00C0 rjmp .L29
+ 580 0080 8530 cpi r24,lo8(5)
+ 581 0082 9105 cpc r25,__zero_reg__
+ 582 0084 A105 cpc r26,__zero_reg__
+ 583 0086 B105 cpc r27,__zero_reg__
+ 584 0088 00F4 brsh .L33
+ 585 008a 8230 cpi r24,lo8(2)
+ 586 008c 9105 cpc r25,__zero_reg__
+ 587 008e A105 cpc r26,__zero_reg__
+ 588 0090 B105 cpc r27,__zero_reg__
+ 589 0092 01F0 breq .L27
+ 590 0094 0397 sbiw r24,3
+ 591 0096 A105 cpc r26,__zero_reg__
+ 592 0098 B105 cpc r27,__zero_reg__
+ 593 009a 01F0 breq .+2
+ 594 009c 00C0 rjmp .L63
+ 595 009e 00C0 rjmp .L72
+ 596 .L33:
+ 597 00a0 8630 cpi r24,lo8(6)
+ 598 00a2 9105 cpc r25,__zero_reg__
+ 599 00a4 A105 cpc r26,__zero_reg__
+ 600 00a6 B105 cpc r27,__zero_reg__
+ 601 00a8 01F4 brne .+2
+ 602 00aa 00C0 rjmp .L31
+ 603 00ac 8630 cpi r24,lo8(6)
+ 604 00ae 9105 cpc r25,__zero_reg__
+ 605 00b0 A105 cpc r26,__zero_reg__
+ 606 00b2 B105 cpc r27,__zero_reg__
+ 607 00b4 00F4 brsh .+2
+ 608 00b6 00C0 rjmp .L30
+ 609 00b8 0897 sbiw r24,8
+ 610 00ba A105 cpc r26,__zero_reg__
+ 611 00bc B105 cpc r27,__zero_reg__
+ 612 00be 01F0 breq .+2
+ 613 00c0 00C0 rjmp .L63
+ 614 00c2 00C0 rjmp .L73
+ 615 .L27:
+ 616 .LBB97:
+ 617 .LSM65:
+ 618 00c4 CB56 subi r28,lo8(-(149))
+ 619 00c6 DF4F sbci r29,hi8(-(149))
+ 620 00c8 21E0 ldi r18,lo8(1)
+ 621 00ca 2883 st Y,r18
+ 622 00cc C559 subi r28,lo8(-(-149))
+ 623 00ce D040 sbci r29,hi8(-(-149))
+ 624 .LSM66:
+ 625 00d0 82E0 ldi r24,lo8(-2147483646)
+ 626 00d2 90E0 ldi r25,hi8(-2147483646)
+ 627 00d4 A0E0 ldi r26,hlo8(-2147483646)
+ 628 00d6 B0E8 ldi r27,hhi8(-2147483646)
+ 629 00d8 8D8B std Y+21,r24
+ 630 00da 9E8B std Y+22,r25
+ 631 00dc AF8B std Y+23,r26
+ 632 00de B88F std Y+24,r27
+ 633 .LSM67:
+ 634 00e0 84E3 ldi r24,lo8(52)
+ 635 00e2 90E0 ldi r25,hi8(52)
+ 636 00e4 A0E0 ldi r26,hlo8(52)
+ 637 00e6 B0E0 ldi r27,hhi8(52)
+ 638 00e8 F801 movw r30,r16
+ 639 00ea 8483 std Z+4,r24
+ 640 00ec 9583 std Z+5,r25
+ 641 00ee A683 std Z+6,r26
+ 642 00f0 B783 std Z+7,r27
+ 643 .LSM68:
+ 644 00f2 1486 std Z+12,__zero_reg__
+ 645 00f4 1586 std Z+13,__zero_reg__
+ 646 00f6 1686 std Z+14,__zero_reg__
+ 647 00f8 1786 std Z+15,__zero_reg__
+ 648 .LSM69:
+ 649 00fa 81E0 ldi r24,lo8(1)
+ 650 00fc 90E0 ldi r25,hi8(1)
+ 651 00fe A0E0 ldi r26,hlo8(1)
+ 652 0100 B0E0 ldi r27,hhi8(1)
+ 653 0102 808B std Z+16,r24
+ 654 0104 918B std Z+17,r25
+ 655 0106 A28B std Z+18,r26
+ 656 0108 B38B std Z+19,r27
+ 657 .LSM70:
+ 658 010a 148A std Z+20,__zero_reg__
+ 659 010c 158A std Z+21,__zero_reg__
+ 660 010e 168A std Z+22,__zero_reg__
+ 661 0110 178A std Z+23,__zero_reg__
+ 662 .LSM71:
+ 663 0112 808F std Z+24,r24
+ 664 0114 918F std Z+25,r25
+ 665 0116 A28F std Z+26,r26
+ 666 0118 B38F std Z+27,r27
+ 667 .LSM72:
+ 668 011a 148E std Z+28,__zero_reg__
+ 669 011c 158E std Z+29,__zero_reg__
+ 670 011e 168E std Z+30,__zero_reg__
+ 671 0120 178E std Z+31,__zero_reg__
+ 672 .LSM73:
+ 673 0122 80A3 std Z+32,r24
+ 674 0124 91A3 std Z+33,r25
+ 675 0126 A2A3 std Z+34,r26
+ 676 0128 B3A3 std Z+35,r27
+ 677 .LSM74:
+ 678 012a 88E0 ldi r24,lo8(1544)
+ 679 012c 96E0 ldi r25,hi8(1544)
+ 680 012e A0E0 ldi r26,hlo8(1544)
+ 681 0130 B0E0 ldi r27,hhi8(1544)
+ 682 0132 84A3 std Z+36,r24
+ 683 0134 95A3 std Z+37,r25
+ 684 0136 A6A3 std Z+38,r26
+ 685 0138 B7A3 std Z+39,r27
+ 686 .LSM75:
+ 687 013a 10A6 std Z+40,__zero_reg__
+ 688 013c 11A6 std Z+41,__zero_reg__
+ 689 013e 12A6 std Z+42,__zero_reg__
+ 690 0140 13A6 std Z+43,__zero_reg__
+ 691 .LSM76:
+ 692 0142 14A6 std Z+44,__zero_reg__
+ 693 0144 15A6 std Z+45,__zero_reg__
+ 694 0146 16A6 std Z+46,__zero_reg__
+ 695 0148 17A6 std Z+47,__zero_reg__
+ 696 .LSM77:
+ 697 014a 10AA std Z+48,__zero_reg__
+ 698 014c 11AA std Z+49,__zero_reg__
+ 699 014e 12AA std Z+50,__zero_reg__
+ 700 0150 13AA std Z+51,__zero_reg__
+ 701 .LSM78:
+ 702 0152 CA56 subi r28,lo8(-(150))
+ 703 0154 DF4F sbci r29,hi8(-(150))
+ 704 0156 2883 st Y,r18
+ 705 0158 00C0 rjmp .L63
+ 706 .L72:
+ 707 .LSM79:
+ 708 015a CB56 subi r28,lo8(-(149))
+ 709 015c DF4F sbci r29,hi8(-(149))
+ 710 015e 1992 st Y+,__zero_reg__
+ 711 .LSM80:
+ 712 0160 F801 movw r30,r16
+ 713 0162 1482 std Z+4,__zero_reg__
+ 714 0164 1582 std Z+5,__zero_reg__
+ 715 0166 1682 std Z+6,__zero_reg__
+ 716 0168 1782 std Z+7,__zero_reg__
+ 717 .LSM81:
+ 718 016a 1882 st Y,__zero_reg__
+ 719 .LVL27:
+ 720 016c 00C0 rjmp .L63
+ 721 .LVL28:
+ 722 .L29:
+ 723 .LSM82:
+ 724 016e CB56 subi r28,lo8(-(149))
+ 725 0170 DF4F sbci r29,hi8(-(149))
+ 726 0172 81E0 ldi r24,lo8(1)
+ 727 0174 8883 st Y,r24
+ 728 0176 C559 subi r28,lo8(-(-149))
+ 729 0178 D040 sbci r29,hi8(-(-149))
+ 730 .LSM83:
+ 731 017a F801 movw r30,r16
+ 732 017c 2485 ldd r18,Z+12
+ 733 017e 3585 ldd r19,Z+13
+ 734 0180 4685 ldd r20,Z+14
+ 735 0182 5785 ldd r21,Z+15
+ 736 .LVL29:
+ 737 .LSM84:
+ 738 0184 6DE2 ldi r22,lo8(45)
+ 739 0186 E62E mov r14,r22
+ 740 0188 F12C mov r15,__zero_reg__
+ 741 .LVL30:
+ 742 018a EC0E add r14,r28
+ 743 018c FD1E adc r15,r29
+ 744 .LSM85:
+ 745 018e 84E0 ldi r24,lo8(-2147483644)
+ 746 0190 90E0 ldi r25,hi8(-2147483644)
+ 747 0192 A0E0 ldi r26,hlo8(-2147483644)
+ 748 0194 B0E8 ldi r27,hhi8(-2147483644)
+ 749 0196 8D8B std Y+21,r24
+ 750 0198 9E8B std Y+22,r25
+ 751 019a AF8B std Y+23,r26
+ 752 019c B88F std Y+24,r27
+ 753 .LSM86:
+ 754 019e 88E1 ldi r24,lo8(24)
+ 755 01a0 90E0 ldi r25,hi8(24)
+ 756 01a2 A0E0 ldi r26,hlo8(24)
+ 757 01a4 B0E0 ldi r27,hhi8(24)
+ 758 01a6 8483 std Z+4,r24
+ 759 01a8 9583 std Z+5,r25
+ 760 01aa A683 std Z+6,r26
+ 761 01ac B783 std Z+7,r27
+ 762 .LBB100:
+ 763 .LBB101:
+ 764 .LSM87:
+ 765 01ae 2E30 cpi r18,lo8(65806)
+ 766 01b0 F1E0 ldi r31,hi8(65806)
+ 767 01b2 3F07 cpc r19,r31
+ 768 01b4 F1E0 ldi r31,hlo8(65806)
+ 769 01b6 4F07 cpc r20,r31
+ 770 01b8 F0E0 ldi r31,hhi8(65806)
+ 771 01ba 5F07 cpc r21,r31
+ 772 01bc 01F4 brne .+2
+ 773 01be 00C0 rjmp .L42
+ 774 01c0 2F30 cpi r18,lo8(65807)
+ 775 01c2 61E0 ldi r22,hi8(65807)
+ 776 01c4 3607 cpc r19,r22
+ 777 01c6 61E0 ldi r22,hlo8(65807)
+ 778 01c8 4607 cpc r20,r22
+ 779 01ca 60E0 ldi r22,hhi8(65807)
+ 780 01cc 5607 cpc r21,r22
+ 781 01ce 00F0 brlo .+2
+ 782 01d0 00C0 rjmp .L49
+ 783 01d2 2630 cpi r18,lo8(65798)
+ 784 01d4 81E0 ldi r24,hi8(65798)
+ 785 01d6 3807 cpc r19,r24
+ 786 01d8 81E0 ldi r24,hlo8(65798)
+ 787 01da 4807 cpc r20,r24
+ 788 01dc 80E0 ldi r24,hhi8(65798)
+ 789 01de 5807 cpc r21,r24
+ 790 01e0 01F4 brne .+2
+ 791 01e2 00C0 rjmp .L38
+ 792 01e4 2730 cpi r18,lo8(65799)
+ 793 01e6 E1E0 ldi r30,hi8(65799)
+ 794 01e8 3E07 cpc r19,r30
+ 795 01ea E1E0 ldi r30,hlo8(65799)
+ 796 01ec 4E07 cpc r20,r30
+ 797 01ee E0E0 ldi r30,hhi8(65799)
+ 798 01f0 5E07 cpc r21,r30
+ 799 01f2 00F4 brsh .L50
+ 800 01f4 2230 cpi r18,lo8(65794)
+ 801 01f6 F1E0 ldi r31,hi8(65794)
+ 802 01f8 3F07 cpc r19,r31
+ 803 01fa F1E0 ldi r31,hlo8(65794)
+ 804 01fc 4F07 cpc r20,r31
+ 805 01fe F0E0 ldi r31,hhi8(65794)
+ 806 0200 5F07 cpc r21,r31
+ 807 0202 01F4 brne .+2
+ 808 0204 00C0 rjmp .L46
+ 809 0206 2330 cpi r18,lo8(65795)
+ 810 0208 61E0 ldi r22,hi8(65795)
+ 811 020a 3607 cpc r19,r22
+ 812 020c 61E0 ldi r22,hlo8(65795)
+ 813 020e 4607 cpc r20,r22
+ 814 0210 60E0 ldi r22,hhi8(65795)
+ 815 0212 5607 cpc r21,r22
+ 816 0214 00F4 brsh .L51
+ 817 0216 2150 subi r18,lo8(65793)
+ 818 0218 3140 sbci r19,hi8(65793)
+ 819 021a 4140 sbci r20,hlo8(65793)
+ 820 021c 5040 sbci r21,hhi8(65793)
+ 821 021e 01F0 breq .+2
+ 822 0220 00C0 rjmp .L34
+ 823 0222 00C0 rjmp .L74
+ 824 .L51:
+ 825 0224 2550 subi r18,lo8(65797)
+ 826 0226 3140 sbci r19,hi8(65797)
+ 827 0228 4140 sbci r20,hlo8(65797)
+ 828 022a 5040 sbci r21,hhi8(65797)
+ 829 022c 00F0 brlo .+2
+ 830 022e 00C0 rjmp .L34
+ 831 0230 00C0 rjmp .L46
+ 832 .L50:
+ 833 0232 2C30 cpi r18,lo8(65804)
+ 834 0234 F1E0 ldi r31,hi8(65804)
+ 835 0236 3F07 cpc r19,r31
+ 836 0238 F1E0 ldi r31,hlo8(65804)
+ 837 023a 4F07 cpc r20,r31
+ 838 023c F0E0 ldi r31,hhi8(65804)
+ 839 023e 5F07 cpc r21,r31
+ 840 0240 00F4 brsh .L52
+ 841 0242 2A30 cpi r18,lo8(65802)
+ 842 0244 61E0 ldi r22,hi8(65802)
+ 843 0246 3607 cpc r19,r22
+ 844 0248 61E0 ldi r22,hlo8(65802)
+ 845 024a 4607 cpc r20,r22
+ 846 024c 60E0 ldi r22,hhi8(65802)
+ 847 024e 5607 cpc r21,r22
+ 848 0250 00F0 brlo .+2
+ 849 0252 00C0 rjmp .L38
+ 850 0254 2750 subi r18,lo8(65799)
+ 851 0256 3140 sbci r19,hi8(65799)
+ 852 0258 4140 sbci r20,hlo8(65799)
+ 853 025a 5040 sbci r21,hhi8(65799)
+ 854 025c 01F0 breq .+2
+ 855 025e 00C0 rjmp .L34
+ 856 0260 00C0 rjmp .L75
+ 857 .L52:
+ 858 0262 2C30 cpi r18,lo8(65804)
+ 859 0264 E1E0 ldi r30,hi8(65804)
+ 860 0266 3E07 cpc r19,r30
+ 861 0268 E1E0 ldi r30,hlo8(65804)
+ 862 026a 4E07 cpc r20,r30
+ 863 026c E0E0 ldi r30,hhi8(65804)
+ 864 026e 5E07 cpc r21,r30
+ 865 0270 01F4 brne .+2
+ 866 0272 00C0 rjmp .L40
+ 867 0274 2D50 subi r18,lo8(65805)
+ 868 0276 3140 sbci r19,hi8(65805)
+ 869 0278 4140 sbci r20,hlo8(65805)
+ 870 027a 5040 sbci r21,hhi8(65805)
+ 871 027c 01F0 breq .+2
+ 872 027e 00C0 rjmp .L34
+ 873 0280 00C0 rjmp .L76
+ 874 .L49:
+ 875 0282 2630 cpi r18,lo8(131334)
+ 876 0284 61E0 ldi r22,hi8(131334)
+ 877 0286 3607 cpc r19,r22
+ 878 0288 62E0 ldi r22,hlo8(131334)
+ 879 028a 4607 cpc r20,r22
+ 880 028c 60E0 ldi r22,hhi8(131334)
+ 881 028e 5607 cpc r21,r22
+ 882 0290 00F4 brsh .L53
+ 883 0292 2130 cpi r18,lo8(131329)
+ 884 0294 81E0 ldi r24,hi8(131329)
+ 885 0296 3807 cpc r19,r24
+ 886 0298 82E0 ldi r24,hlo8(131329)
+ 887 029a 4807 cpc r20,r24
+ 888 029c 80E0 ldi r24,hhi8(131329)
+ 889 029e 5807 cpc r21,r24
+ 890 02a0 00F0 brlo .+2
+ 891 02a2 00C0 rjmp .L46
+ 892 02a4 2431 cpi r18,lo8(65812)
+ 893 02a6 E1E0 ldi r30,hi8(65812)
+ 894 02a8 3E07 cpc r19,r30
+ 895 02aa E1E0 ldi r30,hlo8(65812)
+ 896 02ac 4E07 cpc r20,r30
+ 897 02ae E0E0 ldi r30,hhi8(65812)
+ 898 02b0 5E07 cpc r21,r30
+ 899 02b2 01F4 brne .+2
+ 900 02b4 00C0 rjmp .L46
+ 901 02b6 2230 cpi r18,lo8(66050)
+ 902 02b8 F2E0 ldi r31,hi8(66050)
+ 903 02ba 3F07 cpc r19,r31
+ 904 02bc F1E0 ldi r31,hlo8(66050)
+ 905 02be 4F07 cpc r20,r31
+ 906 02c0 F0E0 ldi r31,hhi8(66050)
+ 907 02c2 5F07 cpc r21,r31
+ 908 02c4 01F4 brne .+2
+ 909 02c6 00C0 rjmp .L46
+ 910 02c8 2151 subi r18,lo8(65809)
+ 911 02ca 3140 sbci r19,hi8(65809)
+ 912 02cc 4140 sbci r20,hlo8(65809)
+ 913 02ce 5040 sbci r21,hhi8(65809)
+ 914 02d0 01F0 breq .+2
+ 915 02d2 00C0 rjmp .L34
+ 916 02d4 00C0 rjmp .L77
+ 917 .L53:
+ 918 02d6 2430 cpi r18,lo8(16843012)
+ 919 02d8 81E0 ldi r24,hi8(16843012)
+ 920 02da 3807 cpc r19,r24
+ 921 02dc 81E0 ldi r24,hlo8(16843012)
+ 922 02de 4807 cpc r20,r24
+ 923 02e0 81E0 ldi r24,hhi8(16843012)
+ 924 02e2 5807 cpc r21,r24
+ 925 02e4 01F4 brne .+2
+ 926 02e6 00C0 rjmp .L48
+ 927 02e8 2530 cpi r18,lo8(16843013)
+ 928 02ea E1E0 ldi r30,hi8(16843013)
+ 929 02ec 3E07 cpc r19,r30
+ 930 02ee E1E0 ldi r30,hlo8(16843013)
+ 931 02f0 4E07 cpc r20,r30
+ 932 02f2 E1E0 ldi r30,hhi8(16843013)
+ 933 02f4 5E07 cpc r21,r30
+ 934 02f6 00F4 brsh .L54
+ 935 02f8 2150 subi r18,lo8(-(-16843009))
+ 936 02fa 3140 sbci r19,hi8(-(-16843009))
+ 937 02fc 4140 sbci r20,hlo8(-(-16843009))
+ 938 02fe 5140 sbci r21,hhi8(-(-16843009))
+ 939 0300 2230 cpi r18,lo8(2)
+ 940 0302 3105 cpc r19,__zero_reg__
+ 941 0304 4105 cpc r20,__zero_reg__
+ 942 0306 5105 cpc r21,__zero_reg__
+ 943 0308 00F0 brlo .+2
+ 944 030a 00C0 rjmp .L34
+ 945 030c 00C0 rjmp .L78
+ 946 .L54:
+ 947 030e 2150 subi r18,lo8(-(-16908545))
+ 948 0310 3140 sbci r19,hi8(-(-16908545))
+ 949 0312 4240 sbci r20,hlo8(-(-16908545))
+ 950 0314 5140 sbci r21,hhi8(-(-16908545))
+ 951 0316 2330 cpi r18,lo8(3)
+ 952 0318 3105 cpc r19,__zero_reg__
+ 953 031a 4105 cpc r20,__zero_reg__
+ 954 031c 5105 cpc r21,__zero_reg__
+ 955 031e 00F0 brlo .+2
+ 956 0320 00C0 rjmp .L34
+ 957 0322 00C0 rjmp .L46
+ 958 .L74:
+ 959 .LSM88:
+ 960 0324 C701 movw r24,r14
+ 961 0326 60E0 ldi r22,lo8(AdapterSupportedOIDList)
+ 962 0328 70E0 ldi r23,hi8(AdapterSupportedOIDList)
+ 963 032a 4CE6 ldi r20,lo8(108)
+ 964 032c 50E0 ldi r21,hi8(108)
+ 965 032e 0E94 0000 call memcpy_P
+ 966 .LVL31:
+ 967 0332 CCE6 ldi r28,lo8(108)
+ 968 0334 D0E0 ldi r29,hi8(108)
+ 969 .LVL32:
+ 970 0336 00C0 rjmp .L55
+ 971 .LVL33:
+ 972 .L40:
+ 973 .LSM89:
+ 974 0338 8FEF ldi r24,lo8(16777215)
+ 975 033a 9FEF ldi r25,hi8(16777215)
+ 976 033c AFEF ldi r26,hlo8(16777215)
+ 977 033e B0E0 ldi r27,hhi8(16777215)
+ 978 0340 00C0 rjmp .L70
+ 979 .L38:
+ 980 .LSM90:
+ 981 0342 8CED ldi r24,lo8(1500)
+ 982 0344 95E0 ldi r25,hi8(1500)
+ 983 0346 A0E0 ldi r26,hlo8(1500)
+ 984 0348 B0E0 ldi r27,hhi8(1500)
+ 985 034a 00C0 rjmp .L70
+ 986 .L76:
+ 987 .LSM91:
+ 988 034c 6D85 ldd r22,Y+13
+ 989 034e 7E85 ldd r23,Y+14
+ 990 .LBE101:
+ 991 0350 FB01 movw r30,r22
+ 992 0352 EF01 movw r28,r30
+ 993 .LVL34:
+ 994 0354 0990 ld __tmp_reg__,Y+
+ 995 0356 0020 tst __tmp_reg__
+ 996 0358 01F4 brne .-6
+ 997 .LBB102:
+ 998 035a CE1B sub r28,r30
+ 999 035c DF0B sbc r29,r31
+ 1000 .LSM92:
+ 1001 035e C701 movw r24,r14
+ 1002 .LVL35:
+ 1003 0360 AE01 movw r20,r28
+ 1004 .LVL36:
+ 1005 0362 0E94 0000 call memcpy
+ 1006 .LVL37:
+ 1007 0366 00C0 rjmp .L55
+ 1008 .LVL38:
+ 1009 .L75:
+ 1010 .LSM93:
+ 1011 0368 80EA ldi r24,lo8(100000)
+ 1012 036a 96E8 ldi r25,hi8(100000)
+ 1013 036c A1E0 ldi r26,hlo8(100000)
+ 1014 036e B0E0 ldi r27,hhi8(100000)
+ 1015 0370 00C0 rjmp .L70
+ 1016 .L78:
+ 1017 .LSM94:
+ 1018 0372 D701 movw r26,r14
+ 1019 0374 FE01 movw r30,r28
+ 1020 0376 3F96 adiw r30,15
+ 1021 0378 86E0 ldi r24,lo8(6)
+ 1022 .LVL39:
+ 1023 .L57:
+ 1024 037a 0190 ld r0,Z+
+ 1025 037c 0D92 st X+,r0
+ 1026 037e 8150 subi r24,lo8(-(-1))
+ 1027 0380 01F4 brne .L57
+ 1028 0382 C6E0 ldi r28,lo8(6)
+ 1029 0384 D0E0 ldi r29,hi8(6)
+ 1030 .LVL40:
+ 1031 0386 00C0 rjmp .L55
+ 1032 .LVL41:
+ 1033 .L48:
+ 1034 .LSM95:
+ 1035 0388 81E0 ldi r24,lo8(1)
+ 1036 038a 90E0 ldi r25,hi8(1)
+ 1037 038c A0E0 ldi r26,hlo8(1)
+ 1038 038e B0E0 ldi r27,hhi8(1)
+ 1039 0390 00C0 rjmp .L70
+ 1040 .L42:
+ 1041 .LSM96:
+ 1042 0392 C956 subi r28,lo8(-(151))
+ 1043 0394 DF4F sbci r29,hi8(-(151))
+ 1044 0396 8881 ld r24,Y
+ 1045 0398 9981 ldd r25,Y+1
+ 1046 039a AA81 ldd r26,Y+2
+ 1047 039c BB81 ldd r27,Y+3
+ 1048 039e C759 subi r28,lo8(-(-151))
+ 1049 03a0 D040 sbci r29,hi8(-(-151))
+ 1050 03a2 00C0 rjmp .L70
+ 1051 .L46:
+ 1052 .LSM97:
+ 1053 03a4 1DA6 std Y+45,__zero_reg__
+ 1054 03a6 1EA6 std Y+46,__zero_reg__
+ 1055 03a8 1FA6 std Y+47,__zero_reg__
+ 1056 03aa 18AA std Y+48,__zero_reg__
+ 1057 03ac 00C0 rjmp .L68
+ 1058 .L77:
+ 1059 .LSM98:
+ 1060 03ae 8CE5 ldi r24,lo8(1628)
+ 1061 03b0 96E0 ldi r25,hi8(1628)
+ 1062 03b2 A0E0 ldi r26,hlo8(1628)
+ 1063 03b4 B0E0 ldi r27,hhi8(1628)
+ 1064 .L70:
+ 1065 03b6 8DA7 std Y+45,r24
+ 1066 03b8 9EA7 std Y+46,r25
+ 1067 03ba AFA7 std Y+47,r26
+ 1068 03bc B8AB std Y+48,r27
+ 1069 .L68:
+ 1070 03be C4E0 ldi r28,lo8(4)
+ 1071 03c0 D0E0 ldi r29,hi8(4)
+ 1072 .LVL42:
+ 1073 03c2 00C0 rjmp .L55
+ 1074 .LVL43:
+ 1075 .L34:
+ 1076 .LBE102:
+ 1077 .LBE100:
+ 1078 .LSM99:
+ 1079 03c4 8BEB ldi r24,lo8(-1073741637)
+ 1080 03c6 90E0 ldi r25,hi8(-1073741637)
+ 1081 03c8 A0E0 ldi r26,hlo8(-1073741637)
+ 1082 03ca B0EC ldi r27,hhi8(-1073741637)
+ 1083 03cc F801 movw r30,r16
+ 1084 03ce 8487 std Z+12,r24
+ 1085 03d0 9587 std Z+13,r25
+ 1086 03d2 A687 std Z+14,r26
+ 1087 03d4 B787 std Z+15,r27
+ 1088 .LSM100:
+ 1089 03d6 108A std Z+16,__zero_reg__
+ 1090 03d8 118A std Z+17,__zero_reg__
+ 1091 03da 128A std Z+18,__zero_reg__
+ 1092 03dc 138A std Z+19,__zero_reg__
+ 1093 .LSM101:
+ 1094 03de 148A std Z+20,__zero_reg__
+ 1095 03e0 158A std Z+21,__zero_reg__
+ 1096 03e2 168A std Z+22,__zero_reg__
+ 1097 03e4 178A std Z+23,__zero_reg__
+ 1098 03e6 00C0 rjmp .L63
+ 1099 .LVL44:
+ 1100 .L30:
+ 1101 .LSM102:
+ 1102 03e8 CB56 subi r28,lo8(-(149))
+ 1103 03ea DF4F sbci r29,hi8(-(149))
+ 1104 03ec 81E0 ldi r24,lo8(1)
+ 1105 03ee 8883 st Y,r24
+ 1106 03f0 C559 subi r28,lo8(-(-149))
+ 1107 03f2 D040 sbci r29,hi8(-(-149))
+ 1108 .LSM103:
+ 1109 03f4 F801 movw r30,r16
+ 1110 03f6 2485 ldd r18,Z+12
+ 1111 03f8 3585 ldd r19,Z+13
+ 1112 03fa 4685 ldd r20,Z+14
+ 1113 03fc 5785 ldd r21,Z+15
+ 1114 .LVL45:
+ 1115 .LSM104:
+ 1116 03fe 85E0 ldi r24,lo8(-2147483643)
+ 1117 0400 90E0 ldi r25,hi8(-2147483643)
+ 1118 0402 A0E0 ldi r26,hlo8(-2147483643)
+ 1119 0404 B0E8 ldi r27,hhi8(-2147483643)
+ 1120 0406 8D8B std Y+21,r24
+ 1121 0408 9E8B std Y+22,r25
+ 1122 040a AF8B std Y+23,r26
+ 1123 040c B88F std Y+24,r27
+ 1124 .LSM105:
+ 1125 040e 80E1 ldi r24,lo8(16)
+ 1126 0410 90E0 ldi r25,hi8(16)
+ 1127 0412 A0E0 ldi r26,hlo8(16)
+ 1128 0414 B0E0 ldi r27,hhi8(16)
+ 1129 0416 8483 std Z+4,r24
+ 1130 0418 9583 std Z+5,r25
+ 1131 041a A683 std Z+6,r26
+ 1132 041c B783 std Z+7,r27
+ 1133 .LSM106:
+ 1134 041e 8489 ldd r24,Z+20
+ 1135 0420 9589 ldd r25,Z+21
+ 1136 0422 A689 ldd r26,Z+22
+ 1137 0424 B789 ldd r27,Z+23
+ 1138 .LBB98:
+ 1139 .LBB99:
+ 1140 .LSM107:
+ 1141 0426 2E30 cpi r18,lo8(65806)
+ 1142 0428 F1E0 ldi r31,hi8(65806)
+ 1143 042a 3F07 cpc r19,r31
+ 1144 042c F1E0 ldi r31,hlo8(65806)
+ 1145 042e 4F07 cpc r20,r31
+ 1146 0430 F0E0 ldi r31,hhi8(65806)
+ 1147 0432 5F07 cpc r21,r31
+ 1148 0434 01F0 breq .L59
+ 1149 0436 2350 subi r18,lo8(16843011)
+ 1150 0438 3140 sbci r19,hi8(16843011)
+ 1151 043a 4140 sbci r20,hlo8(16843011)
+ 1152 043c 5140 sbci r21,hhi8(16843011)
+ 1153 043e 01F0 breq .L67
+ 1154 0440 8BEB ldi r24,lo8(-1073741637)
+ 1155 0442 90E0 ldi r25,hi8(-1073741637)
+ 1156 0444 A0E0 ldi r26,hlo8(-1073741637)
+ 1157 0446 B0EC ldi r27,hhi8(-1073741637)
+ 1158 0448 00C0 rjmp .L61
+ 1159 .L59:
+ 1160 .LSM108:
+ 1161 044a FE01 movw r30,r28
+ 1162 044c E80F add r30,r24
+ 1163 044e F91F adc r31,r25
+ 1164 0450 858D ldd r24,Z+29
+ 1165 0452 968D ldd r25,Z+30
+ 1166 0454 A78D ldd r26,Z+31
+ 1167 0456 B0A1 ldd r27,Z+32
+ 1168 0458 C956 subi r28,lo8(-(151))
+ 1169 045a DF4F sbci r29,hi8(-(151))
+ 1170 045c 8883 st Y,r24
+ 1171 045e 9983 std Y+1,r25
+ 1172 0460 AA83 std Y+2,r26
+ 1173 0462 BB83 std Y+3,r27
+ 1174 .LSM109:
+ 1175 0464 FE01 movw r30,r28
+ 1176 0466 82E0 ldi r24,lo8(2)
+ 1177 0468 8293 st -Z,r24
+ 1178 .L67:
+ 1179 046a 80E0 ldi r24,lo8(0)
+ 1180 046c 90E0 ldi r25,hi8(0)
+ 1181 046e A0E0 ldi r26,hlo8(0)
+ 1182 0470 B0E0 ldi r27,hhi8(0)
+ 1183 .L61:
+ 1184 .LBE99:
+ 1185 .LBE98:
+ 1186 .LSM110:
+ 1187 0472 F801 movw r30,r16
+ 1188 0474 8487 std Z+12,r24
+ 1189 0476 9587 std Z+13,r25
+ 1190 0478 A687 std Z+14,r26
+ 1191 047a B787 std Z+15,r27
+ 1192 047c 00C0 rjmp .L63
+ 1193 .LVL46:
+ 1194 .L31:
+ 1195 .LSM111:
+ 1196 047e CB56 subi r28,lo8(-(149))
+ 1197 0480 DF4F sbci r29,hi8(-(149))
+ 1198 0482 81E0 ldi r24,lo8(1)
+ 1199 0484 8883 st Y,r24
+ 1200 0486 C559 subi r28,lo8(-(-149))
+ 1201 0488 D040 sbci r29,hi8(-(-149))
+ 1202 .LSM112:
+ 1203 048a 86E0 ldi r24,lo8(-2147483642)
+ 1204 048c 90E0 ldi r25,hi8(-2147483642)
+ 1205 048e A0E0 ldi r26,hlo8(-2147483642)
+ 1206 0490 B0E8 ldi r27,hhi8(-2147483642)
+ 1207 0492 8D8B std Y+21,r24
+ 1208 0494 9E8B std Y+22,r25
+ 1209 0496 AF8B std Y+23,r26
+ 1210 0498 B88F std Y+24,r27
+ 1211 .LSM113:
+ 1212 049a 80E1 ldi r24,lo8(16)
+ 1213 049c 90E0 ldi r25,hi8(16)
+ 1214 049e A0E0 ldi r26,hlo8(16)
+ 1215 04a0 B0E0 ldi r27,hhi8(16)
+ 1216 04a2 F801 movw r30,r16
+ 1217 04a4 8483 std Z+4,r24
+ 1218 04a6 9583 std Z+5,r25
+ 1219 04a8 A683 std Z+6,r26
+ 1220 04aa B783 std Z+7,r27
+ 1221 .LSM114:
+ 1222 04ac 1086 std Z+8,__zero_reg__
+ 1223 04ae 1186 std Z+9,__zero_reg__
+ 1224 04b0 1286 std Z+10,__zero_reg__
+ 1225 04b2 1386 std Z+11,__zero_reg__
+ 1226 04b4 00C0 rjmp .L69
+ 1227 .L73:
+ 1228 .LSM115:
+ 1229 04b6 CB56 subi r28,lo8(-(149))
+ 1230 04b8 DF4F sbci r29,hi8(-(149))
+ 1231 04ba 81E0 ldi r24,lo8(1)
+ 1232 04bc 8883 st Y,r24
+ 1233 04be C559 subi r28,lo8(-(-149))
+ 1234 04c0 D040 sbci r29,hi8(-(-149))
+ 1235 .LSM116:
+ 1236 04c2 88E0 ldi r24,lo8(-2147483640)
+ 1237 04c4 90E0 ldi r25,hi8(-2147483640)
+ 1238 04c6 A0E0 ldi r26,hlo8(-2147483640)
+ 1239 04c8 B0E8 ldi r27,hhi8(-2147483640)
+ 1240 04ca 8D8B std Y+21,r24
+ 1241 04cc 9E8B std Y+22,r25
+ 1242 04ce AF8B std Y+23,r26
+ 1243 04d0 B88F std Y+24,r27
+ 1244 .LSM117:
+ 1245 04d2 80E1 ldi r24,lo8(16)
+ 1246 04d4 90E0 ldi r25,hi8(16)
+ 1247 04d6 A0E0 ldi r26,hlo8(16)
+ 1248 04d8 B0E0 ldi r27,hhi8(16)
+ 1249 04da F801 movw r30,r16
+ 1250 04dc 8483 std Z+4,r24
+ 1251 04de 9583 std Z+5,r25
+ 1252 04e0 A683 std Z+6,r26
+ 1253 04e2 B783 std Z+7,r27
+ 1254 .L69:
+ 1255 .LSM118:
+ 1256 04e4 1486 std Z+12,__zero_reg__
+ 1257 04e6 1586 std Z+13,__zero_reg__
+ 1258 04e8 1686 std Z+14,__zero_reg__
+ 1259 04ea 1786 std Z+15,__zero_reg__
+ 1260 04ec 00C0 rjmp .L63
+ 1261 .L71:
+ 1262 .LBE97:
+ 1263 .LBE96:
+ 1264 .LBE95:
+ 1265 .LSM119:
+ 1266 04ee 8091 0000 lds r24,USB_ControlRequest
+ 1267 04f2 813A cpi r24,lo8(-95)
+ 1268 04f4 01F0 breq .+2
+ 1269 04f6 00C0 rjmp .L63
+ 1270 .LBB105:
+ 1271 .LSM120:
+ 1272 04f8 8E01 movw r16,r28
+ 1273 .LVL47:
+ 1274 04fa 0B5E subi r16,lo8(-(21))
+ 1275 04fc 1F4F sbci r17,hi8(-(21))
+ 1276 .LSM121:
+ 1277 04fe F801 movw r30,r16
+ 1278 0500 8481 ldd r24,Z+4
+ 1279 0502 9581 ldd r25,Z+5
+ 1280 0504 A681 ldd r26,Z+6
+ 1281 0506 B781 ldd r27,Z+7
+ 1282 0508 0097 sbiw r24,0
+ 1283 050a A105 cpc r26,__zero_reg__
+ 1284 050c B105 cpc r27,__zero_reg__
+ 1285 050e 01F4 brne .L62
+ 1286 .LSM122:
+ 1287 0510 1D8A std Y+21,__zero_reg__
+ 1288 .LSM123:
+ 1289 0512 81E0 ldi r24,lo8(1)
+ 1290 0514 90E0 ldi r25,hi8(1)
+ 1291 0516 A0E0 ldi r26,hlo8(1)
+ 1292 0518 B0E0 ldi r27,hhi8(1)
+ 1293 051a 8483 std Z+4,r24
+ 1294 051c 9583 std Z+5,r25
+ 1295 051e A683 std Z+6,r26
+ 1296 0520 B783 std Z+7,r27
+ 1297 .L62:
+ 1298 .LBB106:
+ 1299 .LBB107:
+ 1300 .LSM124:
+ 1301 0522 8091 E800 lds r24,232
+ 1302 0526 877F andi r24,lo8(-9)
+ 1303 0528 8093 E800 sts 232,r24
+ 1304 .LBE107:
+ 1305 .LBE106:
+ 1306 .LSM125:
+ 1307 052c F801 movw r30,r16
+ 1308 052e 6481 ldd r22,Z+4
+ 1309 0530 7581 ldd r23,Z+5
+ 1310 0532 CE01 movw r24,r28
+ 1311 0534 4596 adiw r24,21
+ 1312 0536 0E94 0000 call Endpoint_Write_Control_Stream_LE
+ 1313 .LBB108:
+ 1314 .LBB109:
+ 1315 .LSM126:
+ 1316 053a 8091 E800 lds r24,232
+ 1317 053e 8B77 andi r24,lo8(123)
+ 1318 0540 8093 E800 sts 232,r24
+ 1319 .LBE109:
+ 1320 .LBE108:
+ 1321 .LSM127:
+ 1322 0544 F801 movw r30,r16
+ 1323 0546 1482 std Z+4,__zero_reg__
+ 1324 0548 1582 std Z+5,__zero_reg__
+ 1325 054a 1682 std Z+6,__zero_reg__
+ 1326 054c 1782 std Z+7,__zero_reg__
+ 1327 054e 00C0 rjmp .L63
+ 1328 .LVL48:
+ 1329 .L55:
+ 1330 .LBE105:
+ 1331 .LBB110:
+ 1332 .LBB104:
+ 1333 .LBB103:
+ 1334 .LSM128:
+ 1335 0550 F801 movw r30,r16
+ 1336 0552 1486 std Z+12,__zero_reg__
+ 1337 0554 1586 std Z+13,__zero_reg__
+ 1338 0556 1686 std Z+14,__zero_reg__
+ 1339 0558 1786 std Z+15,__zero_reg__
+ 1340 .LSM129:
+ 1341 055a CE01 movw r24,r28
+ 1342 055c A0E0 ldi r26,lo8(0)
+ 1343 055e B0E0 ldi r27,hi8(0)
+ 1344 0560 2481 ldd r18,Z+4
+ 1345 0562 3581 ldd r19,Z+5
+ 1346 0564 4681 ldd r20,Z+6
+ 1347 0566 5781 ldd r21,Z+7
+ 1348 .LVL49:
+ 1349 0568 280F add r18,r24
+ 1350 056a 391F adc r19,r25
+ 1351 056c 4A1F adc r20,r26
+ 1352 056e 5B1F adc r21,r27
+ 1353 0570 2483 std Z+4,r18
+ 1354 0572 3583 std Z+5,r19
+ 1355 0574 4683 std Z+6,r20
+ 1356 0576 5783 std Z+7,r21
+ 1357 .LSM130:
+ 1358 0578 808B std Z+16,r24
+ 1359 057a 918B std Z+17,r25
+ 1360 057c A28B std Z+18,r26
+ 1361 057e B38B std Z+19,r27
+ 1362 .LSM131:
+ 1363 0580 80E1 ldi r24,lo8(16)
+ 1364 0582 90E0 ldi r25,hi8(16)
+ 1365 0584 A0E0 ldi r26,hlo8(16)
+ 1366 0586 B0E0 ldi r27,hhi8(16)
+ 1367 0588 848B std Z+20,r24
+ 1368 058a 958B std Z+21,r25
+ 1369 058c A68B std Z+22,r26
+ 1370 058e B78B std Z+23,r27
+ 1371 .LVL50:
+ 1372 .L63:
+ 1373 /* epilogue start */
+ 1374 .LBE103:
+ 1375 .LBE104:
+ 1376 .LBE110:
+ 1377 .LSM132:
+ 1378 0590 DF91 pop r29
+ 1379 0592 CF91 pop r28
+ 1380 .LVL51:
+ 1381 0594 1F91 pop r17
+ 1382 0596 0F91 pop r16
+ 1383 .LVL52:
+ 1384 0598 FF90 pop r15
+ 1385 059a EF90 pop r14
+ 1386 .LVL53:
+ 1387 059c 0895 ret
+ 1388 .LFE81:
+ 1390 .data
+ 1393 C.9.3485:
+ 1394 0000 A1 .byte -95
+ 1395 0001 01 .byte 1
+ 1396 0002 0000 .word 0
+ 1397 0004 0000 .word 0
+ 1398 0006 0000 .word 0
+ 1399 .section .progmem.data,"a",@progbits
+ 1402 AdapterSupportedOIDList:
+ 1403 0000 01 .byte 1
+ 1404 0001 01 .byte 1
+ 1405 0002 01 .byte 1
+ 1406 0003 00 .byte 0
+ 1407 0004 02 .byte 2
+ 1408 0005 02 .byte 2
+ 1409 0006 01 .byte 1
+ 1410 0007 00 .byte 0
+ 1411 0008 02 .byte 2
+ 1412 0009 01 .byte 1
+ 1413 000a 01 .byte 1
+ 1414 000b 00 .byte 0
+ 1415 000c 03 .byte 3
+ 1416 000d 01 .byte 1
+ 1417 000e 01 .byte 1
+ 1418 000f 00 .byte 0
+ 1419 0010 04 .byte 4
+ 1420 0011 01 .byte 1
+ 1421 0012 01 .byte 1
+ 1422 0013 00 .byte 0
+ 1423 0014 06 .byte 6
+ 1424 0015 01 .byte 1
+ 1425 0016 01 .byte 1
+ 1426 0017 00 .byte 0
+ 1427 0018 11 .byte 17
+ 1428 0019 01 .byte 1
+ 1429 001a 01 .byte 1
+ 1430 001b 00 .byte 0
+ 1431 001c 07 .byte 7
+ 1432 001d 01 .byte 1
+ 1433 001e 01 .byte 1
+ 1434 001f 00 .byte 0
+ 1435 0020 0A .byte 10
+ 1436 0021 01 .byte 1
+ 1437 0022 01 .byte 1
+ 1438 0023 00 .byte 0
+ 1439 0024 0B .byte 11
+ 1440 0025 01 .byte 1
+ 1441 0026 01 .byte 1
+ 1442 0027 00 .byte 0
+ 1443 0028 0C .byte 12
+ 1444 0029 01 .byte 1
+ 1445 002a 01 .byte 1
+ 1446 002b 00 .byte 0
+ 1447 002c 0D .byte 13
+ 1448 002d 01 .byte 1
+ 1449 002e 01 .byte 1
+ 1450 002f 00 .byte 0
+ 1451 0030 0E .byte 14
+ 1452 0031 01 .byte 1
+ 1453 0032 01 .byte 1
+ 1454 0033 00 .byte 0
+ 1455 0034 11 .byte 17
+ 1456 0035 01 .byte 1
+ 1457 0036 01 .byte 1
+ 1458 0037 00 .byte 0
+ 1459 0038 14 .byte 20
+ 1460 0039 01 .byte 1
+ 1461 003a 01 .byte 1
+ 1462 003b 00 .byte 0
+ 1463 003c 01 .byte 1
+ 1464 003d 01 .byte 1
+ 1465 003e 02 .byte 2
+ 1466 003f 00 .byte 0
+ 1467 0040 02 .byte 2
+ 1468 0041 01 .byte 1
+ 1469 0042 02 .byte 2
+ 1470 0043 00 .byte 0
+ 1471 0044 03 .byte 3
+ 1472 0045 01 .byte 1
+ 1473 0046 02 .byte 2
+ 1474 0047 00 .byte 0
+ 1475 0048 04 .byte 4
+ 1476 0049 01 .byte 1
+ 1477 004a 02 .byte 2
+ 1478 004b 00 .byte 0
+ 1479 004c 05 .byte 5
+ 1480 004d 01 .byte 1
+ 1481 004e 02 .byte 2
+ 1482 004f 00 .byte 0
+ 1483 0050 01 .byte 1
+ 1484 0051 01 .byte 1
+ 1485 0052 01 .byte 1
+ 1486 0053 01 .byte 1
+ 1487 0054 02 .byte 2
+ 1488 0055 01 .byte 1
+ 1489 0056 01 .byte 1
+ 1490 0057 01 .byte 1
+ 1491 0058 03 .byte 3
+ 1492 0059 01 .byte 1
+ 1493 005a 01 .byte 1
+ 1494 005b 01 .byte 1
+ 1495 005c 04 .byte 4
+ 1496 005d 01 .byte 1
+ 1497 005e 01 .byte 1
+ 1498 005f 01 .byte 1
+ 1499 0060 01 .byte 1
+ 1500 0061 01 .byte 1
+ 1501 0062 02 .byte 2
+ 1502 0063 01 .byte 1
+ 1503 0064 02 .byte 2
+ 1504 0065 01 .byte 1
+ 1505 0066 02 .byte 2
+ 1506 0067 01 .byte 1
+ 1507 0068 03 .byte 3
+ 1508 0069 01 .byte 1
+ 1509 006a 02 .byte 2
+ 1510 006b 01 .byte 1
+ 1551 .Letext0:
+DEFINED SYMBOLS
+ *ABS*:0000000000000000 RNDIS.c
+ /tmp/ccEJ1rts.s:2 *ABS*:000000000000003f __SREG__
+ /tmp/ccEJ1rts.s:3 *ABS*:000000000000003e __SP_H__
+ /tmp/ccEJ1rts.s:4 *ABS*:000000000000003d __SP_L__
+ /tmp/ccEJ1rts.s:5 *ABS*:0000000000000034 __CCP__
+ /tmp/ccEJ1rts.s:6 *ABS*:0000000000000000 __tmp_reg__
+ /tmp/ccEJ1rts.s:7 *ABS*:0000000000000001 __zero_reg__
+ /tmp/ccEJ1rts.s:19 .text.RNDIS_Device_USBTask:0000000000000000 RNDIS_Device_USBTask
+ /tmp/ccEJ1rts.s:1393 .data:0000000000000000 C.9.3485
+ /tmp/ccEJ1rts.s:347 .text.RNDIS_Device_ConfigureEndpoints:0000000000000000 RNDIS_Device_ConfigureEndpoints
+ /tmp/ccEJ1rts.s:497 .text.RNDIS_Device_ProcessControlRequest:0000000000000000 RNDIS_Device_ProcessControlRequest
+ /tmp/ccEJ1rts.s:1402 .progmem.data:0000000000000000 AdapterSupportedOIDList
+
+UNDEFINED SYMBOLS
+USB_DeviceState
+Endpoint_Write_Stream_LE
+Endpoint_Read_Stream_LE
+Endpoint_ConfigureEndpoint_Prv
+USB_ControlRequest
+Endpoint_Read_Control_Stream_LE
+memcpy_P
+memcpy
+Endpoint_Write_Control_Stream_LE
+__do_copy_data
diff --git a/firmware/LUFA/Drivers/USB/Class/Device/RNDIS.o b/firmware/LUFA/Drivers/USB/Class/Device/RNDIS.o
new file mode 100644
index 0000000..f525cda
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Device/RNDIS.o
Binary files differ
diff --git a/firmware/LUFA/Drivers/USB/Class/HID.h b/firmware/LUFA/Drivers/USB/Class/HID.h
new file mode 100644
index 0000000..7748f44
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/HID.h
@@ -0,0 +1,81 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Master include file for the library USB HID Class driver.
+ *
+ * Master include file for the library USB HID 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_USBClassHID HID 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/Device/HID.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ * - LUFA/Drivers/USB/Class/Host/HID.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ * - LUFA/Drivers/USB/Class/Host/HIDParser.c <i>(Makefile source module name: LUFA_SRC_USB)</i>
+ *
+ * \section Module Description
+ * HID Class Driver module. This module contains an internal implementation of the USB HID Class, for both Device
+ * and Host USB modes. User applications can use this class driver instead of implementing the HID 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
+ * Hosts or Devices using the USB HID Class.
+ *
+ * @{
+ */
+
+#ifndef _HID_CLASS_H_
+#define _HID_CLASS_H_
+
+ /* Macros: */
+ #define __INCLUDE_FROM_USB_DRIVER
+ #define __INCLUDE_FROM_HID_DRIVER
+
+ /* Includes: */
+ #include "../HighLevel/USBMode.h"
+
+ #if defined(USB_CAN_BE_DEVICE)
+ #include "Device/HID.h"
+ #endif
+
+ #if defined(USB_CAN_BE_HOST)
+ #include "Host/HID.h"
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/CDC.c b/firmware/LUFA/Drivers/USB/Class/Host/CDC.c
new file mode 100644
index 0000000..afa4629
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/CDC.c
@@ -0,0 +1,465 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define __INCLUDE_FROM_USB_DRIVER
+#include "../../HighLevel/USBMode.h"
+#if defined(USB_CAN_BE_HOST)
+
+#define __INCLUDE_FROM_CDC_DRIVER
+#define __INCLUDE_FROM_CDC_HOST_C
+#include "CDC.h"
+
+uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+ uint16_t ConfigDescriptorSize,
+ void* ConfigDescriptorData)
+{
+ USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
+ USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
+ USB_Descriptor_Endpoint_t* NotificationEndpoint = NULL;
+ USB_Descriptor_Interface_t* CDCControlInterface = NULL;
+
+ memset(&CDCInterfaceInfo->State, 0x00, sizeof(CDCInterfaceInfo->State));
+
+ if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
+ return CDC_ENUMERROR_InvalidConfigDescriptor;
+
+ while (!(DataINEndpoint) || !(DataOUTEndpoint) || !(NotificationEndpoint))
+ {
+ if (!(CDCControlInterface) ||
+ USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+ DCOMP_CDC_Host_NextCDCInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
+ {
+ if (NotificationEndpoint)
+ {
+ if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+ DCOMP_CDC_Host_NextCDCDataInterface) != DESCRIPTOR_SEARCH_COMP_Found)
+ {
+ return CDC_ENUMERROR_NoCompatibleInterfaceFound;
+ }
+
+ DataINEndpoint = NULL;
+ DataOUTEndpoint = NULL;
+ }
+ else
+ {
+ if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+ DCOMP_CDC_Host_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
+ {
+ return CDC_ENUMERROR_NoCompatibleInterfaceFound;
+ }
+
+ CDCControlInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
+
+ NotificationEndpoint = NULL;
+ }
+
+ continue;
+ }
+
+ USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
+
+ if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
+ {
+ if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
+ NotificationEndpoint = EndpointData;
+ else
+ DataINEndpoint = EndpointData;
+ }
+ else
+ {
+ DataOUTEndpoint = EndpointData;
+ }
+ }
+
+ for (uint8_t PipeNum = 1; PipeNum < PIPE_TOTAL_PIPES; PipeNum++)
+ {
+ if (PipeNum == CDCInterfaceInfo->Config.DataINPipeNumber)
+ {
+ Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_IN,
+ DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize,
+ CDCInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
+
+ CDCInterfaceInfo->State.DataINPipeSize = DataINEndpoint->EndpointSize;
+ }
+ else if (PipeNum == CDCInterfaceInfo->Config.DataOUTPipeNumber)
+ {
+ Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_OUT,
+ DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize,
+ CDCInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
+
+ CDCInterfaceInfo->State.DataOUTPipeSize = DataOUTEndpoint->EndpointSize;
+ }
+ else if (PipeNum == CDCInterfaceInfo->Config.NotificationPipeNumber)
+ {
+ Pipe_ConfigurePipe(PipeNum, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
+ NotificationEndpoint->EndpointAddress, NotificationEndpoint->EndpointSize,
+ CDCInterfaceInfo->Config.NotificationPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
+ Pipe_SetInterruptPeriod(NotificationEndpoint->PollingIntervalMS);
+
+ CDCInterfaceInfo->State.NotificationPipeSize = NotificationEndpoint->EndpointSize;
+ }
+ }
+
+ CDCInterfaceInfo->State.ControlInterfaceNumber = CDCControlInterface->InterfaceNumber;
+ CDCInterfaceInfo->State.ControlLineStates.HostToDevice = (CDC_CONTROL_LINE_OUT_RTS | CDC_CONTROL_LINE_OUT_DTR);
+ CDCInterfaceInfo->State.ControlLineStates.DeviceToHost = (CDC_CONTROL_LINE_IN_DCD | CDC_CONTROL_LINE_IN_DSR);
+ CDCInterfaceInfo->State.IsActive = true;
+
+ return CDC_ENUMERROR_NoError;
+}
+
+static uint8_t DCOMP_CDC_Host_NextCDCControlInterface(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 == CDC_CSCP_CDCClass) &&
+ (Interface->SubClass == CDC_CSCP_ACMSubclass) &&
+ (Interface->Protocol == CDC_CSCP_ATCommandProtocol))
+ {
+ return DESCRIPTOR_SEARCH_Found;
+ }
+ }
+
+ return DESCRIPTOR_SEARCH_NotFound;
+}
+
+static uint8_t DCOMP_CDC_Host_NextCDCDataInterface(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 == CDC_CSCP_CDCDataClass) &&
+ (Interface->SubClass == CDC_CSCP_NoDataSubclass) &&
+ (Interface->Protocol == CDC_CSCP_NoDataProtocol))
+ {
+ return DESCRIPTOR_SEARCH_Found;
+ }
+ }
+
+ return DESCRIPTOR_SEARCH_NotFound;
+}
+
+static uint8_t DCOMP_CDC_Host_NextCDCInterfaceEndpoint(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) || (EndpointType == EP_TYPE_INTERRUPT)) &&
+ !(Pipe_IsEndpointBound(Endpoint->EndpointAddress)))
+ {
+ return DESCRIPTOR_SEARCH_Found;
+ }
+ }
+ else if (Header->Type == DTYPE_Interface)
+ {
+ return DESCRIPTOR_SEARCH_Fail;
+ }
+
+ return DESCRIPTOR_SEARCH_NotFound;
+}
+
+void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
+ return;
+
+ Pipe_SelectPipe(CDCInterfaceInfo->Config.NotificationPipeNumber);
+ Pipe_Unfreeze();
+
+ if (Pipe_IsINReceived())
+ {
+ USB_Request_Header_t Notification;
+ Pipe_Read_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NO_STREAM_CALLBACK);
+
+ if ((Notification.bRequest == CDC_NOTIF_SerialState) &&
+ (Notification.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)))
+ {
+ Pipe_Read_Stream_LE(&CDCInterfaceInfo->State.ControlLineStates.DeviceToHost,
+ sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost),
+ NO_STREAM_CALLBACK);
+
+ Pipe_ClearIN();
+
+ EVENT_CDC_Host_ControLineStateChanged(CDCInterfaceInfo);
+ }
+ else
+ {
+ Pipe_ClearIN();
+ }
+ }
+
+ Pipe_Freeze();
+
+ #if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
+ CDC_Host_Flush(CDCInterfaceInfo);
+ #endif
+}
+
+uint8_t CDC_Host_SetLineEncoding(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
+{
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = CDC_REQ_SetLineEncoding,
+ .wValue = 0,
+ .wIndex = CDCInterfaceInfo->State.ControlInterfaceNumber,
+ .wLength = sizeof(CDCInterfaceInfo->State.LineEncoding),
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+ return USB_Host_SendControlRequest(&CDCInterfaceInfo->State.LineEncoding);
+}
+
+uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
+{
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = CDC_REQ_SetControlLineState,
+ .wValue = CDCInterfaceInfo->State.ControlLineStates.HostToDevice,
+ .wIndex = CDCInterfaceInfo->State.ControlInterfaceNumber,
+ .wLength = 0,
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+ return USB_Host_SendControlRequest(NULL);
+}
+
+uint8_t CDC_Host_SendBreak(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+ const uint8_t Duration)
+{
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = CDC_REQ_SendBreak,
+ .wValue = Duration,
+ .wIndex = CDCInterfaceInfo->State.ControlInterfaceNumber,
+ .wLength = 0,
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+ return USB_Host_SendControlRequest(NULL);
+}
+
+uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+ const char* const Data,
+ const uint16_t Length)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
+ return PIPE_READYWAIT_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
+
+ Pipe_Unfreeze();
+ ErrorCode = Pipe_Write_Stream_LE(Data, Length, NO_STREAM_CALLBACK);
+ Pipe_Freeze();
+
+ return ErrorCode;
+}
+
+uint8_t CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+ const uint8_t Data)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
+ return PIPE_READYWAIT_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
+ Pipe_Unfreeze();
+
+ if (!(Pipe_IsReadWriteAllowed()))
+ {
+ Pipe_ClearOUT();
+
+ if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)
+ return ErrorCode;
+ }
+
+ Pipe_Write_Byte(Data);
+ Pipe_Freeze();
+
+ return PIPE_READYWAIT_NoError;
+}
+
+uint16_t CDC_Host_BytesReceived(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
+ return 0;
+
+ Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
+ 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 CDC_Host_ReceiveByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
+ return -1;
+
+ int16_t ReceivedByte = -1;
+
+ Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
+ Pipe_Unfreeze();
+
+ if (Pipe_IsINReceived())
+ {
+ if (Pipe_BytesInPipe())
+ ReceivedByte = Pipe_Read_Byte();
+
+ if (!(Pipe_BytesInPipe()))
+ Pipe_ClearIN();
+ }
+
+ Pipe_Freeze();
+
+ return ReceivedByte;
+}
+
+uint8_t CDC_Host_Flush(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
+ return PIPE_READYWAIT_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
+ 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;
+}
+
+void CDC_Host_CreateStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+ FILE* const Stream)
+{
+ *Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar, _FDEV_SETUP_RW);
+ fdev_set_udata(Stream, CDCInterfaceInfo);
+}
+
+void CDC_Host_CreateBlockingStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+ FILE* const Stream)
+{
+ *Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar_Blocking, _FDEV_SETUP_RW);
+ fdev_set_udata(Stream, CDCInterfaceInfo);
+}
+
+static int CDC_Host_putchar(char c,
+ FILE* Stream)
+{
+ return CDC_Host_SendByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0;
+}
+
+static int CDC_Host_getchar(FILE* Stream)
+{
+ int16_t ReceivedByte = CDC_Host_ReceiveByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream));
+
+ if (ReceivedByte < 0)
+ return _FDEV_EOF;
+
+ return ReceivedByte;
+}
+
+static int CDC_Host_getchar_Blocking(FILE* Stream)
+{
+ int16_t ReceivedByte;
+
+ while ((ReceivedByte = CDC_Host_ReceiveByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream))) < 0)
+ {
+ if (USB_HostState == HOST_STATE_Unattached)
+ return _FDEV_EOF;
+
+ CDC_Host_USBTask((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream));
+ USB_USBTask();
+ }
+
+ return ReceivedByte;
+}
+
+void CDC_Host_Event_Stub(void)
+{
+
+}
+
+#endif
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/CDC.h b/firmware/LUFA/Drivers/USB/Class/Host/CDC.h
new file mode 100644
index 0000000..4128fe1
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/CDC.h
@@ -0,0 +1,334 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Host mode driver for the library USB CDC Class driver.
+ *
+ * Host mode driver for the library USB CDC 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_USBClassCDC
+ * @defgroup Group_USBClassCDCHost CDC 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/CDC.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ *
+ * \section Module Description
+ * Host Mode USB Class driver framework interface, for the CDC USB Class driver.
+ *
+ * @{
+ */
+
+#ifndef __CDC_CLASS_HOST_H__
+#define __CDC_CLASS_HOST_H__
+
+ /* Includes: */
+ #include "../../USB.h"
+ #include "../Common/CDC.h"
+
+ #include <stdio.h>
+ #include <string.h>
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_CDC_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ #if defined(__INCLUDE_FROM_CDC_HOST_C) && defined(NO_STREAM_CALLBACKS)
+ #error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
+ #endif
+
+ /* Public Interface - May be used in end-application: */
+ /* Type Defines: */
+ /** \brief CDC 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 CDC class driver functions as the CDCInterfaceInfo parameter. This
+ * stores each CDC interface's configuration and state information.
+ */
+ typedef struct
+ {
+ const struct
+ {
+ uint8_t DataINPipeNumber; /**< Pipe number of the CDC interface's IN data pipe. */
+ bool DataINPipeDoubleBank; /**< Indicates if the CDC interface's IN data pipe should use double banking. */
+
+ uint8_t DataOUTPipeNumber; /**< Pipe number of the CDC interface's OUT data pipe. */
+ bool DataOUTPipeDoubleBank; /**< Indicates if the CDC interface's OUT data pipe should use double banking. */
+
+ uint8_t NotificationPipeNumber; /**< Pipe number of the CDC interface's IN notification endpoint, if used. */
+ bool NotificationPipeDoubleBank; /**< Indicates if the CDC interface's notification pipe should use double banking. */
+ } Config; /**< Config data for the USB class interface within the device. All elements in this section
+ * <b>must</b> 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 CDC_Host_ConfigurePipes() is called and the Host state machine is in the
+ * Configured state.
+ */
+ uint8_t ControlInterfaceNumber; /**< Interface index of the CDC-ACM control interface within the attached device. */
+
+ uint16_t DataINPipeSize; /**< Size in bytes of the CDC interface's IN data pipe. */
+ uint16_t DataOUTPipeSize; /**< Size in bytes of the CDC interface's OUT data pipe. */
+ uint16_t NotificationPipeSize; /**< Size in bytes of the CDC interface's IN notification pipe, if used. */
+
+ struct
+ {
+ uint8_t HostToDevice; /**< Control line states from the host to device, as a set of CDC_CONTROL_LINE_OUT_*
+ * masks - to notify the device of changes to these values, call the
+ * \ref CDC_Host_SendControlLineStateChange() function.
+ */
+ uint8_t DeviceToHost; /**< Control line states from the device to host, as a set of CDC_CONTROL_LINE_IN_*
+ * masks. This value is updated each time \ref CDC_Host_USBTask() is called.
+ */
+ } ControlLineStates; /**< Current states of the virtual serial port's control lines between the device and host. */
+
+ CDC_LineEncoding_t LineEncoding; /**< Line encoding used in the virtual serial port, for the device's information.
+ * This is generally only used if the virtual serial port data is to be
+ * reconstructed on a physical UART. When set by the host application, the
+ * \ref CDC_Host_SetLineEncoding() function must be called to push the changes
+ * to the device.
+ */
+ } State; /**< State data for the USB class interface within the device. All elements in this section
+ * <b>may</b> be set to initial values, but may also be ignored to default to sane values when
+ * the interface is enumerated.
+ */
+ } USB_ClassInfo_CDC_Host_t;
+
+ /* Enums: */
+ /** Enum for the possible error codes returned by the \ref CDC_Host_ConfigurePipes() function. */
+ enum CDC_Host_EnumerationFailure_ErrorCodes_t
+ {
+ CDC_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */
+ CDC_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */
+ CDC_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible CDC interface was not found in the device's Configuration Descriptor. */
+ };
+
+ /* Function Prototypes: */
+ /** General management task for a given CDC 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] CDCInterfaceInfo Pointer to a structure containing an CDC Class host configuration and state.
+ */
+ void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Host interface configuration routine, to configure a given CDC host interface instance using the Configuration
+ * Descriptor read from an attached USB device. This function automatically updates the given CDC 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.
+ *
+ * \note The pipe index numbers as given in the interface's configuration structure must not overlap with any other
+ * interface, or pipe bank corruption will occur. Gaps in the allocated pipe numbers or non-sequential indexes
+ * within a single interface is allowed, but no two interfaces of any type have have interleaved pipe indexes.
+ *
+ * \param[in,out] CDCInterfaceInfo Pointer to a structure containing an CDC Class host configuration and state.
+ * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor.
+ * \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor.
+ *
+ * \return A value from the \ref CDC_Host_EnumerationFailure_ErrorCodes_t enum.
+ */
+ uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+ uint16_t ConfigDescriptorSize,
+ void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
+
+ /** Sets the line encoding for the attached device's virtual serial port. This should be called when the LineEncoding
+ * values of the interface have been changed to push the new settings to the USB device.
+ *
+ * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
+ *
+ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
+ */
+ uint8_t CDC_Host_SetLineEncoding(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Sends a Serial Control Line State Change notification to the device. This should be called when the virtual serial
+ * control lines (DTR, RTS, etc.) have changed states. Line states persist until they are cleared via a second
+ * notification. This should be called each time the CDC class driver's ControlLineStates.HostToDevice value is updated
+ * to push the new states to the USB device.
+ *
+ * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
+ *
+ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
+ */
+ uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Sends a Send Break request to the device. This is generally used to separate data data or to indicate a special condition
+ * to the receiving device.
+ *
+ * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
+ * \param[in] Duration Duration of the break, in milliseconds.
+ *
+ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
+ */
+ uint8_t CDC_Host_SendBreak(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+ const uint8_t Duration) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Sends a given 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 CDC_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] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
+ * \param[in] Data Pointer to the string to send to the device.
+ * \param[in] Length Size in bytes of the string to send to the device.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+ const char* const Data,
+ const uint16_t Length) 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 CDC_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] CDCInterfaceInfo Pointer to a structure containing a CDC 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 CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+ const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Determines the number of bytes received by the CDC 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 CDC_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] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
+ *
+ * \return Total number of buffered bytes received from the device.
+ */
+ uint16_t CDC_Host_BytesReceived(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) 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 CDC_Host_BytesReceived() function may be queried in advance to determine how many bytes
+ * are currently buffered in the CDC 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] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
+ *
+ * \return Next received byte from the device, or a negative value if no data received.
+ */
+ int16_t CDC_Host_ReceiveByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) 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] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
+ *
+ * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum.
+ */
+ uint8_t CDC_Host_Flush(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Creates a standard character stream for the given CDC Device instance so that it can be used with all the regular
+ * functions in the avr-libc <stdio.h> library that accept a FILE stream as a destination (e.g. fprintf). The created
+ * stream is bidirectional and can be used for both input and output functions.
+ *
+ * \note The created stream can be given as stdout if desired to direct the standard output from all <stdio.h> functions
+ * to the given CDC interface.
+ *
+ * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
+ * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed.
+ */
+ void CDC_Host_CreateStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+ FILE* const Stream);
+
+ /** Identical to CDC_Host_CreateStream(), except that reads are blocking until the calling stream function terminates
+ * the transfer. While blocking, the USB and CDC service tasks are called repeatedly to maintain USB communications.
+ *
+ * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
+ * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed.
+ */
+ void CDC_Host_CreateBlockingStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
+ FILE* const Stream);
+
+ /** 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
+ * are available in the ControlLineStates.DeviceToHost value inside the CDC host interface structure passed as a parameter, set as
+ * a mask of CDC_CONTROL_LINE_IN_* masks.
+ *
+ * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
+ */
+ void EVENT_CDC_Host_ControLineStateChanged(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /* Private Interface - For use in library only: */
+ #if !defined(__DOXYGEN__)
+ /* Function Prototypes: */
+ #if defined(__INCLUDE_FROM_CDC_HOST_C)
+ static int CDC_Host_putchar(char c,
+ FILE* Stream) ATTR_NON_NULL_PTR_ARG(2);
+ static int CDC_Host_getchar(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1);
+ static int CDC_Host_getchar_Blocking(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1);
+
+ void CDC_Host_Event_Stub(void);
+ void EVENT_CDC_Host_ControLineStateChanged(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
+ ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Host_Event_Stub);
+
+ static uint8_t DCOMP_CDC_Host_NextCDCControlInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
+ static uint8_t DCOMP_CDC_Host_NextCDCDataInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
+ static uint8_t DCOMP_CDC_Host_NextCDCInterfaceEndpoint(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
+ #endif
+ #endif
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/CDC.lst b/firmware/LUFA/Drivers/USB/Class/Host/CDC.lst
new file mode 100644
index 0000000..5243ec9
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/CDC.lst
@@ -0,0 +1,19 @@
+ 1 .file "CDC.c"
+ 2 __SREG__ = 0x3f
+ 3 __SP_H__ = 0x3e
+ 4 __SP_L__ = 0x3d
+ 5 __CCP__ = 0x34
+ 6 __tmp_reg__ = 0
+ 7 __zero_reg__ = 1
+ 15 .Ltext0:
+ 16 .Letext0:
+DEFINED SYMBOLS
+ *ABS*:0000000000000000 CDC.c
+ /tmp/cck4n38w.s:2 *ABS*:000000000000003f __SREG__
+ /tmp/cck4n38w.s:3 *ABS*:000000000000003e __SP_H__
+ /tmp/cck4n38w.s:4 *ABS*:000000000000003d __SP_L__
+ /tmp/cck4n38w.s:5 *ABS*:0000000000000034 __CCP__
+ /tmp/cck4n38w.s:6 *ABS*:0000000000000000 __tmp_reg__
+ /tmp/cck4n38w.s:7 *ABS*:0000000000000001 __zero_reg__
+
+NO UNDEFINED SYMBOLS
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/CDC.o b/firmware/LUFA/Drivers/USB/Class/Host/CDC.o
new file mode 100644
index 0000000..c1333af
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/CDC.o
Binary files differ
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/HID.c b/firmware/LUFA/Drivers/USB/Class/Host/HID.c
new file mode 100644
index 0000000..7343631
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/HID.c
@@ -0,0 +1,387 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define __INCLUDE_FROM_USB_DRIVER
+#include "../../HighLevel/USBMode.h"
+#if defined(USB_CAN_BE_HOST)
+
+#define __INCLUDE_FROM_HID_DRIVER
+#define __INCLUDE_FROM_HID_HOST_C
+#include "HID.h"
+
+uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
+ uint16_t ConfigDescriptorSize,
+ void* ConfigDescriptorData)
+{
+ USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
+ USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
+ USB_Descriptor_Interface_t* HIDInterface = NULL;
+ USB_HID_Descriptor_HID_t* HIDDescriptor = NULL;
+
+ memset(&HIDInterfaceInfo->State, 0x00, sizeof(HIDInterfaceInfo->State));
+
+ if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
+ return HID_ENUMERROR_InvalidConfigDescriptor;
+
+ while (!(DataINEndpoint) || !(DataOUTEndpoint))
+ {
+ if (!(HIDInterface) ||
+ USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+ DCOMP_HID_Host_NextHIDInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
+ {
+ if (DataINEndpoint || DataOUTEndpoint)
+ break;
+
+ do
+ {
+ if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+ DCOMP_HID_Host_NextHIDInterface) != DESCRIPTOR_SEARCH_COMP_Found)
+ {
+ return HID_ENUMERROR_NoCompatibleInterfaceFound;
+ }
+
+ HIDInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
+ } while (HIDInterfaceInfo->Config.HIDInterfaceProtocol &&
+ (HIDInterface->Protocol != HIDInterfaceInfo->Config.HIDInterfaceProtocol));
+
+ if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+ DCOMP_HID_Host_NextHID) != DESCRIPTOR_SEARCH_COMP_Found)
+ {
+ return HID_ENUMERROR_NoCompatibleInterfaceFound;
+ }
+
+ HIDDescriptor = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_HID_Descriptor_HID_t);
+
+ DataINEndpoint = NULL;
+ DataOUTEndpoint = NULL;
+
+ continue;
+ }
+
+ USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
+
+ if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
+ DataINEndpoint = EndpointData;
+ else
+ DataOUTEndpoint = EndpointData;
+ }
+
+ for (uint8_t PipeNum = 1; PipeNum < PIPE_TOTAL_PIPES; PipeNum++)
+ {
+ if (PipeNum == HIDInterfaceInfo->Config.DataINPipeNumber)
+ {
+ Pipe_ConfigurePipe(PipeNum, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
+ DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize,
+ HIDInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
+ Pipe_SetInterruptPeriod(DataINEndpoint->PollingIntervalMS);
+
+ HIDInterfaceInfo->State.DataINPipeSize = DataINEndpoint->EndpointSize;
+ }
+ else if (PipeNum == HIDInterfaceInfo->Config.DataOUTPipeNumber)
+ {
+ Pipe_ConfigurePipe(PipeNum, EP_TYPE_INTERRUPT, PIPE_TOKEN_OUT,
+ DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize,
+ HIDInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
+ Pipe_SetInterruptPeriod(DataOUTEndpoint->PollingIntervalMS);
+
+ HIDInterfaceInfo->State.DataOUTPipeSize = DataOUTEndpoint->EndpointSize;
+ HIDInterfaceInfo->State.DeviceUsesOUTPipe = true;
+ }
+ }
+
+ HIDInterfaceInfo->State.InterfaceNumber = HIDInterface->InterfaceNumber;
+ HIDInterfaceInfo->State.HIDReportSize = HIDDescriptor->HIDReportLength;
+ HIDInterfaceInfo->State.SupportsBootProtocol = (HIDInterface->SubClass != HID_CSCP_NonBootProtocol);
+ HIDInterfaceInfo->State.LargestReportSize = 8;
+ HIDInterfaceInfo->State.IsActive = true;
+
+ return HID_ENUMERROR_NoError;
+}
+
+static uint8_t DCOMP_HID_Host_NextHIDInterface(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 == HID_CSCP_HIDClass)
+ return DESCRIPTOR_SEARCH_Found;
+ }
+
+ return DESCRIPTOR_SEARCH_NotFound;
+}
+
+static uint8_t DCOMP_HID_Host_NextHID(void* const CurrentDescriptor)
+{
+ USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
+
+ if (Header->Type == HID_DTYPE_HID)
+ return DESCRIPTOR_SEARCH_Found;
+ else if (Header->Type == DTYPE_Interface)
+ return DESCRIPTOR_SEARCH_Fail;
+ else
+ return DESCRIPTOR_SEARCH_NotFound;
+}
+
+static uint8_t DCOMP_HID_Host_NextHIDInterfaceEndpoint(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);
+
+ if (!(Pipe_IsEndpointBound(Endpoint->EndpointAddress)))
+ return DESCRIPTOR_SEARCH_Found;
+ }
+ else if (Header->Type == DTYPE_Interface)
+ {
+ return DESCRIPTOR_SEARCH_Fail;
+ }
+
+ return DESCRIPTOR_SEARCH_NotFound;
+}
+
+#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
+uint8_t HID_Host_ReceiveReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
+ const uint8_t ReportID,
+ void* Buffer)
+{
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = HID_REQ_SetReport,
+ .wValue = ((HID_REPORT_ITEM_In + 1) << 8) | ReportID,
+ .wIndex = HIDInterfaceInfo->State.InterfaceNumber,
+ .wLength = USB_GetHIDReportSize(HIDInterfaceInfo->Config.HIDParserData, ReportID, HID_REPORT_ITEM_In),
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+ return USB_Host_SendControlRequest(Buffer);
+}
+#endif
+
+uint8_t HID_Host_ReceiveReport(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
+ void* Buffer)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive))
+ return PIPE_READYWAIT_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ Pipe_SelectPipe(HIDInterfaceInfo->Config.DataINPipeNumber);
+ Pipe_Unfreeze();
+
+ uint16_t ReportSize;
+ uint8_t* BufferPos = Buffer;
+
+#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
+ if (!(HIDInterfaceInfo->State.UsingBootProtocol))
+ {
+ uint8_t ReportID = 0;
+
+ if (HIDInterfaceInfo->Config.HIDParserData->UsingReportIDs)
+ {
+ ReportID = Pipe_Read_Byte();
+ *(BufferPos++) = ReportID;
+ }
+
+ ReportSize = USB_GetHIDReportSize(HIDInterfaceInfo->Config.HIDParserData, ReportID, HID_REPORT_ITEM_In);
+ }
+ else
+#endif
+ {
+ ReportSize = Pipe_BytesInPipe();
+ }
+
+ if ((ErrorCode = Pipe_Read_Stream_LE(BufferPos, ReportSize, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ Pipe_ClearIN();
+ Pipe_Freeze();
+
+ return PIPE_RWSTREAM_NoError;
+}
+
+uint8_t HID_Host_SendReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
+#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
+ const uint8_t ReportID,
+#endif
+ const uint8_t ReportType,
+ void* Buffer,
+ const uint16_t ReportSize)
+{
+#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
+ if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive))
+ return false;
+
+ if (HIDInterfaceInfo->State.DeviceUsesOUTPipe && (ReportType == HID_REPORT_ITEM_Out))
+ {
+ uint8_t ErrorCode;
+
+ Pipe_SelectPipe(HIDInterfaceInfo->Config.DataOUTPipeNumber);
+ Pipe_Unfreeze();
+
+ if (ReportID)
+ Pipe_Write_Stream_LE(&ReportID, sizeof(ReportID), NO_STREAM_CALLBACK);
+
+ if ((ErrorCode = Pipe_Write_Stream_LE(Buffer, ReportSize, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ Pipe_ClearOUT();
+ Pipe_Freeze();
+
+ return PIPE_RWSTREAM_NoError;
+ }
+ else
+#endif
+ {
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = HID_REQ_SetReport,
+#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
+ .wValue = ((ReportType + 1) << 8) | ReportID,
+#else
+ .wValue = ((ReportType + 1) << 8),
+#endif
+ .wIndex = HIDInterfaceInfo->State.InterfaceNumber,
+ .wLength = ReportSize,
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+ return USB_Host_SendControlRequest(Buffer);
+ }
+}
+
+bool HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive))
+ return false;
+
+ bool ReportReceived;
+
+ Pipe_SelectPipe(HIDInterfaceInfo->Config.DataINPipeNumber);
+ Pipe_Unfreeze();
+
+ ReportReceived = Pipe_IsINReceived();
+
+ Pipe_Freeze();
+
+ return ReportReceived;
+}
+
+uint8_t HID_Host_SetBootProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo)
+{
+ uint8_t ErrorCode;
+
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = HID_REQ_SetProtocol,
+ .wValue = 0,
+ .wIndex = HIDInterfaceInfo->State.InterfaceNumber,
+ .wLength = 0,
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+ if (!(HIDInterfaceInfo->State.SupportsBootProtocol))
+ return HID_ERROR_LOGICAL;
+
+ if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
+ return ErrorCode;
+
+ HIDInterfaceInfo->State.LargestReportSize = 8;
+ HIDInterfaceInfo->State.UsingBootProtocol = true;
+
+ return HOST_SENDCONTROL_Successful;
+}
+
+#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
+uint8_t HID_Host_SetReportProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo)
+{
+ uint8_t ErrorCode;
+
+ uint8_t HIDReportData[HIDInterfaceInfo->State.HIDReportSize];
+
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE),
+ .bRequest = REQ_GetDescriptor,
+ .wValue = (HID_DTYPE_Report << 8),
+ .wIndex = HIDInterfaceInfo->State.InterfaceNumber,
+ .wLength = HIDInterfaceInfo->State.HIDReportSize,
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+ if ((ErrorCode = USB_Host_SendControlRequest(HIDReportData)) != HOST_SENDCONTROL_Successful)
+ return ErrorCode;
+
+ if (HIDInterfaceInfo->State.UsingBootProtocol)
+ {
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = HID_REQ_SetProtocol,
+ .wValue = 1,
+ .wIndex = HIDInterfaceInfo->State.InterfaceNumber,
+ .wLength = 0,
+ };
+
+ if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
+ return ErrorCode;
+
+ HIDInterfaceInfo->State.UsingBootProtocol = false;
+ }
+
+ if (HIDInterfaceInfo->Config.HIDParserData == NULL)
+ return HID_ERROR_LOGICAL;
+
+ if ((ErrorCode = USB_ProcessHIDReport(HIDReportData, HIDInterfaceInfo->State.HIDReportSize,
+ HIDInterfaceInfo->Config.HIDParserData)) != HID_PARSE_Successful)
+ {
+ return HID_ERROR_LOGICAL | ErrorCode;
+ }
+
+ uint8_t LargestReportSizeBits = HIDInterfaceInfo->Config.HIDParserData->LargestReportSizeBits;
+ HIDInterfaceInfo->State.LargestReportSize = (LargestReportSizeBits >> 3) + ((LargestReportSizeBits & 0x07) != 0);
+
+ return 0;
+}
+#endif
+
+#endif
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/HID.h b/firmware/LUFA/Drivers/USB/Class/Host/HID.h
new file mode 100644
index 0000000..2d6fd9e
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/HID.h
@@ -0,0 +1,316 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Host mode driver for the library USB HID Class driver.
+ *
+ * Host mode driver for the library USB HID 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_USBClassHID
+ * @defgroup Group_USBClassHIDHost HID 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/HID.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ * - LUFA/Drivers/USB/Class/Host/HIDParser.c <i>(Makefile source module name: LUFA_SRC_USB)</i>
+ *
+ * \section Module Description
+ * Host Mode USB Class driver framework interface, for the HID USB Class driver.
+ *
+ * @{
+ */
+
+#ifndef __HID_CLASS_HOST_H__
+#define __HID_CLASS_HOST_H__
+
+ /* Includes: */
+ #include "../../USB.h"
+ #include "../Common/HID.h"
+ #include "HIDParser.h"
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_HID_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ #if defined(__INCLUDE_FROM_HID_HOST_C) && defined(NO_STREAM_CALLBACKS)
+ #error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
+ #endif
+
+
+ /* Public Interface - May be used in end-application: */
+ /* Macros: */
+ /** Error code for some HID Host functions, indicating a logical (and not hardware) error. */
+ #define HID_ERROR_LOGICAL 0x80
+
+ /* Type Defines: */
+ /** \brief HID 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 HID class driver functions as the HIDInterfaceInfo parameter. This
+ * stores each HID interface's configuration and state information.
+ */
+ typedef struct
+ {
+ const struct
+ {
+ uint8_t DataINPipeNumber; /**< Pipe number of the HID interface's IN data pipe. */
+ bool DataINPipeDoubleBank; /**< Indicates if the HID interface's IN data pipe should use double banking. */
+
+ uint8_t DataOUTPipeNumber; /**< Pipe number of the HID interface's OUT data pipe. */
+ bool DataOUTPipeDoubleBank; /**< Indicates if the HID interface's OUT data pipe should use double banking. */
+
+ uint8_t HIDInterfaceProtocol; /**< HID interface protocol value to match against if a specific
+ * boot subclass protocol is required, a protocol value from the
+ * \ref HID_Descriptor_ClassSubclassProtocol_t enum.
+ */
+ #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
+ HID_ReportInfo_t* HIDParserData; /**< HID parser data to store the parsed HID report data, when boot protocol
+ * is not used.
+ *
+ * \note When the HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined,
+ * this method is unavailable.
+ */
+ #endif
+ } Config; /**< Config data for the USB class interface within the device. All elements in this section
+ * <b>must</b> 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 HID_Host_ConfigurePipes() is called and the Host state machine is in the
+ * Configured state.
+ */
+ uint8_t InterfaceNumber; /**< Interface index of the HID interface within the attached device. */
+
+ uint16_t DataINPipeSize; /**< Size in bytes of the HID interface's IN data pipe. */
+ uint16_t DataOUTPipeSize; /**< Size in bytes of the HID interface's OUT data pipe. */
+
+ bool SupportsBootProtocol; /**< Indicates if the current interface instance supports the HID Boot
+ * Protocol when enabled via \ref HID_Host_SetBootProtocol().
+ */
+ bool DeviceUsesOUTPipe; /**< Indicates if the current interface instance uses a separate OUT data pipe for
+ * OUT reports, or if OUT reports are sent via the control pipe instead.
+ */
+ bool UsingBootProtocol; /**< Indicates that the interface is currently initialized in Boot Protocol mode */
+ uint16_t HIDReportSize; /**< Size in bytes of the HID report descriptor in the device. */
+
+ uint8_t LargestReportSize; /**< Largest report the device will send, in bytes. */
+ } State; /**< State data for the USB class interface within the device. All elements in this section
+ * <b>may</b> be set to initial values, but may also be ignored to default to sane values when
+ * the interface is enumerated.
+ */
+ } USB_ClassInfo_HID_Host_t;
+
+ /* Enums: */
+ /** Enum for the possible error codes returned by the \ref HID_Host_ConfigurePipes() function. */
+ enum HID_Host_EnumerationFailure_ErrorCodes_t
+ {
+ HID_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */
+ HID_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */
+ HID_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible HID interface was not found in the device's Configuration Descriptor. */
+ };
+
+ /* Function Prototypes: */
+ /** Host interface configuration routine, to configure a given HID host interface instance using the Configuration
+ * Descriptor read from an attached USB device. This function automatically updates the given HID 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.
+ *
+ * \note The pipe index numbers as given in the interface's configuration structure must not overlap with any other
+ * interface, or pipe bank corruption will occur. Gaps in the allocated pipe numbers or non-sequential indexes
+ * within a single interface is allowed, but no two interfaces of any type have have interleaved pipe indexes.
+ * \n\n
+ *
+ * \note Once the device pipes are configured, the HID device's reporting protocol <b>must</b> be set via a call
+ * to either the \ref HID_Host_SetBootProtocol() or \ref HID_Host_SetReportProtocol() function.
+ *
+ * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state.
+ * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor.
+ * \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor.
+ *
+ * \return A value from the \ref HID_Host_EnumerationFailure_ErrorCodes_t enum.
+ */
+ uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
+ uint16_t ConfigDescriptorSize,
+ void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
+
+
+ /** Receives a HID IN report from the attached HID device, when a report has been received on the HID IN Data 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.
+ *
+ * \note The destination buffer should be large enough to accommodate the largest report that the attached device
+ * can generate.
+ *
+ * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state.
+ * \param[in] Buffer Buffer to store the received report into.
+ *
+ * \return An error code from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t HID_Host_ReceiveReport(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
+ void* Buffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+
+ #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
+ /** Receives a HID IN report from the attached device, by the report ID.
+ *
+ * \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.
+ *
+ * \note When the HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, this method is unavailable.
+ *
+ * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state.
+ * \param[in] ReportID Report ID of the received report if ControlRequest is false, set by the to the Report ID to fetch.
+ * \param[in] Buffer Buffer to store the received report into.
+ *
+ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
+ */
+ uint8_t HID_Host_ReceiveReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
+ const uint8_t ReportID,
+ void* Buffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
+ #endif
+
+ /** Sends an OUT or FEATURE report to the currently attached HID device, using the device's OUT pipe if available,
+ * or the device's Control pipe if not.
+ *
+ * \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.
+ *
+ * \note When the HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, the ReportID parameter is removed
+ * from the parameter list of this function.
+ *
+ * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state.
+ * \param[in] ReportID Report ID of the report to send to the device, or 0 if the device does not use report IDs.
+ * \param[in] ReportType Type of report to issue to the device, either \ref HID_REPORT_ITEM_Out or \ref HID_REPORT_ITEM_Feature.
+ * \param[in] Buffer Buffer containing the report to send to the attached device.
+ * \param[in] ReportSize Report size in bytes to send to the attached device.
+ *
+ * \return An error code from the \ref USB_Host_SendControlErrorCodes_t enum if the DeviceUsesOUTPipe flag is set in
+ * the interface's state structure, a value from the \ref Pipe_Stream_RW_ErrorCodes_t enum otherwise.
+ */
+ uint8_t HID_Host_SendReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo,
+ #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
+ const uint8_t ReportID,
+ #endif
+ const uint8_t ReportType,
+ void* Buffer,
+ const uint16_t ReportSize) ATTR_NON_NULL_PTR_ARG(1)
+ #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
+ ATTR_NON_NULL_PTR_ARG(4);
+ #else
+ ATTR_NON_NULL_PTR_ARG(3);
+ #endif
+
+ /** Determines if a HID IN report has been received from the attached device on the data IN 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] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state.
+ *
+ * \return Boolean true if a report has been received, false otherwise.
+ */
+ bool HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Switches the attached HID device's reporting protocol over to the Boot Report protocol mode, on supported devices.
+ *
+ * \note When the HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, this method must still be called
+ * to explicitly place the attached device into boot protocol mode before use.
+ *
+ * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state.
+ *
+ * \return \ref HID_ERROR_LOGICAL if the device does not support Boot Protocol mode, a value from the
+ * \ref USB_Host_SendControlErrorCodes_t enum otherwise.
+ */
+ uint8_t HID_Host_SetBootProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY)
+ /** Switches the attached HID device's reporting protocol over to the standard Report protocol mode. This also retrieves
+ * and parses the device's HID report descriptor, so that the size of each report can be determined in advance.
+ *
+ * \note Whether this function is used or not, the \ref CALLBACK_HIDParser_FilterHIDReportItem() callback from the HID
+ * Report Parser this function references <b>must</b> be implemented in the user code.
+ * \n\n
+ *
+ * \note When the HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, this method is unavailable.
+ *
+ * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state.
+ *
+ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum if an error occurs while retrieving the HID
+ * Report descriptor or the setting of the Report protocol, \ref HID_ERROR_LOGICAL if the HID interface does
+ * not have a valid \ref HID_ReportInfo_t structure set in its configuration, a mask of \ref HID_ERROR_LOGICAL
+ * and a value from the \ref HID_Parse_ErrorCodes_t otherwise.
+ */
+ uint8_t HID_Host_SetReportProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+ #endif
+
+ /* Inline Functions: */
+ /** General management task for a given Human Interface Class 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] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state.
+ */
+ static inline void HID_Host_USBTask(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo);
+ static inline void HID_Host_USBTask(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo)
+ {
+ (void)HIDInterfaceInfo;
+ }
+
+ /* Private Interface - For use in library only: */
+ #if !defined(__DOXYGEN__)
+ /* Function Prototypes: */
+ #if defined(__INCLUDE_FROM_HID_HOST_C)
+ static uint8_t DCOMP_HID_Host_NextHIDInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
+ static uint8_t DCOMP_HID_Host_NextHID(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
+ static uint8_t DCOMP_HID_Host_NextHIDInterfaceEndpoint(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
+ #endif
+ #endif
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/HID.lst b/firmware/LUFA/Drivers/USB/Class/Host/HID.lst
new file mode 100644
index 0000000..ac15d24
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/HID.lst
@@ -0,0 +1,19 @@
+ 1 .file "HID.c"
+ 2 __SREG__ = 0x3f
+ 3 __SP_H__ = 0x3e
+ 4 __SP_L__ = 0x3d
+ 5 __CCP__ = 0x34
+ 6 __tmp_reg__ = 0
+ 7 __zero_reg__ = 1
+ 15 .Ltext0:
+ 16 .Letext0:
+DEFINED SYMBOLS
+ *ABS*:0000000000000000 HID.c
+ /tmp/ccOMFwTz.s:2 *ABS*:000000000000003f __SREG__
+ /tmp/ccOMFwTz.s:3 *ABS*:000000000000003e __SP_H__
+ /tmp/ccOMFwTz.s:4 *ABS*:000000000000003d __SP_L__
+ /tmp/ccOMFwTz.s:5 *ABS*:0000000000000034 __CCP__
+ /tmp/ccOMFwTz.s:6 *ABS*:0000000000000000 __tmp_reg__
+ /tmp/ccOMFwTz.s:7 *ABS*:0000000000000001 __zero_reg__
+
+NO UNDEFINED SYMBOLS
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/HID.o b/firmware/LUFA/Drivers/USB/Class/Host/HID.o
new file mode 100644
index 0000000..ab0765d
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/HID.o
Binary files differ
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/HIDParser.c b/firmware/LUFA/Drivers/USB/Class/Host/HIDParser.c
new file mode 100644
index 0000000..f0e7db8
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/HIDParser.c
@@ -0,0 +1,361 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define __INCLUDE_FROM_USB_DRIVER
+#include "../../HighLevel/USBMode.h"
+#if defined(USB_CAN_BE_HOST)
+
+#define __INCLUDE_FROM_HID_DRIVER
+#include "HIDParser.h"
+
+uint8_t USB_ProcessHIDReport(const uint8_t* ReportData,
+ uint16_t ReportSize,
+ HID_ReportInfo_t* const ParserData)
+{
+ HID_StateTable_t StateTable[HID_STATETABLE_STACK_DEPTH];
+ HID_StateTable_t* CurrStateTable = &StateTable[0];
+ HID_CollectionPath_t* CurrCollectionPath = NULL;
+ HID_ReportSizeInfo_t* CurrReportIDInfo = &ParserData->ReportIDSizes[0];
+ uint16_t UsageList[HID_USAGE_STACK_DEPTH];
+ uint8_t UsageListSize = 0;
+ HID_MinMax_t UsageMinMax = {0, 0};
+
+ memset(ParserData, 0x00, sizeof(HID_ReportInfo_t));
+ memset(CurrStateTable, 0x00, sizeof(HID_StateTable_t));
+ memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t));
+
+ ParserData->TotalDeviceReports = 1;
+
+ while (ReportSize)
+ {
+ uint8_t HIDReportItem = *ReportData;
+ uint32_t ReportItemData = 0;
+
+ ReportData++;
+ ReportSize--;
+
+ switch (HIDReportItem & DATA_SIZE_MASK)
+ {
+ case DATA_SIZE_4:
+ ReportItemData = *((uint32_t*)ReportData);
+ ReportSize -= 4;
+ ReportData += 4;
+ break;
+ case DATA_SIZE_2:
+ ReportItemData = *((uint16_t*)ReportData);
+ ReportSize -= 2;
+ ReportData += 2;
+ break;
+ case DATA_SIZE_1:
+ ReportItemData = *((uint8_t*)ReportData);
+ ReportSize -= 1;
+ ReportData += 1;
+ break;
+ }
+
+ switch (HIDReportItem & (TYPE_MASK | TAG_MASK))
+ {
+ case (TYPE_GLOBAL | TAG_GLOBAL_PUSH):
+ if (CurrStateTable == &StateTable[HID_STATETABLE_STACK_DEPTH - 1])
+ return HID_PARSE_HIDStackOverflow;
+
+ memcpy((CurrStateTable + 1),
+ CurrStateTable,
+ sizeof(HID_ReportItem_t));
+
+ CurrStateTable++;
+ break;
+ case (TYPE_GLOBAL | TAG_GLOBAL_POP):
+ if (CurrStateTable == &StateTable[0])
+ return HID_PARSE_HIDStackUnderflow;
+
+ CurrStateTable--;
+ break;
+ case (TYPE_GLOBAL | TAG_GLOBAL_USAGEPAGE):
+ CurrStateTable->Attributes.Usage.Page = ReportItemData;
+ break;
+ case (TYPE_GLOBAL | TAG_GLOBAL_LOGICALMIN):
+ CurrStateTable->Attributes.Logical.Minimum = ReportItemData;
+ break;
+ case (TYPE_GLOBAL | TAG_GLOBAL_LOGICALMAX):
+ CurrStateTable->Attributes.Logical.Maximum = ReportItemData;
+ break;
+ case (TYPE_GLOBAL | TAG_GLOBAL_PHYSMIN):
+ CurrStateTable->Attributes.Physical.Minimum = ReportItemData;
+ break;
+ case (TYPE_GLOBAL | TAG_GLOBAL_PHYSMAX):
+ CurrStateTable->Attributes.Physical.Maximum = ReportItemData;
+ break;
+ case (TYPE_GLOBAL | TAG_GLOBAL_UNITEXP):
+ CurrStateTable->Attributes.Unit.Exponent = ReportItemData;
+ break;
+ case (TYPE_GLOBAL | TAG_GLOBAL_UNIT):
+ CurrStateTable->Attributes.Unit.Type = ReportItemData;
+ break;
+ case (TYPE_GLOBAL | TAG_GLOBAL_REPORTSIZE):
+ CurrStateTable->Attributes.BitSize = ReportItemData;
+ break;
+ case (TYPE_GLOBAL | TAG_GLOBAL_REPORTCOUNT):
+ CurrStateTable->ReportCount = ReportItemData;
+ break;
+ case (TYPE_GLOBAL | TAG_GLOBAL_REPORTID):
+ CurrStateTable->ReportID = ReportItemData;
+
+ if (ParserData->UsingReportIDs)
+ {
+ CurrReportIDInfo = NULL;
+
+ for (uint8_t i = 0; i < ParserData->TotalDeviceReports; i++)
+ {
+ if (ParserData->ReportIDSizes[i].ReportID == CurrStateTable->ReportID)
+ {
+ CurrReportIDInfo = &ParserData->ReportIDSizes[i];
+ break;
+ }
+ }
+
+ if (CurrReportIDInfo == NULL)
+ {
+ if (ParserData->TotalDeviceReports == HID_MAX_REPORT_IDS)
+ return HID_PARSE_InsufficientReportIDItems;
+
+ CurrReportIDInfo = &ParserData->ReportIDSizes[ParserData->TotalDeviceReports++];
+ memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t));
+ }
+ }
+
+ ParserData->UsingReportIDs = true;
+
+ CurrReportIDInfo->ReportID = CurrStateTable->ReportID;
+ break;
+ case (TYPE_LOCAL | TAG_LOCAL_USAGE):
+ if (UsageListSize == HID_USAGE_STACK_DEPTH)
+ return HID_PARSE_UsageListOverflow;
+
+ UsageList[UsageListSize++] = ReportItemData;
+ break;
+ case (TYPE_LOCAL | TAG_LOCAL_USAGEMIN):
+ UsageMinMax.Minimum = ReportItemData;
+ break;
+ case (TYPE_LOCAL | TAG_LOCAL_USAGEMAX):
+ UsageMinMax.Maximum = ReportItemData;
+ break;
+ case (TYPE_MAIN | TAG_MAIN_COLLECTION):
+ if (CurrCollectionPath == NULL)
+ {
+ CurrCollectionPath = &ParserData->CollectionPaths[0];
+ }
+ else
+ {
+ HID_CollectionPath_t* ParentCollectionPath = CurrCollectionPath;
+
+ CurrCollectionPath = &ParserData->CollectionPaths[1];
+
+ while (CurrCollectionPath->Parent != NULL)
+ {
+ if (CurrCollectionPath == &ParserData->CollectionPaths[HID_MAX_COLLECTIONS - 1])
+ return HID_PARSE_InsufficientCollectionPaths;
+
+ CurrCollectionPath++;
+ }
+
+ CurrCollectionPath->Parent = ParentCollectionPath;
+ }
+
+ CurrCollectionPath->Type = ReportItemData;
+ CurrCollectionPath->Usage.Page = CurrStateTable->Attributes.Usage.Page;
+
+ if (UsageListSize)
+ {
+ CurrCollectionPath->Usage.Usage = UsageList[0];
+
+ for (uint8_t i = 0; i < UsageListSize; i++)
+ UsageList[i] = UsageList[i + 1];
+
+ UsageListSize--;
+ }
+ else if (UsageMinMax.Minimum <= UsageMinMax.Maximum)
+ {
+ CurrCollectionPath->Usage.Usage = UsageMinMax.Minimum++;
+ }
+
+ break;
+ case (TYPE_MAIN | TAG_MAIN_ENDCOLLECTION):
+ if (CurrCollectionPath == NULL)
+ return HID_PARSE_UnexpectedEndCollection;
+
+ CurrCollectionPath = CurrCollectionPath->Parent;
+ break;
+ case (TYPE_MAIN | TAG_MAIN_INPUT):
+ case (TYPE_MAIN | TAG_MAIN_OUTPUT):
+ case (TYPE_MAIN | TAG_MAIN_FEATURE):
+ for (uint8_t ReportItemNum = 0; ReportItemNum < CurrStateTable->ReportCount; ReportItemNum++)
+ {
+ HID_ReportItem_t NewReportItem;
+
+ memcpy(&NewReportItem.Attributes,
+ &CurrStateTable->Attributes,
+ sizeof(HID_ReportItem_Attributes_t));
+
+ NewReportItem.ItemFlags = ReportItemData;
+ NewReportItem.CollectionPath = CurrCollectionPath;
+ NewReportItem.ReportID = CurrStateTable->ReportID;
+
+ if (UsageListSize)
+ {
+ NewReportItem.Attributes.Usage.Usage = UsageList[0];
+
+ for (uint8_t i = 0; i < UsageListSize; i++)
+ UsageList[i] = UsageList[i + 1];
+
+ UsageListSize--;
+ }
+ else if (UsageMinMax.Minimum <= UsageMinMax.Maximum)
+ {
+ NewReportItem.Attributes.Usage.Usage = UsageMinMax.Minimum++;
+ }
+
+ uint8_t ItemTag = (HIDReportItem & TAG_MASK);
+
+ if (ItemTag == TAG_MAIN_INPUT)
+ NewReportItem.ItemType = HID_REPORT_ITEM_In;
+ else if (ItemTag == TAG_MAIN_OUTPUT)
+ NewReportItem.ItemType = HID_REPORT_ITEM_Out;
+ else
+ NewReportItem.ItemType = HID_REPORT_ITEM_Feature;
+
+ NewReportItem.BitOffset = CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType];
+
+ CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType] += CurrStateTable->Attributes.BitSize;
+
+ if (ParserData->LargestReportSizeBits < NewReportItem.BitOffset)
+ ParserData->LargestReportSizeBits = NewReportItem.BitOffset;
+
+ if (!(ReportItemData & IOF_CONSTANT) && CALLBACK_HIDParser_FilterHIDReportItem(&NewReportItem))
+ {
+ if (ParserData->TotalReportItems == HID_MAX_REPORTITEMS)
+ return HID_PARSE_InsufficientReportItems;
+
+ memcpy(&ParserData->ReportItems[ParserData->TotalReportItems],
+ &NewReportItem, sizeof(HID_ReportItem_t));
+
+ ParserData->TotalReportItems++;
+ }
+ }
+
+ break;
+ }
+
+ if ((HIDReportItem & TYPE_MASK) == TYPE_MAIN)
+ {
+ UsageMinMax.Minimum = 0;
+ UsageMinMax.Maximum = 0;
+ UsageListSize = 0;
+ }
+ }
+
+ if (!(ParserData->TotalReportItems))
+ return HID_PARSE_NoUnfilteredReportItems;
+
+ return HID_PARSE_Successful;
+}
+
+bool USB_GetHIDReportItemInfo(const uint8_t* ReportData,
+ HID_ReportItem_t* const ReportItem)
+{
+ uint16_t DataBitsRem = ReportItem->Attributes.BitSize;
+ uint16_t CurrentBit = ReportItem->BitOffset;
+ uint32_t BitMask = (1 << 0);
+
+ if (ReportItem->ReportID)
+ {
+ if (ReportItem->ReportID != ReportData[0])
+ return false;
+
+ ReportData++;
+ }
+
+ ReportItem->PreviousValue = ReportItem->Value;
+ ReportItem->Value = 0;
+
+ while (DataBitsRem--)
+ {
+ if (ReportData[CurrentBit / 8] & (1 << (CurrentBit % 8)))
+ ReportItem->Value |= BitMask;
+
+ CurrentBit++;
+ BitMask <<= 1;
+ }
+
+ return true;
+}
+
+void USB_SetHIDReportItemInfo(uint8_t* ReportData,
+ HID_ReportItem_t* const ReportItem)
+{
+ uint16_t DataBitsRem = ReportItem->Attributes.BitSize;
+ uint16_t CurrentBit = ReportItem->BitOffset;
+ uint32_t BitMask = (1 << 0);
+
+ if (ReportItem->ReportID)
+ {
+ ReportData[0] = ReportItem->ReportID;
+ ReportData++;
+ }
+
+ ReportItem->PreviousValue = ReportItem->Value;
+
+ while (DataBitsRem--)
+ {
+ if (ReportItem->Value & (1 << (CurrentBit % 8)))
+ ReportData[CurrentBit / 8] |= BitMask;
+
+ CurrentBit++;
+ BitMask <<= 1;
+ }
+}
+
+uint16_t USB_GetHIDReportSize(HID_ReportInfo_t* const ParserData,
+ const uint8_t ReportID,
+ const uint8_t ReportType)
+{
+ for (uint8_t i = 0; i < HID_MAX_REPORT_IDS; i++)
+ {
+ uint16_t ReportSizeBits = ParserData->ReportIDSizes[i].ReportSizeBits[ReportType];
+
+ if (ParserData->ReportIDSizes[i].ReportID == ReportID)
+ return ((ReportSizeBits >> 3) + ((ReportSizeBits & 0x07) ? 1 : 0));
+ }
+
+ return 0;
+}
+
+#endif
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/HIDParser.h b/firmware/LUFA/Drivers/USB/Class/Host/HIDParser.h
new file mode 100644
index 0000000..cb3b98f
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/HIDParser.h
@@ -0,0 +1,356 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief USB Human Interface Device (HID) Class report descriptor parser.
+ *
+ * This file allows for the easy parsing of complex HID report descriptors, which describes the data that
+ * a HID device transmits to the host. It also provides an easy API for extracting and processing the data
+ * elements inside a HID report sent from an attached HID device.
+ */
+
+/** \ingroup Group_USB
+ * @defgroup Group_HIDParser HID Report Parser
+ *
+ * \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/HIDParser.c <i>(Makefile source module name: LUFA_SRC_USB)</i>
+ *
+ * \section Module Description
+ * Functions, macros, variables, enums and types related to the parsing of HID class device report descriptors.
+ *
+ * The processed HID report is presented back to the user application as a flat structure containing each report
+ * item's IN, OUT and FEATURE items along with each item's attributes.
+ *
+ * This library portion also allows for easy setting and retrieval of data from a HID report, including devices
+ * with multiple reports on the one HID interface.
+ *
+ * @{
+ */
+
+#ifndef __HIDPARSER_H__
+#define __HIDPARSER_H__
+
+ /* Includes: */
+ #include <string.h>
+ #include <stdbool.h>
+
+ #include "HIDReportData.h"
+ #include "../Common/HID.h"
+
+ #include "../../../../Common/Common.h"
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Macros: */
+ #if !defined(HID_STATETABLE_STACK_DEPTH) || defined(__DOXYGEN__)
+ /** Constant indicating the maximum stack depth of the state table. A larger state table
+ * allows for more PUSH/POP report items to be nested, but consumes more memory. By default
+ * this is set to 2 levels (allowing non-nested PUSH items) but this can be overridden by
+ * defining HID_STATETABLE_STACK_DEPTH to another value in the user project makefile, passing the
+ * define to the compiler using the -D compiler switch.
+ */
+ #define HID_STATETABLE_STACK_DEPTH 2
+ #endif
+
+ #if !defined(HID_USAGE_STACK_DEPTH) || defined(__DOXYGEN__)
+ /** Constant indicating the maximum stack depth of the usage table. A larger usage table
+ * allows for more USAGE items to be indicated sequentially for REPORT COUNT entries of more than
+ * one, but requires more stack space. By default this is set to 8 levels (allowing for a report
+ * item with a count of 8) but this can be overridden by defining HID_USAGE_STACK_DEPTH to another
+ * value in the user project makefile, passing the define to the compiler using the -D compiler
+ * switch.
+ */
+ #define HID_USAGE_STACK_DEPTH 8
+ #endif
+
+ #if !defined(HID_MAX_COLLECTIONS) || defined(__DOXYGEN__)
+ /** Constant indicating the maximum number of COLLECTION items (nested or unnested) that can be
+ * processed in the report item descriptor. A large value allows for more COLLECTION items to be
+ * processed, but consumes more memory. By default this is set to 10 collections, but this can be
+ * overridden by defining HID_MAX_COLLECTIONS to another value in the user project makefile, passing
+ * the define to the compiler using the -D compiler switch.
+ */
+ #define HID_MAX_COLLECTIONS 10
+ #endif
+
+ #if !defined(HID_MAX_REPORTITEMS) || defined(__DOXYGEN__)
+ /** Constant indicating the maximum number of report items (IN, OUT or FEATURE) that can be processed
+ * in the report item descriptor and stored in the user HID Report Info structure. A large value allows
+ * for more report items to be stored, but consumes more memory. By default this is set to 20 items,
+ * but this can be overridden by defining HID_MAX_REPORTITEMS to another value in the user project
+ * makefile, and passing the define to the compiler using the -D compiler switch.
+ */
+ #define HID_MAX_REPORTITEMS 20
+ #endif
+
+ #if !defined(HID_MAX_REPORT_IDS) || defined(__DOXYGEN__)
+ /** Constant indicating the maximum number of unique report IDs that can be processed in the report item
+ * descriptor for the report size information array in the user HID Report Info structure. A large value
+ * allows for more report ID report sizes to be stored, but consumes more memory. By default this is set
+ * to 10 items, but this can be overridden by defining HID_MAX_REPORT_IDS to another value in the user project
+ * makefile, and passing the define to the compiler using the -D compiler switch. Note that IN, OUT and FEATURE
+ * items sharing the same report ID consume only one size item in the array.
+ */
+ #define HID_MAX_REPORT_IDS 10
+ #endif
+
+ /** Returns the value a given HID report item (once its value has been fetched via \ref USB_GetHIDReportItemInfo())
+ * left-aligned to the given data type. This allows for signed data to be interpreted correctly, by shifting the data
+ * leftwards until the data's sign bit is in the correct position.
+ *
+ * \param[in] ReportItem HID Report Item whose retrieved value is to be aligned.
+ * \param[in] Type Data type to align the HID report item's value to.
+ *
+ * \return Left-aligned data of the given report item's pre-retrieved value for the given datatype.
+ */
+ #define HID_ALIGN_DATA(ReportItem, Type) ((Type)(ReportItem->Value << ((8 * sizeof(Type)) - ReportItem->Attributes.BitSize)))
+
+ /* Public Interface - May be used in end-application: */
+ /* Enums: */
+ /** Enum for the possible error codes in the return value of the \ref USB_ProcessHIDReport() function. */
+ enum HID_Parse_ErrorCodes_t
+ {
+ HID_PARSE_Successful = 0, /**< Successful parse of the HID report descriptor, no error. */
+ HID_PARSE_HIDStackOverflow = 1, /**< More than \ref HID_STATETABLE_STACK_DEPTH nested PUSHes in the report. */
+ HID_PARSE_HIDStackUnderflow = 2, /**< A POP was found when the state table stack was empty. */
+ HID_PARSE_InsufficientReportItems = 3, /**< More than \ref HID_MAX_REPORTITEMS report items in the report. */
+ HID_PARSE_UnexpectedEndCollection = 4, /**< An END COLLECTION item found without matching COLLECTION item. */
+ HID_PARSE_InsufficientCollectionPaths = 5, /**< More than \ref HID_MAX_COLLECTIONS collections in the report. */
+ HID_PARSE_UsageListOverflow = 6, /**< More than \ref HID_USAGE_STACK_DEPTH usages listed in a row. */
+ HID_PARSE_InsufficientReportIDItems = 7, /**< More than \ref HID_MAX_REPORT_IDS report IDs in the device. */
+ HID_PARSE_NoUnfilteredReportItems = 8, /**< All report items from the device were filtered by the filtering callback routine. */
+ };
+
+ /* Type Defines: */
+ /** \brief HID Parser Report Item Min/Max Structure.
+ *
+ * Type define for an attribute with both minimum and maximum values (e.g. Logical Min/Max).
+ */
+ typedef struct
+ {
+ uint32_t Minimum; /**< Minimum value for the attribute. */
+ uint32_t Maximum; /**< Maximum value for the attribute. */
+ } HID_MinMax_t;
+
+ /** \brief HID Parser Report Item Unit Structure.
+ *
+ * Type define for the Unit attributes of a report item.
+ */
+ typedef struct
+ {
+ uint32_t Type; /**< Unit type (refer to HID specifications for details). */
+ uint8_t Exponent; /**< Unit exponent (refer to HID specifications for details). */
+ } HID_Unit_t;
+
+ /** \brief HID Parser Report Item Usage Structure.
+ *
+ * Type define for the Usage attributes of a report item.
+ */
+ typedef struct
+ {
+ uint16_t Page; /**< Usage page of the report item. */
+ uint16_t Usage; /**< Usage of the report item. */
+ } HID_Usage_t;
+
+ /** \brief HID Parser Report Item Collection Path Structure.
+ *
+ * Type define for a COLLECTION object. Contains the collection attributes and a reference to the
+ * parent collection if any.
+ */
+ typedef struct CollectionPath
+ {
+ uint8_t Type; /**< Collection type (e.g. "Generic Desktop"). */
+ HID_Usage_t Usage; /**< Collection usage. */
+ struct CollectionPath* Parent; /**< Reference to parent collection, or NULL if root collection. */
+ } HID_CollectionPath_t;
+
+ /** \brief HID Parser Report Item Attributes Structure.
+ *
+ * Type define for all the data attributes of a report item, except flags.
+ */
+ typedef struct
+ {
+ uint8_t BitSize; /**< Size in bits of the report item's data. */
+
+ HID_Usage_t Usage; /**< Usage of the report item. */
+ HID_Unit_t Unit; /**< Unit type and exponent of the report item. */
+ HID_MinMax_t Logical; /**< Logical minimum and maximum of the report item. */
+ HID_MinMax_t Physical; /**< Physical minimum and maximum of the report item. */
+ } HID_ReportItem_Attributes_t;
+
+ /** \brief HID Parser Report Item Details Structure.
+ *
+ * Type define for a report item (IN, OUT or FEATURE) layout attributes and other details.
+ */
+ typedef struct
+ {
+ uint16_t BitOffset; /**< Bit offset in the IN, OUT or FEATURE report of the item. */
+ uint8_t ItemType; /**< Report item type, a value in HID_ReportItemTypes_t. */
+ uint16_t ItemFlags; /**< Item data flags, such as constant/variable, etc. */
+ uint8_t ReportID; /**< Report ID this item belongs to, or 0x00 if device has only one report */
+ HID_CollectionPath_t* CollectionPath; /**< Collection path of the item. */
+
+ HID_ReportItem_Attributes_t Attributes; /**< Report item attributes. */
+
+ uint32_t Value; /**< Current value of the report item - use \ref HID_ALIGN_DATA() when processing
+ * a retrieved value so that it is aligned to a specific type.
+ */
+ uint32_t PreviousValue; /**< Previous value of the report item. */
+ } HID_ReportItem_t;
+
+ /** \brief HID Parser Report Size Structure.
+ *
+ * Type define for a report item size information structure, to retain the size of a device's reports by ID.
+ */
+ typedef struct
+ {
+ uint8_t ReportID; /**< Report ID of the report within the HID interface. */
+ uint16_t ReportSizeBits[3]; /**< Total number of bits in each report type for the given Report ID,
+ * indexed by the \ref HID_ReportItemTypes_t enum.
+ */
+ } HID_ReportSizeInfo_t;
+
+ /** \brief HID Parser State Structure.
+ *
+ * Type define for a complete processed HID report, including all report item data and collections.
+ */
+ typedef struct
+ {
+ uint8_t TotalReportItems; /**< Total number of report items stored in the
+ * ReportItems array.
+ */
+ HID_ReportItem_t ReportItems[HID_MAX_REPORTITEMS]; /**< Report items array, including
+ * all IN, OUT and FEATURE items.
+ */
+ HID_CollectionPath_t CollectionPaths[HID_MAX_COLLECTIONS]; /**< All collection items, referenced
+ * by the report items.
+ */
+ uint8_t TotalDeviceReports; /**< Number of reports within the HID interface */
+ HID_ReportSizeInfo_t ReportIDSizes[HID_MAX_REPORT_IDS]; /**< Report sizes for each report in the interface */
+ uint16_t LargestReportSizeBits; /**< Largest report that the attached device will generate, in bits */
+ bool UsingReportIDs; /**< Indicates if the device has at least one REPORT ID
+ * element in its HID report descriptor.
+ */
+ } HID_ReportInfo_t;
+
+ /* Function Prototypes: */
+ /** Function to process a given HID report returned from an attached device, and store it into a given
+ * \ref HID_ReportInfo_t structure.
+ *
+ * \param[in] ReportData Buffer containing the device's HID report table.
+ * \param[in] ReportSize Size in bytes of the HID report table.
+ * \param[out] ParserData Pointer to a \ref HID_ReportInfo_t instance for the parser output.
+ *
+ * \return A value in the \ref HID_Parse_ErrorCodes_t enum.
+ */
+ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData,
+ uint16_t ReportSize,
+ HID_ReportInfo_t* const ParserData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
+
+ /** Extracts the given report item's value out of the given HID report and places it into the Value
+ * member of the report item's \ref HID_ReportItem_t structure.
+ *
+ * When called on a report with an item that exists in that report, this copies the report item's Value
+ * to it's PreviousValue element for easy checking to see if an item's value has changed before processing
+ * a report. If the given item does not exist in the report, the function does not modify the report item's
+ * data.
+ *
+ * \param[in] ReportData Buffer containing an IN or FEATURE report from an attached device.
+ * \param[in,out] ReportItem Pointer to the report item of interest in a \ref HID_ReportInfo_t ReportItem array.
+ *
+ * \returns Boolean true if the item to retrieve was located in the given report, false otherwise.
+ */
+ bool USB_GetHIDReportItemInfo(const uint8_t* ReportData,
+ HID_ReportItem_t* const ReportItem) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+
+ /** Retrieves the given report item's value out of the Value member of the report item's
+ * \ref HID_ReportItem_t structure and places it into the correct position in the HID report
+ * buffer. The report buffer is assumed to have the appropriate bits cleared before calling
+ * this function (i.e., the buffer should be explicitly cleared before report values are added).
+ *
+ * When called, this copies the report item's Value element to it's PreviousValue element for easy
+ * checking to see if an item's value has changed before sending a report.
+ *
+ * If the device has multiple HID reports, the first byte in the report is set to the report ID of the given item.
+ *
+ * \param[out] ReportData Buffer holding the current OUT or FEATURE report data.
+ * \param[in] ReportItem Pointer to the report item of interest in a \ref HID_ReportInfo_t ReportItem array.
+ */
+ void USB_SetHIDReportItemInfo(uint8_t* ReportData,
+ HID_ReportItem_t* const ReportItem) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+
+ /** Retrieves the size of a given HID report in bytes from it's Report ID.
+ *
+ * \param[in] ParserData Pointer to a \ref HID_ReportInfo_t instance containing the parser output.
+ * \param[in] ReportID Report ID of the report whose size is to be retrieved.
+ * \param[in] ReportType Type of the report whose size is to be determined, a valued from the
+ * \ref HID_ReportItemTypes_t enum.
+ *
+ * \return Size of the report in bytes, or 0 if the report does not exist.
+ */
+ uint16_t USB_GetHIDReportSize(HID_ReportInfo_t* const ParserData,
+ const uint8_t ReportID,
+ const uint8_t ReportType) ATTR_CONST ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Callback routine for the HID Report Parser. This callback <b>must</b> be implemented by the user code when
+ * the parser is used, to determine what report IN, OUT and FEATURE item's information is stored into the user
+ * HID_ReportInfo_t structure. This can be used to filter only those items the application will be using, so that
+ * no RAM is wasted storing the attributes for report items which will never be referenced by the application.
+ *
+ * \param[in] CurrentItem Pointer to the current report item for user checking.
+ *
+ * \return Boolean true if the item should be stored into the HID_ReportInfo_t structure, false if it should be ignored.
+ */
+ bool CALLBACK_HIDParser_FilterHIDReportItem(HID_ReportItem_t* const CurrentItem);
+
+ /* Private Interface - For use in library only: */
+ #if !defined(__DOXYGEN__)
+ /* Type Defines: */
+ typedef struct
+ {
+ HID_ReportItem_Attributes_t Attributes;
+ uint8_t ReportCount;
+ uint8_t ReportID;
+ } HID_StateTable_t;
+ #endif
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/HIDParser.lst b/firmware/LUFA/Drivers/USB/Class/Host/HIDParser.lst
new file mode 100644
index 0000000..79add07
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/HIDParser.lst
@@ -0,0 +1,19 @@
+ 1 .file "HIDParser.c"
+ 2 __SREG__ = 0x3f
+ 3 __SP_H__ = 0x3e
+ 4 __SP_L__ = 0x3d
+ 5 __CCP__ = 0x34
+ 6 __tmp_reg__ = 0
+ 7 __zero_reg__ = 1
+ 15 .Ltext0:
+ 16 .Letext0:
+DEFINED SYMBOLS
+ *ABS*:0000000000000000 HIDParser.c
+ /tmp/ccpm8Lt2.s:2 *ABS*:000000000000003f __SREG__
+ /tmp/ccpm8Lt2.s:3 *ABS*:000000000000003e __SP_H__
+ /tmp/ccpm8Lt2.s:4 *ABS*:000000000000003d __SP_L__
+ /tmp/ccpm8Lt2.s:5 *ABS*:0000000000000034 __CCP__
+ /tmp/ccpm8Lt2.s:6 *ABS*:0000000000000000 __tmp_reg__
+ /tmp/ccpm8Lt2.s:7 *ABS*:0000000000000001 __zero_reg__
+
+NO UNDEFINED SYMBOLS
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/HIDParser.o b/firmware/LUFA/Drivers/USB/Class/Host/HIDParser.o
new file mode 100644
index 0000000..da84c79
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/HIDParser.o
Binary files differ
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/HIDReportData.h b/firmware/LUFA/Drivers/USB/Class/Host/HIDReportData.h
new file mode 100644
index 0000000..6ce6b8a
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/HIDReportData.h
@@ -0,0 +1,142 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Constants for HID report item attributes.
+ *
+ * HID report item constants for report item attributes. Refer to the HID specification for
+ * details on each flag's meaning when applied to an IN, OUT or FEATURE item.
+ */
+
+/** \ingroup Group_HIDParser
+ * @defgroup Group_HIDIOFConst Input/Output/Feature Masks
+ *
+ * Masks indicating the type of Input, Output of Feature HID report item.
+ *
+ * @{
+ */
+
+#ifndef __HIDREPORTDATA_H__
+#define __HIDREPORTDATA_H__
+
+ /* Public Interface - May be used in end-application: */
+ /* Macros: */
+ /** \ref HID_ReportItem_t.ItemFlags flag for constant data. */
+ #define IOF_CONSTANT (1 << 0)
+
+ /** \ref HID_ReportItem_t.ItemFlags flag for data. */
+ #define IOF_DATA (0 << 0)
+
+ /** \ref HID_ReportItem_t.ItemFlags flag for variable data. */
+ #define IOF_VARIABLE (1 << 1)
+
+ /** \ref HID_ReportItem_t.ItemFlags flag for array data. */
+ #define IOF_ARRAY (0 << 1)
+
+ /** \ref HID_ReportItem_t.ItemFlags flag for relative data. */
+ #define IOF_RELATIVE (1 << 2)
+
+ /** \ref HID_ReportItem_t.ItemFlags flag for absolute data. */
+ #define IOF_ABSOLUTE (0 << 2)
+
+ /** \ref HID_ReportItem_t.ItemFlags flag for wrapped value data. */
+ #define IOF_WRAP (1 << 3)
+
+ /** \ref HID_ReportItem_t.ItemFlags flag for non-wrapped value data. */
+ #define IOF_NOWRAP (0 << 3)
+
+ /** \ref HID_ReportItem_t.ItemFlags flag for non linear data. */
+ #define IOF_NONLINEAR (1 << 4)
+
+ /** \ref HID_ReportItem_t.ItemFlags flag for linear data. */
+ #define IOF_LINEAR (0 << 4)
+
+ /** \ref HID_ReportItem_t.ItemFlags flag for no preferred state. */
+ #define IOF_NOPREFERRED (1 << 5)
+
+ /** \ref HID_ReportItem_t.ItemFlags flag for preferred state items. */
+ #define IOF_PREFERREDSTATE (0 << 5)
+
+ /** \ref HID_ReportItem_t.ItemFlags flag for null state items. */
+ #define IOF_NULLSTATE (1 << 6)
+
+ /** \ref HID_ReportItem_t.ItemFlags flag for no null position data. */
+ #define IOF_NONULLPOSITION (0 << 6)
+
+ /** \ref HID_ReportItem_t.ItemFlags flag for buffered bytes. */
+ #define IOF_BUFFEREDBYTES (1 << 8)
+
+ /** \ref HID_ReportItem_t.ItemFlags flag for bit field data. */
+ #define IOF_BITFIELD (0 << 8)
+
+ /* Private Interface - For use in library only: */
+ #if !defined(__DOXYGEN__)
+ /* Macros: */
+ #define DATA_SIZE_MASK 0x03
+ #define TYPE_MASK 0x0C
+ #define TAG_MASK 0xF0
+
+ #define DATA_SIZE_0 0x00
+ #define DATA_SIZE_1 0x01
+ #define DATA_SIZE_2 0x02
+ #define DATA_SIZE_4 0x03
+
+ #define TYPE_MAIN 0x00
+ #define TYPE_GLOBAL 0x04
+ #define TYPE_LOCAL 0x08
+
+ #define TAG_MAIN_INPUT 0x80
+ #define TAG_MAIN_OUTPUT 0x90
+ #define TAG_MAIN_COLLECTION 0xA0
+ #define TAG_MAIN_FEATURE 0xB0
+ #define TAG_MAIN_ENDCOLLECTION 0xC0
+
+ #define TAG_GLOBAL_USAGEPAGE 0x00
+ #define TAG_GLOBAL_LOGICALMIN 0x10
+ #define TAG_GLOBAL_LOGICALMAX 0x20
+ #define TAG_GLOBAL_PHYSMIN 0x30
+ #define TAG_GLOBAL_PHYSMAX 0x40
+ #define TAG_GLOBAL_UNITEXP 0x50
+ #define TAG_GLOBAL_UNIT 0x60
+ #define TAG_GLOBAL_REPORTSIZE 0x70
+ #define TAG_GLOBAL_REPORTID 0x80
+ #define TAG_GLOBAL_REPORTCOUNT 0x90
+ #define TAG_GLOBAL_PUSH 0xA0
+ #define TAG_GLOBAL_POP 0xB0
+
+ #define TAG_LOCAL_USAGE 0x00
+ #define TAG_LOCAL_USAGEMIN 0x10
+ #define TAG_LOCAL_USAGEMAX 0x20
+ #endif
+
+/** @} */
+
+#endif
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/MIDI.c b/firmware/LUFA/Drivers/USB/Class/Host/MIDI.c
new file mode 100644
index 0000000..4877dbe
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/MIDI.c
@@ -0,0 +1,215 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define __INCLUDE_FROM_USB_DRIVER
+#include "../../HighLevel/USBMode.h"
+#if defined(USB_CAN_BE_HOST)
+
+#define __INCLUDE_FROM_MIDI_DRIVER
+#define __INCLUDE_FROM_MIDI_HOST_C
+#include "MIDI.h"
+
+uint8_t MIDI_Host_ConfigurePipes(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,
+ uint16_t ConfigDescriptorSize,
+ void* ConfigDescriptorData)
+{
+ USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
+ USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
+ USB_Descriptor_Interface_t* MIDIInterface = NULL;
+
+ memset(&MIDIInterfaceInfo->State, 0x00, sizeof(MIDIInterfaceInfo->State));
+
+ if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
+ return MIDI_ENUMERROR_InvalidConfigDescriptor;
+
+ while (!(DataINEndpoint) || !(DataOUTEndpoint))
+ {
+ if (!(MIDIInterface) ||
+ USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+ DCOMP_MIDI_Host_NextMIDIStreamingDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
+ {
+ if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+ DCOMP_MIDI_Host_NextMIDIStreamingInterface) != DESCRIPTOR_SEARCH_COMP_Found)
+ {
+ return MIDI_ENUMERROR_NoCompatibleInterfaceFound;
+ }
+
+ MIDIInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
+
+ DataINEndpoint = NULL;
+ DataOUTEndpoint = NULL;
+
+ continue;
+ }
+
+ USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
+
+ if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
+ DataINEndpoint = EndpointData;
+ else
+ DataOUTEndpoint = EndpointData;
+ }
+
+ for (uint8_t PipeNum = 1; PipeNum < PIPE_TOTAL_PIPES; PipeNum++)
+ {
+ if (PipeNum == MIDIInterfaceInfo->Config.DataINPipeNumber)
+ {
+ Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_IN,
+ DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize,
+ MIDIInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
+
+ MIDIInterfaceInfo->State.DataINPipeSize = DataINEndpoint->EndpointSize;
+ }
+ else if (PipeNum == MIDIInterfaceInfo->Config.DataOUTPipeNumber)
+ {
+ Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_OUT,
+ DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize,
+ MIDIInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
+
+ MIDIInterfaceInfo->State.DataOUTPipeSize = DataOUTEndpoint->EndpointSize;
+ }
+ }
+
+ MIDIInterfaceInfo->State.InterfaceNumber = MIDIInterface->InterfaceNumber;
+ MIDIInterfaceInfo->State.IsActive = true;
+
+ return MIDI_ENUMERROR_NoError;
+}
+
+static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingInterface(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 == AUDIO_CSCP_AudioClass) &&
+ (Interface->SubClass == AUDIO_CSCP_MIDIStreamingSubclass) &&
+ (Interface->Protocol == AUDIO_CSCP_StreamingProtocol))
+ {
+ return DESCRIPTOR_SEARCH_Found;
+ }
+ }
+
+ return DESCRIPTOR_SEARCH_NotFound;
+}
+
+static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingDataEndpoint(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 MIDI_Host_USBTask(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))
+ return;
+
+ #if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
+ MIDI_Host_Flush(MIDIInterfaceInfo);
+ #endif
+}
+
+uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))
+ return PIPE_RWSTREAM_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataOUTPipeNumber);
+
+ if (Pipe_BytesInPipe())
+ {
+ Pipe_ClearOUT();
+
+ if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)
+ return ErrorCode;
+ }
+
+ return PIPE_READYWAIT_NoError;
+}
+
+uint8_t MIDI_Host_SendEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,
+ MIDI_EventPacket_t* const Event)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))
+ return HOST_SENDCONTROL_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataOUTPipeNumber);
+
+ if ((ErrorCode = Pipe_Write_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ if (!(Pipe_IsReadWriteAllowed()))
+ Pipe_ClearOUT();
+
+ return PIPE_RWSTREAM_NoError;
+}
+
+bool MIDI_Host_ReceiveEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,
+ MIDI_EventPacket_t* const Event)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))
+ return HOST_SENDCONTROL_DeviceDisconnected;
+
+ Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataINPipeNumber);
+
+ if (!(Pipe_IsReadWriteAllowed()))
+ return false;
+
+ Pipe_Read_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NO_STREAM_CALLBACK);
+
+ if (!(Pipe_IsReadWriteAllowed()))
+ Pipe_ClearIN();
+
+ return true;
+}
+
+#endif
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/MIDI.h b/firmware/LUFA/Drivers/USB/Class/Host/MIDI.h
new file mode 100644
index 0000000..0cb778f
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/MIDI.h
@@ -0,0 +1,201 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Host mode driver for the library USB MIDI Class driver.
+ *
+ * Host mode driver for the library USB MIDI 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_USBClassMIDI
+ * @defgroup Group_USBClassMIDIHost MIDI 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/MIDI.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ *
+ * \section Module Description
+ * Host Mode USB Class driver framework interface, for the MIDI USB Class driver.
+ *
+ * @{
+ */
+
+#ifndef __MIDI_CLASS_HOST_H__
+#define __MIDI_CLASS_HOST_H__
+
+ /* Includes: */
+ #include "../../USB.h"
+ #include "../Common/MIDI.h"
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_MIDI_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ #if defined(__INCLUDE_FROM_MIDI_HOST_C) && defined(NO_STREAM_CALLBACKS)
+ #error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
+ #endif
+
+ /* Public Interface - May be used in end-application: */
+ /* Type Defines: */
+ /** \brief MIDI 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 MIDI class driver functions as the MIDIInterfaceInfo parameter. This
+ * stores each MIDI interface's configuration and state information.
+ */
+ typedef struct
+ {
+ const struct
+ {
+ uint8_t DataINPipeNumber; /**< Pipe number of the MIDI interface's streaming IN data pipe. */
+ bool DataINPipeDoubleBank; /**< Indicates if the MIDI interface's IN data pipe should use double banking. */
+
+ uint8_t DataOUTPipeNumber; /**< Pipe number of the MIDI interface's streaming OUT data pipe. */
+ bool DataOUTPipeDoubleBank; /**< Indicates if the MIDI interface's OUT data pipe should use double banking. */
+ } Config; /**< Config data for the USB class interface within the device. All elements in this section
+ * <b>must</b> 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 MIDI_Host_ConfigurePipes() is called and the Host state machine is in the
+ * Configured state.
+ */
+ uint8_t InterfaceNumber; /**< Interface index of the MIDI interface within the attached device. */
+
+ uint16_t DataINPipeSize; /**< Size in bytes of the MIDI Streaming Data interface's IN data pipe. */
+ uint16_t DataOUTPipeSize; /**< Size in bytes of the MIDI Streaming Data interface's OUT data pipe. */
+ } State; /**< State data for the USB class interface within the device. All elements in this section
+ * <b>may</b> be set to initial values, but may also be ignored to default to sane values when
+ * the interface is enumerated.
+ */
+ } USB_ClassInfo_MIDI_Host_t;
+
+ /* Enums: */
+ /** Enum for the possible error codes returned by the \ref MIDI_Host_ConfigurePipes() function. */
+ enum MIDI_Host_EnumerationFailure_ErrorCodes_t
+ {
+ MIDI_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */
+ MIDI_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */
+ MIDI_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible MIDI interface was not found in the device's Configuration Descriptor. */
+ };
+
+ /* Function Prototypes: */
+ /** Host interface configuration routine, to configure a given MIDI host interface instance using the Configuration
+ * Descriptor read from an attached USB device. This function automatically updates the given MIDI 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.
+ *
+ * \note The pipe index numbers as given in the interface's configuration structure must not overlap with any other
+ * interface, or pipe bank corruption will occur. Gaps in the allocated pipe numbers or non-sequential indexes
+ * within a single interface is allowed, but no two interfaces of any type have have interleaved pipe indexes.
+ *
+ * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing an MIDI Class host configuration and state.
+ * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor.
+ * \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor.
+ *
+ * \return A value from the \ref MIDI_Host_EnumerationFailure_ErrorCodes_t enum.
+ */
+ uint8_t MIDI_Host_ConfigurePipes(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,
+ uint16_t ConfigDescriptorSize,
+ void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
+
+ /** General management task for a given MIDI 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] MIDIInterfaceInfo Pointer to a structure containing an MIDI Class host configuration and state.
+ */
+ void MIDI_Host_USBTask(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Sends a MIDI event packet to the device. If no device is connected, the event packet is discarded.
+ *
+ * \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] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
+ * \param[in] Event Pointer to a populated USB_MIDI_EventPacket_t structure containing the MIDI event to send.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t MIDI_Host_SendEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,
+ 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
+ * 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.
+ *
+ * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
+ *
+ * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum.
+ */
+ uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Receives a MIDI event packet from the device.
+ *
+ * \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] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state.
+ * \param[out] Event Pointer to a USB_MIDI_EventPacket_t structure where the received MIDI event is to be placed.
+ *
+ * \return Boolean true if a MIDI event packet was received, false otherwise.
+ */
+ bool MIDI_Host_ReceiveEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,
+ MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+
+ /* Private Interface - For use in library only: */
+ #if !defined(__DOXYGEN__)
+ /* Function Prototypes: */
+ #if defined(__INCLUDE_FROM_MIDI_HOST_C)
+ static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
+ static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingDataEndpoint(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
+ #endif
+ #endif
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/MIDI.lst b/firmware/LUFA/Drivers/USB/Class/Host/MIDI.lst
new file mode 100644
index 0000000..eb26be7
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/MIDI.lst
@@ -0,0 +1,19 @@
+ 1 .file "MIDI.c"
+ 2 __SREG__ = 0x3f
+ 3 __SP_H__ = 0x3e
+ 4 __SP_L__ = 0x3d
+ 5 __CCP__ = 0x34
+ 6 __tmp_reg__ = 0
+ 7 __zero_reg__ = 1
+ 15 .Ltext0:
+ 16 .Letext0:
+DEFINED SYMBOLS
+ *ABS*:0000000000000000 MIDI.c
+ /tmp/cc5LIYAF.s:2 *ABS*:000000000000003f __SREG__
+ /tmp/cc5LIYAF.s:3 *ABS*:000000000000003e __SP_H__
+ /tmp/cc5LIYAF.s:4 *ABS*:000000000000003d __SP_L__
+ /tmp/cc5LIYAF.s:5 *ABS*:0000000000000034 __CCP__
+ /tmp/cc5LIYAF.s:6 *ABS*:0000000000000000 __tmp_reg__
+ /tmp/cc5LIYAF.s:7 *ABS*:0000000000000001 __zero_reg__
+
+NO UNDEFINED SYMBOLS
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/MIDI.o b/firmware/LUFA/Drivers/USB/Class/Host/MIDI.o
new file mode 100644
index 0000000..bb3defc
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/MIDI.o
Binary files differ
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/MassStorage.c b/firmware/LUFA/Drivers/USB/Class/Host/MassStorage.c
new file mode 100644
index 0000000..0ecaca9
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/MassStorage.c
@@ -0,0 +1,629 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define __INCLUDE_FROM_USB_DRIVER
+#include "../../HighLevel/USBMode.h"
+#if defined(USB_CAN_BE_HOST)
+
+#define __INCLUDE_FROM_MS_DRIVER
+#define __INCLUDE_FROM_MASSSTORAGE_HOST_C
+#include "MassStorage.h"
+
+uint8_t MS_Host_ConfigurePipes(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ uint16_t ConfigDescriptorSize,
+ void* ConfigDescriptorData)
+{
+ USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
+ USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
+ USB_Descriptor_Interface_t* MassStorageInterface = NULL;
+
+ memset(&MSInterfaceInfo->State, 0x00, sizeof(MSInterfaceInfo->State));
+
+ if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
+ return MS_ENUMERROR_InvalidConfigDescriptor;
+
+ while (!(DataINEndpoint) || !(DataOUTEndpoint))
+ {
+ if (!(MassStorageInterface) ||
+ USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+ DCOMP_MS_Host_NextMSInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
+ {
+ if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+ DCOMP_MS_Host_NextMSInterface) != DESCRIPTOR_SEARCH_COMP_Found)
+ {
+ return MS_ENUMERROR_NoCompatibleInterfaceFound;
+ }
+
+ MassStorageInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
+
+ DataINEndpoint = NULL;
+ DataOUTEndpoint = NULL;
+
+ continue;
+ }
+
+ USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
+
+ if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
+ DataINEndpoint = EndpointData;
+ else
+ DataOUTEndpoint = EndpointData;
+ }
+
+ for (uint8_t PipeNum = 1; PipeNum < PIPE_TOTAL_PIPES; PipeNum++)
+ {
+ if (PipeNum == MSInterfaceInfo->Config.DataINPipeNumber)
+ {
+ Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_IN,
+ DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize,
+ MSInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
+
+ MSInterfaceInfo->State.DataINPipeSize = DataINEndpoint->EndpointSize;
+ }
+ else if (PipeNum == MSInterfaceInfo->Config.DataOUTPipeNumber)
+ {
+ Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_OUT,
+ DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize,
+ MSInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
+
+ MSInterfaceInfo->State.DataOUTPipeSize = DataOUTEndpoint->EndpointSize;
+ }
+ }
+
+ MSInterfaceInfo->State.InterfaceNumber = MassStorageInterface->InterfaceNumber;
+ MSInterfaceInfo->State.IsActive = true;
+
+ return MS_ENUMERROR_NoError;
+}
+
+static uint8_t DCOMP_MS_Host_NextMSInterface(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 == MS_CSCP_MassStorageClass) &&
+ (Interface->SubClass == MS_CSCP_SCSITransparentSubclass) &&
+ (Interface->Protocol == MS_CSCP_BulkOnlyTransportProtocol))
+ {
+ return DESCRIPTOR_SEARCH_Found;
+ }
+ }
+
+ return DESCRIPTOR_SEARCH_NotFound;
+}
+
+static uint8_t DCOMP_MS_Host_NextMSInterfaceEndpoint(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;
+}
+
+static uint8_t MS_Host_SendCommand(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ MS_CommandBlockWrapper_t* const SCSICommandBlock,
+ const void* const BufferPtr)
+{
+ uint8_t ErrorCode = PIPE_RWSTREAM_NoError;
+
+ SCSICommandBlock->Signature = MS_CBW_SIGNATURE;
+ SCSICommandBlock->Tag = ++MSInterfaceInfo->State.TransactionTag;
+
+ if (MSInterfaceInfo->State.TransactionTag == 0xFFFFFFFF)
+ MSInterfaceInfo->State.TransactionTag = 1;
+
+ Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipeNumber);
+ Pipe_Unfreeze();
+
+ if ((ErrorCode = Pipe_Write_Stream_LE(SCSICommandBlock, sizeof(MS_CommandBlockWrapper_t),
+ NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ Pipe_ClearOUT();
+ Pipe_WaitUntilReady();
+
+ Pipe_Freeze();
+
+ if ((BufferPtr != NULL) &&
+ ((ErrorCode = MS_Host_SendReceiveData(MSInterfaceInfo, SCSICommandBlock, (void*)BufferPtr)) != PIPE_RWSTREAM_NoError))
+ {
+ Pipe_Freeze();
+ return ErrorCode;
+ }
+
+ return ErrorCode;
+}
+
+static uint8_t MS_Host_WaitForDataReceived(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo)
+{
+ uint16_t TimeoutMSRem = MS_COMMAND_DATA_TIMEOUT_MS;
+ uint16_t PreviousFrameNumber = USB_Host_GetFrameNumber();
+
+ Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber);
+ Pipe_Unfreeze();
+
+ while (!(Pipe_IsINReceived()))
+ {
+ uint16_t CurrentFrameNumber = USB_Host_GetFrameNumber();
+
+ if (CurrentFrameNumber != PreviousFrameNumber)
+ {
+ PreviousFrameNumber = CurrentFrameNumber;
+
+ if (!(TimeoutMSRem--))
+ return PIPE_RWSTREAM_Timeout;
+ }
+
+ Pipe_Freeze();
+ Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipeNumber);
+ Pipe_Unfreeze();
+
+ if (Pipe_IsStalled())
+ {
+ USB_Host_ClearPipeStall(MSInterfaceInfo->Config.DataOUTPipeNumber);
+
+ return PIPE_RWSTREAM_PipeStalled;
+ }
+
+ Pipe_Freeze();
+ Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber);
+ Pipe_Unfreeze();
+
+ if (Pipe_IsStalled())
+ {
+ USB_Host_ClearPipeStall(MSInterfaceInfo->Config.DataINPipeNumber);
+
+ return PIPE_RWSTREAM_PipeStalled;
+ }
+
+ if (USB_HostState == HOST_STATE_Unattached)
+ return PIPE_RWSTREAM_DeviceDisconnected;
+ };
+
+ Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber);
+ Pipe_Freeze();
+
+ Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipeNumber);
+ Pipe_Freeze();
+
+ return PIPE_RWSTREAM_NoError;
+}
+
+static uint8_t MS_Host_SendReceiveData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ MS_CommandBlockWrapper_t* const SCSICommandBlock,
+ void* BufferPtr)
+{
+ uint8_t ErrorCode = PIPE_RWSTREAM_NoError;
+ uint16_t BytesRem = SCSICommandBlock->DataTransferLength;
+
+ if (SCSICommandBlock->Flags & MS_COMMAND_DIR_DATA_IN)
+ {
+ if ((ErrorCode = MS_Host_WaitForDataReceived(MSInterfaceInfo)) != PIPE_RWSTREAM_NoError)
+ {
+ Pipe_Freeze();
+ return ErrorCode;
+ }
+
+ Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber);
+ Pipe_Unfreeze();
+
+ if ((ErrorCode = Pipe_Read_Stream_LE(BufferPtr, BytesRem, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ Pipe_ClearIN();
+ }
+ else
+ {
+ Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipeNumber);
+ Pipe_Unfreeze();
+
+ if ((ErrorCode = Pipe_Write_Stream_LE(BufferPtr, BytesRem, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ Pipe_ClearOUT();
+
+ while (!(Pipe_IsOUTReady()))
+ {
+ if (USB_HostState == HOST_STATE_Unattached)
+ return PIPE_RWSTREAM_DeviceDisconnected;
+ }
+ }
+
+ Pipe_Freeze();
+
+ return ErrorCode;
+}
+
+static uint8_t MS_Host_GetReturnedStatus(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ MS_CommandStatusWrapper_t* const SCSICommandStatus)
+{
+ uint8_t ErrorCode = PIPE_RWSTREAM_NoError;
+
+ if ((ErrorCode = MS_Host_WaitForDataReceived(MSInterfaceInfo)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber);
+ Pipe_Unfreeze();
+
+ if ((ErrorCode = Pipe_Read_Stream_LE(SCSICommandStatus, sizeof(MS_CommandStatusWrapper_t),
+ NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
+ {
+ return ErrorCode;
+ }
+
+ Pipe_ClearIN();
+ Pipe_Freeze();
+
+ if (SCSICommandStatus->Status != MS_SCSI_COMMAND_Pass)
+ ErrorCode = MS_ERROR_LOGICAL_CMD_FAILED;
+
+ return ErrorCode;
+}
+
+uint8_t MS_Host_ResetMSInterface(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo)
+{
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = MS_REQ_MassStorageReset,
+ .wValue = 0,
+ .wIndex = MSInterfaceInfo->State.InterfaceNumber,
+ .wLength = 0,
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+ return USB_Host_SendControlRequest(NULL);
+}
+
+uint8_t MS_Host_GetMaxLUN(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ uint8_t* const MaxLUNIndex)
+{
+ uint8_t ErrorCode = HOST_SENDCONTROL_Successful;
+
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = MS_REQ_GetMaxLUN,
+ .wValue = 0,
+ .wIndex = MSInterfaceInfo->State.InterfaceNumber,
+ .wLength = 1,
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+ if ((ErrorCode = USB_Host_SendControlRequest(MaxLUNIndex)) != HOST_SENDCONTROL_Successful)
+ {
+ *MaxLUNIndex = 0;
+ ErrorCode = HOST_SENDCONTROL_Successful;
+ }
+
+ return ErrorCode;
+}
+
+uint8_t MS_Host_GetInquiryData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ const uint8_t LUNIndex,
+ SCSI_Inquiry_Response_t* const InquiryData)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive))
+ return HOST_SENDCONTROL_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
+ {
+ .DataTransferLength = sizeof(SCSI_Inquiry_Response_t),
+ .Flags = MS_COMMAND_DIR_DATA_IN,
+ .LUN = LUNIndex,
+ .SCSICommandLength = 6,
+ .SCSICommandData =
+ {
+ SCSI_CMD_INQUIRY,
+ 0x00, // Reserved
+ 0x00, // Reserved
+ 0x00, // Reserved
+ sizeof(SCSI_Inquiry_Response_t), // Allocation Length
+ 0x00 // Unused (control)
+ }
+ };
+
+ MS_CommandStatusWrapper_t SCSICommandStatus;
+
+ if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, InquiryData)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ if ((ErrorCode = MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSICommandStatus)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ return PIPE_RWSTREAM_NoError;
+}
+
+uint8_t MS_Host_TestUnitReady(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ const uint8_t LUNIndex)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive))
+ return HOST_SENDCONTROL_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
+ {
+ .DataTransferLength = 0,
+ .Flags = MS_COMMAND_DIR_DATA_IN,
+ .LUN = LUNIndex,
+ .SCSICommandLength = 6,
+ .SCSICommandData =
+ {
+ SCSI_CMD_TEST_UNIT_READY,
+ 0x00, // Reserved
+ 0x00, // Reserved
+ 0x00, // Reserved
+ 0x00, // Reserved
+ 0x00 // Unused (control)
+ }
+ };
+
+ MS_CommandStatusWrapper_t SCSICommandStatus;
+
+ if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, NULL)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ if ((ErrorCode = MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSICommandStatus)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ return PIPE_RWSTREAM_NoError;
+}
+
+uint8_t MS_Host_ReadDeviceCapacity(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ const uint8_t LUNIndex,
+ SCSI_Capacity_t* const DeviceCapacity)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive))
+ return HOST_SENDCONTROL_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
+ {
+ .DataTransferLength = sizeof(SCSI_Capacity_t),
+ .Flags = MS_COMMAND_DIR_DATA_IN,
+ .LUN = LUNIndex,
+ .SCSICommandLength = 10,
+ .SCSICommandData =
+ {
+ SCSI_CMD_READ_CAPACITY_10,
+ 0x00, // Reserved
+ 0x00, // MSB of Logical block address
+ 0x00,
+ 0x00,
+ 0x00, // LSB of Logical block address
+ 0x00, // Reserved
+ 0x00, // Reserved
+ 0x00, // Partial Medium Indicator
+ 0x00 // Unused (control)
+ }
+ };
+
+ MS_CommandStatusWrapper_t SCSICommandStatus;
+
+ if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, DeviceCapacity)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ SwapEndian_n(&DeviceCapacity->Blocks, sizeof(DeviceCapacity->Blocks));
+ SwapEndian_n(&DeviceCapacity->BlockSize, sizeof(DeviceCapacity->BlockSize));
+
+ if ((ErrorCode = MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSICommandStatus)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ return PIPE_RWSTREAM_NoError;
+}
+
+uint8_t MS_Host_RequestSense(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ const uint8_t LUNIndex,
+ SCSI_Request_Sense_Response_t* const SenseData)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive))
+ return HOST_SENDCONTROL_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
+ {
+ .DataTransferLength = sizeof(SCSI_Request_Sense_Response_t),
+ .Flags = MS_COMMAND_DIR_DATA_IN,
+ .LUN = LUNIndex,
+ .SCSICommandLength = 6,
+ .SCSICommandData =
+ {
+ SCSI_CMD_REQUEST_SENSE,
+ 0x00, // Reserved
+ 0x00, // Reserved
+ 0x00, // Reserved
+ sizeof(SCSI_Request_Sense_Response_t), // Allocation Length
+ 0x00 // Unused (control)
+ }
+ };
+
+ MS_CommandStatusWrapper_t SCSICommandStatus;
+
+ if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, SenseData)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ if ((ErrorCode = MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSICommandStatus)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ return PIPE_RWSTREAM_NoError;
+}
+
+uint8_t MS_Host_PreventAllowMediumRemoval(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ const uint8_t LUNIndex,
+ const bool PreventRemoval)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive))
+ return HOST_SENDCONTROL_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
+ {
+ .DataTransferLength = 0,
+ .Flags = MS_COMMAND_DIR_DATA_OUT,
+ .LUN = LUNIndex,
+ .SCSICommandLength = 6,
+ .SCSICommandData =
+ {
+ SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL,
+ 0x00, // Reserved
+ 0x00, // Reserved
+ PreventRemoval, // Prevent flag
+ 0x00, // Reserved
+ 0x00 // Unused (control)
+ }
+ };
+
+ MS_CommandStatusWrapper_t SCSICommandStatus;
+
+ if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, NULL)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ if ((ErrorCode = MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSICommandStatus)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ return PIPE_RWSTREAM_NoError;
+}
+
+uint8_t MS_Host_ReadDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ const uint8_t LUNIndex,
+ const uint32_t BlockAddress,
+ const uint8_t Blocks,
+ const uint16_t BlockSize,
+ void* BlockBuffer)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive))
+ return HOST_SENDCONTROL_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
+ {
+ .DataTransferLength = ((uint32_t)Blocks * BlockSize),
+ .Flags = MS_COMMAND_DIR_DATA_IN,
+ .LUN = LUNIndex,
+ .SCSICommandLength = 10,
+ .SCSICommandData =
+ {
+ SCSI_CMD_READ_10,
+ 0x00, // Unused (control bits, all off)
+ (BlockAddress >> 24), // MSB of Block Address
+ (BlockAddress >> 16),
+ (BlockAddress >> 8),
+ (BlockAddress & 0xFF), // LSB of Block Address
+ 0x00, // Reserved
+ 0x00, // MSB of Total Blocks to Read
+ Blocks, // LSB of Total Blocks to Read
+ 0x00 // Unused (control)
+ }
+ };
+
+ MS_CommandStatusWrapper_t SCSICommandStatus;
+
+ if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, BlockBuffer)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ if ((ErrorCode = MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSICommandStatus)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ return PIPE_RWSTREAM_NoError;
+}
+
+uint8_t MS_Host_WriteDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ const uint8_t LUNIndex,
+ const uint32_t BlockAddress,
+ const uint8_t Blocks,
+ const uint16_t BlockSize,
+ const void* BlockBuffer)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive))
+ return HOST_SENDCONTROL_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t)
+ {
+ .DataTransferLength = ((uint32_t)Blocks * BlockSize),
+ .Flags = MS_COMMAND_DIR_DATA_OUT,
+ .LUN = LUNIndex,
+ .SCSICommandLength = 10,
+ .SCSICommandData =
+ {
+ SCSI_CMD_WRITE_10,
+ 0x00, // Unused (control bits, all off)
+ (BlockAddress >> 24), // MSB of Block Address
+ (BlockAddress >> 16),
+ (BlockAddress >> 8),
+ (BlockAddress & 0xFF), // LSB of Block Address
+ 0x00, // Reserved
+ 0x00, // MSB of Total Blocks to Write
+ Blocks, // LSB of Total Blocks to Write
+ 0x00 // Unused (control)
+ }
+ };
+
+ MS_CommandStatusWrapper_t SCSICommandStatus;
+
+ if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, BlockBuffer)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ if ((ErrorCode = MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSICommandStatus)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ return PIPE_RWSTREAM_NoError;
+}
+
+#endif
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/MassStorage.h b/firmware/LUFA/Drivers/USB/Class/Host/MassStorage.h
new file mode 100644
index 0000000..ad4286d
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/MassStorage.h
@@ -0,0 +1,344 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Host mode driver for the library USB Mass Storage Class driver.
+ *
+ * Host mode driver for the library USB Mass Storage 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_USBClassMS
+ * @defgroup Group_USBClassMassStorageHost Mass Storage 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/MassStorage.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ *
+ * \section Module Description
+ * Host Mode USB Class driver framework interface, for the Mass Storage USB Class driver.
+ *
+ * @{
+ */
+
+#ifndef __MS_CLASS_HOST_H__
+#define __MS_CLASS_HOST_H__
+
+ /* Includes: */
+ #include "../../USB.h"
+ #include "../Common/MassStorage.h"
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_MS_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ #if defined(__INCLUDE_FROM_MASSSTORAGE_HOST_C) && defined(NO_STREAM_CALLBACKS)
+ #error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
+ #endif
+
+ /* Public Interface - May be used in end-application: */
+ /* Macros: */
+ /** Error code for some Mass Storage Host functions, indicating a logical (and not hardware) error. */
+ #define MS_ERROR_LOGICAL_CMD_FAILED 0x80
+
+ /* Type Defines: */
+ /** \brief Mass Storage 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 Mass Storage class driver functions as the MSInterfaceInfo parameter. This
+ * stores each Mass Storage interface's configuration and state information.
+ */
+ typedef struct
+ {
+ const struct
+ {
+ uint8_t DataINPipeNumber; /**< Pipe number of the Mass Storage interface's IN data pipe. */
+ bool DataINPipeDoubleBank; /**< Indicates if the Mass Storage interface's IN data pipe should use double banking. */
+
+ uint8_t DataOUTPipeNumber; /**< Pipe number of the Mass Storage interface's OUT data pipe. */
+ bool DataOUTPipeDoubleBank; /**< Indicates if the Mass Storage interface's OUT data pipe should use double banking. */
+ } Config; /**< Config data for the USB class interface within the device. All elements in this section
+ * <b>must</b> 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 MS_Host_ConfigurePipes() is called and the Host state machine is in the
+ * Configured state.
+ */
+ uint8_t InterfaceNumber; /**< Interface index of the Mass Storage interface within the attached device. */
+
+ uint16_t DataINPipeSize; /**< Size in bytes of the Mass Storage interface's IN data pipe. */
+ uint16_t DataOUTPipeSize; /**< Size in bytes of the Mass Storage interface's OUT data pipe. */
+
+ uint32_t TransactionTag; /**< Current transaction tag for data synchronizing of packets. */
+ } State; /**< State data for the USB class interface within the device. All elements in this section
+ * <b>may</b> be set to initial values, but may also be ignored to default to sane values when
+ * the interface is enumerated.
+ */
+ } USB_ClassInfo_MS_Host_t;
+
+ /** \brief SCSI Device LUN Capacity Structure.
+ *
+ * SCSI capacity structure, to hold the total capacity of the device in both the number
+ * of blocks in the current LUN, and the size of each block. This structure is filled by
+ * the device when the \ref MS_Host_ReadDeviceCapacity() function is called.
+ */
+ typedef struct
+ {
+ uint32_t Blocks; /**< Number of blocks in the addressed LUN of the device. */
+ uint32_t BlockSize; /**< Number of bytes in each block in the addressed LUN. */
+ } SCSI_Capacity_t;
+
+ /* Enums: */
+ enum MS_Host_EnumerationFailure_ErrorCodes_t
+ {
+ MS_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */
+ MS_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */
+ MS_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible Mass Storage interface was not found in the device's Configuration Descriptor. */
+ };
+
+ /* Function Prototypes: */
+ /** Host interface configuration routine, to configure a given Mass Storage host interface instance using the
+ * Configuration Descriptor read from an attached USB device. This function automatically updates the given Mass
+ * Storage 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.
+ *
+ * \note The pipe index numbers as given in the interface's configuration structure must not overlap with any other
+ * interface, or pipe bank corruption will occur. Gaps in the allocated pipe numbers or non-sequential indexes
+ * within a single interface is allowed, but no two interfaces of any type have have interleaved pipe indexes.
+ *
+ * \param[in,out] MSInterfaceInfo Pointer to a structure containing an MS 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 MS_Host_EnumerationFailure_ErrorCodes_t enum.
+ */
+ uint8_t MS_Host_ConfigurePipes(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ uint16_t ConfigDescriptorSize,
+ void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
+
+ /** Sends a MASS STORAGE RESET control request to the attached device, resetting the Mass Storage Interface
+ * and readying it for the next Mass Storage command.
+ *
+ * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state.
+ *
+ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
+ */
+ uint8_t MS_Host_ResetMSInterface(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Sends a GET MAX LUN control request to the attached device, retrieving the index of the highest LUN (Logical
+ * UNit, a logical drive) in the device. This value can then be used in the other functions of the Mass Storage
+ * Host mode Class driver to address a specific LUN within the device.
+ *
+ * \note Some devices do not support this request, and will STALL it when issued. To get around this,
+ * on unsupported devices the max LUN index will be reported as zero and no error will be returned
+ * if the device STALLs the request.
+ *
+ * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state.
+ * \param[out] MaxLUNIndex Pointer to a location where the highest LUN index value should be stored.
+ *
+ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
+ */
+ uint8_t MS_Host_GetMaxLUN(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ uint8_t* const MaxLUNIndex) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+
+ /** Retrieves the Mass Storage device's inquiry data for the specified LUN, indicating the device characteristics and
+ * properties.
+ *
+ * \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] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state.
+ * \param[in] LUNIndex LUN index within the device the command is being issued to.
+ * \param[out] InquiryData Location where the read inquiry data should be stored.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED.
+ */
+ uint8_t MS_Host_GetInquiryData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ const uint8_t LUNIndex,
+ SCSI_Inquiry_Response_t* const InquiryData) ATTR_NON_NULL_PTR_ARG(1)
+ ATTR_NON_NULL_PTR_ARG(3);
+
+ /** Sends a TEST UNIT READY command to the device, to determine if it is ready to accept other SCSI commands.
+ *
+ * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state.
+ * \param[in] LUNIndex LUN index within the device the command is being issued to.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready.
+ */
+ uint8_t MS_Host_TestUnitReady(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ const uint8_t LUNIndex) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Retrieves the total capacity of the attached USB Mass Storage device, in blocks, and block size.
+ *
+ * \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] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state.
+ * \param[in] LUNIndex LUN index within the device the command is being issued to.
+ * \param[out] DeviceCapacity Pointer to the location where the capacity information should be stored.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready.
+ */
+ uint8_t MS_Host_ReadDeviceCapacity(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ const uint8_t LUNIndex,
+ SCSI_Capacity_t* const DeviceCapacity) ATTR_NON_NULL_PTR_ARG(1)
+ ATTR_NON_NULL_PTR_ARG(3);
+
+ /** Retrieves the device sense data, indicating the current device state and error codes for the previously
+ * issued command.
+ *
+ * \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] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state.
+ * \param[in] LUNIndex LUN index within the device the command is being issued to.
+ * \param[out] SenseData Pointer to the location where the sense information should be stored.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready.
+ */
+ uint8_t MS_Host_RequestSense(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ const uint8_t LUNIndex,
+ SCSI_Request_Sense_Response_t* const SenseData) ATTR_NON_NULL_PTR_ARG(1)
+ ATTR_NON_NULL_PTR_ARG(3);
+
+ /** Issues a PREVENT MEDIUM REMOVAL command, to logically (or, depending on the type of device, physically) lock
+ * the device from removal so that blocks of data on the medium can be read or altered.
+ *
+ * \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] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state.
+ * \param[in] LUNIndex LUN index within the device the command is being issued to.
+ * \param[in] PreventRemoval Boolean true if the device should be locked from removal, false otherwise.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready.
+ */
+ uint8_t MS_Host_PreventAllowMediumRemoval(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ const uint8_t LUNIndex,
+ const bool PreventRemoval) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Reads blocks of data from the attached Mass Storage device's medium.
+ *
+ * \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] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state.
+ * \param[in] LUNIndex LUN index within the device the command is being issued to.
+ * \param[in] BlockAddress Starting block address within the device to read from.
+ * \param[in] Blocks Total number of blocks to read.
+ * \param[in] BlockSize Size in bytes of each block within the device.
+ * \param[out] BlockBuffer Pointer to where the read data from the device should be stored.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready.
+ */
+ uint8_t MS_Host_ReadDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ const uint8_t LUNIndex,
+ const uint32_t BlockAddress,
+ const uint8_t Blocks,
+ const uint16_t BlockSize,
+ void* BlockBuffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(6);
+
+ /** Writes blocks of data to the attached Mass Storage device's medium.
+ *
+ * \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] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state.
+ * \param[in] LUNIndex LUN index within the device the command is being issued to.
+ * \param[in] BlockAddress Starting block address within the device to write to.
+ * \param[in] Blocks Total number of blocks to read.
+ * \param[in] BlockSize Size in bytes of each block within the device.
+ * \param[in] BlockBuffer Pointer to where the data to write should be sourced from.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready.
+ */
+ uint8_t MS_Host_WriteDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ const uint8_t LUNIndex,
+ const uint32_t BlockAddress,
+ const uint8_t Blocks,
+ const uint16_t BlockSize,
+ const void* BlockBuffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(6);
+
+ /* Inline Functions: */
+ /** General management task for a given Mass Storage 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] MSInterfaceInfo Pointer to a structure containing an Mass Storage Class host configuration and state.
+ */
+ static inline void MS_Host_USBTask(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo);
+ static inline void MS_Host_USBTask(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo)
+ {
+ (void)MSInterfaceInfo;
+ }
+
+ /* Private Interface - For use in library only: */
+ #if !defined(__DOXYGEN__)
+ /* Macros: */
+ #define MS_COMMAND_DATA_TIMEOUT_MS 10000
+
+ /* Function Prototypes: */
+ #if defined(__INCLUDE_FROM_MASSSTORAGE_HOST_C)
+ static uint8_t DCOMP_MS_Host_NextMSInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
+ static uint8_t DCOMP_MS_Host_NextMSInterfaceEndpoint(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
+
+ static uint8_t MS_Host_SendCommand(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ MS_CommandBlockWrapper_t* const SCSICommandBlock,
+ const void* const BufferPtr) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+ static uint8_t MS_Host_WaitForDataReceived(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+ static uint8_t MS_Host_SendReceiveData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ MS_CommandBlockWrapper_t* const SCSICommandBlock,
+ void* BufferPtr) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+ static uint8_t MS_Host_GetReturnedStatus(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo,
+ MS_CommandStatusWrapper_t* const SCSICommandStatus)
+ ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+ #endif
+ #endif
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/MassStorage.lst b/firmware/LUFA/Drivers/USB/Class/Host/MassStorage.lst
new file mode 100644
index 0000000..41f6f0e
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/MassStorage.lst
@@ -0,0 +1,19 @@
+ 1 .file "MassStorage.c"
+ 2 __SREG__ = 0x3f
+ 3 __SP_H__ = 0x3e
+ 4 __SP_L__ = 0x3d
+ 5 __CCP__ = 0x34
+ 6 __tmp_reg__ = 0
+ 7 __zero_reg__ = 1
+ 15 .Ltext0:
+ 16 .Letext0:
+DEFINED SYMBOLS
+ *ABS*:0000000000000000 MassStorage.c
+ /tmp/ccgRRIOC.s:2 *ABS*:000000000000003f __SREG__
+ /tmp/ccgRRIOC.s:3 *ABS*:000000000000003e __SP_H__
+ /tmp/ccgRRIOC.s:4 *ABS*:000000000000003d __SP_L__
+ /tmp/ccgRRIOC.s:5 *ABS*:0000000000000034 __CCP__
+ /tmp/ccgRRIOC.s:6 *ABS*:0000000000000000 __tmp_reg__
+ /tmp/ccgRRIOC.s:7 *ABS*:0000000000000001 __zero_reg__
+
+NO UNDEFINED SYMBOLS
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/MassStorage.o b/firmware/LUFA/Drivers/USB/Class/Host/MassStorage.o
new file mode 100644
index 0000000..8a2b34b
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/MassStorage.o
Binary files differ
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/Printer.c b/firmware/LUFA/Drivers/USB/Class/Host/Printer.c
new file mode 100644
index 0000000..ddcece8
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/Printer.c
@@ -0,0 +1,392 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define __INCLUDE_FROM_USB_DRIVER
+#include "../../HighLevel/USBMode.h"
+#if defined(USB_CAN_BE_HOST)
+
+#define __INCLUDE_FROM_PRINTER_DRIVER
+#define __INCLUDE_FROM_PRINTER_HOST_C
+#include "Printer.h"
+
+uint8_t PRNT_Host_ConfigurePipes(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
+ uint16_t ConfigDescriptorSize,
+ void* ConfigDescriptorData)
+{
+ USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
+ USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
+ USB_Descriptor_Interface_t* PrinterInterface = NULL;
+
+ memset(&PRNTInterfaceInfo->State, 0x00, sizeof(PRNTInterfaceInfo->State));
+
+ if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
+ return PRNT_ENUMERROR_InvalidConfigDescriptor;
+
+ while (!(DataINEndpoint) || !(DataOUTEndpoint))
+ {
+ if (!(PrinterInterface) ||
+ USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+ DCOMP_PRNT_Host_NextPRNTInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
+ {
+ if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+ DCOMP_PRNT_Host_NextPRNTInterface) != DESCRIPTOR_SEARCH_COMP_Found)
+ {
+ return PRNT_ENUMERROR_NoCompatibleInterfaceFound;
+ }
+
+ PrinterInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
+
+ DataINEndpoint = NULL;
+ DataOUTEndpoint = NULL;
+
+ continue;
+ }
+
+ USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
+
+ if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
+ DataINEndpoint = EndpointData;
+ else
+ DataOUTEndpoint = EndpointData;
+ }
+
+ for (uint8_t PipeNum = 1; PipeNum < PIPE_TOTAL_PIPES; PipeNum++)
+ {
+ if (PipeNum == PRNTInterfaceInfo->Config.DataINPipeNumber)
+ {
+ Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_IN,
+ DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize,
+ PRNTInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
+
+ PRNTInterfaceInfo->State.DataINPipeSize = DataINEndpoint->EndpointSize;
+ }
+ else if (PipeNum == PRNTInterfaceInfo->Config.DataOUTPipeNumber)
+ {
+ Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_OUT,
+ DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize,
+ PRNTInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
+
+ PRNTInterfaceInfo->State.DataOUTPipeSize = DataOUTEndpoint->EndpointSize;
+ }
+ }
+
+ PRNTInterfaceInfo->State.InterfaceNumber = PrinterInterface->InterfaceNumber;
+ PRNTInterfaceInfo->State.AlternateSetting = PrinterInterface->AlternateSetting;
+ PRNTInterfaceInfo->State.IsActive = true;
+
+ return PRNT_ENUMERROR_NoError;
+}
+
+static uint8_t DCOMP_PRNT_Host_NextPRNTInterface(void* 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 == PRNT_CSCP_PrinterClass) &&
+ (Interface->SubClass == PRNT_CSCP_PrinterSubclass) &&
+ (Interface->Protocol == PRNT_CSCP_BidirectionalProtocol))
+ {
+ return DESCRIPTOR_SEARCH_Found;
+ }
+ }
+
+ return DESCRIPTOR_SEARCH_NotFound;
+}
+
+static uint8_t DCOMP_PRNT_Host_NextPRNTInterfaceEndpoint(void* 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)
+ return DESCRIPTOR_SEARCH_Found;
+ }
+ else if (Header->Type == DTYPE_Interface)
+ {
+ return DESCRIPTOR_SEARCH_Fail;
+ }
+
+ return DESCRIPTOR_SEARCH_NotFound;
+}
+
+void PRNT_Host_USBTask(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
+ return;
+
+ #if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
+ PRNT_Host_Flush(PRNTInterfaceInfo);
+ #endif
+}
+
+uint8_t PRNT_Host_SetBidirectionalMode(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
+{
+ if (PRNTInterfaceInfo->State.AlternateSetting)
+ {
+ uint8_t ErrorCode;
+
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE),
+ .bRequest = REQ_SetInterface,
+ .wValue = PRNTInterfaceInfo->State.AlternateSetting,
+ .wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
+ .wLength = 0,
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+ if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
+ return ErrorCode;
+ }
+
+ return HOST_SENDCONTROL_Successful;
+}
+
+uint8_t PRNT_Host_GetPortStatus(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
+ uint8_t* const PortStatus)
+{
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = PRNT_REQ_GetPortStatus,
+ .wValue = 0,
+ .wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
+ .wLength = sizeof(uint8_t),
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+ return USB_Host_SendControlRequest(PortStatus);
+}
+
+uint8_t PRNT_Host_SoftReset(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
+{
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = PRNT_REQ_SoftReset,
+ .wValue = 0,
+ .wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
+ .wLength = 0,
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+ return USB_Host_SendControlRequest(NULL);
+}
+
+uint8_t PRNT_Host_Flush(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
+ return PIPE_READYWAIT_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipeNumber);
+ 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;
+}
+
+uint8_t PRNT_Host_SendByte(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
+ const uint8_t Data)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
+ return PIPE_READYWAIT_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipeNumber);
+ Pipe_Unfreeze();
+
+ if (!(Pipe_IsReadWriteAllowed()))
+ {
+ Pipe_ClearOUT();
+
+ if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError)
+ return ErrorCode;
+ }
+
+ Pipe_Write_Byte(Data);
+ Pipe_Freeze();
+
+ return PIPE_READYWAIT_NoError;
+}
+
+uint8_t PRNT_Host_SendString(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
+ void* Buffer,
+ const uint16_t Length)
+{
+ uint8_t ErrorCode;
+
+ if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
+ return PIPE_RWSTREAM_DeviceDisconnected;
+
+ Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipeNumber);
+ Pipe_Unfreeze();
+
+ if ((ErrorCode = Pipe_Write_Stream_LE(Buffer, Length, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ Pipe_ClearOUT();
+
+ ErrorCode = Pipe_WaitUntilReady();
+
+ Pipe_Freeze();
+
+ return ErrorCode;
+}
+
+uint16_t PRNT_Host_BytesReceived(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
+ return 0;
+
+ Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataINPipeNumber);
+ 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 PRNT_Host_ReceiveByte(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive))
+ return PIPE_RWSTREAM_DeviceDisconnected;
+
+ int16_t ReceivedByte = -1;
+
+ Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataINPipeNumber);
+ Pipe_Unfreeze();
+
+ if (Pipe_IsINReceived())
+ {
+ if (Pipe_BytesInPipe())
+ ReceivedByte = Pipe_Read_Byte();
+
+ if (!(Pipe_BytesInPipe()))
+ Pipe_ClearIN();
+ }
+
+ Pipe_Freeze();
+
+ return ReceivedByte;
+}
+
+uint8_t PRNT_Host_GetDeviceID(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
+ char* const DeviceIDString,
+ const uint16_t BufferSize)
+{
+ uint8_t ErrorCode = HOST_SENDCONTROL_Successful;
+ uint16_t DeviceIDStringLength = 0;
+
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = PRNT_REQ_GetDeviceID,
+ .wValue = 0,
+ .wIndex = PRNTInterfaceInfo->State.InterfaceNumber,
+ .wLength = sizeof(DeviceIDStringLength),
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+ if ((ErrorCode = USB_Host_SendControlRequest(&DeviceIDStringLength)) != HOST_SENDCONTROL_Successful)
+ return ErrorCode;
+
+ if (!(DeviceIDStringLength))
+ {
+ DeviceIDString[0] = 0x00;
+ return HOST_SENDCONTROL_Successful;
+ }
+
+ DeviceIDStringLength = SwapEndian_16(DeviceIDStringLength);
+
+ if (DeviceIDStringLength > BufferSize)
+ DeviceIDStringLength = BufferSize;
+
+ USB_ControlRequest.wLength = DeviceIDStringLength;
+
+ if ((ErrorCode = USB_Host_SendControlRequest(DeviceIDString)) != HOST_SENDCONTROL_Successful)
+ return ErrorCode;
+
+ memmove(&DeviceIDString[0], &DeviceIDString[2], DeviceIDStringLength - 2);
+
+ DeviceIDString[DeviceIDStringLength - 2] = 0x00;
+
+ return HOST_SENDCONTROL_Successful;
+}
+
+#endif
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/Printer.h b/firmware/LUFA/Drivers/USB/Class/Host/Printer.h
new file mode 100644
index 0000000..cc77e96
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/Printer.h
@@ -0,0 +1,282 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Host mode driver for the library USB Printer Class driver.
+ *
+ * Host mode driver for the library USB Printer 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_USBClassPrinter
+ * @defgroup Group_USBClassPrinterHost Printer 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/Printer.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ *
+ * \section Module Description
+ * Host Mode USB Class driver framework interface, for the Printer USB Class driver.
+ *
+ * @{
+ */
+
+#ifndef __PRINTER_CLASS_HOST_H__
+#define __PRINTER_CLASS_HOST_H__
+
+ /* Includes: */
+ #include "../../USB.h"
+ #include "../Common/Printer.h"
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_PRINTER_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ #if defined(__INCLUDE_FROM_PRINTER_HOST_C) && defined(NO_STREAM_CALLBACKS)
+ #error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
+ #endif
+
+ /* Public Interface - May be used in end-application: */
+ /* Type Defines: */
+ /** \brief Printer 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 Printer class driver functions as the PRNTInterfaceInfo parameter. This
+ * stores each Printer interface's configuration and state information.
+ */
+ typedef struct
+ {
+ const struct
+ {
+ uint8_t DataINPipeNumber; /**< Pipe number of the Printer interface's IN data pipe. */
+ bool DataINPipeDoubleBank; /**< Indicates if the Printer interface's IN data pipe should use double banking. */
+
+ uint8_t DataOUTPipeNumber; /**< Pipe number of the Printer interface's OUT data pipe. */
+ bool DataOUTPipeDoubleBank; /**< Indicates if the Printer interface's OUT data pipe should use double banking. */
+ } Config; /**< Config data for the USB class interface within the device. All elements in this section
+ * <b>must</b> 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 PRNT_Host_ConfigurePipes() is called and the Host state machine is in the
+ * Configured state.
+ */
+ uint8_t InterfaceNumber; /**< Interface index of the Printer interface within the attached device. */
+ uint8_t AlternateSetting; /**< Alternate setting within the Printer Interface in the attached device. */
+
+ uint16_t DataINPipeSize; /**< Size in bytes of the Printer interface's IN data pipe. */
+ uint16_t DataOUTPipeSize; /**< Size in bytes of the Printer interface's OUT data pipe. */
+ } State; /**< State data for the USB class interface within the device. All elements in this section
+ * <b>may</b> be set to initial values, but may also be ignored to default to sane values when
+ * the interface is enumerated.
+ */
+ } USB_ClassInfo_PRNT_Host_t;
+
+ /* Enums: */
+ enum PRNT_Host_EnumerationFailure_ErrorCodes_t
+ {
+ PRNT_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */
+ PRNT_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */
+ PRNT_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible Printer interface was not found in the device's Configuration Descriptor. */
+ };
+
+ /* Function Prototypes: */
+ /** General management task for a given Printer 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] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
+ */
+ void PRNT_Host_USBTask(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Host interface configuration routine, to configure a given Printer host interface instance using the
+ * Configuration Descriptor read from an attached USB device. This function automatically updates the given Printer
+ * 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.
+ *
+ * \note The pipe index numbers as given in the interface's configuration structure must not overlap with any other
+ * interface, or pipe bank corruption will occur. Gaps in the allocated pipe numbers or non-sequential indexes
+ * within a single interface is allowed, but no two interfaces of any type have have interleaved pipe indexes.
+ *
+ * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
+ * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor.
+ * \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor.
+ *
+ * \return A value from the \ref PRNT_Host_EnumerationFailure_ErrorCodes_t enum.
+ */
+ uint8_t PRNT_Host_ConfigurePipes(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
+ uint16_t ConfigDescriptorSize,
+ void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
+
+ /** Configures the printer to enable Bidirectional mode, if it is not already in this mode. This should be called
+ * once the connected device's configuration has been set, to ensure the printer is ready to accept commands.
+ *
+ * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
+ *
+ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
+ */
+ uint8_t PRNT_Host_SetBidirectionalMode(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Retrieves the status of the virtual Printer port's inbound status lines. The result can then be masked against the
+ * PRNT_PORTSTATUS_* macros to determine the printer port's status.
+ *
+ * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
+ * \param[out] PortStatus Location where the retrieved port status should be stored.
+ *
+ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
+ */
+ uint8_t PRNT_Host_GetPortStatus(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
+ uint8_t* const PortStatus)
+ ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+
+ /** Soft-resets the attached printer, readying it for new commands.
+ *
+ * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
+ *
+ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum.
+ */
+ uint8_t PRNT_Host_SoftReset(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) 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] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
+ *
+ * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum.
+ */
+ uint8_t PRNT_Host_Flush(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Sends the given raw data stream to the attached printer's input endpoint. This should contain commands that the
+ * printer is able to understand - for example, PCL data. Not all printers accept all printer languages; see
+ * \ref PRNT_Host_GetDeviceID() for details on determining acceptable languages for an attached printer.
+ *
+ * \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] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
+ * \param[in] Buffer Pointer to a buffer containing the raw command stream to send to the printer.
+ * \param[in] Length Size in bytes of the command stream to be sent.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t PRNT_Host_SendString(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
+ void* Buffer,
+ const uint16_t Length) 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 PRNT_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] PRNTInterfaceInfo Pointer to a structure containing a Printer 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 PRNT_Host_SendByte(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
+ const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Determines the number of bytes received by the printer 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 PRNT_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] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
+ *
+ * \return Total number of buffered bytes received from the device.
+ */
+ uint16_t PRNT_Host_BytesReceived(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo);
+
+ /** 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 PRNT_Host_BytesReceived() function may be queried in advance to determine how many bytes
+ * are currently buffered in the Printer 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] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
+ *
+ * \return Next received byte from the device, or a negative value if no data received.
+ */
+ int16_t PRNT_Host_ReceiveByte(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo);
+
+ /** Retrieves the attached printer device's ID string, formatted according to IEEE 1284. This string is sent as a
+ * Unicode string from the device and is automatically converted to an ASCII encoded C string by this function, thus
+ * the maximum reportable string length is two less than the size given (to accommodate the Unicode string length
+ * bytes which are removed).
+ *
+ * This string, when supported, contains the model, manufacturer and acceptable printer languages for the attached device.
+ *
+ * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state.
+ * \param[out] DeviceIDString Pointer to a buffer where the Device ID string should be stored, in ASCII format.
+ * \param[in] BufferSize Size in bytes of the buffer allocated for the Device ID string.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t PRNT_Host_GetDeviceID(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo,
+ char* const DeviceIDString,
+ const uint16_t BufferSize) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+
+ /* Private Interface - For use in library only: */
+ #if !defined(__DOXYGEN__)
+ /* Function Prototypes: */
+ #if defined(__INCLUDE_FROM_PRINTER_HOST_C)
+ static uint8_t DCOMP_PRNT_Host_NextPRNTInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
+ static uint8_t DCOMP_PRNT_Host_NextPRNTInterfaceEndpoint(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
+ #endif
+ #endif
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/Printer.lst b/firmware/LUFA/Drivers/USB/Class/Host/Printer.lst
new file mode 100644
index 0000000..6e74140
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/Printer.lst
@@ -0,0 +1,19 @@
+ 1 .file "Printer.c"
+ 2 __SREG__ = 0x3f
+ 3 __SP_H__ = 0x3e
+ 4 __SP_L__ = 0x3d
+ 5 __CCP__ = 0x34
+ 6 __tmp_reg__ = 0
+ 7 __zero_reg__ = 1
+ 15 .Ltext0:
+ 16 .Letext0:
+DEFINED SYMBOLS
+ *ABS*:0000000000000000 Printer.c
+ /tmp/cchSsxeH.s:2 *ABS*:000000000000003f __SREG__
+ /tmp/cchSsxeH.s:3 *ABS*:000000000000003e __SP_H__
+ /tmp/cchSsxeH.s:4 *ABS*:000000000000003d __SP_L__
+ /tmp/cchSsxeH.s:5 *ABS*:0000000000000034 __CCP__
+ /tmp/cchSsxeH.s:6 *ABS*:0000000000000000 __tmp_reg__
+ /tmp/cchSsxeH.s:7 *ABS*:0000000000000001 __zero_reg__
+
+NO UNDEFINED SYMBOLS
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/Printer.o b/firmware/LUFA/Drivers/USB/Class/Host/Printer.o
new file mode 100644
index 0000000..400656d
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/Printer.o
Binary files differ
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/RNDIS.c b/firmware/LUFA/Drivers/USB/Class/Host/RNDIS.c
new file mode 100644
index 0000000..11f7d9e
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/RNDIS.c
@@ -0,0 +1,480 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define __INCLUDE_FROM_USB_DRIVER
+#include "../../HighLevel/USBMode.h"
+#if defined(USB_CAN_BE_HOST)
+
+#define __INCLUDE_FROM_RNDIS_DRIVER
+#define __INCLUDE_FROM_RNDIS_HOST_C
+#include "RNDIS.h"
+
+uint8_t RNDIS_Host_ConfigurePipes(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
+ uint16_t ConfigDescriptorSize,
+ void* ConfigDescriptorData)
+{
+ USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
+ USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
+ USB_Descriptor_Endpoint_t* NotificationEndpoint = NULL;
+ USB_Descriptor_Interface_t* RNDISControlInterface = NULL;
+
+ memset(&RNDISInterfaceInfo->State, 0x00, sizeof(RNDISInterfaceInfo->State));
+
+ if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
+ return RNDIS_ENUMERROR_InvalidConfigDescriptor;
+
+ RNDISControlInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
+
+ while (!(DataINEndpoint) || !(DataOUTEndpoint) || !(NotificationEndpoint))
+ {
+ if (!(RNDISControlInterface) ||
+ USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+ DCOMP_RNDIS_Host_NextRNDISInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
+ {
+ if (NotificationEndpoint)
+ {
+ if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+ DCOMP_RNDIS_Host_NextRNDISDataInterface) != DESCRIPTOR_SEARCH_COMP_Found)
+ {
+ return RNDIS_ENUMERROR_NoCompatibleInterfaceFound;
+ }
+
+ DataINEndpoint = NULL;
+ DataOUTEndpoint = NULL;
+ }
+ else
+ {
+ if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+ DCOMP_RNDIS_Host_NextRNDISControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
+ {
+ return RNDIS_ENUMERROR_NoCompatibleInterfaceFound;
+ }
+
+ RNDISControlInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
+
+ NotificationEndpoint = NULL;
+ }
+
+ continue;
+ }
+
+ USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
+
+ if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
+ {
+ if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
+ NotificationEndpoint = EndpointData;
+ else
+ DataINEndpoint = EndpointData;
+ }
+ else
+ {
+ DataOUTEndpoint = EndpointData;
+ }
+ }
+
+ for (uint8_t PipeNum = 1; PipeNum < PIPE_TOTAL_PIPES; PipeNum++)
+ {
+ if (PipeNum == RNDISInterfaceInfo->Config.DataINPipeNumber)
+ {
+ Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_IN,
+ DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize,
+ RNDISInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
+
+ RNDISInterfaceInfo->State.DataINPipeSize = DataINEndpoint->EndpointSize;
+ }
+ else if (PipeNum == RNDISInterfaceInfo->Config.DataOUTPipeNumber)
+ {
+ Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_OUT,
+ DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize,
+ RNDISInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
+
+ RNDISInterfaceInfo->State.DataOUTPipeSize = DataOUTEndpoint->EndpointSize;
+ }
+ else if (PipeNum == RNDISInterfaceInfo->Config.NotificationPipeNumber)
+ {
+ Pipe_ConfigurePipe(PipeNum, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
+ NotificationEndpoint->EndpointAddress, NotificationEndpoint->EndpointSize,
+ RNDISInterfaceInfo->Config.NotificationPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
+ Pipe_SetInterruptPeriod(NotificationEndpoint->PollingIntervalMS);
+
+ RNDISInterfaceInfo->State.NotificationPipeSize = NotificationEndpoint->EndpointSize;
+ }
+ }
+
+ RNDISInterfaceInfo->State.ControlInterfaceNumber = RNDISControlInterface->InterfaceNumber;
+ RNDISInterfaceInfo->State.IsActive = true;
+
+ return RNDIS_ENUMERROR_NoError;
+}
+
+static uint8_t DCOMP_RNDIS_Host_NextRNDISControlInterface(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 == CDC_CSCP_CDCClass) &&
+ (Interface->SubClass == CDC_CSCP_ACMSubclass) &&
+ (Interface->Protocol == CDC_CSCP_VendorSpecificProtocol))
+ {
+ return DESCRIPTOR_SEARCH_Found;
+ }
+ }
+
+ return DESCRIPTOR_SEARCH_NotFound;
+}
+
+static uint8_t DCOMP_RNDIS_Host_NextRNDISDataInterface(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 == CDC_CSCP_CDCDataClass) &&
+ (Interface->SubClass == CDC_CSCP_NoDataSubclass) &&
+ (Interface->Protocol == CDC_CSCP_NoDataProtocol))
+ {
+ return DESCRIPTOR_SEARCH_Found;
+ }
+ }
+
+ return DESCRIPTOR_SEARCH_NotFound;
+}
+
+static uint8_t DCOMP_RNDIS_Host_NextRNDISInterfaceEndpoint(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) || (EndpointType == EP_TYPE_INTERRUPT)) &&
+ !(Pipe_IsEndpointBound(Endpoint->EndpointAddress)))
+ {
+ return DESCRIPTOR_SEARCH_Found;
+ }
+ }
+ else if (Header->Type == DTYPE_Interface)
+ {
+ return DESCRIPTOR_SEARCH_Fail;
+ }
+
+ return DESCRIPTOR_SEARCH_NotFound;
+}
+
+static uint8_t RNDIS_SendEncapsulatedCommand(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
+ void* Buffer,
+ const uint16_t Length)
+{
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = RNDIS_REQ_SendEncapsulatedCommand,
+ .wValue = 0,
+ .wIndex = RNDISInterfaceInfo->State.ControlInterfaceNumber,
+ .wLength = Length,
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+ return USB_Host_SendControlRequest(Buffer);
+}
+
+static uint8_t RNDIS_GetEncapsulatedResponse(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
+ void* Buffer,
+ const uint16_t Length)
+{
+ USB_ControlRequest = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = RNDIS_REQ_GetEncapsulatedResponse,
+ .wValue = 0,
+ .wIndex = RNDISInterfaceInfo->State.ControlInterfaceNumber,
+ .wLength = Length,
+ };
+
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);
+ return USB_Host_SendControlRequest(Buffer);
+}
+
+uint8_t RNDIS_Host_SendKeepAlive(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo)
+{
+ uint8_t ErrorCode;
+
+ RNDIS_KeepAlive_Message_t KeepAliveMessage;
+ RNDIS_KeepAlive_Complete_t KeepAliveMessageResponse;
+
+ KeepAliveMessage.MessageType = REMOTE_NDIS_KEEPALIVE_MSG;
+ KeepAliveMessage.MessageLength = sizeof(RNDIS_KeepAlive_Message_t);
+ KeepAliveMessage.RequestId = RNDISInterfaceInfo->State.RequestID++;
+
+ if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &KeepAliveMessage,
+ sizeof(RNDIS_KeepAlive_Message_t))) != HOST_SENDCONTROL_Successful)
+ {
+ return ErrorCode;
+ }
+
+ if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &KeepAliveMessageResponse,
+ sizeof(RNDIS_KeepAlive_Complete_t))) != HOST_SENDCONTROL_Successful)
+ {
+ return ErrorCode;
+ }
+
+ return HOST_SENDCONTROL_Successful;
+}
+
+uint8_t RNDIS_Host_InitializeDevice(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo)
+{
+ uint8_t ErrorCode;
+
+ RNDIS_Initialize_Message_t InitMessage;
+ RNDIS_Initialize_Complete_t InitMessageResponse;
+
+ InitMessage.MessageType = REMOTE_NDIS_INITIALIZE_MSG;
+ InitMessage.MessageLength = sizeof(RNDIS_Initialize_Message_t);
+ InitMessage.RequestId = RNDISInterfaceInfo->State.RequestID++;
+
+ InitMessage.MajorVersion = REMOTE_NDIS_VERSION_MAJOR;
+ InitMessage.MinorVersion = REMOTE_NDIS_VERSION_MINOR;
+ InitMessage.MaxTransferSize = RNDISInterfaceInfo->Config.HostMaxPacketSize;
+
+ if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &InitMessage,
+ sizeof(RNDIS_Initialize_Message_t))) != HOST_SENDCONTROL_Successful)
+ {
+ return ErrorCode;
+ }
+
+ if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &InitMessageResponse,
+ sizeof(RNDIS_Initialize_Complete_t))) != HOST_SENDCONTROL_Successful)
+ {
+ return ErrorCode;
+ }
+
+ if (InitMessageResponse.Status != REMOTE_NDIS_STATUS_SUCCESS)
+ return RNDIS_COMMAND_FAILED;
+
+ RNDISInterfaceInfo->State.DeviceMaxPacketSize = InitMessageResponse.MaxTransferSize;
+
+ return HOST_SENDCONTROL_Successful;
+}
+
+uint8_t RNDIS_Host_SetRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
+ const uint32_t Oid,
+ void* Buffer,
+ const uint16_t Length)
+{
+ uint8_t ErrorCode;
+
+ struct
+ {
+ RNDIS_Set_Message_t SetMessage;
+ uint8_t ContiguousBuffer[Length];
+ } SetMessageData;
+
+ RNDIS_Set_Complete_t SetMessageResponse;
+
+ SetMessageData.SetMessage.MessageType = REMOTE_NDIS_SET_MSG;
+ SetMessageData.SetMessage.MessageLength = sizeof(RNDIS_Set_Message_t) + Length;
+ SetMessageData.SetMessage.RequestId = RNDISInterfaceInfo->State.RequestID++;
+
+ SetMessageData.SetMessage.Oid = Oid;
+ SetMessageData.SetMessage.InformationBufferLength = Length;
+ SetMessageData.SetMessage.InformationBufferOffset = (sizeof(RNDIS_Set_Message_t) - sizeof(RNDIS_Message_Header_t));
+ SetMessageData.SetMessage.DeviceVcHandle = 0;
+
+ memcpy(&SetMessageData.ContiguousBuffer, Buffer, Length);
+
+ if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &SetMessageData,
+ SetMessageData.SetMessage.MessageLength)) != HOST_SENDCONTROL_Successful)
+ {
+ return ErrorCode;
+ }
+
+ if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &SetMessageResponse,
+ sizeof(RNDIS_Set_Complete_t))) != HOST_SENDCONTROL_Successful)
+ {
+ return ErrorCode;
+ }
+
+ if (SetMessageResponse.Status != REMOTE_NDIS_STATUS_SUCCESS)
+ return RNDIS_COMMAND_FAILED;
+
+ return HOST_SENDCONTROL_Successful;
+}
+
+uint8_t RNDIS_Host_QueryRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
+ const uint32_t Oid,
+ void* Buffer,
+ const uint16_t MaxLength)
+{
+ uint8_t ErrorCode;
+
+ RNDIS_Query_Message_t QueryMessage;
+
+ struct
+ {
+ RNDIS_Query_Complete_t QueryMessageResponse;
+ uint8_t ContiguousBuffer[MaxLength];
+ } QueryMessageResponseData;
+
+ QueryMessage.MessageType = REMOTE_NDIS_QUERY_MSG;
+ QueryMessage.MessageLength = sizeof(RNDIS_Query_Message_t);
+ QueryMessage.RequestId = RNDISInterfaceInfo->State.RequestID++;
+
+ QueryMessage.Oid = Oid;
+ QueryMessage.InformationBufferLength = 0;
+ QueryMessage.InformationBufferOffset = 0;
+ QueryMessage.DeviceVcHandle = 0;
+
+ if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &QueryMessage,
+ sizeof(RNDIS_Query_Message_t))) != HOST_SENDCONTROL_Successful)
+ {
+ return ErrorCode;
+ }
+
+ if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &QueryMessageResponseData,
+ sizeof(QueryMessageResponseData))) != HOST_SENDCONTROL_Successful)
+ {
+ return ErrorCode;
+ }
+
+ if (QueryMessageResponseData.QueryMessageResponse.Status != REMOTE_NDIS_STATUS_SUCCESS)
+ return RNDIS_COMMAND_FAILED;
+
+ memcpy(Buffer, &QueryMessageResponseData.ContiguousBuffer, MaxLength);
+
+ return HOST_SENDCONTROL_Successful;
+}
+
+bool RNDIS_Host_IsPacketReceived(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo)
+{
+ bool PacketWaiting;
+
+ if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive))
+ return false;
+
+ Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataINPipeNumber);
+
+ Pipe_Unfreeze();
+ PacketWaiting = Pipe_IsINReceived();
+ Pipe_Freeze();
+
+ return PacketWaiting;
+}
+
+uint8_t RNDIS_Host_ReadPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
+ void* Buffer,
+ uint16_t* const PacketLength)
+{
+ uint8_t ErrorCode;
+
+ if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive))
+ return PIPE_READYWAIT_DeviceDisconnected;
+
+ Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataINPipeNumber);
+ Pipe_Unfreeze();
+
+ if (!(Pipe_IsReadWriteAllowed()))
+ {
+ if (Pipe_IsINReceived())
+ Pipe_ClearIN();
+
+ *PacketLength = 0;
+ Pipe_Freeze();
+ return PIPE_RWSTREAM_NoError;
+ }
+
+ RNDIS_Packet_Message_t DeviceMessage;
+
+ if ((ErrorCode = Pipe_Read_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t),
+ NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
+ {
+ return ErrorCode;
+ }
+
+ *PacketLength = (uint16_t)DeviceMessage.DataLength;
+
+ Pipe_Discard_Stream(DeviceMessage.DataOffset - (sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t)),
+ NO_STREAM_CALLBACK);
+
+ Pipe_Read_Stream_LE(Buffer, *PacketLength, NO_STREAM_CALLBACK);
+
+ if (!(Pipe_BytesInPipe()))
+ Pipe_ClearIN();
+
+ Pipe_Freeze();
+
+ return PIPE_RWSTREAM_NoError;
+}
+
+uint8_t RNDIS_Host_SendPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
+ void* Buffer,
+ const uint16_t PacketLength)
+{
+ uint8_t ErrorCode;
+
+ if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive))
+ return PIPE_READYWAIT_DeviceDisconnected;
+
+ RNDIS_Packet_Message_t DeviceMessage;
+
+ memset(&DeviceMessage, 0, sizeof(RNDIS_Packet_Message_t));
+ DeviceMessage.MessageType = REMOTE_NDIS_PACKET_MSG;
+ DeviceMessage.MessageLength = (sizeof(RNDIS_Packet_Message_t) + PacketLength);
+ DeviceMessage.DataOffset = (sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t));
+ DeviceMessage.DataLength = PacketLength;
+
+ Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataOUTPipeNumber);
+ Pipe_Unfreeze();
+
+ if ((ErrorCode = Pipe_Write_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t),
+ NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
+ {
+ return ErrorCode;
+ }
+
+ Pipe_Write_Stream_LE(Buffer, PacketLength, NO_STREAM_CALLBACK);
+ Pipe_ClearOUT();
+
+ Pipe_Freeze();
+
+ return PIPE_RWSTREAM_NoError;
+}
+
+#endif
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/RNDIS.h b/firmware/LUFA/Drivers/USB/Class/Host/RNDIS.h
new file mode 100644
index 0000000..611e59e
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/RNDIS.h
@@ -0,0 +1,290 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Host mode driver for the library USB RNDIS Class driver.
+ *
+ * Host mode driver for the library USB RNDIS 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_USBClassRNDIS
+ * @defgroup Group_USBClassRNDISHost RNDIS 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/RNDIS.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ *
+ * \section Module Description
+ * Host Mode USB Class driver framework interface, for the Microsoft RNDIS Ethernet
+ * USB Class driver.
+ *
+ * @{
+ */
+
+#ifndef __RNDIS_CLASS_HOST_H__
+#define __RNDIS_CLASS_HOST_H__
+
+ /* Includes: */
+ #include "../../USB.h"
+ #include "../Common/RNDIS.h"
+
+ #include <stdio.h>
+ #include <string.h>
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_RNDIS_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ #if defined(__INCLUDE_FROM_RNDIS_HOST_C) && defined(NO_STREAM_CALLBACKS)
+ #error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
+ #endif
+
+ /* Public Interface - May be used in end-application: */
+ /* Type Defines: */
+ /** \brief RNDIS 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 RNDIS class driver functions as the RNDISInterfaceInfo parameter. This
+ * stores each RNDIS interface's configuration and state information.
+ */
+ typedef struct
+ {
+ const struct
+ {
+ uint8_t DataINPipeNumber; /**< Pipe number of the RNDIS interface's IN data pipe. */
+ bool DataINPipeDoubleBank; /**< Indicates if the RNDIS interface's IN data pipe should use double banking. */
+
+ uint8_t DataOUTPipeNumber; /**< Pipe number of the RNDIS interface's OUT data pipe. */
+ bool DataOUTPipeDoubleBank; /**< Indicates if the RNDIS interface's OUT data pipe should use double banking. */
+
+ uint8_t NotificationPipeNumber; /**< Pipe number of the RNDIS interface's IN notification endpoint, if used. */
+ bool NotificationPipeDoubleBank; /**< Indicates if the RNDIS interface's notification pipe should use double banking. */
+
+ uint32_t HostMaxPacketSize; /**< Maximum size of a packet which can be buffered by the host. */
+ } Config; /**< Config data for the USB class interface within the device. All elements in this section
+ * <b>must</b> 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 RNDIS_Host_ConfigurePipes() is called and the Host state machine is in the
+ * Configured state.
+ */
+ uint8_t ControlInterfaceNumber; /**< Interface index of the RNDIS control interface within the attached device. */
+
+ uint16_t DataINPipeSize; /**< Size in bytes of the RNDIS interface's IN data pipe. */
+ uint16_t DataOUTPipeSize; /**< Size in bytes of the RNDIS interface's OUT data pipe. */
+ uint16_t NotificationPipeSize; /**< Size in bytes of the RNDIS interface's IN notification pipe, if used. */
+
+ uint32_t DeviceMaxPacketSize; /**< Maximum size of a packet which can be buffered by the attached RNDIS device. */
+
+ uint32_t RequestID; /**< Request ID counter to give a unique ID for each command/response pair. */
+ } State; /**< State data for the USB class interface within the device. All elements in this section
+ * <b>may</b> be set to initial values, but may also be ignored to default to sane values when
+ * the interface is enumerated.
+ */
+ } USB_ClassInfo_RNDIS_Host_t;
+
+ /* Enums: */
+ /** Enum for the possible error codes returned by the \ref RNDIS_Host_ConfigurePipes() function. */
+ enum RNDIS_Host_EnumerationFailure_ErrorCodes_t
+ {
+ RNDIS_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */
+ RNDIS_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */
+ RNDIS_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible RNDIS interface was not found in the device's Configuration Descriptor. */
+ };
+
+ /* Macros: */
+ /** Additional error code for RNDIS functions when a device returns a logical command failure. */
+ #define RNDIS_COMMAND_FAILED 0xC0
+
+ /* Function Prototypes: */
+ /** Host interface configuration routine, to configure a given RNDIS host interface instance using the Configuration
+ * Descriptor read from an attached USB device. This function automatically updates the given RNDIS 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.
+ *
+ * \note The pipe index numbers as given in the interface's configuration structure must not overlap with any other
+ * interface, or pipe bank corruption will occur. Gaps in the allocated pipe numbers or non-sequential indexes
+ * within a single interface is allowed, but no two interfaces of any type have have interleaved pipe indexes.
+ *
+ * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state.
+ * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor.
+ * \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor.
+ *
+ * \return A value from the \ref RNDIS_Host_EnumerationFailure_ErrorCodes_t enum.
+ */
+ uint8_t RNDIS_Host_ConfigurePipes(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
+ uint16_t ConfigDescriptorSize,
+ void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
+
+ /** Sends a RNDIS KEEPALIVE command to the device, to ensure that it does not enter standby mode after periods
+ * of long inactivity.
+ *
+ * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state.
+ *
+ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_COMMAND_FAILED if the device returned a
+ * logical command failure.
+ */
+ uint8_t RNDIS_Host_SendKeepAlive(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Initialises the attached RNDIS device's RNDIS interface. This should be called after the device's pipes have been
+ * configured via the call to \ref RNDIS_Host_ConfigurePipes().
+ *
+ * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state.
+ *
+ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_COMMAND_FAILED if the device returned a
+ * logical command failure.
+ */
+ uint8_t RNDIS_Host_InitializeDevice(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Sets a given RNDIS property of an attached RNDIS device.
+ *
+ * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state.
+ * \param[in] Oid OID number of the parameter to set.
+ * \param[in] Buffer Pointer to where the property data is to be sourced from.
+ * \param[in] Length Length in bytes of the property data to sent to the device.
+ *
+ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_COMMAND_FAILED if the device returned a
+ * logical command failure.
+ */
+ uint8_t RNDIS_Host_SetRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
+ const uint32_t Oid,
+ void* Buffer,
+ const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
+
+ /** Gets a given RNDIS property of an attached RNDIS device.
+ *
+ * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state.
+ * \param[in] Oid OID number of the parameter to get.
+ * \param[in] Buffer Pointer to where the property data is to be written to.
+ * \param[in] MaxLength Length in bytes of the destination buffer size.
+ *
+ * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_COMMAND_FAILED if the device returned a
+ * logical command failure.
+ */
+ uint8_t RNDIS_Host_QueryRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
+ const uint32_t Oid,
+ void* Buffer,
+ const uint16_t MaxLength) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
+
+ /** Determines if a packet is currently waiting for the host to read in and process.
+ *
+ * \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] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state.
+ *
+ * \return Boolean true if a packet is waiting to be read in by the host, false otherwise.
+ */
+ bool RNDIS_Host_IsPacketReceived(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Retrieves the next pending packet from the device, discarding the remainder of the RNDIS packet header to leave
+ * only the packet contents for processing by the host in the nominated buffer.
+ *
+ * \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] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state.
+ * \param[out] Buffer Pointer to a buffer where the packer data is to be written to.
+ * \param[out] PacketLength Pointer to where the length in bytes of the read packet is to be stored.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t RNDIS_Host_ReadPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
+ void* Buffer,
+ uint16_t* const PacketLength) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2)
+ ATTR_NON_NULL_PTR_ARG(3);
+
+ /** Sends the given packet to the attached RNDIS device, after adding a RNDIS packet message header.
+ *
+ * \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] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state.
+ * \param[in] Buffer Pointer to a buffer where the packer data is to be read from.
+ * \param[in] PacketLength Length in bytes of the packet to send.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t RNDIS_Host_SendPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
+ void* Buffer,
+ const uint16_t PacketLength) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+
+ /* Inline Functions: */
+ /** General management task for a given RNDIS 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] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state.
+ */
+ static inline void RNDIS_Host_USBTask(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+ static inline void RNDIS_Host_USBTask(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo)
+ {
+ (void)RNDISInterfaceInfo;
+ }
+
+ /* Private Interface - For use in library only: */
+ #if !defined(__DOXYGEN__)
+ /* Function Prototypes: */
+ #if defined(__INCLUDE_FROM_RNDIS_HOST_C)
+ static uint8_t RNDIS_SendEncapsulatedCommand(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
+ void* Buffer,
+ const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1)
+ ATTR_NON_NULL_PTR_ARG(2);
+ static uint8_t RNDIS_GetEncapsulatedResponse(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo,
+ void* Buffer,
+ const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1)
+ ATTR_NON_NULL_PTR_ARG(2);
+
+ static uint8_t DCOMP_RNDIS_Host_NextRNDISControlInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
+ static uint8_t DCOMP_RNDIS_Host_NextRNDISDataInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
+ static uint8_t DCOMP_RNDIS_Host_NextRNDISInterfaceEndpoint(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
+ #endif
+ #endif
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/RNDIS.lst b/firmware/LUFA/Drivers/USB/Class/Host/RNDIS.lst
new file mode 100644
index 0000000..9dfa2cb
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/RNDIS.lst
@@ -0,0 +1,19 @@
+ 1 .file "RNDIS.c"
+ 2 __SREG__ = 0x3f
+ 3 __SP_H__ = 0x3e
+ 4 __SP_L__ = 0x3d
+ 5 __CCP__ = 0x34
+ 6 __tmp_reg__ = 0
+ 7 __zero_reg__ = 1
+ 15 .Ltext0:
+ 16 .Letext0:
+DEFINED SYMBOLS
+ *ABS*:0000000000000000 RNDIS.c
+ /tmp/ccQYGsRG.s:2 *ABS*:000000000000003f __SREG__
+ /tmp/ccQYGsRG.s:3 *ABS*:000000000000003e __SP_H__
+ /tmp/ccQYGsRG.s:4 *ABS*:000000000000003d __SP_L__
+ /tmp/ccQYGsRG.s:5 *ABS*:0000000000000034 __CCP__
+ /tmp/ccQYGsRG.s:6 *ABS*:0000000000000000 __tmp_reg__
+ /tmp/ccQYGsRG.s:7 *ABS*:0000000000000001 __zero_reg__
+
+NO UNDEFINED SYMBOLS
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/RNDIS.o b/firmware/LUFA/Drivers/USB/Class/Host/RNDIS.o
new file mode 100644
index 0000000..63b9e84
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/RNDIS.o
Binary files differ
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/StillImage.c b/firmware/LUFA/Drivers/USB/Class/Host/StillImage.c
new file mode 100644
index 0000000..7b31e10
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/StillImage.c
@@ -0,0 +1,443 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define __INCLUDE_FROM_USB_DRIVER
+#include "../../HighLevel/USBMode.h"
+#if defined(USB_CAN_BE_HOST)
+
+#define __INCLUDE_FROM_SI_DRIVER
+#define __INCLUDE_FROM_STILLIMAGE_HOST_C
+#include "StillImage.h"
+
+uint8_t SI_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
+ uint16_t ConfigDescriptorSize,
+ void* ConfigDescriptorData)
+{
+ USB_Descriptor_Endpoint_t* DataINEndpoint = NULL;
+ USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL;
+ USB_Descriptor_Endpoint_t* EventsEndpoint = NULL;
+ USB_Descriptor_Interface_t* StillImageInterface = NULL;
+
+ memset(&SIInterfaceInfo->State, 0x00, sizeof(SIInterfaceInfo->State));
+
+ if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
+ return SI_ENUMERROR_InvalidConfigDescriptor;
+
+ while (!(DataINEndpoint) || !(DataOUTEndpoint))
+ {
+ if (!(StillImageInterface) ||
+ USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+ DCOMP_SI_Host_NextSIInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
+ {
+ if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+ DCOMP_SI_Host_NextSIInterface) != DESCRIPTOR_SEARCH_COMP_Found)
+ {
+ return SI_ENUMERROR_NoCompatibleInterfaceFound;
+ }
+
+ StillImageInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
+
+ DataINEndpoint = NULL;
+ DataOUTEndpoint = NULL;
+ EventsEndpoint = NULL;
+
+ continue;
+ }
+
+ USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
+
+ if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
+ {
+ if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT)
+ EventsEndpoint = EndpointData;
+ else
+ DataINEndpoint = EndpointData;
+ }
+ else
+ {
+ DataOUTEndpoint = EndpointData;
+ }
+ }
+
+ for (uint8_t PipeNum = 1; PipeNum < PIPE_TOTAL_PIPES; PipeNum++)
+ {
+ if (PipeNum == SIInterfaceInfo->Config.DataINPipeNumber)
+ {
+ Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_IN,
+ DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize,
+ SIInterfaceInfo->Config.DataINPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
+
+ SIInterfaceInfo->State.DataINPipeSize = DataINEndpoint->EndpointSize;
+ }
+ else if (PipeNum == SIInterfaceInfo->Config.DataOUTPipeNumber)
+ {
+ Pipe_ConfigurePipe(PipeNum, EP_TYPE_BULK, PIPE_TOKEN_OUT,
+ DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize,
+ SIInterfaceInfo->Config.DataOUTPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
+
+ SIInterfaceInfo->State.DataOUTPipeSize = DataOUTEndpoint->EndpointSize;
+ }
+ else if (PipeNum == SIInterfaceInfo->Config.EventsPipeNumber)
+ {
+ Pipe_ConfigurePipe(PipeNum, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
+ EventsEndpoint->EndpointAddress, EventsEndpoint->EndpointSize,
+ SIInterfaceInfo->Config.EventsPipeDoubleBank ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE);
+ Pipe_SetInterruptPeriod(EventsEndpoint->PollingIntervalMS);
+
+ SIInterfaceInfo->State.EventsPipeSize = EventsEndpoint->EndpointSize;
+ }
+ }
+
+ SIInterfaceInfo->State.InterfaceNumber = StillImageInterface->InterfaceNumber;
+ SIInterfaceInfo->State.IsActive = true;
+
+ return SI_ENUMERROR_NoError;
+}
+
+uint8_t DCOMP_SI_Host_NextSIInterface(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 == SI_CSCP_StillImageClass) &&
+ (Interface->SubClass == SI_CSCP_StillImageSubclass) &&
+ (Interface->Protocol == SI_CSCP_BulkOnlyProtocol))
+ {
+ return DESCRIPTOR_SEARCH_Found;
+ }
+ }
+
+ return DESCRIPTOR_SEARCH_NotFound;
+}
+
+uint8_t DCOMP_SI_Host_NextSIInterfaceEndpoint(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) || (EndpointType == EP_TYPE_INTERRUPT)) &&
+ (!(Pipe_IsEndpointBound(Endpoint->EndpointAddress))))
+ {
+ return DESCRIPTOR_SEARCH_Found;
+ }
+ }
+ else if (Header->Type == DTYPE_Interface)
+ {
+ return DESCRIPTOR_SEARCH_Fail;
+ }
+
+ return DESCRIPTOR_SEARCH_NotFound;
+}
+
+uint8_t SI_Host_SendBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
+ PIMA_Container_t* const PIMAHeader)
+{
+ uint8_t ErrorCode;
+
+ if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
+ return PIPE_RWSTREAM_DeviceDisconnected;
+
+ if (SIInterfaceInfo->State.IsSessionOpen)
+ PIMAHeader->TransactionID = SIInterfaceInfo->State.TransactionID++;
+
+ Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipeNumber);
+ Pipe_Unfreeze();
+
+ if ((ErrorCode = Pipe_Write_Stream_LE(PIMAHeader, PIMA_COMMAND_SIZE(0), NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ uint8_t ParamBytes = (PIMAHeader->DataLength - PIMA_COMMAND_SIZE(0));
+
+ if (ParamBytes)
+ {
+ if ((ErrorCode = Pipe_Write_Stream_LE(&PIMAHeader->Params, ParamBytes, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+ }
+
+ Pipe_ClearOUT();
+ Pipe_Freeze();
+
+ return PIPE_RWSTREAM_NoError;
+}
+
+uint8_t SI_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
+ PIMA_Container_t* const PIMAHeader)
+{
+ uint16_t TimeoutMSRem = SI_COMMAND_DATA_TIMEOUT_MS;
+ uint16_t PreviousFrameNumber = USB_Host_GetFrameNumber();
+
+ if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
+ return PIPE_RWSTREAM_DeviceDisconnected;
+
+ Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipeNumber);
+ Pipe_Unfreeze();
+
+ while (!(Pipe_IsINReceived()))
+ {
+ uint16_t CurrentFrameNumber = USB_Host_GetFrameNumber();
+
+ if (CurrentFrameNumber != PreviousFrameNumber)
+ {
+ PreviousFrameNumber = CurrentFrameNumber;
+
+ if (!(TimeoutMSRem--))
+ return PIPE_RWSTREAM_Timeout;
+ }
+
+ Pipe_Freeze();
+ Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipeNumber);
+ Pipe_Unfreeze();
+
+ if (Pipe_IsStalled())
+ {
+ USB_Host_ClearPipeStall(SIInterfaceInfo->Config.DataOUTPipeNumber);
+ return PIPE_RWSTREAM_PipeStalled;
+ }
+
+ Pipe_Freeze();
+ Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipeNumber);
+ Pipe_Unfreeze();
+
+ if (Pipe_IsStalled())
+ {
+ USB_Host_ClearPipeStall(SIInterfaceInfo->Config.DataINPipeNumber);
+ return PIPE_RWSTREAM_PipeStalled;
+ }
+
+ if (USB_HostState == HOST_STATE_Unattached)
+ return PIPE_RWSTREAM_DeviceDisconnected;
+ }
+
+ Pipe_Read_Stream_LE(PIMAHeader, PIMA_COMMAND_SIZE(0), NO_STREAM_CALLBACK);
+
+ if (PIMAHeader->Type == PIMA_CONTAINER_ResponseBlock)
+ {
+ uint8_t ParamBytes = (PIMAHeader->DataLength - PIMA_COMMAND_SIZE(0));
+
+ if (ParamBytes)
+ Pipe_Read_Stream_LE(&PIMAHeader->Params, ParamBytes, NO_STREAM_CALLBACK);
+
+ Pipe_ClearIN();
+ }
+
+ Pipe_Freeze();
+
+ return PIPE_RWSTREAM_NoError;
+}
+
+uint8_t SI_Host_SendData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
+ void* Buffer,
+ const uint16_t Bytes)
+{
+ uint8_t ErrorCode;
+
+ if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
+ return PIPE_RWSTREAM_DeviceDisconnected;
+
+ Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipeNumber);
+ Pipe_Unfreeze();
+
+ ErrorCode = Pipe_Write_Stream_LE(Buffer, Bytes, NO_STREAM_CALLBACK);
+
+ Pipe_ClearOUT();
+ Pipe_Freeze();
+
+ return ErrorCode;
+}
+
+uint8_t SI_Host_ReadData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
+ void* Buffer,
+ const uint16_t Bytes)
+{
+ uint8_t ErrorCode;
+
+ if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
+ return PIPE_RWSTREAM_DeviceDisconnected;
+
+ Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipeNumber);
+ Pipe_Unfreeze();
+
+ ErrorCode = Pipe_Read_Stream_LE(Buffer, Bytes, NO_STREAM_CALLBACK);
+
+ Pipe_Freeze();
+
+ return ErrorCode;
+}
+
+bool SI_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo)
+{
+ bool IsEventReceived = false;
+
+ if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
+ return false;
+
+ Pipe_SelectPipe(SIInterfaceInfo->Config.EventsPipeNumber);
+ Pipe_Unfreeze();
+
+ if (Pipe_BytesInPipe())
+ IsEventReceived = true;
+
+ Pipe_Freeze();
+
+ return IsEventReceived;
+}
+
+uint8_t SI_Host_ReceiveEventHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
+ PIMA_Container_t* const PIMAHeader)
+{
+ uint8_t ErrorCode;
+
+ if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
+ return PIPE_RWSTREAM_DeviceDisconnected;
+
+ Pipe_SelectPipe(SIInterfaceInfo->Config.EventsPipeNumber);
+ Pipe_Unfreeze();
+
+ ErrorCode = Pipe_Read_Stream_LE(PIMAHeader, sizeof(PIMA_Container_t), NO_STREAM_CALLBACK);
+
+ Pipe_ClearIN();
+ Pipe_Freeze();
+
+ return ErrorCode;
+}
+
+uint8_t SI_Host_OpenSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
+ return HOST_SENDCONTROL_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ SIInterfaceInfo->State.TransactionID = 0;
+ SIInterfaceInfo->State.IsSessionOpen = false;
+
+ PIMA_Container_t PIMABlock = (PIMA_Container_t)
+ {
+ .DataLength = PIMA_COMMAND_SIZE(1),
+ .Type = PIMA_CONTAINER_CommandBlock,
+ .Code = 0x1002,
+ .Params = {1},
+ };
+
+ if ((ErrorCode = SI_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ if ((ErrorCode = SI_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ if ((PIMABlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMABlock.Code != 0x2001))
+ return SI_ERROR_LOGICAL_CMD_FAILED;
+
+ SIInterfaceInfo->State.IsSessionOpen = true;
+
+ return PIPE_RWSTREAM_NoError;
+}
+
+uint8_t SI_Host_CloseSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
+ return HOST_SENDCONTROL_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ PIMA_Container_t PIMABlock = (PIMA_Container_t)
+ {
+ .DataLength = PIMA_COMMAND_SIZE(1),
+ .Type = PIMA_CONTAINER_CommandBlock,
+ .Code = 0x1003,
+ .Params = {1},
+ };
+
+ if ((ErrorCode = SI_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ if ((ErrorCode = SI_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ SIInterfaceInfo->State.IsSessionOpen = false;
+
+ if ((PIMABlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMABlock.Code != 0x2001))
+ return SI_ERROR_LOGICAL_CMD_FAILED;
+
+ return PIPE_RWSTREAM_NoError;
+}
+
+uint8_t SI_Host_SendCommand(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
+ const uint16_t Operation,
+ const uint8_t TotalParams,
+ uint32_t* const Params)
+{
+ if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
+ return HOST_SENDCONTROL_DeviceDisconnected;
+
+ uint8_t ErrorCode;
+
+ PIMA_Container_t PIMABlock = (PIMA_Container_t)
+ {
+ .DataLength = PIMA_COMMAND_SIZE(TotalParams),
+ .Type = PIMA_CONTAINER_CommandBlock,
+ .Code = Operation,
+ };
+
+ memcpy(&PIMABlock.Params, Params, sizeof(uint32_t) * TotalParams);
+
+ if ((ErrorCode = SI_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ return PIPE_RWSTREAM_NoError;
+}
+
+uint8_t SI_Host_ReceiveResponse(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo)
+{
+ uint8_t ErrorCode;
+ PIMA_Container_t PIMABlock;
+
+ if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive))
+ return HOST_SENDCONTROL_DeviceDisconnected;
+
+ if ((ErrorCode = SI_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError)
+ return ErrorCode;
+
+ if ((PIMABlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMABlock.Code != 0x2001))
+ return SI_ERROR_LOGICAL_CMD_FAILED;
+
+ return PIPE_RWSTREAM_NoError;
+}
+
+#endif
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/StillImage.h b/firmware/LUFA/Drivers/USB/Class/Host/StillImage.h
new file mode 100644
index 0000000..5a6de02
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/StillImage.h
@@ -0,0 +1,331 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Host mode driver for the library USB Still Image Class driver.
+ *
+ * Host mode driver for the library USB Still Image 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_USBClassSI
+ * @defgroup Group_USBClassStillImageHost Still Image 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/StillImage.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ *
+ * \section Module Description
+ * Host Mode USB Class driver framework interface, for the Still Image USB Class driver.
+ *
+ * @{
+ */
+
+#ifndef __SI_CLASS_HOST_H__
+#define __SI_CLASS_HOST_H__
+
+ /* Includes: */
+ #include "../../USB.h"
+ #include "../Common/StillImage.h"
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_SI_DRIVER)
+ #error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
+ #endif
+
+ #if defined(__INCLUDE_FROM_STILLIMAGE_HOST_C) && defined(NO_STREAM_CALLBACKS)
+ #error The NO_STREAM_CALLBACKS compile time option cannot be used in projects using the library Class drivers.
+ #endif
+
+ /* Public Interface - May be used in end-application: */
+ /* Macros: */
+ /** Error code for some Still Image Host functions, indicating a logical (and not hardware) error. */
+ #define SI_ERROR_LOGICAL_CMD_FAILED 0x80
+
+ /* Type Defines: */
+ /** \brief Still Image 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 Still Image class driver functions as the SIInterfaceInfo parameter. This
+ * stores each Still Image interface's configuration and state information.
+ */
+ typedef struct
+ {
+ const struct
+ {
+ uint8_t DataINPipeNumber; /**< Pipe number of the Still Image interface's IN data pipe. */
+ bool DataINPipeDoubleBank; /**< Indicates if the Still Image interface's IN data pipe should use double banking. */
+
+ uint8_t DataOUTPipeNumber; /**< Pipe number of the Still Image interface's OUT data pipe. */
+ bool DataOUTPipeDoubleBank; /**< Indicates if the Still Image interface's OUT data pipe should use double banking. */
+
+ uint8_t EventsPipeNumber; /**< Pipe number of the Still Image interface's IN events endpoint, if used. */
+ bool EventsPipeDoubleBank; /**< Indicates if the Still Image interface's events data pipe should use double banking. */
+ } Config; /**< Config data for the USB class interface within the device. All elements in this section
+ * <b>must</b> 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 SI_Host_ConfigurePipes() is called and the Host state machine is in the
+ * Configured state.
+ */
+ uint8_t InterfaceNumber; /**< Interface index of the Mass Storage interface within the attached device. */
+
+ uint16_t DataINPipeSize; /**< Size in bytes of the Still Image interface's IN data pipe. */
+ uint16_t DataOUTPipeSize; /**< Size in bytes of the Still Image interface's OUT data pipe. */
+ uint16_t EventsPipeSize; /**< Size in bytes of the Still Image interface's IN events pipe. */
+
+ bool IsSessionOpen; /**< Indicates if a PIMA session is currently open with the attached device. */
+ uint32_t TransactionID; /**< Transaction ID for the next transaction to send to the device. */
+ } State; /**< State data for the USB class interface within the device. All elements in this section
+ * <b>may</b> be set to initial values, but may also be ignored to default to sane values when
+ * the interface is enumerated.
+ */
+ } USB_ClassInfo_SI_Host_t;
+
+ /* Enums: */
+ /** Enum for the possible error codes returned by the \ref SI_Host_ConfigurePipes() function. */
+ enum SI_Host_EnumerationFailure_ErrorCodes_t
+ {
+ SI_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */
+ SI_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */
+ SI_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible Still Image interface was not found in the device's
+ * Configuration Descriptor.
+ */
+ };
+
+ /* Function Prototypes: */
+ /** Host interface configuration routine, to configure a given Still Image host interface instance using the
+ * Configuration Descriptor read from an attached USB device. This function automatically updates the given Still
+ * Image 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.
+ *
+ * \note The pipe index numbers as given in the interface's configuration structure must not overlap with any other
+ * interface, or pipe bank corruption will occur. Gaps in the allocated pipe numbers or non-sequential indexes
+ * within a single interface is allowed, but no two interfaces of any type have have interleaved pipe indexes.
+ *
+ * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image 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 SI_Host_EnumerationFailure_ErrorCodes_t enum.
+ */
+ uint8_t SI_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
+ uint16_t ConfigDescriptorSize,
+ void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3);
+
+ /** Opens a new PIMA session with the attached device. This should be used before any session-orientated PIMA commands
+ * are issued to the device. Only one session can be open at the one time.
+ *
+ * \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] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device
+ * returned a logical command failure.
+ */
+ uint8_t SI_Host_OpenSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Closes an already opened PIMA session with the attached device. This should be used after all session-orientated
+ * PIMA commands have been issued to the device.
+ *
+ * \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] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device
+ * returned a logical command failure.
+ */
+ uint8_t SI_Host_CloseSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Sends a raw PIMA block header to the device, filling out the transaction ID automatically. This can be used to send
+ * arbitrary PIMA blocks to the device with or without parameters.
+ *
+ * \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] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
+ * \param[in] PIMAHeader Pointer to a PIMA container structure that is to be sent.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t SI_Host_SendBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
+ PIMA_Container_t* const PIMAHeader) ATTR_NON_NULL_PTR_ARG(1)
+ ATTR_NON_NULL_PTR_ARG(2);
+
+ /** Receives a raw PIMA block header to the device. This can be used to receive arbitrary PIMA blocks from the device with
+ * or without parameters.
+ *
+ * \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] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
+ * \param[out] PIMAHeader Pointer to a PIMA container structure where the received block is to be stored.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t SI_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
+ PIMA_Container_t* const PIMAHeader) ATTR_NON_NULL_PTR_ARG(1)
+ ATTR_NON_NULL_PTR_ARG(2);
+
+ /** Sends a given PIMA command to the attached device, filling out the PIMA command header's Transaction ID automatically.
+ *
+ * \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] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
+ * \param[in] Operation PIMA operation code to issue to the device.
+ * \param[in] TotalParams Total number of 32-bit parameters to send to the device in the issued command block.
+ * \param[in] Params Pointer to an array of 32-bit values containing the parameters to send in the command block.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device
+ * returned a logical command failure.
+ */
+ uint8_t SI_Host_SendCommand(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
+ const uint16_t Operation,
+ const uint8_t TotalParams,
+ uint32_t* const Params) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Receives and checks a response block from the attached PIMA device, once a command has been issued and all data
+ * associated with the command has been transferred.
+ *
+ * \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] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device
+ * returned a logical command failure.
+ */
+ uint8_t SI_Host_ReceiveResponse(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Indicates if the device has issued a PIMA event block to the host via the asynchronous events 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] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
+ *
+ * \return Boolean true if an event is waiting to be read, false otherwise.
+ */
+ bool SI_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Receives an asynchronous event block from the device via the asynchronous events 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] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
+ * \param[out] PIMAHeader Pointer to a PIMA container structure where the event should be stored.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device
+ * returned a logical command failure.
+ */
+ uint8_t SI_Host_ReceiveEventHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
+ PIMA_Container_t* const PIMAHeader) ATTR_NON_NULL_PTR_ARG(1)
+ ATTR_NON_NULL_PTR_ARG(2);
+
+ /** Sends arbitrary data to the attached device, for use in the data phase of PIMA commands which require data
+ * transfer beyond the regular PIMA command block parameters.
+ *
+ * \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] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
+ * \param[in] Buffer Pointer to a buffer where the data to send has been stored.
+ * \param[in] Bytes Length in bytes of the data in the buffer to send to the attached device.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t SI_Host_SendData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
+ void* Buffer,
+ const uint16_t Bytes) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+
+ /** Receives arbitrary data from the attached device, for use in the data phase of PIMA commands which require data
+ * transfer beyond the regular PIMA command block parameters.
+ *
+ * \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] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
+ * \param[out] Buffer Pointer to a buffer where the received data is to be stored.
+ * \param[in] Bytes Length in bytes of the data to read.
+ *
+ * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
+ */
+ uint8_t SI_Host_ReadData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo,
+ void* Buffer,
+ const uint16_t Bytes) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
+
+ /* Inline Functions: */
+ /** General management task for a given Still Image 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] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state.
+ */
+ static inline void SI_Host_USBTask(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+ static inline void SI_Host_USBTask(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo)
+ {
+ (void)SIInterfaceInfo;
+ }
+
+ /* Private Interface - For use in library only: */
+ #if !defined(__DOXYGEN__)
+ /* Macros: */
+ #define SI_COMMAND_DATA_TIMEOUT_MS 10000
+
+ /* Function Prototypes: */
+ #if defined(__INCLUDE_FROM_STILLIMAGE_HOST_C)
+ static uint8_t DCOMP_SI_Host_NextSIInterface(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
+ static uint8_t DCOMP_SI_Host_NextSIInterfaceEndpoint(void* const CurrentDescriptor) ATTR_NON_NULL_PTR_ARG(1);
+ #endif
+ #endif
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/StillImage.lst b/firmware/LUFA/Drivers/USB/Class/Host/StillImage.lst
new file mode 100644
index 0000000..7f91201
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/StillImage.lst
@@ -0,0 +1,19 @@
+ 1 .file "StillImage.c"
+ 2 __SREG__ = 0x3f
+ 3 __SP_H__ = 0x3e
+ 4 __SP_L__ = 0x3d
+ 5 __CCP__ = 0x34
+ 6 __tmp_reg__ = 0
+ 7 __zero_reg__ = 1
+ 15 .Ltext0:
+ 16 .Letext0:
+DEFINED SYMBOLS
+ *ABS*:0000000000000000 StillImage.c
+ /tmp/ccgWRdZN.s:2 *ABS*:000000000000003f __SREG__
+ /tmp/ccgWRdZN.s:3 *ABS*:000000000000003e __SP_H__
+ /tmp/ccgWRdZN.s:4 *ABS*:000000000000003d __SP_L__
+ /tmp/ccgWRdZN.s:5 *ABS*:0000000000000034 __CCP__
+ /tmp/ccgWRdZN.s:6 *ABS*:0000000000000000 __tmp_reg__
+ /tmp/ccgWRdZN.s:7 *ABS*:0000000000000001 __zero_reg__
+
+NO UNDEFINED SYMBOLS
diff --git a/firmware/LUFA/Drivers/USB/Class/Host/StillImage.o b/firmware/LUFA/Drivers/USB/Class/Host/StillImage.o
new file mode 100644
index 0000000..46bdbe2
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Host/StillImage.o
Binary files differ
diff --git a/firmware/LUFA/Drivers/USB/Class/MIDI.h b/firmware/LUFA/Drivers/USB/Class/MIDI.h
new file mode 100644
index 0000000..d26c5f7
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/MIDI.h
@@ -0,0 +1,83 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Master include file for the library USB MIDI Class driver.
+ *
+ * Master include file for the library USB MIDI 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_USBClassMIDI MIDI 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/Device/MIDI.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ * - LUFA/Drivers/USB/Class/Host/MIDI.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ *
+ * \section Module Description
+ * MIDI Class Driver module. This module contains an internal implementation of the USB MIDI Class, for both Device
+ * and Host USB modes. User applications can use this class driver instead of implementing the MIDI 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
+ * Hosts or Devices using the USB MIDI Class.
+ *
+ * \note The USB MIDI class is actually a special case of the regular Audio class, thus this module depends on
+ * structure definitions from the \ref Group_USBClassAudioDevice class driver module.
+ *
+ * @{
+ */
+
+#ifndef _MIDI_CLASS_H_
+#define _MIDI_CLASS_H_
+
+ /* Macros: */
+ #define __INCLUDE_FROM_USB_DRIVER
+ #define __INCLUDE_FROM_MIDI_DRIVER
+
+ /* Includes: */
+ #include "../HighLevel/USBMode.h"
+
+ #if defined(USB_CAN_BE_DEVICE)
+ #include "Device/MIDI.h"
+ #endif
+
+ #if defined(USB_CAN_BE_HOST)
+ #include "Host/MIDI.h"
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/MassStorage.h b/firmware/LUFA/Drivers/USB/Class/MassStorage.h
new file mode 100644
index 0000000..c4b03dd
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/MassStorage.h
@@ -0,0 +1,80 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Master include file for the library USB Mass Storage Class driver.
+ *
+ * Master include file for the library USB Mass Storage 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_USBClassMS Mass Storage 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/Device/MassStorage.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ * - LUFA/Drivers/USB/Class/Host/MassStorage.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ *
+ * \section Module Description
+ * Mass Storage Class Driver module. This module contains an internal implementation of the USB Mass Storage Class, for both
+ * Device and Host USB modes. User applications can use this class driver instead of implementing the Mass Storage 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
+ * Hosts or Devices using the USB Mass Storage Class.
+ *
+ * @{
+ */
+
+#ifndef _MS_CLASS_H_
+#define _MS_CLASS_H_
+
+ /* Macros: */
+ #define __INCLUDE_FROM_USB_DRIVER
+ #define __INCLUDE_FROM_MS_DRIVER
+
+ /* Includes: */
+ #include "../HighLevel/USBMode.h"
+
+ #if defined(USB_CAN_BE_DEVICE)
+ #include "Device/MassStorage.h"
+ #endif
+
+ #if defined(USB_CAN_BE_HOST)
+ #include "Host/MassStorage.h"
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/Printer.h b/firmware/LUFA/Drivers/USB/Class/Printer.h
new file mode 100644
index 0000000..2d5504f
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/Printer.h
@@ -0,0 +1,77 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Master include file for the library USB Printer Class driver.
+ *
+ * Master include file for the library USB Printer 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_USBClassPrinter Printer 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/Printer.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ *
+ * \section Module Description
+ * Printer Class Driver module. This module contains an internal implementation of the USB Printer Class, for the base
+ * USB Printer transport layer for USB Host mode only. Note that printers are free to implement whatever printer language
+ * they choose on top of this (e.g. Postscript), and so this driver exposes low level data transport functions only rather
+ * than high level raster or text functions. User applications can use this class driver instead of implementing the Printer
+ * 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
+ * Devices using the USB Printer Class.
+ *
+ * @{
+ */
+
+#ifndef _PRINTER_CLASS_H_
+#define _PRINTER_CLASS_H_
+
+ /* Macros: */
+ #define __INCLUDE_FROM_USB_DRIVER
+ #define __INCLUDE_FROM_PRINTER_DRIVER
+
+ /* Includes: */
+ #include "../HighLevel/USBMode.h"
+
+ #if defined(USB_CAN_BE_HOST)
+ #include "Host/Printer.h"
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/RNDIS.h b/firmware/LUFA/Drivers/USB/Class/RNDIS.h
new file mode 100644
index 0000000..98dbda4
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/RNDIS.h
@@ -0,0 +1,80 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Master include file for the library USB RNDIS Class driver.
+ *
+ * Master include file for the library USB RNDIS 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_USBClassRNDIS RNDIS (Networking) 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/Device/RNDIS.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ * - LUFA/Drivers/USB/Class/Host/RNDIS.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ *
+ * \section Module Description
+ * RNDIS Class Driver module. This module contains an internal implementation of the Microsoft USB RNDIS Networking
+ * Class, for both Device and Host USB modes. User applications can use this class driver instead of implementing the
+ * RNDIS 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
+ * Hosts using the USB RNDIS Class.
+ *
+ * @{
+ */
+
+#ifndef _RNDIS_CLASS_H_
+#define _RNDIS_CLASS_H_
+
+ /* Macros: */
+ #define __INCLUDE_FROM_USB_DRIVER
+ #define __INCLUDE_FROM_RNDIS_DRIVER
+
+ /* Includes: */
+ #include "../HighLevel/USBMode.h"
+
+ #if defined(USB_CAN_BE_DEVICE)
+ #include "Device/RNDIS.h"
+ #endif
+
+ #if defined(USB_CAN_BE_HOST)
+ #include "Host/RNDIS.h"
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/firmware/LUFA/Drivers/USB/Class/StillImage.h b/firmware/LUFA/Drivers/USB/Class/StillImage.h
new file mode 100644
index 0000000..dd1b16b
--- /dev/null
+++ b/firmware/LUFA/Drivers/USB/Class/StillImage.h
@@ -0,0 +1,75 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2010.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief Master include file for the library USB Still Image Class driver.
+ *
+ * Master include file for the library USB Still Image 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_USBClassSI Still Image 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/StillImage.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
+ *
+ * \section Module Description
+ * Still Image Class Driver module. This module contains an internal implementation of the USB Still Image Class,
+ * for USB Host mode only. User applications can use this class driver instead of implementing the Still Image 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
+ * Devices using the USB Still Image Class.
+ *
+ * @{
+ */
+
+#ifndef _SI_CLASS_H_
+#define _SI_CLASS_H_
+
+ /* Macros: */
+ #define __INCLUDE_FROM_USB_DRIVER
+ #define __INCLUDE_FROM_SI_DRIVER
+
+ /* Includes: */
+ #include "../HighLevel/USBMode.h"
+
+ #if defined(USB_CAN_BE_HOST)
+ #include "Host/StillImage.h"
+ #endif
+
+#endif
+
+/** @} */
+