aboutsummaryrefslogtreecommitdiffstats
path: root/LUFA
diff options
context:
space:
mode:
Diffstat (limited to 'LUFA')
-rw-r--r--LUFA/ChangeLog.txt10
-rw-r--r--LUFA/DirectorySummaries.txt13
-rw-r--r--LUFA/Drivers/USB/Class/Device/Audio.c154
-rw-r--r--LUFA/Drivers/USB/Class/Device/Audio.h70
-rw-r--r--LUFA/Drivers/USB/Class/Device/CDC.c185
-rw-r--r--LUFA/Drivers/USB/Class/Device/CDC.h188
-rw-r--r--LUFA/Drivers/USB/Class/Device/HID.c211
-rw-r--r--LUFA/Drivers/USB/Class/Device/HID.h115
-rw-r--r--LUFA/Drivers/USB/Class/Device/MassStorage.c208
-rw-r--r--LUFA/Drivers/USB/Class/Device/MassStorage.h127
-rw-r--r--LUFA/Drivers/USB/Class/Device/RNDIS.c456
-rw-r--r--LUFA/Drivers/USB/Class/Device/RNDIS.h260
-rw-r--r--LUFA/Drivers/USB/Class/Device/RNDISConstants.h99
-rw-r--r--LUFA/Drivers/USB/Class/Host/HIDParser.c (renamed from LUFA/Drivers/USB/Class/HIDParser.c)0
-rw-r--r--LUFA/Drivers/USB/Class/Host/HIDParser.h (renamed from LUFA/Drivers/USB/Class/HIDParser.h)2
-rw-r--r--LUFA/Drivers/USB/Class/Host/HIDReportData.h (renamed from LUFA/Drivers/USB/Class/HIDReportData.h)0
-rw-r--r--LUFA/Drivers/USB/HighLevel/Events.h6
-rw-r--r--LUFA/Drivers/USB/HighLevel/USBInterrupt.c18
-rw-r--r--LUFA/Drivers/USB/HighLevel/USBTask.c2
-rw-r--r--LUFA/Drivers/USB/HighLevel/USBTask.h7
-rw-r--r--LUFA/Drivers/USB/LowLevel/Endpoint.c6
-rw-r--r--LUFA/Drivers/USB/LowLevel/Host.c12
-rw-r--r--LUFA/Drivers/USB/LowLevel/LowLevel.c8
-rw-r--r--LUFA/Drivers/USB/LowLevel/LowLevel.h3
-rw-r--r--LUFA/Drivers/USB/LowLevel/Pipe.c6
-rw-r--r--LUFA/Drivers/USB/USB.h2
-rw-r--r--LUFA/MemoryAllocator/DynAlloc.c226
-rw-r--r--LUFA/MemoryAllocator/DynAlloc.h198
-rw-r--r--LUFA/Scheduler/Scheduler.c95
-rw-r--r--LUFA/Scheduler/Scheduler.h285
-rw-r--r--LUFA/SchedulerOverview.txt31
-rw-r--r--LUFA/makefile6
32 files changed, 2135 insertions, 874 deletions
diff --git a/LUFA/ChangeLog.txt b/LUFA/ChangeLog.txt
index ac675348b..fe3b63360 100644
--- a/LUFA/ChangeLog.txt
+++ b/LUFA/ChangeLog.txt
@@ -4,6 +4,14 @@
* documentation pages. It is not a project source file.
*/
+========== TODO: ===========
+ - Document new class drivers
+ - Re-document all demos now that they have changed
+ - Add standardized descriptor names to class driver structures, controlled by USE_NONSTANDARD_DESCRIPTOR_NAMES
+ - Add C++ compatibility to class drivers
+ - Disable JTAG in demos
+============================
+
/** \page Page_ChangeLog Project Changelog
*
* \section Sec_ChangeLogXXXXXX Version XXXXXX
@@ -30,6 +38,8 @@
* LUFA/Drivers/USB/Class/ directory to LUFA/Drivers/USB/HighLevel/ in preperation for the new USB class APIs
* - Moved out each demos' functionality library files (e.g. Ring Buffer library) to /Lib directories for a better directory structure
* - Removed Tx interrupt from the USBtoSerial demo; now sends characters via polling to ensure more time for the Rx interrupt
+ * - Added new EVENT_USB_StartOfFrame event in the library to indicate the start of each USB frame (when generated)
+ * - Removed psuedo-scheduler, dynamic memory block allocator from the library (no longer needed and not used respectively)
*
*
* \section Sec_ChangeLog090510 Version 090510
diff --git a/LUFA/DirectorySummaries.txt b/LUFA/DirectorySummaries.txt
index f43984760..3fae9c18e 100644
--- a/LUFA/DirectorySummaries.txt
+++ b/LUFA/DirectorySummaries.txt
@@ -10,19 +10,6 @@
* This folder contains header files which are common to all parts of the LUFA library. They may be used freely in
* user applications.
*
- * \dir MemoryAllocator
- * \brief Auto-defragmenting dynamic memory allocation library.
- *
- * This folder contains a simple handle-based dynamic memory allocation library, capable of handing out memory in
- * block chunks. As new memory is allocated, the library will defragment the already allocated memory to ensure
- * optimal memory usage. It is not used within the LUFA library, and is provided as a convenience for user applications.
- *
- * \dir Scheduler
- * \brief Simple round-robbin scheduler.
- *
- * This folder contains the simple LUFA round-robbin scheduler, provided as a convenience for user applications. It
- * is very simple in design, and is intended to make code easier to read, rather than providing a complete RTOS kernel.
- *
* \dir Drivers
* \brief Library hardware and software drivers.
*
diff --git a/LUFA/Drivers/USB/Class/Device/Audio.c b/LUFA/Drivers/USB/Class/Device/Audio.c
new file mode 100644
index 000000000..b0800ba0f
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/Audio.c
@@ -0,0 +1,154 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#include "Audio.h"
+
+void USB_Audio_ProcessControlPacket(USB_ClassInfo_Audio_t* AudioInterfaceInfo)
+{
+ if (!(Endpoint_IsSETUPReceived()))
+ return;
+
+// if (USB_ControlRequest.wIndex != AudioInterfaceInfo->InterfaceNumber)
+// return;
+
+ switch (USB_ControlRequest.bRequest)
+ {
+ case REQ_SetInterface:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ AudioInterfaceInfo->InterfaceEnabled = (USB_ControlRequest.wValue != 0);
+
+ while (!(Endpoint_IsINReady()));
+ Endpoint_ClearIN();
+ }
+
+ break;
+ }
+}
+
+bool USB_Audio_ConfigureEndpoints(USB_ClassInfo_Audio_t* AudioInterfaceInfo)
+{
+ if (AudioInterfaceInfo->DataINEndpointNumber)
+ {
+ if (!(Endpoint_ConfigureEndpoint(AudioInterfaceInfo->DataINEndpointNumber, EP_TYPE_ISOCHRONOUS,
+ ENDPOINT_DIR_IN, AudioInterfaceInfo->DataINEndpointSize,
+ ENDPOINT_BANK_DOUBLE)))
+ {
+ return false;
+ }
+ }
+
+ if (AudioInterfaceInfo->DataOUTEndpointNumber)
+ {
+ if (!(Endpoint_ConfigureEndpoint(AudioInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_ISOCHRONOUS,
+ ENDPOINT_DIR_OUT, AudioInterfaceInfo->DataOUTEndpointSize,
+ ENDPOINT_BANK_DOUBLE)))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+int8_t USB_Audio_ReadSample8(void)
+{
+ int8_t Sample;
+
+ Sample = Endpoint_Read_Byte();
+
+ if (!(Endpoint_IsReadWriteAllowed()))
+ Endpoint_ClearOUT();
+
+ return Sample;
+}
+
+int16_t USB_Audio_ReadSample16(void)
+{
+ int16_t Sample;
+
+ Sample = (int16_t)Endpoint_Read_Word_LE();
+
+ if (!(Endpoint_IsReadWriteAllowed()))
+ Endpoint_ClearOUT();
+
+ return Sample;
+}
+
+int32_t USB_Audio_ReadSample24(void)
+{
+ int32_t Sample;
+
+ Sample = (((uint32_t)Endpoint_Read_Byte() << 16) | Endpoint_Read_Word_LE());
+
+ if (!(Endpoint_IsReadWriteAllowed()))
+ Endpoint_ClearOUT();
+
+ return Sample;
+}
+
+void USB_Audio_WriteSample8(int8_t Sample)
+{
+ Endpoint_Write_Byte(Sample);
+
+ if (!(Endpoint_IsReadWriteAllowed()))
+ Endpoint_ClearIN();
+}
+
+void USB_Audio_WriteSample16(int16_t Sample)
+{
+ Endpoint_Write_Word_LE(Sample);
+
+ if (!(Endpoint_IsReadWriteAllowed()))
+ Endpoint_ClearIN();
+}
+
+void USB_Audio_WriteSample24(int32_t Sample)
+{
+ Endpoint_Write_Byte(Sample >> 16);
+ Endpoint_Write_Word_LE(Sample);
+
+ if (!(Endpoint_IsReadWriteAllowed()))
+ Endpoint_ClearIN();
+}
+
+bool USB_Audio_IsSampleReceived(USB_ClassInfo_Audio_t* AudioInterfaceInfo)
+{
+ Endpoint_SelectEndpoint(AudioInterfaceInfo->DataOUTEndpointNumber);
+ return Endpoint_IsOUTReceived();
+}
+
+bool USB_Audio_IsReadyForNextSample(USB_ClassInfo_Audio_t* AudioInterfaceInfo)
+{
+ Endpoint_SelectEndpoint(AudioInterfaceInfo->DataINEndpointNumber);
+ return Endpoint_IsINReady();
+}
diff --git a/LUFA/Drivers/USB/Class/Device/Audio.h b/LUFA/Drivers/USB/Class/Device/Audio.h
new file mode 100644
index 000000000..aa7b4069c
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/Audio.h
@@ -0,0 +1,70 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#ifndef _AUDIO_CLASS_H_
+#define _AUDIO_CLASS_H_
+
+ /* Includes: */
+ #include "../../USB.h"
+
+ #include <string.h>
+
+ /* Macros: */
+
+ /* Enums: */
+
+ /* Type Defines: */
+ typedef struct
+ {
+ uint8_t InterfaceNumber;
+
+ uint8_t DataINEndpointNumber;
+ uint16_t DataINEndpointSize;
+
+ uint8_t DataOUTEndpointNumber;
+ uint16_t DataOUTEndpointSize;
+
+ bool InterfaceEnabled;
+ } USB_ClassInfo_Audio_t;
+
+ /* Function Prototypes: */
+ bool USB_Audio_ConfigureEndpoints(USB_ClassInfo_Audio_t* AudioInterfaceInfo);
+ void USB_Audio_ProcessControlPacket(USB_ClassInfo_Audio_t* AudioInterfaceInfo);
+ void USB_Audio_USBTask(USB_ClassInfo_Audio_t* AudioInterfaceInfo);
+
+ int8_t USB_Audio_ReadSample8(void);
+ int16_t USB_Audio_ReadSample16(void);
+ int32_t USB_Audio_ReadSample24(void);
+ void USB_Audio_WriteSample8(int8_t Sample);
+ void USB_Audio_WriteSample16(int16_t Sample);
+ void USB_Audio_WriteSample24(int32_t Sample);
+ bool USB_Audio_IsSampleReceived(USB_ClassInfo_Audio_t* AudioInterfaceInfo);
+ bool USB_Audio_IsReadyForNextSample(USB_ClassInfo_Audio_t* AudioInterfaceInfo);
+#endif
diff --git a/LUFA/Drivers/USB/Class/Device/CDC.c b/LUFA/Drivers/USB/Class/Device/CDC.c
new file mode 100644
index 000000000..8acaac7a1
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/CDC.c
@@ -0,0 +1,185 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define INCLUDE_FROM_CDC_CLASS_C
+#include "CDC.h"
+
+void USB_CDC_Event_Stub(void)
+{
+
+}
+
+void USB_CDC_ProcessControlPacket(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
+{
+ if (!(Endpoint_IsSETUPReceived()))
+ return;
+
+ if (USB_ControlRequest.wIndex != CDCInterfaceInfo->ControlInterfaceNumber)
+ return;
+
+ switch (USB_ControlRequest.bRequest)
+ {
+ case REQ_GetLineEncoding:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+ Endpoint_Write_Control_Stream_LE(&CDCInterfaceInfo->LineEncoding, sizeof(CDCInterfaceInfo->LineEncoding));
+ Endpoint_ClearOUT();
+ }
+
+ break;
+ case REQ_SetLineEncoding:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+ Endpoint_Read_Control_Stream_LE(&CDCInterfaceInfo->LineEncoding, sizeof(CDCInterfaceInfo->LineEncoding));
+ Endpoint_ClearIN();
+
+ EVENT_USB_CDC_LineEncodingChanged(CDCInterfaceInfo);
+ }
+
+ break;
+ case REQ_SetControlLineState:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ CDCInterfaceInfo->ControlLineState = USB_ControlRequest.wValue;
+
+ EVENT_USB_CDC_ControLineStateChanged();
+
+ while (!(Endpoint_IsINReady()));
+ Endpoint_ClearIN();
+ }
+
+ break;
+ }
+}
+
+bool USB_CDC_ConfigureEndpoints(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
+{
+ if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->DataINEndpointNumber, EP_TYPE_BULK,
+ ENDPOINT_DIR_IN, CDCInterfaceInfo->DataINEndpointSize,
+ ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+
+ if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_BULK,
+ ENDPOINT_DIR_OUT, CDCInterfaceInfo->DataOUTEndpointSize,
+ ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+
+ if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->NotificationEndpointNumber, EP_TYPE_INTERRUPT,
+ ENDPOINT_DIR_IN, CDCInterfaceInfo->NotificationEndpointSize,
+ ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void USB_CDC_USBTask(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
+{
+ if (!(USB_IsConnected))
+ return;
+
+ Endpoint_SelectEndpoint(CDCInterfaceInfo->DataINEndpointNumber);
+
+ if (!(Endpoint_BytesInEndpoint()))
+ return;
+
+ if (!(Endpoint_IsReadWriteAllowed()))
+ {
+ Endpoint_ClearIN();
+ while (!(Endpoint_IsReadWriteAllowed()));
+ }
+
+ Endpoint_ClearIN();
+}
+
+void USB_CDC_SendString(USB_ClassInfo_CDC_t* CDCInterfaceInfo, char* Data, uint16_t Length)
+{
+ Endpoint_SelectEndpoint(CDCInterfaceInfo->DataINEndpointNumber);
+ Endpoint_Write_Stream_LE(Data, Length, NO_STREAM_CALLBACK);
+}
+
+void USB_CDC_SendByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint8_t Data)
+{
+ Endpoint_SelectEndpoint(CDCInterfaceInfo->DataINEndpointNumber);
+
+ if (!(Endpoint_IsReadWriteAllowed()))
+ {
+ Endpoint_ClearIN();
+ while (!(Endpoint_IsReadWriteAllowed()));
+ }
+
+ Endpoint_Write_Byte(Data);
+}
+
+uint16_t USB_CDC_BytesReceived(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
+{
+ Endpoint_SelectEndpoint(CDCInterfaceInfo->DataOUTEndpointNumber);
+
+ return Endpoint_BytesInEndpoint();
+}
+
+uint8_t USB_CDC_ReceiveByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
+{
+ Endpoint_SelectEndpoint(CDCInterfaceInfo->DataOUTEndpointNumber);
+
+ uint8_t DataByte = Endpoint_Read_Byte();
+
+ if (!(Endpoint_BytesInEndpoint()))
+ Endpoint_ClearOUT();
+
+ return DataByte;
+}
+
+void USB_CDC_SendSerialLineStateChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint16_t LineStateMask)
+{
+ Endpoint_SelectEndpoint(CDCInterfaceInfo->NotificationEndpointNumber);
+
+ USB_Request_Header_t Notification = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = NOTIF_SerialState,
+ .wValue = 0,
+ .wIndex = 0,
+ .wLength = sizeof(uint16_t),
+ };
+
+ Endpoint_Write_Stream_LE(&Notification, sizeof(Notification), NO_STREAM_CALLBACK);
+ Endpoint_Write_Stream_LE(&LineStateMask, sizeof(LineStateMask), NO_STREAM_CALLBACK);
+ Endpoint_ClearIN();
+}
diff --git a/LUFA/Drivers/USB/Class/Device/CDC.h b/LUFA/Drivers/USB/Class/Device/CDC.h
new file mode 100644
index 000000000..bbe1c9838
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/CDC.h
@@ -0,0 +1,188 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#ifndef _CDC_CLASS_H_
+#define _CDC_CLASS_H_
+
+ /* Includes: */
+ #include "../../USB.h"
+
+ #include <string.h>
+
+ /* Macros: */
+ /** CDC Class specific request to get the current virtual serial port configuration settings. */
+ #define REQ_GetLineEncoding 0x21
+
+ /** CDC Class specific request to set the current virtual serial port configuration settings. */
+ #define REQ_SetLineEncoding 0x20
+
+ /** CDC Class specific request to set the current virtual serial port handshake line states. */
+ #define REQ_SetControlLineState 0x22
+
+ /** Notification type constant for a change in the virtual serial port handshake line states, for
+ * use with a USB_Notification_Header_t notification structure when sent to the host via the CDC
+ * notification endpoint.
+ */
+ #define NOTIF_SerialState 0x20
+
+ /** Mask for the DTR handshake line for use with the REQ_SetControlLineState class specific request
+ * from the host, to indicate that the DTR line state should be high.
+ */
+ #define CONTROL_LINE_OUT_DTR (1 << 0)
+
+ /** Mask for the RTS handshake line for use with the REQ_SetControlLineState class specific request
+ * from the host, to indicate that theRTS line state should be high.
+ */
+ #define CONTROL_LINE_OUT_RTS (1 << 1)
+
+ /** Mask for the DCD handshake line for use with the a NOTIF_SerialState class specific notification
+ * from the device to the host, to indicate that the DCD line state is currently high.
+ */
+ #define CONTROL_LINE_IN_DCD (1 << 0)
+
+ /** Mask for the DSR handshake line for use with the a NOTIF_SerialState class specific notification
+ * from the device to the host, to indicate that the DSR line state is currently high.
+ */
+ #define CONTROL_LINE_IN_DSR (1 << 1)
+
+ /** Mask for the BREAK handshake line for use with the a NOTIF_SerialState class specific notification
+ * from the device to the host, to indicate that the BREAK line state is currently high.
+ */
+ #define CONTROL_LINE_IN_BREAK (1 << 2)
+
+ /** Mask for the RING handshake line for use with the a NOTIF_SerialState class specific notification
+ * from the device to the host, to indicate that the RING line state is currently high.
+ */
+ #define CONTROL_LINE_IN_RING (1 << 3)
+
+ /** Mask for use with the a 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 CONTROL_LINE_IN_FRAMEERROR (1 << 4)
+
+ /** Mask for use with the a 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 CONTROL_LINE_IN_PARITYERROR (1 << 5)
+
+ /** Mask for use with the a 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 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 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 the possible line encoding formats of a virtual serial port. */
+ enum CDCDevice_CDC_LineCodingFormats_t
+ {
+ OneStopBit = 0, /**< Each frame contains one stop bit */
+ OneAndAHalfStopBits = 1, /**< Each frame contains one and a half stop bits */
+ TwoStopBits = 2, /**< Each frame contains two stop bits */
+ };
+
+ /** Enum for the possible line encoding parity settings of a virtual serial port. */
+ enum CDCDevice_LineCodingParity_t
+ {
+ Parity_None = 0, /**< No parity bit mode on each frame */
+ Parity_Odd = 1, /**< Odd parity bit mode on each frame */
+ Parity_Even = 2, /**< Even parity bit mode on each frame */
+ Parity_Mark = 3, /**< Mark parity bit mode on each frame */
+ Parity_Space = 4, /**< Space parity bit mode on each frame */
+ };
+
+ /* Type Defines: */
+ /** Type define for the virtual serial port line encoding settings, for storing the current USART configuration
+ * as set by the host via a class specific request.
+ */
+ typedef 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 */
+
+ 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 */
+
+ 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 */
+
+ uint8_t ControlLineState;
+
+ 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
+ * CDCDevice_CDC_LineCodingFormats_t enum
+ */
+ uint8_t ParityType; /**< Parity setting of the virtual serial port, a value from the
+ * CDCDevice_LineCodingParity_t enum
+ */
+ uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
+ } LineEncoding;
+ } USB_ClassInfo_CDC_t;
+
+ /* Function Prototypes: */
+ #if defined(INCLUDE_FROM_CDC_CLASS_C)
+ void USB_CDC_Event_Stub(void);
+ void EVENT_USB_CDC_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
+ ATTR_WEAK ATTR_ALIAS(USB_CDC_Event_Stub);
+ void EVENT_USB_CDC_ControLineStateChanged(void) ATTR_WEAK ATTR_ALIAS(USB_CDC_Event_Stub);;
+ #endif
+
+ void USB_CDC_USBTask(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+ bool USB_CDC_ConfigureEndpoints(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+ void USB_CDC_ProcessControlPacket(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+ void USB_CDC_USBTask(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+
+ void EVENT_USB_CDC_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+ void EVENT_USB_CDC_ControLineStateChanged(void);
+
+ void USB_CDC_SendString(USB_ClassInfo_CDC_t* CDCInterfaceInfo, char* Data, uint16_t Length);
+ void USB_CDC_SendByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint8_t Data);
+ uint16_t USB_CDC_BytesReceived(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+ uint8_t USB_CDC_ReceiveByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+ void USB_CDC_SendSerialLineStateChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint16_t LineStateMask);
+
+#endif
diff --git a/LUFA/Drivers/USB/Class/Device/HID.c b/LUFA/Drivers/USB/Class/Device/HID.c
new file mode 100644
index 000000000..fbc5e3a5c
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/HID.c
@@ -0,0 +1,211 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#include "HID.h"
+
+void USB_HID_ProcessControlPacket(USB_ClassInfo_HID_t* HIDInterfaceInfo)
+{
+ if (!(Endpoint_IsSETUPReceived()))
+ return;
+
+ if (USB_ControlRequest.wIndex != HIDInterfaceInfo->InterfaceNumber)
+ return;
+
+ switch (USB_ControlRequest.bRequest)
+ {
+ case REQ_GetReport:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ uint8_t ReportINData[HIDInterfaceInfo->ReportBufferSize];
+ uint16_t ReportINSize;
+
+ memset(ReportINData, 0, sizeof(ReportINData));
+
+ ReportINSize = CALLBACK_USB_HID_CreateNextHIDReport(HIDInterfaceInfo, ReportINData);
+
+ Endpoint_Write_Control_Stream_LE(ReportINData, ReportINSize);
+ Endpoint_ClearOUT();
+ }
+
+ break;
+ case REQ_SetReport:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ uint16_t ReportOUTSize = USB_ControlRequest.wLength;
+ uint8_t ReportOUTData[ReportOUTSize];
+
+ Endpoint_Read_Control_Stream_LE(ReportOUTData, ReportOUTSize);
+ Endpoint_ClearIN();
+
+ CALLBACK_USB_HID_ProcessReceivedHIDReport(HIDInterfaceInfo, ReportOUTData, ReportOUTSize);
+ }
+
+ break;
+ case REQ_GetProtocol:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ Endpoint_Write_Byte(HIDInterfaceInfo->UsingReportProtocol);
+ Endpoint_ClearIN();
+
+ while (!(Endpoint_IsOUTReceived()));
+ Endpoint_ClearOUT();
+ }
+
+ break;
+ case REQ_SetProtocol:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ HIDInterfaceInfo->UsingReportProtocol = (USB_ControlRequest.wValue != 0x0000);
+
+ while (!(Endpoint_IsINReady()));
+ Endpoint_ClearIN();
+ }
+
+ break;
+ case REQ_SetIdle:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ HIDInterfaceInfo->IdleCount = ((USB_ControlRequest.wValue >> 8) << 2);
+
+ while (!(Endpoint_IsINReady()));
+ Endpoint_ClearIN();
+ }
+
+ break;
+ case REQ_GetIdle:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ Endpoint_Write_Byte(HIDInterfaceInfo->IdleCount >> 2);
+ Endpoint_ClearIN();
+
+ while (!(Endpoint_IsOUTReceived()));
+ Endpoint_ClearOUT();
+ }
+
+ break;
+ }
+}
+
+bool USB_HID_ConfigureEndpoints(USB_ClassInfo_HID_t* HIDInterfaceInfo)
+{
+ HIDInterfaceInfo->UsingReportProtocol = true;
+
+ if (!(Endpoint_ConfigureEndpoint(HIDInterfaceInfo->ReportINEndpointNumber, EP_TYPE_INTERRUPT,
+ ENDPOINT_DIR_IN, HIDInterfaceInfo->ReportINEndpointSize, ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+
+ if (HIDInterfaceInfo->ReportOUTEndpointNumber)
+ {
+ if (!(Endpoint_ConfigureEndpoint(HIDInterfaceInfo->ReportOUTEndpointNumber, EP_TYPE_INTERRUPT,
+ ENDPOINT_DIR_OUT, HIDInterfaceInfo->ReportOUTEndpointSize, ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void USB_HID_RegisterStartOfFrame(USB_ClassInfo_HID_t* HIDInterfaceInfo)
+{
+ if (HIDInterfaceInfo->IdleMSRemaining)
+ HIDInterfaceInfo->IdleMSRemaining--;
+}
+
+void USB_HID_USBTask(USB_ClassInfo_HID_t* HIDInterfaceInfo)
+{
+ if (!(USB_IsConnected))
+ return;
+
+ Endpoint_SelectEndpoint(HIDInterfaceInfo->ReportINEndpointNumber);
+
+ if (Endpoint_IsReadWriteAllowed() &&
+ !(HIDInterfaceInfo->IdleCount && HIDInterfaceInfo->IdleMSRemaining))
+ {
+ if (HIDInterfaceInfo->IdleCount && !(HIDInterfaceInfo->IdleMSRemaining))
+ HIDInterfaceInfo->IdleMSRemaining = HIDInterfaceInfo->IdleCount;
+
+ uint8_t ReportINData[HIDInterfaceInfo->ReportBufferSize];
+ uint16_t ReportINSize;
+
+ memset(ReportINData, 0, sizeof(ReportINData));
+
+ ReportINSize = CALLBACK_USB_HID_CreateNextHIDReport(HIDInterfaceInfo, ReportINData);
+
+ if (ReportINSize)
+ {
+ Endpoint_Write_Stream_LE(ReportINData, ReportINSize
+ #if !defined(NO_STREAM_CALLBACKS)
+ , NO_STREAM_CALLBACK
+ #endif
+ );
+ }
+
+ Endpoint_ClearIN();
+ }
+
+ if (HIDInterfaceInfo->ReportOUTEndpointNumber)
+ {
+ Endpoint_SelectEndpoint(HIDInterfaceInfo->ReportOUTEndpointNumber);
+
+ if (Endpoint_IsOUTReceived())
+ {
+ uint16_t ReportOUTSize = Endpoint_BytesInEndpoint();
+ uint8_t ReportOUTData[ReportOUTSize];
+
+ if (ReportOUTSize)
+ {
+ Endpoint_Read_Stream_LE(ReportOUTData, ReportOUTSize
+ #if !defined(NO_STREAM_CALLBACKS)
+ , NO_STREAM_CALLBACK
+ #endif
+ );
+ }
+
+ CALLBACK_USB_HID_ProcessReceivedHIDReport(HIDInterfaceInfo, ReportOUTData, ReportOUTSize);
+
+ Endpoint_ClearOUT();
+ }
+ }
+}
diff --git a/LUFA/Drivers/USB/Class/Device/HID.h b/LUFA/Drivers/USB/Class/Device/HID.h
new file mode 100644
index 000000000..8fdeb064a
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/HID.h
@@ -0,0 +1,115 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#ifndef _HID_CLASS_H_
+#define _HID_CLASS_H_
+
+ /* Includes: */
+ #include "../../USB.h"
+
+ #include <string.h>
+
+ /* Macros: */
+ /** HID Class Specific Request to get the current HID report from the device. */
+ #define REQ_GetReport 0x01
+
+ /** HID Class Specific Request to get the current device idle count. */
+ #define REQ_GetIdle 0x02
+
+ /** HID Class Specific Request to set the current HID report to the device. */
+ #define REQ_SetReport 0x09
+
+ /** HID Class Specific Request to set the device's idle count. */
+ #define REQ_SetIdle 0x0A
+
+ /** HID Class Specific Request to get the current HID report protocol mode. */
+ #define REQ_GetProtocol 0x03
+
+ /** HID Class Specific Request to set the current HID report protocol mode. */
+ #define REQ_SetProtocol 0x0B
+
+ /** Descriptor header type value, to indicate a HID class HID descriptor. */
+ #define DTYPE_HID 0x21
+
+ /** Descriptor header type value, to indicate a HID class HID report descriptor. */
+ #define DTYPE_Report 0x22
+
+ /* Type Defines: */
+ /** 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.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Header_t Header;
+
+ uint16_t HIDSpec;
+ uint8_t CountryCode;
+
+ uint8_t TotalReportDescriptors;
+
+ uint8_t HIDReportType;
+ uint16_t HIDReportLength;
+ } USB_Descriptor_HID_t;
+
+ /** Type define for the data type used to store HID report descriptor elements. */
+ typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
+
+ /** 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. The contents of this structure should be set to their correct
+ * values when used, or ommitted to force the library to use default values.
+ */
+ typedef 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 */
+
+ uint8_t ReportOUTEndpointNumber; /**< Endpoint number of the HID interface's OUT report endpoint, if used */
+ uint16_t ReportOUTEndpointSize; /**< Size in bytes of the HID interface's OUT report endpoint, if used */
+
+ uint8_t ReportBufferSize;
+
+ bool UsingReportProtocol; /**< Indicates if the HID interface is set to Boot or Report protocol mode */
+ uint16_t IdleCount; /**< Report idle period, in ms, set by the host */
+ uint16_t IdleMSRemaining; /**< Total number of ms remaining before the idle period elapses */
+ } USB_ClassInfo_HID_t;
+
+ /* Function Prototypes: */
+ bool USB_HID_ConfigureEndpoints(USB_ClassInfo_HID_t* HIDInterfaceInfo);
+ void USB_HID_ProcessControlPacket(USB_ClassInfo_HID_t* HIDInterfaceInfo);
+ void USB_HID_RegisterStartOfFrame(USB_ClassInfo_HID_t* HIDInterfaceInfo);
+ void USB_HID_USBTask(USB_ClassInfo_HID_t* HIDInterfaceInfo);
+
+ uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);
+ void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize);
+
+#endif
diff --git a/LUFA/Drivers/USB/Class/Device/MassStorage.c b/LUFA/Drivers/USB/Class/Device/MassStorage.c
new file mode 100644
index 000000000..1c41f6046
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/MassStorage.c
@@ -0,0 +1,208 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define INCLUDE_FROM_MS_CLASS_C
+#include "MassStorage.h"
+
+static USB_ClassInfo_MS_t* CallbackMSInterfaceInfo;
+
+void USB_MS_ProcessControlPacket(USB_ClassInfo_MS_t* MSInterfaceInfo)
+{
+ if (!(Endpoint_IsSETUPReceived()))
+ return;
+
+ if (USB_ControlRequest.wIndex != MSInterfaceInfo->InterfaceNumber)
+ return;
+
+ switch (USB_ControlRequest.bRequest)
+ {
+ case REQ_MassStorageReset:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ MSInterfaceInfo->IsMassStoreReset = true;
+
+ while (!(Endpoint_IsINReady()));
+ Endpoint_ClearIN();
+ }
+
+ break;
+ case REQ_GetMaxLUN:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ Endpoint_Write_Byte(MSInterfaceInfo->TotalLUNs - 1);
+
+ Endpoint_ClearIN();
+
+ while (!(Endpoint_IsOUTReceived()));
+ Endpoint_ClearOUT();
+ }
+
+ break;
+ }
+}
+
+bool USB_MS_ConfigureEndpoints(USB_ClassInfo_MS_t* MSInterfaceInfo)
+{
+ if (!(Endpoint_ConfigureEndpoint(MSInterfaceInfo->DataINEndpointNumber, EP_TYPE_BULK,
+ ENDPOINT_DIR_IN, MSInterfaceInfo->DataINEndpointSize,
+ ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+
+ if (!(Endpoint_ConfigureEndpoint(MSInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_BULK,
+ ENDPOINT_DIR_OUT, MSInterfaceInfo->DataOUTEndpointSize,
+ ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void USB_MS_USBTask(USB_ClassInfo_MS_t* MSInterfaceInfo)
+{
+ if (!(USB_IsConnected))
+ return;
+
+ Endpoint_SelectEndpoint(MSInterfaceInfo->DataOUTEndpointNumber);
+
+ if (Endpoint_IsReadWriteAllowed())
+ {
+ if (USB_MS_ReadInCommandBlock(MSInterfaceInfo))
+ {
+ if (MSInterfaceInfo->CommandBlock.Flags & COMMAND_DIRECTION_DATA_IN)
+ Endpoint_SelectEndpoint(MSInterfaceInfo->DataINEndpointNumber);
+
+ MSInterfaceInfo->CommandStatus.Status = CALLBACK_USB_MS_SCSICommandReceived(MSInterfaceInfo) ?
+ Command_Pass : Command_Fail;
+ MSInterfaceInfo->CommandStatus.Signature = CSW_SIGNATURE;
+ MSInterfaceInfo->CommandStatus.Tag = MSInterfaceInfo->CommandBlock.Tag;
+ MSInterfaceInfo->CommandStatus.DataTransferResidue = MSInterfaceInfo->CommandBlock.DataTransferLength;
+
+ if ((MSInterfaceInfo->CommandStatus.Status == Command_Fail) && (MSInterfaceInfo->CommandStatus.DataTransferResidue))
+ Endpoint_StallTransaction();
+
+ USB_MS_ReturnCommandStatus(MSInterfaceInfo);
+
+ if (MSInterfaceInfo->IsMassStoreReset)
+ {
+ Endpoint_ResetFIFO(MSInterfaceInfo->DataOUTEndpointNumber);
+ Endpoint_ResetFIFO(MSInterfaceInfo->DataINEndpointNumber);
+
+ Endpoint_SelectEndpoint(MSInterfaceInfo->DataOUTEndpointNumber);
+ Endpoint_ClearStall();
+ Endpoint_SelectEndpoint(MSInterfaceInfo->DataINEndpointNumber);
+ Endpoint_ClearStall();
+
+ MSInterfaceInfo->IsMassStoreReset = false;
+ }
+ }
+ }
+}
+
+static bool USB_MS_ReadInCommandBlock(USB_ClassInfo_MS_t* MSInterfaceInfo)
+{
+ Endpoint_SelectEndpoint(MSInterfaceInfo->DataOUTEndpointNumber);
+
+ CallbackMSInterfaceInfo = MSInterfaceInfo;
+ Endpoint_Read_Stream_LE(&MSInterfaceInfo->CommandBlock,
+ (sizeof(CommandBlockWrapper_t) - MAX_SCSI_COMMAND_LENGTH),
+ StreamCallback_AbortOnMassStoreReset);
+
+ if ((MSInterfaceInfo->CommandBlock.Signature != CBW_SIGNATURE) ||
+ (MSInterfaceInfo->CommandBlock.LUN >= MSInterfaceInfo->TotalLUNs) ||
+ (MSInterfaceInfo->CommandBlock.SCSICommandLength > MAX_SCSI_COMMAND_LENGTH))
+ {
+ Endpoint_StallTransaction();
+ Endpoint_SelectEndpoint(MSInterfaceInfo->DataINEndpointNumber);
+ Endpoint_StallTransaction();
+
+ return false;
+ }
+
+ CallbackMSInterfaceInfo = MSInterfaceInfo;
+ Endpoint_Read_Stream_LE(&MSInterfaceInfo->CommandBlock.SCSICommandData,
+ MSInterfaceInfo->CommandBlock.SCSICommandLength,
+ StreamCallback_AbortOnMassStoreReset);
+
+ Endpoint_ClearOUT();
+
+ if (MSInterfaceInfo->IsMassStoreReset)
+ return false;
+
+ return true;
+}
+
+static void USB_MS_ReturnCommandStatus(USB_ClassInfo_MS_t* MSInterfaceInfo)
+{
+ Endpoint_SelectEndpoint(MSInterfaceInfo->DataOUTEndpointNumber);
+
+ while (Endpoint_IsStalled())
+ {
+ USB_USBTask();
+
+ if (MSInterfaceInfo->IsMassStoreReset)
+ return;
+ }
+
+ Endpoint_SelectEndpoint(MSInterfaceInfo->DataINEndpointNumber);
+
+ while (Endpoint_IsStalled())
+ {
+ USB_USBTask();
+
+ if (MSInterfaceInfo->IsMassStoreReset)
+ return;
+ }
+
+ CallbackMSInterfaceInfo = MSInterfaceInfo;
+ Endpoint_Write_Stream_LE(&MSInterfaceInfo->CommandStatus, sizeof(CommandStatusWrapper_t),
+ StreamCallback_AbortOnMassStoreReset);
+
+ Endpoint_ClearIN();
+
+ if (MSInterfaceInfo->IsMassStoreReset)
+ return;
+}
+
+static uint8_t StreamCallback_AbortOnMassStoreReset(void)
+{
+ USB_MS_USBTask(CallbackMSInterfaceInfo);
+
+ if (CallbackMSInterfaceInfo->IsMassStoreReset)
+ return STREAMCALLBACK_Abort;
+ else
+ return STREAMCALLBACK_Continue;
+}
diff --git a/LUFA/Drivers/USB/Class/Device/MassStorage.h b/LUFA/Drivers/USB/Class/Device/MassStorage.h
new file mode 100644
index 000000000..c1874b218
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/MassStorage.h
@@ -0,0 +1,127 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#ifndef _MS_CLASS_H_
+#define _MS_CLASS_H_
+
+ /* Includes: */
+ #include "../../USB.h"
+
+ #include <string.h>
+
+ /* Macros: */
+ /** Mass Storage Class specific request to reset the Mass Storage interface, ready for the next command. */
+ #define REQ_MassStorageReset 0xFF
+
+ /** Mass Storage Class specific request to retrieve the total number of Logical Units (drives) in the SCSI device. */
+ #define REQ_GetMaxLUN 0xFE
+
+ /** Maximum length of a SCSI command which can be issued by the device or host in a Mass Storage bulk wrapper. */
+ #define MAX_SCSI_COMMAND_LENGTH 16
+
+ /** Magic signature for a Command Block Wrapper used in the Mass Storage Bulk-Only transport protocol. */
+ #define CBW_SIGNATURE 0x43425355UL
+
+ /** Magic signature for a Command Status Wrapper used in the Mass Storage Bulk-Only transport protocol. */
+ #define CSW_SIGNATURE 0x53425355UL
+
+ /** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from host-to-device. */
+ #define COMMAND_DIRECTION_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 COMMAND_DIRECTION_DATA_IN (1 << 7)
+
+ /* Type defines: */
+ /** 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[MAX_SCSI_COMMAND_LENGTH]; /**< Issued SCSI command in the Command Block */
+ } CommandBlockWrapper_t;
+
+ /** 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 MassStorage_CommandStatusCodes_t enum */
+ } CommandStatusWrapper_t;
+
+ /* Enums: */
+ /** Enum for the possible command status wrapper return status codes. */
+ enum MassStorage_CommandStatusCodes_t
+ {
+ Command_Pass = 0, /**< Command completed with no error */
+ Command_Fail = 1, /**< Command failed to complete - host may check the exact error via a SCSI REQUEST SENSE command */
+ Phase_Error = 2 /**< Command failed due to being invalid in the current phase */
+ };
+
+ /* Type Defines: */
+ /** Type define for the virtual serial port line encoding settings, for storing the current USART configuration
+ * as set by the host via a class specific request.
+ */
+ typedef 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 */
+
+ 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 */
+
+ uint8_t TotalLUNs;
+
+ CommandBlockWrapper_t CommandBlock;
+ CommandStatusWrapper_t CommandStatus;
+
+ bool IsMassStoreReset;
+ } USB_ClassInfo_MS_t;
+
+ /* Function Prototypes: */
+ #if defined(INCLUDE_FROM_MS_CLASS_C)
+ static void USB_MS_ReturnCommandStatus(USB_ClassInfo_MS_t* MSInterfaceInfo);
+ static bool USB_MS_ReadInCommandBlock(USB_ClassInfo_MS_t* MSInterfaceInfo);
+ static uint8_t StreamCallback_AbortOnMassStoreReset(void);
+ #endif
+
+ void USB_MS_USBTask(USB_ClassInfo_MS_t* MSInterfaceInfo);
+ bool USB_MS_ConfigureEndpoints(USB_ClassInfo_MS_t* MSInterfaceInfo);
+ void USB_MS_ProcessControlPacket(USB_ClassInfo_MS_t* MSInterfaceInfo);
+
+ bool CALLBACK_USB_MS_SCSICommandReceived(USB_ClassInfo_MS_t* MSInterfaceInfo);
+
+#endif
diff --git a/LUFA/Drivers/USB/Class/Device/RNDIS.c b/LUFA/Drivers/USB/Class/Device/RNDIS.c
new file mode 100644
index 000000000..49c7df01d
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/RNDIS.c
@@ -0,0 +1,456 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define INCLUDE_FROM_RNDIS_CLASS_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 USB_RNDIS_ProcessControlPacket(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
+{
+ if (!(Endpoint_IsSETUPReceived()))
+ return;
+
+ if (USB_ControlRequest.wIndex != RNDISInterfaceInfo->ControlInterfaceNumber)
+ return;
+
+ switch (USB_ControlRequest.bRequest)
+ {
+ case REQ_SendEncapsulatedCommand:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->RNDISMessageBuffer, USB_ControlRequest.wLength);
+ Endpoint_ClearIN();
+
+ USB_RNDIS_ProcessRNDISControlMessage(RNDISInterfaceInfo);
+ }
+
+ break;
+ case REQ_GetEncapsulatedResponse:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+
+ if (!(MessageHeader->MessageLength))
+ {
+ RNDISInterfaceInfo->RNDISMessageBuffer[0] = 0;
+ MessageHeader->MessageLength = 1;
+ }
+
+ Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->RNDISMessageBuffer, MessageHeader->MessageLength);
+ Endpoint_ClearOUT();
+
+ MessageHeader->MessageLength = 0;
+ }
+
+ break;
+ }
+}
+
+bool USB_RNDIS_ConfigureEndpoints(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
+{
+ if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->DataINEndpointNumber, EP_TYPE_BULK,
+ ENDPOINT_DIR_IN, RNDISInterfaceInfo->DataINEndpointSize,
+ ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+
+ if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_BULK,
+ ENDPOINT_DIR_OUT, RNDISInterfaceInfo->DataOUTEndpointSize,
+ ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+
+ if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->NotificationEndpointNumber, EP_TYPE_INTERRUPT,
+ ENDPOINT_DIR_IN, RNDISInterfaceInfo->NotificationEndpointSize,
+ ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void USB_RNDIS_USBTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
+{
+ if (!(USB_IsConnected))
+ return;
+
+ RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+
+ Endpoint_SelectEndpoint(RNDISInterfaceInfo->NotificationEndpointNumber);
+
+ if (Endpoint_IsINReady() && RNDISInterfaceInfo->ResponseReady)
+ {
+ USB_Request_Header_t Notification = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = NOTIF_ResponseAvailable,
+ .wValue = 0,
+ .wIndex = 0,
+ .wLength = 0,
+ };
+
+ Endpoint_Write_Stream_LE(&Notification, sizeof(Notification), NO_STREAM_CALLBACK);
+
+ Endpoint_ClearIN();
+
+ RNDISInterfaceInfo->ResponseReady = false;
+ }
+
+ if ((RNDISInterfaceInfo->CurrRNDISState == RNDIS_Data_Initialized) && !(MessageHeader->MessageLength))
+ {
+ RNDIS_PACKET_MSG_t RNDISPacketHeader;
+
+ Endpoint_SelectEndpoint(RNDISInterfaceInfo->DataOUTEndpointNumber);
+
+ if (Endpoint_IsOUTReceived() && !(RNDISInterfaceInfo->FrameIN.FrameInBuffer))
+ {
+ Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_PACKET_MSG_t), NO_STREAM_CALLBACK);
+
+ if (RNDISPacketHeader.DataLength > ETHERNET_FRAME_SIZE_MAX)
+ {
+ Endpoint_StallTransaction();
+ return;
+ }
+
+ Endpoint_Read_Stream_LE(RNDISInterfaceInfo->FrameIN.FrameData, RNDISPacketHeader.DataLength, NO_STREAM_CALLBACK);
+
+ Endpoint_ClearOUT();
+
+ RNDISInterfaceInfo->FrameIN.FrameLength = RNDISPacketHeader.DataLength;
+
+ RNDISInterfaceInfo->FrameIN.FrameInBuffer = true;
+ }
+
+ Endpoint_SelectEndpoint(RNDISInterfaceInfo->DataINEndpointNumber);
+
+ if (Endpoint_IsINReady() && RNDISInterfaceInfo->FrameOUT.FrameInBuffer)
+ {
+ memset(&RNDISPacketHeader, 0, sizeof(RNDIS_PACKET_MSG_t));
+
+ RNDISPacketHeader.MessageType = REMOTE_NDIS_PACKET_MSG;
+ RNDISPacketHeader.MessageLength = (sizeof(RNDIS_PACKET_MSG_t) + RNDISInterfaceInfo->FrameOUT.FrameLength);
+ RNDISPacketHeader.DataOffset = (sizeof(RNDIS_PACKET_MSG_t) - sizeof(RNDIS_Message_Header_t));
+ RNDISPacketHeader.DataLength = RNDISInterfaceInfo->FrameOUT.FrameLength;
+
+ Endpoint_Write_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_PACKET_MSG_t), NO_STREAM_CALLBACK);
+ Endpoint_Write_Stream_LE(RNDISInterfaceInfo->FrameOUT.FrameData, RNDISPacketHeader.DataLength, NO_STREAM_CALLBACK);
+ Endpoint_ClearIN();
+
+ RNDISInterfaceInfo->FrameOUT.FrameInBuffer = false;
+ }
+ }
+}
+
+void USB_RNDIS_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_t* 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->RNDISMessageBuffer;
+
+ switch (MessageHeader->MessageType)
+ {
+ case REMOTE_NDIS_INITIALIZE_MSG:
+ RNDISInterfaceInfo->ResponseReady = true;
+
+ RNDIS_INITIALIZE_MSG_t* INITIALIZE_Message = (RNDIS_INITIALIZE_MSG_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+ RNDIS_INITIALIZE_CMPLT_t* INITIALIZE_Response = (RNDIS_INITIALIZE_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+
+ INITIALIZE_Response->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
+ INITIALIZE_Response->MessageLength = sizeof(RNDIS_INITIALIZE_CMPLT_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_MSG_t) + ETHERNET_FRAME_SIZE_MAX);
+ INITIALIZE_Response->PacketAlignmentFactor = 0;
+ INITIALIZE_Response->AFListOffset = 0;
+ INITIALIZE_Response->AFListSize = 0;
+
+ RNDISInterfaceInfo->CurrRNDISState = RNDIS_Initialized;
+
+ break;
+ case REMOTE_NDIS_HALT_MSG:
+ RNDISInterfaceInfo->ResponseReady = false;
+ MessageHeader->MessageLength = 0;
+
+ RNDISInterfaceInfo->CurrRNDISState = RNDIS_Uninitialized;
+
+ break;
+ case REMOTE_NDIS_QUERY_MSG:
+ RNDISInterfaceInfo->ResponseReady = true;
+
+ RNDIS_QUERY_MSG_t* QUERY_Message = (RNDIS_QUERY_MSG_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+ RNDIS_QUERY_CMPLT_t* QUERY_Response = (RNDIS_QUERY_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+ uint32_t Query_Oid = QUERY_Message->Oid;
+
+ void* QueryData = &RNDISInterfaceInfo->RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
+ QUERY_Message->InformationBufferOffset];
+ void* ResponseData = &RNDISInterfaceInfo->RNDISMessageBuffer[sizeof(RNDIS_QUERY_CMPLT_t)];
+ uint16_t ResponseSize;
+
+ QUERY_Response->MessageType = REMOTE_NDIS_QUERY_CMPLT;
+ QUERY_Response->MessageLength = sizeof(RNDIS_QUERY_CMPLT_t);
+
+ if (USB_RNDIS_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_CMPLT_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->ResponseReady = true;
+
+ RNDIS_SET_MSG_t* SET_Message = (RNDIS_SET_MSG_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+ RNDIS_SET_CMPLT_t* SET_Response = (RNDIS_SET_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+ uint32_t SET_Oid = SET_Message->Oid;
+
+ SET_Response->MessageType = REMOTE_NDIS_SET_CMPLT;
+ SET_Response->MessageLength = sizeof(RNDIS_SET_CMPLT_t);
+ SET_Response->RequestId = SET_Message->RequestId;
+
+ void* SetData = &RNDISInterfaceInfo->RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
+ SET_Message->InformationBufferOffset];
+
+ if (USB_RNDIS_ProcessNDISSet(RNDISInterfaceInfo, SET_Oid, SetData, SET_Message->InformationBufferLength))
+ SET_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
+ else
+ SET_Response->Status = REMOTE_NDIS_STATUS_NOT_SUPPORTED;
+
+ break;
+ case REMOTE_NDIS_RESET_MSG:
+ RNDISInterfaceInfo->ResponseReady = true;
+
+ RNDIS_RESET_CMPLT_t* RESET_Response = (RNDIS_RESET_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+
+ RESET_Response->MessageType = REMOTE_NDIS_RESET_CMPLT;
+ RESET_Response->MessageLength = sizeof(RNDIS_RESET_CMPLT_t);
+ RESET_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
+ RESET_Response->AddressingReset = 0;
+
+ break;
+ case REMOTE_NDIS_KEEPALIVE_MSG:
+ RNDISInterfaceInfo->ResponseReady = true;
+
+ RNDIS_KEEPALIVE_MSG_t* KEEPALIVE_Message = (RNDIS_KEEPALIVE_MSG_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+ RNDIS_KEEPALIVE_CMPLT_t* KEEPALIVE_Response = (RNDIS_KEEPALIVE_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+
+ KEEPALIVE_Response->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
+ KEEPALIVE_Response->MessageLength = sizeof(RNDIS_KEEPALIVE_CMPLT_t);
+ KEEPALIVE_Response->RequestId = KEEPALIVE_Message->RequestId;
+ KEEPALIVE_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
+
+ break;
+ }
+}
+
+static bool USB_RNDIS_ProcessNDISQuery(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo,
+ uint32_t OId, void* QueryData, uint16_t QuerySize,
+ void* ResponseData, uint16_t* ResponseSize)
+{
+ 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) = NdisHardwareStatusReady;
+
+ 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->AdapterVendorDescription) + 1);
+
+ memcpy(ResponseData, RNDISInterfaceInfo->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->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->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 USB_RNDIS_ProcessNDISSet(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo, uint32_t OId, void* SetData, uint16_t SetSize)
+{
+ switch (OId)
+ {
+ case OID_GEN_CURRENT_PACKET_FILTER:
+ RNDISInterfaceInfo->CurrPacketFilter = *((uint32_t*)SetData);
+ RNDISInterfaceInfo->CurrRNDISState = ((RNDISInterfaceInfo->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;
+ }
+}
diff --git a/LUFA/Drivers/USB/Class/Device/RNDIS.h b/LUFA/Drivers/USB/Class/Device/RNDIS.h
new file mode 100644
index 000000000..73622a4dc
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/RNDIS.h
@@ -0,0 +1,260 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#ifndef _RNDIS_CLASS_H_
+#define _RNDIS_CLASS_H_
+
+ /* Includes: */
+ #include <string.h>
+
+ #include "../../USB.h"
+ #include "RNDISConstants.h"
+
+ /* Macros: */
+ /** Implemented RNDIS Version Major */
+ #define REMOTE_NDIS_VERSION_MAJOR 0x01
+
+ /** Implemented RNDIS Version Minor */
+ #define REMOTE_NDIS_VERSION_MINOR 0x00
+
+ /** RNDIS request to issue a host-to-device NDIS command */
+ #define REQ_SendEncapsulatedCommand 0x00
+
+ /** RNDIS request to issue a device-to-host NDIS response */
+ #define REQ_GetEncapsulatedResponse 0x01
+
+ #define RNDIS_MESSAGE_BUFFER_SIZE 128
+
+ #define ETHERNET_FRAME_SIZE_MAX 1500
+
+ #define NOTIF_ResponseAvailable 1
+
+ /* Enums: */
+ /** 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 NDIS hardware states */
+ enum NDIS_Hardware_Status_t
+ {
+ NdisHardwareStatusReady, /**< Hardware Ready to accept commands from the host */
+ NdisHardwareStatusInitializing, /**< Hardware busy initializing */
+ NdisHardwareStatusReset, /**< Hardware reset */
+ NdisHardwareStatusClosing, /**< Hardware currently closing */
+ NdisHardwareStatusNotReady /**< Hardware not ready to accept commands from the host */
+ };
+
+ /* Type Defines: */
+ /** 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;
+
+ /** 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;
+
+ /** Type define for an Ethernet frame buffer. */
+ 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;
+
+ /** 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_MSG_t;
+
+ typedef 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 */
+
+ 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 */
+
+ 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 */
+
+ char* AdapterVendorDescription;
+ MAC_Address_t AdapterMACAddress;
+
+ uint8_t RNDISMessageBuffer[RNDIS_MESSAGE_BUFFER_SIZE];
+ bool ResponseReady;
+ uint8_t CurrRNDISState;
+ uint32_t CurrPacketFilter;
+ Ethernet_Frame_Info_t FrameIN;
+ Ethernet_Frame_Info_t FrameOUT;
+ } USB_ClassInfo_RNDIS_t;
+
+ /** 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_MSG_t;
+
+ /** 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_CMPLT_t;
+
+ /** Type define for a RNDIS Keepalive command message */
+ typedef struct
+ {
+ uint32_t MessageType;
+ uint32_t MessageLength;
+ uint32_t RequestId;
+ } RNDIS_KEEPALIVE_MSG_t;
+
+ /** Type define for a RNDIS Keepalive complete message */
+ typedef struct
+ {
+ uint32_t MessageType;
+ uint32_t MessageLength;
+ uint32_t RequestId;
+ uint32_t Status;
+ } RNDIS_KEEPALIVE_CMPLT_t;
+
+ /** Type define for a RNDIS Reset complete message */
+ typedef struct
+ {
+ uint32_t MessageType;
+ uint32_t MessageLength;
+ uint32_t Status;
+
+ uint32_t AddressingReset;
+ } RNDIS_RESET_CMPLT_t;
+
+ /** Type define for a RNDIS 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_MSG_t;
+
+ /** Type define for a RNDIS Set complete response message */
+ typedef struct
+ {
+ uint32_t MessageType;
+ uint32_t MessageLength;
+ uint32_t RequestId;
+ uint32_t Status;
+ } RNDIS_SET_CMPLT_t;
+
+ /** Type define for a RNDIS 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_MSG_t;
+
+ /** Type define for a RNDIS 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_CMPLT_t;
+
+ /* Function Prototypes: */
+ #if defined(INCLUDE_FROM_RNDIS_CLASS_C)
+ static void USB_RNDIS_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
+ static bool USB_RNDIS_ProcessNDISQuery(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo,
+ uint32_t OId, void* QueryData, uint16_t QuerySize,
+ void* ResponseData, uint16_t* ResponseSize);
+ static bool USB_RNDIS_ProcessNDISSet(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo, uint32_t OId,
+ void* SetData, uint16_t SetSize);
+ #endif
+
+ void USB_RNDIS_USBTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
+ bool USB_RNDIS_ConfigureEndpoints(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
+ void USB_RNDIS_ProcessControlPacket(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
+ void USB_RNDIS_USBTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
+
+#endif
diff --git a/LUFA/Drivers/USB/Class/Device/RNDISConstants.h b/LUFA/Drivers/USB/Class/Device/RNDISConstants.h
new file mode 100644
index 000000000..ad66f62db
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/RNDISConstants.h
@@ -0,0 +1,99 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ *
+ * RNDIS specification related constants. For more information on these
+ * constants, please refer to the Microsoft RNDIS specification.
+ */
+
+#ifndef _RNDIS_CONSTANTS_H_
+#define _RNDIS_CONSTANTS_H_
+
+ /* Macros: */
+ #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
+
+ #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
+
+ #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
+
+ #define REMOTE_NDIS_MEDIA_STATE_CONNECTED 0x00000000UL
+ #define REMOTE_NDIS_MEDIA_STATE_DISCONNECTED 0x00000001UL
+
+ #define REMOTE_NDIS_MEDIUM_802_3 0x00000000UL
+
+ #define REMOTE_NDIS_DF_CONNECTIONLESS 0x00000001UL
+ #define REMOTE_NDIS_DF_CONNECTION_ORIENTED 0x00000002UL
+
+ #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
+
+#endif
diff --git a/LUFA/Drivers/USB/Class/HIDParser.c b/LUFA/Drivers/USB/Class/Host/HIDParser.c
index 5fb29aa0a..5fb29aa0a 100644
--- a/LUFA/Drivers/USB/Class/HIDParser.c
+++ b/LUFA/Drivers/USB/Class/Host/HIDParser.c
diff --git a/LUFA/Drivers/USB/Class/HIDParser.h b/LUFA/Drivers/USB/Class/Host/HIDParser.h
index 49e57c295..4acce2462 100644
--- a/LUFA/Drivers/USB/Class/HIDParser.h
+++ b/LUFA/Drivers/USB/Class/Host/HIDParser.h
@@ -63,7 +63,7 @@
#include "HIDReportData.h"
- #include "../../../Common/Common.h"
+ #include "../../../../Common/Common.h"
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
diff --git a/LUFA/Drivers/USB/Class/HIDReportData.h b/LUFA/Drivers/USB/Class/Host/HIDReportData.h
index eee38be04..eee38be04 100644
--- a/LUFA/Drivers/USB/Class/HIDReportData.h
+++ b/LUFA/Drivers/USB/Class/Host/HIDReportData.h
diff --git a/LUFA/Drivers/USB/HighLevel/Events.h b/LUFA/Drivers/USB/HighLevel/Events.h
index e6d2beaa7..ded027b12 100644
--- a/LUFA/Drivers/USB/HighLevel/Events.h
+++ b/LUFA/Drivers/USB/HighLevel/Events.h
@@ -267,6 +267,11 @@
* \ref Group_USBManagement documentation).
*/
void EVENT_USB_Reset(void);
+
+ /** Event for the USB start of frame interrupt, firing once each millisecond in either device or host
+ * mode, while USB frames are being generated or recieved.
+ */
+ void EVENT_USB_StartOfFrame(void);
#endif
/* Private Interface - For use in library only: */
@@ -303,6 +308,7 @@
void EVENT_USB_Suspend(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);
void EVENT_USB_WakeUp(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);
void EVENT_USB_Reset(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);
+ void EVENT_USB_StartOfFrame(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);
#endif
#endif
diff --git a/LUFA/Drivers/USB/HighLevel/USBInterrupt.c b/LUFA/Drivers/USB/HighLevel/USBInterrupt.c
index 0b9d08223..0ccbe6155 100644
--- a/LUFA/Drivers/USB/HighLevel/USBInterrupt.c
+++ b/LUFA/Drivers/USB/HighLevel/USBInterrupt.c
@@ -180,6 +180,15 @@ ISR(USB_GEN_vect, ISR_BLOCK)
EVENT_USB_Reset();
}
+
+ if (USB_INT_HasOccurred(USB_INT_SOFI) && USB_INT_IsEnabled(USB_INT_SOFI))
+ {
+ USB_INT_Clear(USB_INT_SOFI);
+
+ FrameElapsed = true;
+
+ EVENT_USB_StartOfFrame();
+ }
#endif
#if defined(USB_CAN_BE_HOST)
@@ -232,6 +241,15 @@ ISR(USB_GEN_vect, ISR_BLOCK)
USB_ResetInterface();
}
+
+ if (USB_INT_HasOccurred(USB_INT_HSOFI) && USB_INT_IsEnabled(USB_INT_HSOFI))
+ {
+ USB_INT_Clear(USB_INT_HSOFI);
+
+ FrameElapsed = true;
+
+ EVENT_USB_StartOfFrame();
+ }
#endif
#if defined(USB_CAN_BE_BOTH)
diff --git a/LUFA/Drivers/USB/HighLevel/USBTask.c b/LUFA/Drivers/USB/HighLevel/USBTask.c
index e2b7e91d5..46fcd5709 100644
--- a/LUFA/Drivers/USB/HighLevel/USBTask.c
+++ b/LUFA/Drivers/USB/HighLevel/USBTask.c
@@ -42,7 +42,7 @@ USB_Request_Header_t USB_ControlRequest;
volatile uint8_t USB_HostState;
#endif
-TASK(USB_USBTask)
+void USB_USBTask(void)
{
#if defined(USB_HOST_ONLY)
USB_HostTask();
diff --git a/LUFA/Drivers/USB/HighLevel/USBTask.h b/LUFA/Drivers/USB/HighLevel/USBTask.h
index 1e1209a5f..e4c8a02ae 100644
--- a/LUFA/Drivers/USB/HighLevel/USBTask.h
+++ b/LUFA/Drivers/USB/HighLevel/USBTask.h
@@ -38,7 +38,6 @@
#include <stdbool.h>
#include <stddef.h>
- #include "../../../Scheduler/Scheduler.h"
#include "../LowLevel/LowLevel.h"
#include "StdRequestType.h"
#include "USBMode.h"
@@ -122,11 +121,11 @@
extern volatile uint8_t USB_HostState;
#endif
- /* Tasks: */
+ /* Function Prototypes: */
/** This is the main USB management task. The USB driver requires that this task be executed
* continuously when the USB system is active (device attached in host mode, or attached to a host
* in device mode) in order to manage USB communications. This task may be executed inside an RTOS,
- * scheduler (e.g. the simple LUFA Scheduler), fast timer ISR or the main user application loop.
+ * fast timer ISR or the main user application loop.
*
* The USB task must be serviced within 30ms while in device mode, or within 1ms while in host mode.
* The task may be serviced at all times, or (for minimum CPU consumption):
@@ -145,7 +144,7 @@
*
* \ingroup Group_USBManagement
*/
- TASK(USB_USBTask);
+ void USB_USBTask(void);
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
diff --git a/LUFA/Drivers/USB/LowLevel/Endpoint.c b/LUFA/Drivers/USB/LowLevel/Endpoint.c
index 099022c1c..d02071bbd 100644
--- a/LUFA/Drivers/USB/LowLevel/Endpoint.c
+++ b/LUFA/Drivers/USB/LowLevel/Endpoint.c
@@ -80,8 +80,6 @@ uint8_t Endpoint_WaitUntilReady(void)
uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
#endif
- USB_INT_Clear(USB_INT_SOFI);
-
for (;;)
{
if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN)
@@ -100,9 +98,9 @@ uint8_t Endpoint_WaitUntilReady(void)
else if (Endpoint_IsStalled())
return ENDPOINT_READYWAIT_EndpointStalled;
- if (USB_INT_HasOccurred(USB_INT_SOFI))
+ if (FrameElapsed)
{
- USB_INT_Clear(USB_INT_SOFI);
+ FrameElapsed = false;
if (!(TimeoutMSRem--))
return ENDPOINT_READYWAIT_Timeout;
diff --git a/LUFA/Drivers/USB/LowLevel/Host.c b/LUFA/Drivers/USB/LowLevel/Host.c
index b606515e6..02a1c2171 100644
--- a/LUFA/Drivers/USB/LowLevel/Host.c
+++ b/LUFA/Drivers/USB/LowLevel/Host.c
@@ -210,14 +210,13 @@ uint8_t USB_Host_WaitMS(uint8_t MS)
bool BusSuspended = USB_Host_IsBusSuspended();
uint8_t ErrorCode = HOST_WAITERROR_Successful;
- USB_INT_Clear(USB_INT_HSOFI);
USB_Host_ResumeBus();
while (MS)
{
- if (USB_INT_HasOccurred(USB_INT_HSOFI))
+ if (FrameElapsed)
{
- USB_INT_Clear(USB_INT_HSOFI);
+ FrameElapsed = false;
MS--;
}
@@ -260,9 +259,10 @@ static void USB_Host_ResetDevice(void)
USB_Host_ResetBus();
while (!(USB_Host_IsBusResetComplete()));
- USB_INT_Clear(USB_INT_HSOFI);
USB_Host_ResumeBus();
+ FrameElapsed = false;
+
for (uint8_t MSRem = 10; MSRem != 0; MSRem--)
{
/* Workaround for powerless-pull-up devices. After a USB bus reset,
@@ -270,8 +270,10 @@ static void USB_Host_ResetDevice(void)
looked for - if it is found within 10ms, the device is still
present. */
- if (USB_INT_HasOccurred(USB_INT_HSOFI))
+ if (FrameElapsed)
{
+ FrameElapsed = false;
+
USB_INT_Clear(USB_INT_DDISCI);
break;
}
diff --git a/LUFA/Drivers/USB/LowLevel/LowLevel.c b/LUFA/Drivers/USB/LowLevel/LowLevel.c
index 8b395be98..255a6ef29 100644
--- a/LUFA/Drivers/USB/LowLevel/LowLevel.c
+++ b/LUFA/Drivers/USB/LowLevel/LowLevel.c
@@ -38,6 +38,8 @@ volatile uint8_t USB_CurrentMode = USB_MODE_NONE;
volatile uint8_t USB_Options;
#endif
+volatile bool FrameElapsed;
+
void USB_Init(
#if defined(USB_CAN_BE_BOTH)
const uint8_t Mode
@@ -150,6 +152,8 @@ void USB_ResetInterface(void)
USB_INT_DisableAllInterrupts();
USB_INT_ClearAllInterrupts();
+ FrameElapsed = false;
+
USB_IsConnected = false;
#if defined(USB_CAN_BE_HOST)
@@ -224,6 +228,7 @@ void USB_ResetInterface(void)
#if defined(USB_DEVICE_ONLY)
USB_INT_Enable(USB_INT_SUSPEND);
USB_INT_Enable(USB_INT_EORSTI);
+ USB_INT_Enable(USB_INT_SOFI);
#if defined(CONTROL_ONLY_DEVICE)
UENUM = ENDPOINT_CONTROLEP;
@@ -240,11 +245,13 @@ void USB_ResetInterface(void)
USB_INT_Enable(USB_INT_SRPI);
USB_INT_Enable(USB_INT_BCERRI);
+ USB_INT_Enable(USB_INT_HSOFI);
#else
if (USB_CurrentMode == USB_MODE_DEVICE)
{
USB_INT_Enable(USB_INT_SUSPEND);
USB_INT_Enable(USB_INT_EORSTI);
+ USB_INT_Enable(USB_INT_SOFI);
#if defined(CONTROL_ONLY_DEVICE)
UENUM = ENDPOINT_CONTROLEP;
@@ -262,6 +269,7 @@ void USB_ResetInterface(void)
USB_INT_Enable(USB_INT_SRPI);
USB_INT_Enable(USB_INT_BCERRI);
+ USB_INT_Enable(USB_INT_HSOFI);
}
#endif
}
diff --git a/LUFA/Drivers/USB/LowLevel/LowLevel.h b/LUFA/Drivers/USB/LowLevel/LowLevel.h
index 41b0ff5f6..4279ca315 100644
--- a/LUFA/Drivers/USB/LowLevel/LowLevel.h
+++ b/LUFA/Drivers/USB/LowLevel/LowLevel.h
@@ -350,6 +350,9 @@
return USB_MODE_HOST;
}
#endif
+
+ /* External Variables: */
+ extern volatile bool FrameElapsed;
#endif
diff --git a/LUFA/Drivers/USB/LowLevel/Pipe.c b/LUFA/Drivers/USB/LowLevel/Pipe.c
index 71a33d62f..720da1772 100644
--- a/LUFA/Drivers/USB/LowLevel/Pipe.c
+++ b/LUFA/Drivers/USB/LowLevel/Pipe.c
@@ -76,8 +76,6 @@ uint8_t Pipe_WaitUntilReady(void)
uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
#endif
- USB_INT_Clear(USB_INT_HSOFI);
-
for (;;)
{
if (Pipe_GetPipeToken() == PIPE_TOKEN_IN)
@@ -96,9 +94,9 @@ uint8_t Pipe_WaitUntilReady(void)
else if (!(USB_IsConnected))
return PIPE_READYWAIT_DeviceDisconnected;
- if (USB_INT_HasOccurred(USB_INT_HSOFI))
+ if (FrameElapsed)
{
- USB_INT_Clear(USB_INT_HSOFI);
+ FrameElapsed = false;
if (!(TimeoutMSRem--))
return PIPE_READYWAIT_Timeout;
diff --git a/LUFA/Drivers/USB/USB.h b/LUFA/Drivers/USB/USB.h
index 6d66c4d14..3c8f06237 100644
--- a/LUFA/Drivers/USB/USB.h
+++ b/LUFA/Drivers/USB/USB.h
@@ -49,7 +49,6 @@
* - LUFA/Drivers/USB/HighLevel/USBInterrupt.c
* - LUFA/Drivers/USB/HighLevel/USBTask.c
* - LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c
- * - LUFA/Drivers/USB/Class/HIDParser.c
*
* \section Module Description
* Functions, macros, variables, enums and types related to the management of USB communications.
@@ -97,7 +96,6 @@
#endif
#include "HighLevel/ConfigDescriptor.h"
- #include "Class/HIDParser.h"
#endif
diff --git a/LUFA/MemoryAllocator/DynAlloc.c b/LUFA/MemoryAllocator/DynAlloc.c
deleted file mode 100644
index 4f1c82241..000000000
--- a/LUFA/MemoryAllocator/DynAlloc.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2009.
-
- dean [at] fourwalledcubicle [dot] com
- www.fourwalledcubicle.com
-*/
-
-/*
- Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, and distribute this software
- and its documentation for any purpose and without fee is hereby
- granted, provided that the above copyright notice appear in all
- copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaim all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-#define INCLUDE_FROM_DYNALLOC_C
-#include "DynAlloc.h"
-
-struct
-{
- char Mem_Heap[NUM_BLOCKS * BLOCK_SIZE];
- void* Mem_Handles[NUM_HANDLES];
- uint8_t Mem_Block_Flags[(NUM_BLOCKS / 4) + ((NUM_BLOCKS % 4) ? 1 : 0)];
- uint8_t FlagMaskLookupMask[4];
- uint8_t FlagMaskLookupNum[4];
-} Mem_MemData = {.FlagMaskLookupMask = {(3 << 0), (3 << 2), (3 << 4), (3 << 6)},
- .FlagMaskLookupNum = { 0, 2, 4, 6}};
-
-static uint8_t Mem_GetBlockFlags(const Block_Number_t BlockNum)
-{
- const Block_Number_t BlockIndex = (BlockNum >> 2);
- const uint8_t FlagMask = Mem_MemData.FlagMaskLookupMask[BlockNum & 0x03];
- const uint8_t FlagMaskShift = Mem_MemData.FlagMaskLookupNum[BlockNum & 0x03];
-
- return ((Mem_MemData.Mem_Block_Flags[BlockIndex] & FlagMask) >> FlagMaskShift);
-}
-
-static void Mem_SetBlockFlags(const Block_Number_t BlockNum, const uint8_t Flags)
-{
- const Block_Number_t BlockIndex = (BlockNum >> 2);
- const uint8_t FlagMask = Mem_MemData.FlagMaskLookupMask[BlockNum & 0x03];
- const uint8_t FlagMaskShift = Mem_MemData.FlagMaskLookupNum[BlockNum & 0x03];
-
- Mem_MemData.Mem_Block_Flags[BlockIndex] &= ~FlagMask;
- Mem_MemData.Mem_Block_Flags[BlockIndex] |= (Flags << FlagMaskShift);
-}
-
-static inline void Mem_Defrag(void)
-{
- Block_Number_t FreeStartBlock = 0;
- char* FreeStartPtr = NULL;
- char* UsedStartPtr = NULL;
- Block_Number_t CurrBlock;
-
- for (CurrBlock = 0; CurrBlock < NUM_BLOCKS; CurrBlock++)
- {
- if (!(Mem_GetBlockFlags(CurrBlock) & BLOCK_USED_MASK))
- {
- FreeStartPtr = &Mem_MemData.Mem_Heap[CurrBlock * BLOCK_SIZE];
- FreeStartBlock = CurrBlock;
- break;
- }
- }
-
- if (FreeStartPtr == NULL)
- return;
-
- while (++CurrBlock < NUM_BLOCKS)
- {
- uint8_t CurrBlockFlags = Mem_GetBlockFlags(CurrBlock);
-
- if (CurrBlockFlags & BLOCK_USED_MASK)
- {
- UsedStartPtr = &Mem_MemData.Mem_Heap[CurrBlock * BLOCK_SIZE];
-
- for (Handle_Number_t HandleNum = 0; HandleNum < NUM_HANDLES; HandleNum++)
- {
- if (Mem_MemData.Mem_Handles[HandleNum] == UsedStartPtr)
- {
- Mem_MemData.Mem_Handles[HandleNum] = FreeStartPtr;
- break;
- }
- }
-
- memcpy(FreeStartPtr, UsedStartPtr, BLOCK_SIZE);
- FreeStartPtr += BLOCK_SIZE;
-
- Mem_SetBlockFlags(FreeStartBlock++, CurrBlockFlags);
- Mem_SetBlockFlags(CurrBlock, 0);
- }
- }
-}
-
-static inline bool Mem_FindFreeBlocks(Block_Number_t* const RetStartPtr, const Block_Number_t Blocks)
-{
- Block_Number_t FreeInCurrSec = 0;
-
- for (Block_Number_t CurrBlock = 0; CurrBlock < NUM_BLOCKS; CurrBlock++)
- {
- if (Mem_GetBlockFlags(CurrBlock) & BLOCK_USED_MASK)
- FreeInCurrSec = 0;
- else
- FreeInCurrSec++;
-
- if (FreeInCurrSec >= Blocks)
- {
- *RetStartPtr = CurrBlock;
- return true;
- }
- }
-
- return false;
-}
-
-Mem_Handle_t Mem_Alloc(const Alloc_Size_t Bytes)
-{
- Block_Number_t ReqBlocks = (Bytes / BLOCK_SIZE);
- Block_Number_t StartBlock;
-
- if (Bytes % BLOCK_SIZE)
- ReqBlocks++;
-
- if (!(Mem_FindFreeBlocks(&StartBlock, ReqBlocks)))
- {
- Mem_Defrag();
-
- if (!(Mem_FindFreeBlocks(&StartBlock, ReqBlocks)))
- return NULL;
- }
-
- for (Block_Number_t UsedBlock = 0; UsedBlock < (ReqBlocks - 1); UsedBlock++)
- Mem_SetBlockFlags((StartBlock + UsedBlock), (BLOCK_USED_MASK | BLOCK_LINKED_MASK));
-
- Mem_SetBlockFlags((StartBlock + (ReqBlocks - 1)), BLOCK_USED_MASK);
-
- for (Handle_Number_t AllocEntry = 0; AllocEntry < NUM_HANDLES; AllocEntry++)
- {
- Mem_Handle_t CurrHdl = (Mem_Handle_t)&Mem_MemData.Mem_Handles[AllocEntry];
-
- if (DEREF(CurrHdl, void*) == NULL)
- {
- DEREF(CurrHdl, void*) = &Mem_MemData.Mem_Heap[StartBlock * BLOCK_SIZE];
- return CurrHdl;
- }
- }
-
- return NULL;
-}
-
-Mem_Handle_t Mem_Realloc(Mem_Handle_t CurrAllocHdl, const Alloc_Size_t Bytes)
-{
- Mem_Free(CurrAllocHdl);
- return Mem_Alloc(Bytes);
-}
-
-Mem_Handle_t Mem_Calloc(const Alloc_Size_t Bytes)
-{
- Mem_Handle_t AllocHdl = Mem_Alloc(Bytes);
-
- if (AllocHdl != NULL)
- memset(DEREF(AllocHdl, void*), 0x00, Bytes);
-
- return AllocHdl;
-}
-
-void Mem_Free(Mem_Handle_t CurrAllocHdl)
-{
- char* MemBlockPtr = DEREF(CurrAllocHdl, char*);
- Block_Number_t CurrBlock = ((uint16_t)(MemBlockPtr - Mem_MemData.Mem_Heap) / BLOCK_SIZE);
- uint8_t CurrBlockFlags;
-
- if ((CurrAllocHdl == NULL) || (MemBlockPtr == NULL))
- return;
-
- do
- {
- CurrBlockFlags = Mem_GetBlockFlags(CurrBlock);
- Mem_SetBlockFlags(CurrBlock, 0);
-
- CurrBlock++;
- }
- while (CurrBlockFlags & BLOCK_LINKED_MASK);
-
- DEREF(CurrAllocHdl, void*) = NULL;
-}
-
-Block_Number_t Mem_TotalFreeBlocks(void)
-{
- Block_Number_t FreeBlocks = 0;
-
- for (Block_Number_t CurrBlock = 0; CurrBlock < NUM_BLOCKS; CurrBlock++)
- {
- if (!(Mem_GetBlockFlags(CurrBlock) & BLOCK_USED_MASK))
- FreeBlocks++;
- }
-
- return FreeBlocks;
-}
-
-Handle_Number_t Mem_TotalFreeHandles(void)
-{
- Handle_Number_t FreeHandles = 0;
-
- for (Handle_Number_t CurrHandle = 0; CurrHandle < NUM_HANDLES; CurrHandle++)
- {
- if (Mem_MemData.Mem_Handles[CurrHandle] == NULL)
- FreeHandles++;
- }
-
- return FreeHandles;
-}
diff --git a/LUFA/MemoryAllocator/DynAlloc.h b/LUFA/MemoryAllocator/DynAlloc.h
deleted file mode 100644
index acbfbd18a..000000000
--- a/LUFA/MemoryAllocator/DynAlloc.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2009.
-
- dean [at] fourwalledcubicle [dot] com
- www.fourwalledcubicle.com
-*/
-
-/*
- Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, and distribute this software
- and its documentation for any purpose and without fee is hereby
- granted, provided that the above copyright notice appear in all
- copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaim all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Dynamic, auto-defragmenting block memory allocator library. This library provides a convenient replacement for
- * the standard avr-libc dynamic memory allocation routines. Memory is handed out in block chunks, to reduce the
- * management memory overhead.
- */
-
-/** @defgroup Group_MemoryAllocator Dynamic Block Memory Allocator - LUFA/MemoryAllocator/DynAlloc.h
- *
- * \section Sec_Dependencies Module Source Dependencies
- * The following files must be built with any user project that uses this module:
- * - LUFA/MemoryAllocator/DynAlloc.c
- *
- * \section Module Description
- * Dynamic, auto-defragmenting block memory allocator library. This library provides a convenient replacement for
- * the standard avr-libc dynamic memory allocation routines. Memory is handed out in block chunks, to reduce the
- * management memory overhead.
- *
- * Unlike the normal memory allocation routines, this library gives out handles to memory which must be dereferenced
- * at the exact time of use, rather than handing back direct memory pointers. By using library managed handles
- * instead of pointers, allocated memory blocks can be shifted around as needed transparently to defragment the
- * memory as more blocks are requested.
- *
- * The memory heap is static, thus the total memory usage of the compiled application (as reported by the avr-size
- * tool of the AVR-GCC toolchain) includes the dynamic memory heap.
- *
- * The constants NUM_BLOCKS, BLOCK_SIZE and NUM_HANDLES must be defined in the project makefile (and passed to the
- * preprocessor via the -D GCC switch) for this library to compile.
- *
- * NUM_BLOCKS indicates the number of memory blocks in the memory psudoheap which can be chained together and handed
- * to the application via a memory handle. NUM_HANDLES is the maximum number of memory handles (pointing to one or
- * more chained memory blocks) which can be handed out simultaneously before requiring a handle (and its associated
- * memory) to be freed. BLOCK_SIZE gives the number of bytes in each memory block.
- *
- * @{
- */
-
-#ifndef __DYN_ALLOC__
-#define __DYN_ALLOC__
-
- /* Includes : */
- #include <avr/io.h>
- #include <stdbool.h>
- #include <string.h>
-
- /* Preprocessor Checks: */
- #if (!defined(NUM_BLOCKS) || !defined(BLOCK_SIZE) || !defined(NUM_HANDLES))
- #error NUM_BLOCKS, BLOCK_SIZE and NUM_HANDLES must be defined before use via makefile.
- #endif
-
- /* Public Interface - May be used in end-application: */
- /* Macros: */
- /** Macro to dereference a given memory handle into the given type. The given type should be a pointer
- * if the memory is to contain an array of items, or should be a standard type (such as a primitive or
- * structure) if the memory is to hold a single item of a single type. */
- #define DEREF(handle, type) (*(type*)handle)
-
- /** Constant, giving the total heap size in bytes. */
- #define ALLOCABLE_BYTES (1UL * NUM_BLOCKS * BLOCK_SIZE)
-
- /* Type Defines: */
- /** Memory handle type, used to store handles given by the library functions. */
- typedef const void** Mem_Handle_t;
-
- #if (ALLOCABLE_BYTES > 0xFFFF) || defined(__DOXYGEN__)
- /** Type define for the size (in bytes) for an allocation for passing to the library functions.
- * The exact type width varies depending on the value of ALLOCABLE_BYTES to ensure that a single
- * allocation can request the entire heap if needed.
- */
- typedef uint32_t Alloc_Size_t;
- #elif (ALLOCABLE_BYTES > 0xFF)
- typedef uint16_t Alloc_Size_t;
- #else
- typedef uint8_t Alloc_Size_t;
- #endif
-
- #if (NUM_BLOCKS > 0xFFFF) || defined(__DOXYGEN__)
- /** Type define for a block number in the heap. The exact type width varies depending on the
- * value of NUM_BLOCKS to ensure that the type can store an index to any block in the block pool.
- */
- typedef uint32_t Block_Number_t;
- #elif (NUM_BLOCKS > 0xFF)
- typedef uint16_t Block_Number_t;
- #else
- typedef uint8_t Block_Number_t;
- #endif
-
- #if (NUM_HANDLES > 0xFFFF) || defined(__DOXYGEN__)
- /** Type define for a handle number. The exact type width varies depending on the value of NUM_HANDLES
- * to ensure that the type can store the index of any handle in the handle pool.
- */
- typedef uint32_t Handle_Number_t;
- #elif (NUM_HANDLES > 0xFF)
- typedef uint16_t Handle_Number_t;
- #else
- typedef uint8_t Handle_Number_t;
- #endif
-
- /* Function Prototypes: */
- /** Allocates a given number of blocks from the heap (calculated from the requested number of bytes) and
- * returns a handle to the newly allocated memory.
- *
- * \param Bytes The number of bytes requested to be allocated from the heap
- *
- * \return NULL handle if the allocation fails, or handle to the allocated memory if the allocation succeeds
- */
- Mem_Handle_t Mem_Alloc(const Alloc_Size_t Bytes);
-
- /** Allocates a given number of blocks from the heap (calculated from the requested number of bytes) and
- * returns a handle to the newly allocated memory. Calloced memory is automatically cleared to all 0x00
- * values at the time of allocation.
- *
- * \param Bytes The number of pre-cleared bytes requested to be allocated from the heap
- *
- * \return NULL handle if the allocation fails, or handle to the allocated memory if the allocation succeeds
- */
- Mem_Handle_t Mem_Calloc(const Alloc_Size_t Bytes);
-
- /** Deallocates a given memory handle, and attempts to allocates the given number of blocks from the heap
- * (calculated from the requested number of bytes) immediately following the deallocation. The new memory
- * may be located in the same area as the previous memory, but this is not guaranteed.
- *
- * \param CurrAllocHdl Handle to an already allocated section of memory in the heap to deallocate
- * \param Bytes The number of bytes requested to be allocated from the heap following the
- * deallocation
- *
- * \return NULL handle if the allocation fails, or handle to the allocated memory if the allocation succeeds
- *
- * \warning Even if the allocation fails, the deallocation will still occur. Care should be taken to ensure
- * that the previously allocated memory is not used following an unsuccessful realloc().
- */
- Mem_Handle_t Mem_Realloc(Mem_Handle_t CurrAllocHdl, const Alloc_Size_t Bytes);
-
- /** Deallocates a given previously allocated section of memory from the heap.
- *
- * \param CurrAllocHdl Handle to a previously allocated section of memory in the heap
- */
- void Mem_Free(Mem_Handle_t CurrAllocHdl);
-
- /** Returns the total number of unallocated blocks in the heap.
- *
- * \return Number of free blocks in the heap, as a Block_Number_t integer
- */
- Block_Number_t Mem_TotalFreeBlocks(void);
-
- /** Returns the total number of unallocated handles in the handle pool.
- *
- * \return Number of free handles in the handle pool, as a Handle_Number_t integer
- */
- Handle_Number_t Mem_TotalFreeHandles(void);
-
- /* Private Interface - For use in library only: */
- #if !defined(__DOXYGEN__)
- /* Macros: */
- #define BLOCK_USED_MASK (1 << 0)
- #define BLOCK_LINKED_MASK (1 << 1)
-
- /* Function Prototypes: */
- #if defined(INCLUDE_FROM_DYNALLOC_C)
- static uint8_t Mem_GetBlockFlags(const Block_Number_t BlockNum);
- static void Mem_SetBlockFlags(const Block_Number_t BlockNum, const uint8_t Flags);
- static void Mem_Defrag(void);
- #endif
- #endif
-
-#endif
-
-/** @} */
diff --git a/LUFA/Scheduler/Scheduler.c b/LUFA/Scheduler/Scheduler.c
deleted file mode 100644
index ff8946a0d..000000000
--- a/LUFA/Scheduler/Scheduler.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2009.
-
- dean [at] fourwalledcubicle [dot] com
- www.fourwalledcubicle.com
-*/
-
-/*
- Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, and distribute this software
- and its documentation for any purpose and without fee is hereby
- granted, provided that the above copyright notice appear in all
- copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaim all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-#include "Scheduler.h"
-
-volatile SchedulerDelayCounter_t Scheduler_TickCounter;
-volatile uint8_t Scheduler_TotalTasks;
-
-bool Scheduler_HasDelayElapsed(const uint16_t Delay, SchedulerDelayCounter_t* const DelayCounter)
-{
- SchedulerDelayCounter_t CurrentTickValue_LCL;
- SchedulerDelayCounter_t DelayCounter_LCL;
-
- ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
- {
- CurrentTickValue_LCL = Scheduler_TickCounter;
- }
-
- DelayCounter_LCL = *DelayCounter;
-
- if (CurrentTickValue_LCL >= DelayCounter_LCL)
- {
- if ((CurrentTickValue_LCL - DelayCounter_LCL) >= Delay)
- {
- *DelayCounter = CurrentTickValue_LCL;
- return true;
- }
- }
- else
- {
- if (((MAX_DELAYCTR_COUNT - DelayCounter_LCL) + CurrentTickValue_LCL) >= Delay)
- {
- *DelayCounter = CurrentTickValue_LCL;
- return true;
- }
- }
-
- return false;
-}
-
-void Scheduler_SetTaskMode(const TaskPtr_t Task, const bool TaskStatus)
-{
- TaskEntry_t* CurrTask = &Scheduler_TaskList[0];
-
- while (CurrTask != &Scheduler_TaskList[Scheduler_TotalTasks])
- {
- if (CurrTask->Task == Task)
- {
- CurrTask->TaskStatus = TaskStatus;
- break;
- }
-
- CurrTask++;
- }
-}
-
-void Scheduler_SetGroupTaskMode(const uint8_t GroupID, const bool TaskStatus)
-{
- TaskEntry_t* CurrTask = &Scheduler_TaskList[0];
-
- while (CurrTask != &Scheduler_TaskList[Scheduler_TotalTasks])
- {
- if (CurrTask->GroupID == GroupID)
- CurrTask->TaskStatus = TaskStatus;
-
- CurrTask++;
- }
-}
diff --git a/LUFA/Scheduler/Scheduler.h b/LUFA/Scheduler/Scheduler.h
deleted file mode 100644
index 0da80bb27..000000000
--- a/LUFA/Scheduler/Scheduler.h
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2009.
-
- dean [at] fourwalledcubicle [dot] com
- www.fourwalledcubicle.com
-*/
-
-/*
- Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, and distribute this software
- and its documentation for any purpose and without fee is hereby
- granted, provided that the above copyright notice appear in all
- copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaim all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Simple round-robbin cooperative scheduler for use in basic projects where non real-time tasks need
- * to be executed. Each task is executed in sequence, and can be enabled or disabled individually or as a group.
- */
-
-/** @defgroup Group_Scheduler Simple Task Scheduler - LUFA/Scheduler/Scheduler.h
- *
- * \section Sec_Dependencies Module Source Dependencies
- * The following files must be built with any user project that uses this module:
- * - LUFA/Scheduler/Scheduler.c
- *
- * \section Module Description
- * Simple round-robbin cooperative scheduler for use in basic projects where non real-time tasks need
- * to be executed. Each task is executed in sequence, and can be enabled or disabled individually or as a group.
- *
- * For a task to yield it must return, thus each task should have persistent data marked with the static attribute.
- *
- * Usage Example:
- * \code
- * #include <LUFA/Scheduler/Scheduler.h>
- *
- * TASK(MyTask1);
- * TASK(MyTask2);
- *
- * TASK_LIST
- * {
- * { .Task = MyTask1, .TaskStatus = TASK_RUN, .GroupID = 1 },
- * { .Task = MyTask2, .TaskStatus = TASK_RUN, .GroupID = 1 },
- * }
- *
- * int main(void)
- * {
- * Scheduler_Start();
- * }
- *
- * TASK(MyTask1)
- * {
- * // Implementation Here
- * }
- *
- * TASK(MyTask2)
- * {
- * // Implementation Here
- * }
- * \endcode
- *
- * @{
- */
-
-#ifndef __SCHEDULER_H__
-#define __SCHEDULER_H__
-
- /* Includes: */
- #include <avr/io.h>
- #include <stdbool.h>
-
- #include <util/atomic.h>
-
- #include "../Common/Common.h"
-
- /* Enable C linkage for C++ Compilers: */
- #if defined(__cplusplus)
- extern "C" {
- #endif
-
- /* Public Interface - May be used in end-application: */
- /* Macros: */
- /** Creates a new scheduler task body or prototype. Should be used in the form:
- * \code
- * TASK(TaskName); // Prototype
- *
- * TASK(TaskName)
- * {
- * // Task body
- * }
- * \endcode
- */
- #define TASK(name) void name (void)
-
- /** Defines a task list array, containing one or more task entries of the type TaskEntry_t. Each task list
- * should be encased in curly braces and ended with a comma.
- *
- * Usage Example:
- * \code
- * TASK_LIST
- * {
- * { .Task = MyTask1, .TaskStatus = TASK_RUN, .GroupID = 1 },
- * // More task entries here
- * }
- * \endcode
- */
- #define TASK_LIST TaskEntry_t Scheduler_TaskList[] =
-
- /** Constant, giving the maximum delay in scheduler ticks which can be stored in a variable of type
- * SchedulerDelayCounter_t.
- */
- #define TASK_MAX_DELAY (MAX_DELAYCTR_COUNT - 1)
-
- /** Task status mode constant, for passing to Scheduler_SetTaskMode() or Scheduler_SetGroupTaskMode(). */
- #define TASK_RUN true
-
- /** Task status mode constant, for passing to Scheduler_SetTaskMode() or Scheduler_SetGroupTaskMode(). */
- #define TASK_STOP false
-
- /* Pseudo-Function Macros: */
- #if defined(__DOXYGEN__)
- /** Starts the scheduler in its infinite loop, executing running tasks. This should be placed at the end
- * of the user application's main() function, as it can never return to the calling function.
- */
- void Scheduler_Start(void);
-
- /** Initializes the scheduler so that the scheduler functions can be called before the scheduler itself
- * is started. This must be executed before any scheduler function calls other than Scheduler_Start(),
- * and can be omitted if no such functions could be called before the scheduler is started.
- */
- void Scheduler_Init(void);
- #else
- #define Scheduler_Start() Scheduler_GoSchedule(TOTAL_TASKS);
-
- #define Scheduler_Init() Scheduler_InitScheduler(TOTAL_TASKS);
- #endif
-
- /* Type Defines: */
- /** Type define for a pointer to a scheduler task. */
- typedef void (*TaskPtr_t)(void);
-
- /** Type define for a variable which can hold a tick delay value for the scheduler up to the maximum delay
- * possible.
- */
- typedef uint16_t SchedulerDelayCounter_t;
-
- /** Structure for holding a single task's information in the scheduler task list. */
- typedef struct
- {
- TaskPtr_t Task; /**< Pointer to the task to execute. */
- bool TaskStatus; /**< Status of the task (either TASK_RUN or TASK_STOP). */
- uint8_t GroupID; /**< Group ID of the task so that its status can be changed as a group. */
- } TaskEntry_t;
-
- /* Global Variables: */
- /** Task entry list, containing the scheduler tasks, task statuses and group IDs. Each entry is of type
- * TaskEntry_t and can be manipulated as desired, although it is preferential that the proper Scheduler
- * functions should be used instead of direct manipulation.
- */
- extern TaskEntry_t Scheduler_TaskList[];
-
- /** Contains the total number of tasks in the task list, irrespective of if the task's status is set to
- * TASK_RUN or TASK_STOP.
- *
- * \note This value should be treated as read-only, and never altered in user-code.
- */
- extern volatile uint8_t Scheduler_TotalTasks;
-
- /** Contains the current scheduler tick count, for use with the delay functions. If the delay functions
- * are used in the user code, this should be incremented each tick period so that the delays can be
- * calculated.
- */
- extern volatile SchedulerDelayCounter_t Scheduler_TickCounter;
-
- /* Inline Functions: */
- /** Resets the delay counter value to the current tick count. This should be called to reset the period
- * for a delay in a task which is dependant on the current tick value.
- *
- * \param DelayCounter Counter which is storing the starting tick count for a given delay.
- */
- static inline void Scheduler_ResetDelay(SchedulerDelayCounter_t* const DelayCounter)
- ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
- static inline void Scheduler_ResetDelay(SchedulerDelayCounter_t* const DelayCounter)
- {
- ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
- {
- *DelayCounter = Scheduler_TickCounter;
- }
- }
-
- /* Function Prototypes: */
- /** Determines if the given tick delay has elapsed, based on the given .
- *
- * \param Delay The delay to test for, measured in ticks
- * \param DelayCounter The counter which is storing the starting tick value for the delay
- *
- * \return Boolean true if the delay has elapsed, false otherwise
- *
- * Usage Example:
- * \code
- * static SchedulerDelayCounter_t DelayCounter = 10000; // Force immediate run on start-up
- *
- * // Task runs every 10000 ticks, 10 seconds for this demo
- * if (Scheduler_HasDelayElapsed(10000, &DelayCounter))
- * {
- * // Code to execute after delay interval elapsed here
- * }
- * \endcode
- */
- bool Scheduler_HasDelayElapsed(const uint16_t Delay,
- SchedulerDelayCounter_t* const DelayCounter)
- ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(2);
-
- /** Sets the task mode for a given task.
- *
- * \param Task Name of the task whose status is to be changed
- * \param TaskStatus New task status for the task (TASK_RUN or TASK_STOP)
- */
- void Scheduler_SetTaskMode(const TaskPtr_t Task, const bool TaskStatus);
-
- /** Sets the task mode for a given task group ID, allowing for an entire group of tasks to have their
- * statuses changed at once.
- *
- * \param GroupID Value of the task group ID whose status is to be changed
- * \param TaskStatus New task status for tasks in the specified group (TASK_RUN or TASK_STOP)
- */
- void Scheduler_SetGroupTaskMode(const uint8_t GroupID, const bool TaskStatus);
-
- /* Private Interface - For use in library only: */
- #if !defined(__DOXYGEN__)
- /* Macros: */
- #define TOTAL_TASKS (sizeof(Scheduler_TaskList) / sizeof(TaskEntry_t))
- #define MAX_DELAYCTR_COUNT 0xFFFF
-
- /* Inline Functions: */
- static inline void Scheduler_InitScheduler(const uint8_t TotalTasks) ATTR_ALWAYS_INLINE;
- static inline void Scheduler_InitScheduler(const uint8_t TotalTasks)
- {
- Scheduler_TotalTasks = TotalTasks;
- }
-
- static inline void Scheduler_GoSchedule(const uint8_t TotalTasks) ATTR_NO_RETURN ATTR_ALWAYS_INLINE;
- static inline void Scheduler_GoSchedule(const uint8_t TotalTasks)
- {
- Scheduler_InitScheduler(TotalTasks);
-
- for (;;)
- {
- TaskEntry_t* CurrTask = &Scheduler_TaskList[0];
-
- while (CurrTask != &Scheduler_TaskList[TotalTasks])
- {
- if (CurrTask->TaskStatus == TASK_RUN)
- CurrTask->Task();
-
- CurrTask++;
- }
- }
- }
- #endif
-
- /* Disable C linkage for C++ Compilers: */
- #if defined(__cplusplus)
- }
- #endif
-
-#endif
-
-/** @} */
diff --git a/LUFA/SchedulerOverview.txt b/LUFA/SchedulerOverview.txt
deleted file mode 100644
index 5c031feac..000000000
--- a/LUFA/SchedulerOverview.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-/** \file
- *
- * This file contains special DoxyGen information for the generation of the main page and other special
- * documentation pages. It is not a project source file.
- */
-
-/** \page Page_SchedulerOverview LUFA Scheduler Overview
- *
- * The LUFA library comes with a small, basic round-robbin scheduler which allows for small "tasks" to be executed
- * continuously in sequence, and enabled/disabled at runtime. Unlike a conventional, complex RTOS scheduler, the
- * LUFA scheduler is very simple in design and operation and is essentially a loop conditionally executing a series
- * of functions.
- *
- * Each LUFA scheduler task should be written similar to an ISR; it should execute quickly (so that no one task
- * hogs the processor, preventing another from running before some sort of timeout is exceeded). Unlike normal RTOS
- * tasks, each LUFA scheduler task is a regular function, and thus must be designed to be called, and designed to
- * return to the calling scheduler function repeatedly. Data which must be preserved between task calls should be
- * declared as global or (preferably) as a static local variable inside the task.
- *
- * The scheduler consists of a task list, listing all the tasks which can be executed by the scheduler. Once started,
- * each task is then called one after another, unless the task is stopped by another running task or interrupt.
- *
- *
- * If desired, the LUFA scheduler <b>does not need to be used</b> in a LUFA powered application. A more conventional
- * approach to application design can be used, or a proper scheduling RTOS inserted in the place of the LUFA scheduler.
- * In the case of the former the USB task must be run manually repeatedly to maintain USB communications, and in the
- * case of the latter a proper RTOS task must be set up to do the same.
- *
- *
- * For more information on the LUFA scheduler, see the Scheduler.h file documentation.
- */
diff --git a/LUFA/makefile b/LUFA/makefile
index fc0009793..20f943aa0 100644
--- a/LUFA/makefile
+++ b/LUFA/makefile
@@ -15,13 +15,9 @@ LUFA_SRC_FILES = ./Drivers/USB/LowLevel/DevChapter9.c \
./Drivers/USB/LowLevel/LowLevel.c \
./Drivers/USB/LowLevel/Pipe.c \
./Drivers/USB/HighLevel/Events.c \
- ./Drivers/USB/HighLevel/StdDescriptors.c \
./Drivers/USB/HighLevel/USBInterrupt.c \
./Drivers/USB/HighLevel/USBTask.c \
- ./Drivers/USB/Class/ConfigDescriptor.c \
- ./Drivers/USB/Class/HIDParser.c \
- ./Scheduler/Scheduler.c \
- ./MemoryAllocator/DynAlloc.c \
+ ./Drivers/USB/HighLevel/ConfigDescriptor.c \
./Drivers/Board/Temperature.c \
./Drivers/Peripheral/Serial.c \
./Drivers/Peripheral/SerialStream.c \