Commit of new class abstraction APIs for all device demos other than the MIDI demo...
authorDean Camera <dean@fourwalledcubicle.com>
Mon, 1 Jun 2009 11:03:39 +0000 (11:03 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Mon, 1 Jun 2009 11:03:39 +0000 (11:03 +0000)
Removed scheduler and memory allocation libraries.

Added new EVENT_USB_StartOfFrame event in the library to indicate the start of each USB frame (when generated).

Removed Tx interrupt from the USBtoSerial demo; now sends characters via polling to ensure more time for the Rx interrupt.

111 files changed:
Bootloaders/CDC/makefile
Bootloaders/DFU/makefile
Bootloaders/TeensyHID/makefile
Demos/Device/AudioInput/AudioInput.c
Demos/Device/AudioInput/AudioInput.h
Demos/Device/AudioInput/makefile
Demos/Device/AudioOutput/AudioOutput.c
Demos/Device/AudioOutput/AudioOutput.h
Demos/Device/AudioOutput/makefile
Demos/Device/CDC/CDC.c
Demos/Device/CDC/CDC.h
Demos/Device/CDC/Descriptors.h
Demos/Device/CDC/makefile
Demos/Device/DualCDC/Descriptors.h
Demos/Device/DualCDC/DualCDC.c
Demos/Device/DualCDC/DualCDC.h
Demos/Device/DualCDC/makefile
Demos/Device/GenericHID/Descriptors.h
Demos/Device/GenericHID/GenericHID.c
Demos/Device/GenericHID/GenericHID.h
Demos/Device/GenericHID/makefile
Demos/Device/Joystick/Descriptors.h
Demos/Device/Joystick/Joystick.c
Demos/Device/Joystick/Joystick.h
Demos/Device/Joystick/makefile
Demos/Device/Keyboard/Descriptors.h
Demos/Device/Keyboard/Keyboard.c
Demos/Device/Keyboard/Keyboard.h
Demos/Device/Keyboard/makefile
Demos/Device/KeyboardMouse/Descriptors.h
Demos/Device/KeyboardMouse/KeyboardMouse.c
Demos/Device/KeyboardMouse/KeyboardMouse.h
Demos/Device/KeyboardMouse/makefile
Demos/Device/MIDI/makefile
Demos/Device/MassStorage/Lib/DataflashManager.c
Demos/Device/MassStorage/Lib/DataflashManager.h
Demos/Device/MassStorage/Lib/SCSI.c
Demos/Device/MassStorage/Lib/SCSI.h
Demos/Device/MassStorage/MassStorage.c
Demos/Device/MassStorage/MassStorage.h
Demos/Device/MassStorage/makefile
Demos/Device/Mouse/Descriptors.h
Demos/Device/Mouse/Mouse.c
Demos/Device/Mouse/Mouse.h
Demos/Device/Mouse/makefile
Demos/Device/RNDISEthernet/Lib/ARP.h
Demos/Device/RNDISEthernet/Lib/Ethernet.c
Demos/Device/RNDISEthernet/Lib/Ethernet.h
Demos/Device/RNDISEthernet/Lib/EthernetProtocols.h
Demos/Device/RNDISEthernet/Lib/ICMP.c
Demos/Device/RNDISEthernet/Lib/ICMP.h
Demos/Device/RNDISEthernet/Lib/IP.c
Demos/Device/RNDISEthernet/Lib/IP.h
Demos/Device/RNDISEthernet/Lib/RNDIS.c [deleted file]
Demos/Device/RNDISEthernet/Lib/RNDIS.h [deleted file]
Demos/Device/RNDISEthernet/Lib/RNDISConstants.h [deleted file]
Demos/Device/RNDISEthernet/Lib/TCP.c
Demos/Device/RNDISEthernet/Lib/TCP.h
Demos/Device/RNDISEthernet/RNDISEthernet.c
Demos/Device/RNDISEthernet/RNDISEthernet.h
Demos/Device/RNDISEthernet/makefile
Demos/Device/USBtoSerial/Descriptors.h
Demos/Device/USBtoSerial/USBtoSerial.c
Demos/Device/USBtoSerial/USBtoSerial.h
Demos/Device/USBtoSerial/makefile
Demos/Host/GenericHIDHost/makefile
Demos/Host/MassStorageHost/Lib/MassStoreCommands.c
Demos/Host/StillImageHost/Lib/StillImageCommands.c
Demos/OTG/TestApp/TestApp.h
Demos/OTG/TestApp/makefile
LUFA.pnproj
LUFA/ChangeLog.txt
LUFA/DirectorySummaries.txt
LUFA/Drivers/USB/Class/Device/Audio.c [new file with mode: 0644]
LUFA/Drivers/USB/Class/Device/Audio.h [new file with mode: 0644]
LUFA/Drivers/USB/Class/Device/CDC.c [new file with mode: 0644]
LUFA/Drivers/USB/Class/Device/CDC.h [new file with mode: 0644]
LUFA/Drivers/USB/Class/Device/HID.c [new file with mode: 0644]
LUFA/Drivers/USB/Class/Device/HID.h [new file with mode: 0644]
LUFA/Drivers/USB/Class/Device/MassStorage.c [new file with mode: 0644]
LUFA/Drivers/USB/Class/Device/MassStorage.h [new file with mode: 0644]
LUFA/Drivers/USB/Class/Device/RNDIS.c [new file with mode: 0644]
LUFA/Drivers/USB/Class/Device/RNDIS.h [new file with mode: 0644]
LUFA/Drivers/USB/Class/Device/RNDISConstants.h [new file with mode: 0644]
LUFA/Drivers/USB/Class/HIDParser.c [deleted file]
LUFA/Drivers/USB/Class/HIDParser.h [deleted file]
LUFA/Drivers/USB/Class/HIDReportData.h [deleted file]
LUFA/Drivers/USB/Class/Host/HIDParser.c [new file with mode: 0644]
LUFA/Drivers/USB/Class/Host/HIDParser.h [new file with mode: 0644]
LUFA/Drivers/USB/Class/Host/HIDReportData.h [new file with mode: 0644]
LUFA/Drivers/USB/HighLevel/Events.h
LUFA/Drivers/USB/HighLevel/USBInterrupt.c
LUFA/Drivers/USB/HighLevel/USBTask.c
LUFA/Drivers/USB/HighLevel/USBTask.h
LUFA/Drivers/USB/LowLevel/Endpoint.c
LUFA/Drivers/USB/LowLevel/Host.c
LUFA/Drivers/USB/LowLevel/LowLevel.c
LUFA/Drivers/USB/LowLevel/LowLevel.h
LUFA/Drivers/USB/LowLevel/Pipe.c
LUFA/Drivers/USB/USB.h
LUFA/MemoryAllocator/DynAlloc.c [deleted file]
LUFA/MemoryAllocator/DynAlloc.h [deleted file]
LUFA/Scheduler/Scheduler.c [deleted file]
LUFA/Scheduler/Scheduler.h [deleted file]
LUFA/SchedulerOverview.txt [deleted file]
LUFA/makefile
Projects/Magstripe/Descriptors.c
Projects/Magstripe/Descriptors.h
Projects/Magstripe/Magstripe.c
Projects/Magstripe/Magstripe.h
Projects/Magstripe/makefile

index bc8e2ca..e3d8e5c 100644 (file)
@@ -124,7 +124,6 @@ SRC = $(TARGET).c                                                 \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \\r
-         $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \\r
 \r
 \r
 # List C++ source files here. (C dependencies are automatically generated.)\r
index 4e51e29..b3eb1b0 100644 (file)
@@ -124,7 +124,6 @@ SRC = $(TARGET).c                                                 \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \\r
-         $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \\r
 \r
  \r
 # List C++ source files here. (C dependencies are automatically generated.)\r
index de929ed..68b0160 100644 (file)
@@ -124,7 +124,6 @@ SRC = $(TARGET).c                                                 \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \\r
-         $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \\r
 \r
 \r
 # List C++ source files here. (C dependencies are automatically generated.)\r
index ecd8cdd..bcfb04b 100644 (file)
   this software.\r
 */\r
 \r
-/** \file\r
- *\r
- *  Main source file for the Audio Input demo. This file contains the main tasks of the demo and\r
- *  is responsible for the initial application hardware configuration.\r
- */\r
-\r
 #include "AudioInput.h"\r
 \r
-/* Scheduler Task List */\r
-TASK_LIST\r
+USB_ClassInfo_Audio_t Microphone_Audio_Interface =\r
+       {\r
+               .InterfaceNumber      = 0,\r
+\r
+               .DataINEndpointNumber = AUDIO_STREAM_EPNUM,\r
+               .DataINEndpointSize   = AUDIO_STREAM_EPSIZE,\r
+       };\r
+               \r
+int main(void)\r
 {\r
-       { .Task = USB_USBTask          , .TaskStatus = TASK_STOP },\r
-       { .Task = USB_Audio_Task       , .TaskStatus = TASK_STOP },\r
-};\r
+       SetupHardware();\r
 \r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
+       \r
+       for (;;)\r
+       {\r
+               if (Microphone_Audio_Interface.InterfaceEnabled)\r
+                 ProcessNextSample();\r
 \r
-/** Main program entry point. This routine configures the hardware required by the application, then\r
- *  starts the scheduler to run the application tasks.\r
- */\r
-int main(void)\r
+               USB_USBTask();\r
+       }\r
+}\r
+\r
+void SetupHardware(void)\r
 {\r
        /* Disable watchdog if enabled by bootloader/fuses */\r
        MCUSR &= ~(1 << WDRF);\r
@@ -58,35 +64,35 @@ int main(void)
        \r
        /* Hardware Initialization */\r
        LEDs_Init();\r
+       USB_Init();\r
        ADC_Init(ADC_FREE_RUNNING | ADC_PRESCALE_32);\r
        ADC_SetupChannel(MIC_IN_ADC_CHANNEL);\r
        \r
        /* Start the ADC conversion in free running mode */\r
        ADC_StartReading(ADC_REFERENCE_AVCC | ADC_RIGHT_ADJUSTED | MIC_IN_ADC_CHANNEL);\r
-       \r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
-       \r
-       /* Initialize Scheduler so that it can be used */\r
-       Scheduler_Init();\r
+}\r
 \r
-       /* Initialize USB Subsystem */\r
-       USB_Init();\r
+void ProcessNextSample(void)\r
+{\r
+       if ((TIFR0 & (1 << OCF0A)) && USB_Audio_IsReadyForNextSample(&Microphone_Audio_Interface))\r
+       {\r
+               TIFR0 |= (1 << OCF0A);\r
+\r
+               /* Audio sample is ADC value scaled to fit the entire range */\r
+               int16_t AudioSample = ((SAMPLE_MAX_RANGE / ADC_MAX_RANGE) * ADC_GetResult());\r
+               \r
+#if defined(MICROPHONE_BIASED_TO_HALF_RAIL)\r
+               /* Microphone is biased to half rail voltage, subtract the bias from the sample value */\r
+               AudioSample -= (SAMPLE_MAX_RANGE / 2));\r
+#endif\r
 \r
-       /* Scheduling - routine never returns, so put this last in the main function */\r
-       Scheduler_Start();\r
+               USB_Audio_WriteSample16(AudioSample);\r
+       }\r
 }\r
 \r
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs, and\r
- *  configures the sample update and PWM timers.\r
- */\r
 void EVENT_USB_Connect(void)\r
 {\r
-       /* Start USB management task */\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);\r
-\r
-       /* Indicate USB enumerating */\r
-       UpdateStatus(Status_USBEnumerating);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);\r
 \r
        /* Sample reload timer initialization */\r
        OCR0A   = (F_CPU / AUDIO_SAMPLE_FREQUENCY) - 1;\r
@@ -94,127 +100,23 @@ void EVENT_USB_Connect(void)
        TCCR0B  = (1 << CS00);   // Fcpu speed\r
 }\r
 \r
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via\r
- *  the status LEDs, disables the sample update and PWM output timers and stops the USB and Audio management tasks.\r
- */\r
 void EVENT_USB_Disconnect(void)\r
 {\r
        /* Stop the sample reload timer */\r
        TCCR0B = 0;\r
 \r
-       /* Stop running audio and USB management tasks */\r
-       Scheduler_SetTaskMode(USB_Audio_Task, TASK_STOP);\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);\r
-\r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
 }\r
 \r
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration\r
- *  of the USB device after enumeration - the device endpoints are configured.\r
- */\r
 void EVENT_USB_ConfigurationChanged(void)\r
 {\r
-       /* Setup audio stream endpoint */\r
-       Endpoint_ConfigureEndpoint(AUDIO_STREAM_EPNUM, EP_TYPE_ISOCHRONOUS,\r
-                                      ENDPOINT_DIR_IN, AUDIO_STREAM_EPSIZE,\r
-                                  ENDPOINT_BANK_DOUBLE);\r
-\r
-       /* Indicate USB connected and ready */\r
-       UpdateStatus(Status_USBReady);\r
-}\r
-\r
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific\r
- *  control requests that are not handled internally by the USB library (including the Audio class-specific\r
- *  requests) so that they can be handled appropriately for the application.\r
- */\r
-void EVENT_USB_UnhandledControlPacket(void)\r
-{\r
-       /* Process General and Audio specific control requests */\r
-       switch (USB_ControlRequest.bRequest)\r
-       {\r
-               case REQ_SetInterface:\r
-                       /* Set Interface is not handled by the library, as its function is application-specific */\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))\r
-                       {\r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* Check if the host is enabling the audio interface (setting AlternateSetting to 1) */\r
-                               if (USB_ControlRequest.wValue)\r
-                               {\r
-                                       /* Start audio task */\r
-                                       Scheduler_SetTaskMode(USB_Audio_Task, TASK_RUN);\r
-                               }\r
-                               else\r
-                               {\r
-                                       /* Stop audio task */\r
-                                       Scheduler_SetTaskMode(USB_Audio_Task, TASK_STOP);                               \r
-                               }\r
-                               \r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsINReady()));\r
-                               Endpoint_ClearIN();\r
-                       }\r
-\r
-                       break;\r
-       }\r
-}\r
-\r
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to\r
- *  log to a serial port, or anything else that is suitable for status updates.\r
- *\r
- *  \param CurrentStatus  Current status of the system, from the AudioInput_StatusCodes_t enum\r
- */\r
-void UpdateStatus(uint8_t CurrentStatus)\r
-{\r
-       uint8_t LEDMask = LEDS_NO_LEDS;\r
+       LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
        \r
-       /* Set the LED mask to the appropriate LED mask based on the given status code */\r
-       switch (CurrentStatus)\r
-       {\r
-               case Status_USBNotReady:\r
-                       LEDMask = (LEDS_LED1);\r
-                       break;\r
-               case Status_USBEnumerating:\r
-                       LEDMask = (LEDS_LED1 | LEDS_LED2);\r
-                       break;\r
-               case Status_USBReady:\r
-                       LEDMask = (LEDS_LED2 | LEDS_LED4);\r
-                       break;\r
-       }\r
-       \r
-       /* Set the board LEDs to the new LED mask */\r
-       LEDs_SetAllLEDs(LEDMask);\r
+       if (!(USB_Audio_ConfigureEndpoints(&Microphone_Audio_Interface)))\r
+         LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
 }\r
 \r
-/** Task to manage the Audio interface, reading in ADC samples from the microphone, and them to the host. */\r
-TASK(USB_Audio_Task)\r
+void EVENT_USB_UnhandledControlPacket(void)\r
 {\r
-       /* Select the audio stream endpoint */\r
-       Endpoint_SelectEndpoint(AUDIO_STREAM_EPNUM);\r
-       \r
-       /* Check if the current endpoint can be written to and that the next sample should be stored */\r
-       if (Endpoint_IsINReady() && (TIFR0 & (1 << OCF0A)))\r
-       {\r
-               /* Clear the sample reload timer */\r
-               TIFR0 |= (1 << OCF0A);\r
-\r
-               /* Audio sample is ADC value scaled to fit the entire range */\r
-               int16_t AudioSample = ((SAMPLE_MAX_RANGE / ADC_MAX_RANGE) * ADC_GetResult());\r
-               \r
-#if defined(MICROPHONE_BIASED_TO_HALF_RAIL)\r
-               /* Microphone is biased to half rail voltage, subtract the bias from the sample value */\r
-               AudioSample -= (SAMPLE_MAX_RANGE / 2));\r
-#endif\r
-\r
-               /* Write the sample to the buffer */\r
-               Endpoint_Write_Word_LE(AudioSample);\r
-\r
-               /* Check to see if the bank is now full */\r
-               if (!(Endpoint_IsReadWriteAllowed()))\r
-               {\r
-                       /* Send the full packet to the host */\r
-                       Endpoint_ClearIN();\r
-               }\r
-       }\r
+       USB_Audio_ProcessControlPacket(&Microphone_Audio_Interface);\r
 }\r
index a394492..e9f56b3 100644 (file)
 \r
                #include "Descriptors.h"\r
                                \r
-               #include <LUFA/Version.h>                      // Library Version Information\r
-               #include <LUFA/Drivers/USB/USB.h>              // USB Functionality\r
-               #include <LUFA/Drivers/Board/LEDs.h>           // LEDs driver\r
-               #include <LUFA/Drivers/Peripheral/ADC.h>       // ADC driver\r
-               #include <LUFA/Scheduler/Scheduler.h>          // Simple scheduler for task management\r
-\r
+               #include <LUFA/Version.h>\r
+               #include <LUFA/Drivers/Board/LEDs.h>\r
+               #include <LUFA/Drivers/Board/Joystick.h>\r
+               #include <LUFA/Drivers/Peripheral/ADC.h>\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/Audio.h>\r
+               \r
        /* Macros: */\r
                /** ADC channel number for the microphone input. */\r
                #define MIC_IN_ADC_CHANNEL               2\r
                /** Maximum ADC range for the microphone input. */\r
                #define ADC_MAX_RANGE                    0x3FF\r
 \r
-       /* Enums: */\r
-               /** Enum for the possible status codes for passing to the UpdateStatus() function. */\r
-               enum AudioInput_StatusCodes_t\r
-               {\r
-                       Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */\r
-                       Status_USBEnumerating = 1, /**< USB interface is enumerating */\r
-                       Status_USBReady       = 2, /**< USB interface is connected and ready */\r
-               };\r
-\r
-       /* Task Definitions: */\r
-               TASK(USB_Audio_Task);\r
-\r
+       /* Macros: */\r
+               #define LEDMASK_USB_NOTREADY      LEDS_LED1\r
+               #define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)\r
+               #define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)\r
+               #define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)\r
+               \r
        /* Function Prototypes: */\r
+               void SetupHardware(void);\r
+               void ProcessNextSample(void);\r
+               \r
                void EVENT_USB_Connect(void);\r
                void EVENT_USB_Disconnect(void);\r
                void EVENT_USB_ConfigurationChanged(void);\r
                void EVENT_USB_UnhandledControlPacket(void);\r
 \r
-               void UpdateStatus(uint8_t CurrentStatus);\r
-               \r
 #endif\r
index c70e98e..9d3adff 100644 (file)
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)\r
 SRC = $(TARGET).c                                                 \\r
          Descriptors.c                                               \\r
-         $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \\r
@@ -136,7 +135,7 @@ SRC = $(TARGET).c                                                 \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \\r
-         $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \\r
+         $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/Audio.c          \\r
 \r
 \r
 # List C++ source files here. (C dependencies are automatically generated.)\r
index 40e376b..0f19356 100644 (file)
   this software.\r
 */\r
 \r
-/** \file\r
- *\r
- *  Main source file for the Audio Output demo. This file contains the main tasks of the demo and\r
- *  is responsible for the initial application hardware configuration.\r
- */\r
\r
 #include "AudioOutput.h"\r
 \r
-/* Scheduler Task List */\r
-TASK_LIST\r
-{\r
-       { .Task = USB_USBTask          , .TaskStatus = TASK_STOP },\r
-       { .Task = USB_Audio_Task       , .TaskStatus = TASK_STOP },\r
-};\r
+USB_ClassInfo_Audio_t Speaker_Audio_Interface =\r
+       {\r
+               .InterfaceNumber       = 0,\r
 \r
+               .DataOUTEndpointNumber = AUDIO_STREAM_EPNUM,\r
+               .DataOUTEndpointSize   = AUDIO_STREAM_EPSIZE,\r
+       };\r
 \r
-/** Main program entry point. This routine configures the hardware required by the application, then\r
- *  starts the scheduler to run the application tasks.\r
- */\r
 int main(void)\r
 {\r
+       SetupHardware();\r
+\r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
+       \r
+       for (;;)\r
+       {\r
+               if (Speaker_Audio_Interface.InterfaceEnabled)\r
+                 ProcessNextSample();\r
+\r
+               USB_USBTask();\r
+       }\r
+}\r
+\r
+void SetupHardware(void)\r
+{\r
        /* Disable watchdog if enabled by bootloader/fuses */\r
        MCUSR &= ~(1 << WDRF);\r
        wdt_disable();\r
@@ -58,186 +64,19 @@ int main(void)
 \r
        /* Hardware Initialization */\r
        LEDs_Init();\r
-       \r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
-       \r
-       /* Initialize Scheduler so that it can be used */\r
-       Scheduler_Init();\r
-\r
-       /* Initialize USB Subsystem */\r
        USB_Init();\r
-\r
-       /* Scheduling - routine never returns, so put this last in the main function */\r
-       Scheduler_Start();\r
-}\r
-\r
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs, and\r
- *  configures the sample update and PWM timers.\r
- */\r
-void EVENT_USB_Connect(void)\r
-{\r
-       /* Start USB management task */\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);\r
-\r
-       /* Indicate USB enumerating */\r
-       UpdateStatus(Status_USBEnumerating);\r
-       \r
-       /* Sample reload timer initialization */\r
-       OCR0A   = (F_CPU / AUDIO_SAMPLE_FREQUENCY) - 1;\r
-       TCCR0A  = (1 << WGM01);  // CTC mode\r
-       TCCR0B  = (1 << CS00);   // Fcpu speed\r
-                       \r
-#if defined(AUDIO_OUT_MONO)\r
-       /* Set speaker as output */\r
-       DDRC   |= (1 << 6);\r
-#elif defined(AUDIO_OUT_STEREO)\r
-       /* Set speakers as outputs */\r
-       DDRC   |= ((1 << 6) | (1 << 5));\r
-#elif defined(AUDIO_OUT_PORTC)\r
-       /* Set PORTC as outputs */\r
-       DDRC   |= 0xFF;\r
-#endif\r
-\r
-#if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))\r
-       /* PWM speaker timer initialization */\r
-       TCCRxA  = ((1 << WGMx0) | (1 << COMxA1) | (1 << COMxA0)\r
-                                                       | (1 << COMxB1) | (1 << COMxB0)); // Set on match, clear on TOP\r
-       TCCRxB  = ((1 << WGMx2) | (1 << CSx0));  // Fast 8-Bit PWM, Fcpu speed\r
-#endif \r
 }\r
 \r
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via\r
- *  the status LEDs, disables the sample update and PWM output timers and stops the USB and Audio management tasks.\r
- */\r
-void EVENT_USB_Disconnect(void)\r
-{\r
-       /* Stop the timers */\r
-       TCCR0B = 0;\r
-#if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))\r
-       TCCRxB = 0;\r
-#endif         \r
-\r
-#if defined(AUDIO_OUT_MONO)\r
-       /* Set speaker as input to reduce current draw */\r
-       DDRC   &= ~(1 << 6);\r
-#elif defined(AUDIO_OUT_STEREO)\r
-       /* Set speakers as inputs to reduce current draw */\r
-       DDRC   &= ~((1 << 6) | (1 << 5));\r
-#elif defined(AUDIO_OUT_PORTC)\r
-       /* Set PORTC low */\r
-       PORTC  = 0x00;\r
-#endif\r
-\r
-       /* Stop running audio and USB management tasks */\r
-       Scheduler_SetTaskMode(USB_Audio_Task, TASK_STOP);\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);\r
-\r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
-}\r
-\r
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration\r
- *  of the USB device after enumeration - the device endpoints are configured.\r
- */\r
-void EVENT_USB_ConfigurationChanged(void)\r
-{\r
-       /* Setup audio stream endpoint */\r
-       Endpoint_ConfigureEndpoint(AUDIO_STREAM_EPNUM, EP_TYPE_ISOCHRONOUS,\r
-                                      ENDPOINT_DIR_OUT, AUDIO_STREAM_EPSIZE,\r
-                                  ENDPOINT_BANK_DOUBLE);\r
-\r
-       /* Indicate USB connected and ready */\r
-       UpdateStatus(Status_USBReady);\r
-}\r
-\r
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific\r
- *  control requests that are not handled internally by the USB library (including the Audio class-specific\r
- *  requests) so that they can be handled appropriately for the application.\r
- */\r
-void EVENT_USB_UnhandledControlPacket(void)\r
+void ProcessNextSample(void)\r
 {\r
-       /* Process General and Audio specific control requests */\r
-       switch (USB_ControlRequest.bRequest)\r
-       {\r
-               case REQ_SetInterface:\r
-                       /* Set Interface is not handled by the library, as its function is application-specific */\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))\r
-                       {\r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* Check if the host is enabling the audio interface (setting AlternateSetting to 1) */\r
-                               if (USB_ControlRequest.wValue)\r
-                               {\r
-                                       /* Start audio task */\r
-                                       Scheduler_SetTaskMode(USB_Audio_Task, TASK_RUN);\r
-                               }\r
-                               else\r
-                               {\r
-                                       /* Stop audio task */\r
-                                       Scheduler_SetTaskMode(USB_Audio_Task, TASK_STOP);                               \r
-                               }\r
-                               \r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsINReady()));\r
-                               Endpoint_ClearIN();\r
-                       }\r
-\r
-                       break;\r
-       }\r
-}\r
-\r
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to\r
- *  log to a serial port, or anything else that is suitable for status updates.\r
- *\r
- *  \param CurrentStatus  Current status of the system, from the AudioOutput_StatusCodes_t enum\r
- */\r
-void UpdateStatus(uint8_t CurrentStatus)\r
-{\r
-       uint8_t LEDMask = LEDS_NO_LEDS;\r
-       \r
-       /* Set the LED mask to the appropriate LED mask based on the given status code */\r
-       switch (CurrentStatus)\r
-       {\r
-               case Status_USBNotReady:\r
-                       LEDMask = (LEDS_LED1);\r
-                       break;\r
-               case Status_USBEnumerating:\r
-                       LEDMask = (LEDS_LED1 | LEDS_LED2);\r
-                       break;\r
-               case Status_USBReady:\r
-                       LEDMask = (LEDS_LED2 | LEDS_LED4);\r
-                       break;\r
-       }\r
-       \r
-       /* Set the board LEDs to the new LED mask */\r
-       LEDs_SetAllLEDs(LEDMask);\r
-}\r
-\r
-/** Task to manage the Audio interface, reading in audio samples from the host, and outputting them to the speakers/LEDs as\r
- *  desired.\r
- */\r
-TASK(USB_Audio_Task)\r
-{\r
-       /* Select the audio stream endpoint */\r
-       Endpoint_SelectEndpoint(AUDIO_STREAM_EPNUM);\r
-       \r
-       /* Check if the current endpoint can be read from (contains a packet) and that the next sample should be read */\r
-       if (Endpoint_IsOUTReceived() && (TIFR0 & (1 << OCF0A)))\r
+       if ((TIFR0 & (1 << OCF0A)) && USB_Audio_IsSampleReceived(&Speaker_Audio_Interface))\r
        {\r
                /* Clear the sample reload timer */\r
                TIFR0 |= (1 << OCF0A);\r
 \r
                /* Retrieve the signed 16-bit left and right audio samples */\r
-               int16_t LeftSample_16Bit  = (int16_t)Endpoint_Read_Word_LE();\r
-               int16_t RightSample_16Bit = (int16_t)Endpoint_Read_Word_LE();\r
-\r
-               /* Check to see if the bank is now empty */\r
-               if (!(Endpoint_IsReadWriteAllowed()))\r
-               {\r
-                       /* Acknowledge the packet, clear the bank ready for the next packet */\r
-                       Endpoint_ClearOUT();\r
-               }\r
+               int16_t LeftSample_16Bit  = (int16_t)USB_Audio_ReadSample16();\r
+               int16_t RightSample_16Bit = (int16_t)USB_Audio_ReadSample16();\r
 \r
                /* Massage signed 16-bit left and right audio samples into signed 8-bit */\r
                int8_t  LeftSample_8Bit   = (LeftSample_16Bit  >> 8);\r
@@ -289,3 +128,69 @@ TASK(USB_Audio_Task)
 #endif\r
        }\r
 }\r
+\r
+void EVENT_USB_Connect(void)\r
+{\r
+       LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);\r
+       \r
+       /* Sample reload timer initialization */\r
+       OCR0A   = (F_CPU / AUDIO_SAMPLE_FREQUENCY) - 1;\r
+       TCCR0A  = (1 << WGM01);  // CTC mode\r
+       TCCR0B  = (1 << CS00);   // Fcpu speed\r
+\r
+#if defined(AUDIO_OUT_MONO)\r
+       /* Set speaker as output */\r
+       DDRC   |= (1 << 6);\r
+#elif defined(AUDIO_OUT_STEREO)\r
+       /* Set speakers as outputs */\r
+       DDRC   |= ((1 << 6) | (1 << 5));\r
+#elif defined(AUDIO_OUT_PORTC)\r
+       /* Set PORTC as outputs */\r
+       DDRC   |= 0xFF;\r
+#endif\r
+\r
+#if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))\r
+       /* PWM speaker timer initialization */\r
+       TCCRxA  = ((1 << WGMx0) | (1 << COMxA1) | (1 << COMxA0)\r
+                                                       | (1 << COMxB1) | (1 << COMxB0)); // Set on match, clear on TOP\r
+       TCCRxB  = ((1 << WGMx2) | (1 << CSx0));  // Fast 8-Bit PWM, Fcpu speed\r
+#endif \r
+}\r
+\r
+/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via\r
+ *  the status LEDs, disables the sample update and PWM output timers and stops the USB and Audio management tasks.\r
+ */\r
+void EVENT_USB_Disconnect(void)\r
+{\r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
+\r
+       /* Stop the timers */\r
+       TCCR0B = 0;\r
+#if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))\r
+       TCCRxB = 0;\r
+#endif         \r
+\r
+#if defined(AUDIO_OUT_MONO)\r
+       /* Set speaker as input to reduce current draw */\r
+       DDRC   &= ~(1 << 6);\r
+#elif defined(AUDIO_OUT_STEREO)\r
+       /* Set speakers as inputs to reduce current draw */\r
+       DDRC   &= ~((1 << 6) | (1 << 5));\r
+#elif defined(AUDIO_OUT_PORTC)\r
+       /* Set PORTC low */\r
+       PORTC  = 0x00;\r
+#endif\r
+}\r
+\r
+void EVENT_USB_ConfigurationChanged(void)\r
+{\r
+       LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
+       \r
+       if (!(USB_Audio_ConfigureEndpoints(&Speaker_Audio_Interface)))\r
+         LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
+}\r
+\r
+void EVENT_USB_UnhandledControlPacket(void)\r
+{\r
+       USB_Audio_ProcessControlPacket(&Speaker_Audio_Interface);\r
+}\r
index d8725a0..7d112db 100644 (file)
 \r
                #include "Descriptors.h"\r
                \r
-               #include <LUFA/Version.h>                    // Library Version Information\r
-               #include <LUFA/Drivers/USB/USB.h>            // USB Functionality\r
-               #include <LUFA/Drivers/Board/LEDs.h>         // LEDs driver\r
-               #include <LUFA/Scheduler/Scheduler.h>        // Simple scheduler for task management\r
+               #include <LUFA/Version.h>\r
+               #include <LUFA/Drivers/Board/LEDs.h>\r
+               #include <LUFA/Drivers/Board/Joystick.h>\r
+               #include <LUFA/Drivers/Peripheral/ADC.h>\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/Audio.h>\r
        \r
        /* Macros: */\r
                #if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER)\r
                        #define CSx0            CS10\r
                #endif\r
                \r
-       /* Enums: */\r
-               /** Enum for the possible status codes for passing to the UpdateStatus() function. */\r
-               enum AudioOutput_StatusCodes_t\r
-               {\r
-                       Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */\r
-                       Status_USBEnumerating = 1, /**< USB interface is enumerating */\r
-                       Status_USBReady       = 2, /**< USB interface is connected and ready */\r
-               };\r
-\r
-       /* Task Definitions: */\r
-               TASK(USB_Audio_Task);\r
-       \r
+       /* Macros: */\r
+               #define LEDMASK_USB_NOTREADY      LEDS_LED1\r
+               #define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)\r
+               #define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)\r
+               #define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)\r
+               \r
        /* Function Prototypes: */\r
+               void SetupHardware(void);\r
+               void ProcessNextSample(void);\r
+               \r
                void EVENT_USB_Connect(void);\r
                void EVENT_USB_Disconnect(void);\r
                void EVENT_USB_ConfigurationChanged(void);\r
                void EVENT_USB_UnhandledControlPacket(void);\r
-               \r
-               void UpdateStatus(uint8_t CurrentStatus);\r
 \r
 #endif\r
index 28f038f..8ad1def 100644 (file)
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)\r
 SRC = $(TARGET).c                                                 \\r
          Descriptors.c                                               \\r
-         $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \\r
@@ -136,7 +135,7 @@ SRC = $(TARGET).c                                                 \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \\r
-         $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \\r
+         $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/Audio.c          \\r
 \r
 \r
 # List C++ source files here. (C dependencies are automatically generated.)\r
@@ -186,7 +185,7 @@ CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)
 CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY\r
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION\r
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"\r
-CDEFS += -DAUDIO_OUT_STEREO\r
+CDEFS += -DAUDIO_OUT_MONO\r
 \r
 # Place -D or -U options here for ASM sources\r
 ADEFS = -DF_CPU=$(F_CPU)\r
index d7ebb9e..e6bc1a4 100644 (file)
   this software.\r
 */\r
 \r
-/** \file\r
- *\r
- *  Main source file for the CDC demo. This file contains the main tasks of the demo and\r
- *  is responsible for the initial application hardware configuration.\r
- */\r
-\r
 #include "CDC.h"\r
 \r
-/* Scheduler Task List */\r
-TASK_LIST\r
-{\r
-       { .Task = USB_USBTask          , .TaskStatus = TASK_STOP },\r
-       { .Task = CDC_Task             , .TaskStatus = TASK_STOP },\r
-};\r
+USB_ClassInfo_CDC_t VirtualSerial_CDC_Interface =\r
+       {\r
+               .ControlInterfaceNumber     = 0,\r
 \r
-/* Globals: */\r
-/** Contains the current baud rate and other settings of the virtual serial port. While this demo does not use\r
- *  the physical USART and thus does not use these settings, they must still be retained and returned to the host\r
- *  upon request or the host will assume the device is non-functional.\r
- *\r
- *  These values are set by the host via a class-specific request, however they are not required to be used accurately.\r
- *  It is possible to completely ignore these value or use other settings as the host is completely unaware of the physical\r
- *  serial link characteristics and instead sends and receives data in endpoint streams.\r
- */\r
-CDC_Line_Coding_t LineCoding = { .BaudRateBPS = 9600,\r
-                                 .CharFormat  = OneStopBit,\r
-                                 .ParityType  = Parity_None,\r
-                                 .DataBits    = 8            };\r
+               .DataINEndpointNumber       = CDC_TX_EPNUM,\r
+               .DataINEndpointSize         = CDC_TXRX_EPSIZE,\r
 \r
-/** String to print through the virtual serial port when the joystick is pressed upwards. */\r
-char JoystickUpString[]      = "Joystick Up\r\n";\r
+               .DataOUTEndpointNumber      = CDC_RX_EPNUM,\r
+               .DataOUTEndpointSize        = CDC_TXRX_EPSIZE,\r
 \r
-/** String to print through the virtual serial port when the joystick is pressed downward. */\r
-char JoystickDownString[]    = "Joystick Down\r\n";\r
+               .NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,\r
+               .NotificationEndpointSize   = CDC_NOTIFICATION_EPSIZE,\r
+       };\r
 \r
-/** String to print through the virtual serial port when the joystick is pressed left. */\r
-char JoystickLeftString[]    = "Joystick Left\r\n";\r
+int main(void)\r
+{\r
+       SetupHardware();\r
+       \r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
 \r
-/** String to print through the virtual serial port when the joystick is pressed right. */\r
-char JoystickRightString[]   = "Joystick Right\r\n";\r
+       for (;;)\r
+       {\r
+               CheckJoystickMovement();\r
+               \r
+               uint16_t BytesToDiscard = USB_CDC_BytesReceived(&VirtualSerial_CDC_Interface);\r
+               while (BytesToDiscard--)\r
+                 USB_CDC_ReceiveByte(&VirtualSerial_CDC_Interface);\r
 \r
-/** String to print through the virtual serial port when the joystick is pressed inwards. */\r
-char JoystickPressedString[] = "Joystick Pressed\r\n";\r
+               USB_CDC_USBTask(&VirtualSerial_CDC_Interface);\r
+               USB_USBTask();\r
+       }\r
+}\r
 \r
-/** Main program entry point. This routine configures the hardware required by the application, then\r
- *  starts the scheduler to run the application tasks.\r
- */\r
-int main(void)\r
+void SetupHardware(void)\r
 {\r
        /* Disable watchdog if enabled by bootloader/fuses */\r
        MCUSR &= ~(1 << WDRF);\r
@@ -87,235 +75,64 @@ int main(void)
        /* Hardware Initialization */\r
        Joystick_Init();\r
        LEDs_Init();\r
-       \r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
-       \r
-       /* Initialize Scheduler so that it can be used */\r
-       Scheduler_Init();\r
-\r
-       /* Initialize USB Subsystem */\r
        USB_Init();\r
-\r
-       /* Scheduling - routine never returns, so put this last in the main function */\r
-       Scheduler_Start();\r
-}\r
-\r
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and\r
- *  starts the library USB task to begin the enumeration and USB management process.\r
- */\r
-void EVENT_USB_Connect(void)\r
-{\r
-       /* Start USB management task */\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);\r
-\r
-       /* Indicate USB enumerating */\r
-       UpdateStatus(Status_USBEnumerating);\r
-}\r
-\r
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via\r
- *  the status LEDs and stops the USB management and CDC management tasks.\r
- */\r
-void EVENT_USB_Disconnect(void)\r
-{\r
-       /* Stop running CDC and USB management tasks */\r
-       Scheduler_SetTaskMode(CDC_Task, TASK_STOP);\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);\r
-\r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
-}\r
-\r
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration\r
- *  of the USB device after enumeration - the device endpoints are configured and the CDC management task started.\r
- */\r
-void EVENT_USB_ConfigurationChanged(void)\r
-{\r
-       /* Setup CDC Notification, Rx and Tx Endpoints */\r
-       Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,\r
-                                      ENDPOINT_DIR_IN, CDC_NOTIFICATION_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
-\r
-       Endpoint_ConfigureEndpoint(CDC_TX_EPNUM, EP_TYPE_BULK,\r
-                                      ENDPOINT_DIR_IN, CDC_TXRX_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
-\r
-       Endpoint_ConfigureEndpoint(CDC_RX_EPNUM, EP_TYPE_BULK,\r
-                                      ENDPOINT_DIR_OUT, CDC_TXRX_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
-\r
-       /* Indicate USB connected and ready */\r
-       UpdateStatus(Status_USBReady);\r
-       \r
-       /* Start CDC task */\r
-       Scheduler_SetTaskMode(CDC_Task, TASK_RUN);\r
-}\r
-\r
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific\r
- *  control requests that are not handled internally by the USB library (including the CDC control commands,\r
- *  which are all issued via the control endpoint), so that they can be handled appropriately for the application.\r
- */\r
-void EVENT_USB_UnhandledControlPacket(void)\r
-{\r
-       uint8_t* LineCodingData = (uint8_t*)&LineCoding;\r
-\r
-       /* Process CDC specific control requests */\r
-       switch (USB_ControlRequest.bRequest)\r
-       {\r
-               case REQ_GetLineEncoding:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {       \r
-                               /* Acknowledge the SETUP packet, ready for data transfer */\r
-                               Endpoint_ClearSETUP();\r
-\r
-                               /* Write the line coding data to the control endpoint */\r
-                               Endpoint_Write_Control_Stream_LE(LineCodingData, sizeof(CDC_Line_Coding_t));\r
-                               \r
-                               /* Finalize the stream transfer to send the last packet or clear the host abort */\r
-                               Endpoint_ClearOUT();\r
-                       }\r
-                       \r
-                       break;\r
-               case REQ_SetLineEncoding:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               /* Acknowledge the SETUP packet, ready for data transfer */\r
-                               Endpoint_ClearSETUP();\r
-\r
-                               /* Read the line coding data in from the host into the global struct */\r
-                               Endpoint_Read_Control_Stream_LE(LineCodingData, sizeof(CDC_Line_Coding_t));\r
-\r
-                               /* Finalize the stream transfer to clear the last packet from the host */\r
-                               Endpoint_ClearIN();\r
-                       }\r
-       \r
-                       break;\r
-               case REQ_SetControlLineState:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               /* Acknowledge the SETUP packet, ready for data transfer */\r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* NOTE: Here you can read in the line state mask from the host, to get the current state of the output handshake\r
-                                        lines. The mask is read in from the wValue parameter in USB_ControlRequest, and can be masked against the\r
-                                                CONTROL_LINE_OUT_* masks to determine the RTS and DTR line states using the following code:\r
-                               */\r
-                               \r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsINReady()));\r
-                               Endpoint_ClearIN();\r
-                       }\r
-       \r
-                       break;\r
-       }\r
 }\r
 \r
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to\r
- *  log to a serial port, or anything else that is suitable for status updates.\r
- *\r
- *  \param CurrentStatus  Current status of the system, from the CDC_StatusCodes_t enum\r
- */\r
-void UpdateStatus(uint8_t CurrentStatus)\r
+void CheckJoystickMovement(void)\r
 {\r
-       uint8_t LEDMask = LEDS_NO_LEDS;\r
-       \r
-       /* Set the LED mask to the appropriate LED mask based on the given status code */\r
-       switch (CurrentStatus)\r
-       {\r
-               case Status_USBNotReady:\r
-                       LEDMask = (LEDS_LED1);\r
-                       break;\r
-               case Status_USBEnumerating:\r
-                       LEDMask = (LEDS_LED1 | LEDS_LED2);\r
-                       break;\r
-               case Status_USBReady:\r
-                       LEDMask = (LEDS_LED2 | LEDS_LED4);\r
-                       break;\r
-       }\r
+       uint8_t     JoyStatus_LCL = Joystick_GetStatus();\r
+       char*       ReportString  = NULL;\r
+       static bool ActionSent = false;\r
        \r
-       /* Set the board LEDs to the new LED mask */\r
-       LEDs_SetAllLEDs(LEDMask);\r
-}\r
-\r
-/** Function to manage CDC data transmission and reception to and from the host. */\r
-TASK(CDC_Task)\r
-{\r
-       char*       ReportString    = NULL;\r
-       uint8_t     JoyStatus_LCL   = Joystick_GetStatus();\r
-       static bool ActionSent      = false;\r
-       \r
-#if 0\r
-       /* NOTE: Here you can use the notification endpoint to send back line state changes to the host, for the special RS-232\r
-                handshake signal lines (and some error states), via the CONTROL_LINE_IN_* masks and the following code:\r
-       */\r
-       USB_Notification_Header_t Notification = (USB_Notification_Header_t)\r
+       char* JoystickStrings[] =\r
                {\r
-                       .NotificationType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),\r
-                       .Notification     = NOTIF_SerialState,\r
-                       .wValue           = 0,\r
-                       .wIndex           = 0,\r
-                       .wLength          = sizeof(uint16_t),\r
+                       "Joystick Up\r\n",\r
+                       "Joystick Down\r\n",\r
+                       "Joystick Left\r\n",\r
+                       "Joystick Right\r\n",\r
+                       "Joystick Pressed\r\n",\r
                };\r
-               \r
-       uint16_t LineStateMask;\r
-       \r
-       // Set LineStateMask here to a mask of CONTROL_LINE_IN_* masks to set the input handshake line states to send to the host\r
-       \r
-       Endpoint_SelectEndpoint(CDC_NOTIFICATION_EPNUM);\r
-       Endpoint_Write_Stream_LE(&Notification, sizeof(Notification));\r
-       Endpoint_Write_Stream_LE(&LineStateMask, sizeof(LineStateMask));\r
-       Endpoint_ClearIN();\r
-#endif\r
 \r
-       /* Determine if a joystick action has occurred */\r
        if (JoyStatus_LCL & JOY_UP)\r
-         ReportString = JoystickUpString;\r
+         ReportString = JoystickStrings[0];\r
        else if (JoyStatus_LCL & JOY_DOWN)\r
-         ReportString = JoystickDownString;\r
+         ReportString = JoystickStrings[1];\r
        else if (JoyStatus_LCL & JOY_LEFT)\r
-         ReportString = JoystickLeftString;\r
+         ReportString = JoystickStrings[2];\r
        else if (JoyStatus_LCL & JOY_RIGHT)\r
-         ReportString = JoystickRightString;\r
+         ReportString = JoystickStrings[3];\r
        else if (JoyStatus_LCL & JOY_PRESS)\r
-         ReportString = JoystickPressedString;\r
-\r
-       /* Flag management - Only allow one string to be sent per action */\r
-       if (ReportString == NULL)\r
-       {\r
-               ActionSent = false;\r
-       }\r
-       else if (ActionSent == false)\r
+         ReportString = JoystickStrings[4];\r
+       else\r
+         ActionSent = false;\r
+         \r
+       if ((ReportString != NULL) && (ActionSent == false))\r
        {\r
                ActionSent = true;\r
+               \r
+               USB_CDC_SendString(&VirtualSerial_CDC_Interface, ReportString, strlen(ReportString));           \r
+       }\r
+}\r
 \r
-               /* Select the Serial Tx Endpoint */\r
-               Endpoint_SelectEndpoint(CDC_TX_EPNUM);\r
+void EVENT_USB_Connect(void)\r
+{\r
+       LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);\r
+}\r
 \r
-               /* Write the String to the Endpoint */\r
-               Endpoint_Write_Stream_LE(ReportString, strlen(ReportString));\r
-               \r
-               /* Remember if the packet to send completely fills the endpoint */\r
-               bool IsFull = (Endpoint_BytesInEndpoint() == CDC_TXRX_EPSIZE);\r
+void EVENT_USB_Disconnect(void)\r
+{\r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
+}\r
 \r
-               /* Finalize the stream transfer to send the last packet */\r
-               Endpoint_ClearIN();\r
+void EVENT_USB_ConfigurationChanged(void)\r
+{\r
+       LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
 \r
-               /* If the last packet filled the endpoint, send an empty packet to release the buffer on \r
-                * the receiver (otherwise all data will be cached until a non-full packet is received) */\r
-               if (IsFull)\r
-               {\r
-                       /* Wait until the endpoint is ready for another packet */\r
-                       while (!(Endpoint_IsINReady()));\r
-                       \r
-                       /* Send an empty packet to ensure that the host does not buffer data sent to it */\r
-                       Endpoint_ClearIN();\r
-               }\r
-       }\r
+       if (!(USB_CDC_ConfigureEndpoints(&VirtualSerial_CDC_Interface)))\r
+         LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
+}\r
 \r
-       /* Select the Serial Rx Endpoint */\r
-       Endpoint_SelectEndpoint(CDC_RX_EPNUM);\r
-       \r
-       /* Throw away any received data from the host */\r
-       if (Endpoint_IsOUTReceived())\r
-         Endpoint_ClearOUT();\r
+void EVENT_USB_UnhandledControlPacket(void)\r
+{\r
+       USB_CDC_ProcessControlPacket(&VirtualSerial_CDC_Interface);\r
 }\r
index 4c4ca74..b487813 100644 (file)
 \r
                #include "Descriptors.h"\r
 \r
-               #include <LUFA/Version.h>                        // Library Version Information\r
-               #include <LUFA/Drivers/USB/USB.h>                // USB Functionality\r
-               #include <LUFA/Drivers/Board/Joystick.h>         // Joystick driver\r
-               #include <LUFA/Drivers/Board/LEDs.h>             // LEDs driver\r
-               #include <LUFA/Scheduler/Scheduler.h>            // Simple scheduler for task management\r
+               #include <LUFA/Version.h>\r
+               #include <LUFA/Drivers/Board/LEDs.h>\r
+               #include <LUFA/Drivers/Board/Joystick.h>\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/CDC.h>\r
 \r
        /* Macros: */\r
-               /** CDC Class specific request to get the current virtual serial port configuration settings. */\r
-               #define REQ_GetLineEncoding          0x21\r
-\r
-               /** CDC Class specific request to set the current virtual serial port configuration settings. */\r
-               #define REQ_SetLineEncoding          0x20\r
-\r
-               /** CDC Class specific request to set the current virtual serial port handshake line states. */\r
-               #define REQ_SetControlLineState      0x22\r
-               \r
-               /** Notification type constant for a change in the virtual serial port handshake line states, for\r
-                *  use with a USB_Notification_Header_t notification structure when sent to the host via the CDC \r
-                *  notification endpoint.\r
-                */\r
-               #define NOTIF_SerialState            0x20\r
-\r
-               /** Mask for the DTR handshake line for use with the REQ_SetControlLineState class specific request\r
-                *  from the host, to indicate that the DTR line state should be high.\r
-                */\r
-               #define CONTROL_LINE_OUT_DTR         (1 << 0)\r
-\r
-               /** Mask for the RTS handshake line for use with the REQ_SetControlLineState class specific request\r
-                *  from the host, to indicate that theRTS line state should be high.\r
-                */\r
-               #define CONTROL_LINE_OUT_RTS         (1 << 1)\r
-               \r
-               /** Mask for the DCD handshake line for use with the a NOTIF_SerialState class specific notification\r
-                *  from the device to the host, to indicate that the DCD line state is currently high.\r
-                */\r
-               #define CONTROL_LINE_IN_DCD          (1 << 0)\r
-\r
-               /** Mask for the DSR handshake line for use with the a NOTIF_SerialState class specific notification\r
-                *  from the device to the host, to indicate that the DSR line state is currently high.\r
-                */\r
-               #define CONTROL_LINE_IN_DSR          (1 << 1)\r
-\r
-               /** Mask for the BREAK handshake line for use with the a NOTIF_SerialState class specific notification\r
-                *  from the device to the host, to indicate that the BREAK line state is currently high.\r
-                */\r
-               #define CONTROL_LINE_IN_BREAK        (1 << 2)\r
-\r
-               /** Mask for the RING handshake line for use with the a NOTIF_SerialState class specific notification\r
-                *  from the device to the host, to indicate that the RING line state is currently high.\r
-                */\r
-               #define CONTROL_LINE_IN_RING         (1 << 3)\r
-\r
-               /** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,\r
-                *  to indicate that a framing error has occurred on the virtual serial port.\r
-                */\r
-               #define CONTROL_LINE_IN_FRAMEERROR   (1 << 4)\r
-\r
-               /** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,\r
-                *  to indicate that a parity error has occurred on the virtual serial port.\r
-                */\r
-               #define CONTROL_LINE_IN_PARITYERROR  (1 << 5)\r
-\r
-               /** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,\r
-                *  to indicate that a data overrun error has occurred on the virtual serial port.\r
-                */\r
-               #define CONTROL_LINE_IN_OVERRUNERROR (1 << 6)\r
-               \r
-       /* Type Defines: */\r
-               /** Type define for the virtual serial port line encoding settings, for storing the current USART configuration\r
-                *  as set by the host via a class specific request.\r
-                */\r
-               typedef struct\r
-               {\r
-                       uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */\r
-                       uint8_t  CharFormat; /**< Character format of the virtual serial port, a value from the\r
-                                             *   CDCDevice_CDC_LineCodingFormats_t enum\r
-                                             */\r
-                       uint8_t  ParityType; /**< Parity setting of the virtual serial port, a value from the\r
-                                             *   CDCDevice_LineCodingParity_t enum\r
-                                             */\r
-                       uint8_t  DataBits; /**< Bits of data per character of the virtual serial port */\r
-               } CDC_Line_Coding_t;\r
-               \r
-               /** Type define for a CDC notification, sent to the host via the CDC notification endpoint to indicate a\r
-                *  change in the device state asynchronously.\r
-                */\r
-               typedef struct\r
-               {\r
-                       uint8_t  NotificationType; /**< Notification type, a mask of REQDIR_*, REQTYPE_* and REQREC_* constants\r
-                                                   *   from the library StdRequestType.h header\r
-                                                   */\r
-                       uint8_t  Notification; /**< Notification value, a NOTIF_* constant */\r
-                       uint16_t wValue; /**< Notification wValue, notification-specific */\r
-                       uint16_t wIndex; /**< Notification wIndex, notification-specific */\r
-                       uint16_t wLength; /**< Notification wLength, notification-specific */\r
-               } USB_Notification_Header_t;\r
-               \r
-       /* Enums: */\r
-               /** Enum for the possible line encoding formats of a virtual serial port. */\r
-               enum CDCDevice_CDC_LineCodingFormats_t\r
-               {\r
-                       OneStopBit          = 0, /**< Each frame contains one stop bit */\r
-                       OneAndAHalfStopBits = 1, /**< Each frame contains one and a half stop bits */\r
-                       TwoStopBits         = 2, /**< Each frame contains two stop bits */\r
-               };\r
+               #define LEDMASK_USB_NOTREADY      LEDS_LED1\r
+               #define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)\r
+               #define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)\r
+               #define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)\r
                \r
-               /** Enum for the possible line encoding parity settings of a virtual serial port. */\r
-               enum CDCDevice_LineCodingParity_t\r
-               {\r
-                       Parity_None         = 0, /**< No parity bit mode on each frame */\r
-                       Parity_Odd          = 1, /**< Odd parity bit mode on each frame */\r
-                       Parity_Even         = 2, /**< Even parity bit mode on each frame */\r
-                       Parity_Mark         = 3, /**< Mark parity bit mode on each frame */\r
-                       Parity_Space        = 4, /**< Space parity bit mode on each frame */\r
-               };\r
-\r
-               /** Enum for the possible status codes for passing to the UpdateStatus() function. */\r
-               enum CDC_StatusCodes_t\r
-               {\r
-                       Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */\r
-                       Status_USBEnumerating = 1, /**< USB interface is enumerating */\r
-                       Status_USBReady       = 2, /**< USB interface is connected and ready */\r
-               };\r
-               \r
-       /* Tasks: */\r
-               TASK(CDC_Task);\r
-\r
        /* Function Prototypes: */\r
+               void SetupHardware(void);\r
+               void CheckJoystickMovement(void);\r
+\r
                void EVENT_USB_Connect(void);\r
                void EVENT_USB_Disconnect(void);\r
                void EVENT_USB_ConfigurationChanged(void);\r
                void EVENT_USB_UnhandledControlPacket(void);\r
-\r
-               void UpdateStatus(uint8_t CurrentStatus);\r
+               void EVENT_USB_StartOfFrame(void);\r
 \r
 #endif\r
index 41b4430..1a9dbb5 100644 (file)
 #define _DESCRIPTORS_H_\r
 \r
        /* Includes: */\r
-               #include <LUFA/Drivers/USB/USB.h>\r
-\r
                #include <avr/pgmspace.h>\r
 \r
-       /* Macros: */\r
-               /** Macro to define a CDC class-specific functional descriptor. CDC functional descriptors have a\r
-                *  uniform structure but variable sized data payloads, thus cannot be represented accurately by\r
-                *  a single typedef struct. A macro is used instead so that functional descriptors can be created\r
-                *  easily by specifying the size of the payload. This allows sizeof() to work correctly.\r
-                *\r
-                *  \param DataSize  Size in bytes of the CDC functional descriptor's data payload\r
-                */\r
-               #define CDC_FUNCTIONAL_DESCRIPTOR(DataSize)        \\r
-                    struct                                        \\r
-                    {                                             \\r
-                         USB_Descriptor_Header_t Header;          \\r
-                             uint8_t                 SubType;         \\r
-                         uint8_t                 Data[DataSize];  \\r
-                    }\r
-                        \r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/CDC.h>\r
+\r
+       /* Macros: */                    \r
                /** Endpoint number of the CDC device-to-host notification IN endpoint. */\r
                #define CDC_NOTIFICATION_EPNUM         2\r
 \r
index bc22be5..bd4ff36 100644 (file)
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)\r
 SRC = $(TARGET).c                                                 \\r
          Descriptors.c                                               \\r
-         $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \\r
@@ -136,7 +135,7 @@ SRC = $(TARGET).c                                                 \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \\r
-         $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \\r
+         $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/CDC.c            \\r
 \r
 \r
 # List C++ source files here. (C dependencies are automatically generated.)\r
@@ -183,7 +182,7 @@ CSTANDARD = -std=gnu99
 \r
 # Place -D or -U options here for C sources\r
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)\r
-CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY\r
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY\r
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION\r
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"\r
 \r
index 2c2311b..97165e5 100644 (file)
 #define _DESCRIPTORS_H_\r
 \r
        /* Includes: */\r
-               #include <LUFA/Drivers/USB/USB.h>\r
-\r
                #include <avr/pgmspace.h>\r
 \r
-       /* Macros: */\r
-               /** Macro to define a CDC class-specific functional descriptor. CDC functional descriptors have a\r
-                *  uniform structure but variable sized data payloads, thus cannot be represented accurately by\r
-                *  a single typedef struct. A macro is used instead so that functional descriptors can be created\r
-                *  easily by specifying the size of the payload. This allows sizeof() to work correctly.\r
-                *\r
-                *  \param DataSize  Size in bytes of the CDC functional descriptor's data payload\r
-                */\r
-               #define CDC_FUNCTIONAL_DESCRIPTOR(DataSize)        \\r
-                    struct                                        \\r
-                    {                                             \\r
-                         USB_Descriptor_Header_t Header;          \\r
-                             uint8_t                 SubType;         \\r
-                         uint8_t                 Data[DataSize];  \\r
-                    }\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/CDC.h>\r
 \r
+       /* Macros: */\r
                /** Endpoint number of the first CDC interface's device-to-host notification IN endpoint. */\r
                #define CDC1_NOTIFICATION_EPNUM        3\r
 \r
index 34d772f..26947f4 100644 (file)
   arising out of or in connection with the use or performance of\r
   this software.\r
 */\r
-\r
-/** \file\r
- *\r
- *  Main source file for the DualCDC demo. This file contains the main tasks of the demo and\r
- *  is responsible for the initial application hardware configuration.\r
- */\r
  \r
 #include "DualCDC.h"\r
 \r
-/* Scheduler Task List */\r
-TASK_LIST\r
-{\r
-       { .Task = USB_USBTask          , .TaskStatus = TASK_STOP },\r
-       { .Task = CDC1_Task            , .TaskStatus = TASK_STOP },\r
-       { .Task = CDC2_Task            , .TaskStatus = TASK_STOP },\r
-};\r
+USB_ClassInfo_CDC_t VirtualSerial1_CDC_Interface =\r
+       {\r
+               .ControlInterfaceNumber     = 0,\r
 \r
-/* Globals: */\r
-/** Contains the current baud rate and other settings of the first virtual serial port. While this demo does not use\r
- *  the physical USART and thus does not use these settings, they must still be retained and returned to the host\r
- *  upon request or the host will assume the device is non-functional.\r
- *\r
- *  These values are set by the host via a class-specific request, however they are not required to be used accurately.\r
- *  It is possible to completely ignore these value or use other settings as the host is completely unaware of the physical\r
- *  serial link characteristics and instead sends and receives data in endpoint streams.\r
- */\r
-CDC_Line_Coding_t LineCoding1 = { .BaudRateBPS = 9600,\r
-                                  .CharFormat  = OneStopBit,\r
-                                  .ParityType  = Parity_None,\r
-                                  .DataBits    = 8            };\r
+               .DataINEndpointNumber       = CDC1_TX_EPNUM,\r
+               .DataINEndpointSize         = CDC_TXRX_EPSIZE,\r
 \r
-/** Contains the current baud rate and other settings of the second virtual serial port. While this demo does not use\r
- *  the physical USART and thus does not use these settings, they must still be retained and returned to the host\r
- *  upon request or the host will assume the device is non-functional.\r
- *\r
- *  These values are set by the host via a class-specific request, however they are not required to be used accurately.\r
- *  It is possible to completely ignore these value or use other settings as the host is completely unaware of the physical\r
- *  serial link characteristics and instead sends and receives data in endpoint streams.\r
- */\r
-CDC_Line_Coding_t LineCoding2 = { .BaudRateBPS = 9600,\r
-                                  .CharFormat  = OneStopBit,\r
-                                  .ParityType  = Parity_None,\r
-                                  .DataBits    = 8            };\r
-                                                                 \r
-/** String to print through the first virtual serial port when the joystick is pressed upwards. */\r
-char JoystickUpString[]      = "Joystick Up\r\n";\r
+               .DataOUTEndpointNumber      = CDC1_RX_EPNUM,\r
+               .DataOUTEndpointSize        = CDC_TXRX_EPSIZE,\r
 \r
-/** String to print through the first virtual serial port when the joystick is pressed downward. */\r
-char JoystickDownString[]    = "Joystick Down\r\n";\r
+               .NotificationEndpointNumber = CDC1_NOTIFICATION_EPNUM,\r
+               .NotificationEndpointSize   = CDC_NOTIFICATION_EPSIZE,\r
+       };\r
+\r
+USB_ClassInfo_CDC_t VirtualSerial2_CDC_Interface =\r
+       {\r
+               .ControlInterfaceNumber     = 0,\r
 \r
-/** String to print through the first virtual serial port when the joystick is pressed left. */\r
-char JoystickLeftString[]    = "Joystick Left\r\n";\r
+               .DataINEndpointNumber       = CDC2_TX_EPNUM,\r
+               .DataINEndpointSize         = CDC_TXRX_EPSIZE,\r
 \r
-/** String to print through the first virtual serial port when the joystick is pressed right. */\r
-char JoystickRightString[]   = "Joystick Right\r\n";\r
+               .DataOUTEndpointNumber      = CDC2_RX_EPNUM,\r
+               .DataOUTEndpointSize        = CDC_TXRX_EPSIZE,\r
 \r
-/** String to print through the first virtual serial port when the joystick is pressed inwards. */\r
-char JoystickPressedString[] = "Joystick Pressed\r\n";\r
+               .NotificationEndpointNumber = CDC2_NOTIFICATION_EPNUM,\r
+               .NotificationEndpointSize   = CDC_NOTIFICATION_EPSIZE,\r
+       };\r
 \r
-/** Main program entry point. This routine configures the hardware required by the application, then\r
- *  starts the scheduler to run the application tasks.\r
- */\r
 int main(void)\r
 {\r
+       SetupHardware();\r
+       \r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
+\r
+       for (;;)\r
+       {\r
+               CheckJoystickMovement();\r
+\r
+               uint16_t BytesToDiscard = USB_CDC_BytesReceived(&VirtualSerial1_CDC_Interface);\r
+               while (BytesToDiscard--)\r
+                 USB_CDC_ReceiveByte(&VirtualSerial1_CDC_Interface);\r
+\r
+               uint16_t BytesToEcho = USB_CDC_BytesReceived(&VirtualSerial2_CDC_Interface);\r
+               while (BytesToEcho--)\r
+                 USB_CDC_SendByte(&VirtualSerial2_CDC_Interface, USB_CDC_ReceiveByte(&VirtualSerial2_CDC_Interface));\r
+                 \r
+               USB_CDC_USBTask(&VirtualSerial1_CDC_Interface);\r
+               USB_CDC_USBTask(&VirtualSerial2_CDC_Interface);\r
+               USB_USBTask();\r
+       }\r
+}\r
+\r
+void SetupHardware(void)\r
+{\r
        /* Disable watchdog if enabled by bootloader/fuses */\r
        MCUSR &= ~(1 << WDRF);\r
        wdt_disable();\r
@@ -101,257 +94,68 @@ int main(void)
        /* Hardware Initialization */\r
        Joystick_Init();\r
        LEDs_Init();\r
-       \r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
-       \r
-       /* Initialize Scheduler so that it can be used */\r
-       Scheduler_Init();\r
-\r
-       /* Initialize USB Subsystem */\r
        USB_Init();\r
-\r
-       /* Scheduling - routine never returns, so put this last in the main function */\r
-       Scheduler_Start();\r
-}\r
-\r
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and\r
- *  starts the library USB task to begin the enumeration and USB management process.\r
- */\r
-void EVENT_USB_Connect(void)\r
-{\r
-       /* Start USB management task */\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);\r
-\r
-       /* Indicate USB enumerating */\r
-       UpdateStatus(Status_USBEnumerating);\r
-}\r
-\r
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via\r
- *  the status LEDs and stops the USB management and CDC management tasks.\r
- */\r
-void EVENT_USB_Disconnect(void)\r
-{\r
-       /* Stop running CDC and USB management tasks */\r
-       Scheduler_SetTaskMode(CDC1_Task, TASK_STOP);\r
-       Scheduler_SetTaskMode(CDC2_Task, TASK_STOP);\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);\r
-\r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
-}\r
-\r
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration\r
- *  of the USB device after enumeration - the device endpoints are configured and the CDC management tasks are started.\r
- */\r
-void EVENT_USB_ConfigurationChanged(void)\r
-{\r
-       /* Setup CDC Notification, Rx and Tx Endpoints for the first CDC */\r
-       Endpoint_ConfigureEndpoint(CDC1_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,\r
-                                      ENDPOINT_DIR_IN, CDC_NOTIFICATION_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
-\r
-       Endpoint_ConfigureEndpoint(CDC1_TX_EPNUM, EP_TYPE_BULK,\r
-                                      ENDPOINT_DIR_IN, CDC_TXRX_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
-\r
-       Endpoint_ConfigureEndpoint(CDC1_RX_EPNUM, EP_TYPE_BULK,\r
-                                      ENDPOINT_DIR_OUT, CDC_TXRX_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
-\r
-       /* Setup CDC Notification, Rx and Tx Endpoints for the second CDC */\r
-       Endpoint_ConfigureEndpoint(CDC2_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,\r
-                                      ENDPOINT_DIR_IN, CDC_NOTIFICATION_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
-\r
-       Endpoint_ConfigureEndpoint(CDC2_TX_EPNUM, EP_TYPE_BULK,\r
-                                      ENDPOINT_DIR_IN, CDC_TXRX_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
-\r
-       Endpoint_ConfigureEndpoint(CDC2_RX_EPNUM, EP_TYPE_BULK,\r
-                                      ENDPOINT_DIR_OUT, CDC_TXRX_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
-                                                          \r
-       /* Indicate USB connected and ready */\r
-       UpdateStatus(Status_USBReady);\r
-       \r
-       /* Start CDC tasks */\r
-       Scheduler_SetTaskMode(CDC1_Task, TASK_RUN);\r
-       Scheduler_SetTaskMode(CDC2_Task, TASK_RUN);\r
-}\r
-\r
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific\r
- *  control requests that are not handled internally by the USB library (including the CDC control commands,\r
- *  which are all issued via the control endpoint), so that they can be handled appropriately for the application.\r
- */\r
-void EVENT_USB_UnhandledControlPacket(void)\r
-{\r
-       /* Determine which interface's Line Coding data is being set from the wIndex parameter */\r
-       uint8_t* LineCodingData = (USB_ControlRequest.wIndex == 0) ? (uint8_t*)&LineCoding1 : (uint8_t*)&LineCoding2;\r
-\r
-       /* Process CDC specific control requests */\r
-       switch (USB_ControlRequest.bRequest)\r
-       {\r
-               case REQ_GetLineEncoding:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {       \r
-                               /* Acknowledge the SETUP packet, ready for data transfer */\r
-                               Endpoint_ClearSETUP();\r
-\r
-                               /* Write the line coding data to the control endpoint */\r
-                               Endpoint_Write_Control_Stream_LE(LineCodingData, sizeof(CDC_Line_Coding_t));\r
-                               \r
-                               /* Finalize the stream transfer to send the last packet or clear the host abort */\r
-                               Endpoint_ClearOUT();\r
-                       }\r
-                       \r
-                       break;\r
-               case REQ_SetLineEncoding:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               /* Acknowledge the SETUP packet, ready for data transfer */\r
-                               Endpoint_ClearSETUP();\r
-\r
-                               /* Read the line coding data in from the host into the global struct */\r
-                               Endpoint_Read_Control_Stream_LE(LineCodingData, sizeof(CDC_Line_Coding_t));\r
-\r
-                               /* Finalize the stream transfer to clear the last packet from the host */\r
-                               Endpoint_ClearIN();\r
-                       }\r
-       \r
-                       break;\r
-               case REQ_SetControlLineState:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               /* Acknowledge the SETUP packet, ready for data transfer */\r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsINReady()));\r
-                               Endpoint_ClearIN();\r
-                       }\r
-       \r
-                       break;\r
-       }\r
-}\r
-\r
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to\r
- *  log to a serial port, or anything else that is suitable for status updates.\r
- *\r
- *  \param CurrentStatus  Current status of the system, from the DualCDC_StatusCodes_t enum\r
- */\r
-void UpdateStatus(uint8_t CurrentStatus)\r
-{\r
-       uint8_t LEDMask = LEDS_NO_LEDS;\r
-       \r
-       /* Set the LED mask to the appropriate LED mask based on the given status code */\r
-       switch (CurrentStatus)\r
-       {\r
-               case Status_USBNotReady:\r
-                       LEDMask = (LEDS_LED1);\r
-                       break;\r
-               case Status_USBEnumerating:\r
-                       LEDMask = (LEDS_LED1 | LEDS_LED2);\r
-                       break;\r
-               case Status_USBReady:\r
-                       LEDMask = (LEDS_LED2 | LEDS_LED4);\r
-                       break;\r
-       }\r
-       \r
-       /* Set the board LEDs to the new LED mask */\r
-       LEDs_SetAllLEDs(LEDMask);\r
 }\r
 \r
-/** Function to manage CDC data transmission and reception to and from the host for the first CDC interface, which sends joystick\r
- *  movements to the host as ASCII strings.\r
- */\r
-TASK(CDC1_Task)\r
+void CheckJoystickMovement(void)\r
 {\r
-       char*       ReportString    = NULL;\r
-       uint8_t     JoyStatus_LCL   = Joystick_GetStatus();\r
-       static bool ActionSent      = false;\r
+       uint8_t     JoyStatus_LCL = Joystick_GetStatus();\r
+       char*       ReportString  = NULL;\r
+       static bool ActionSent = false;\r
+\r
+       char* JoystickStrings[] =\r
+               {\r
+                       "Joystick Up\r\n",\r
+                       "Joystick Down\r\n",\r
+                       "Joystick Left\r\n",\r
+                       "Joystick Right\r\n",\r
+                       "Joystick Pressed\r\n",\r
+               };\r
 \r
-       /* Determine if a joystick action has occurred */\r
        if (JoyStatus_LCL & JOY_UP)\r
-         ReportString = JoystickUpString;\r
+         ReportString = JoystickStrings[0];\r
        else if (JoyStatus_LCL & JOY_DOWN)\r
-         ReportString = JoystickDownString;\r
+         ReportString = JoystickStrings[1];\r
        else if (JoyStatus_LCL & JOY_LEFT)\r
-         ReportString = JoystickLeftString;\r
+         ReportString = JoystickStrings[2];\r
        else if (JoyStatus_LCL & JOY_RIGHT)\r
-         ReportString = JoystickRightString;\r
+         ReportString = JoystickStrings[3];\r
        else if (JoyStatus_LCL & JOY_PRESS)\r
-         ReportString = JoystickPressedString;\r
-\r
-       /* Flag management - Only allow one string to be sent per action */\r
-       if (ReportString == NULL)\r
-       {\r
-               ActionSent = false;\r
-       }\r
-       else if (ActionSent == false)\r
+         ReportString = JoystickStrings[4];\r
+       else\r
+         ActionSent = false;\r
+         \r
+       if ((ReportString != NULL) && (ActionSent == false))\r
        {\r
                ActionSent = true;\r
                \r
-               /* Select the Serial Tx Endpoint */\r
-               Endpoint_SelectEndpoint(CDC1_TX_EPNUM);\r
-\r
-               /* Write the String to the Endpoint */\r
-               Endpoint_Write_Stream_LE(ReportString, strlen(ReportString));\r
-               \r
-               /* Finalize the stream transfer to send the last packet */\r
-               Endpoint_ClearIN();\r
-\r
-               /* Wait until the endpoint is ready for another packet */\r
-               while (!(Endpoint_IsINReady()));\r
-               \r
-               /* Send an empty packet to ensure that the host does not buffer data sent to it */\r
-               Endpoint_ClearIN();\r
+               USB_CDC_SendString(&VirtualSerial1_CDC_Interface, ReportString, strlen(ReportString));          \r
        }\r
-\r
-       /* Select the Serial Rx Endpoint */\r
-       Endpoint_SelectEndpoint(CDC1_RX_EPNUM);\r
-       \r
-       /* Throw away any received data from the host */\r
-       if (Endpoint_IsOUTReceived())\r
-         Endpoint_ClearOUT();\r
 }\r
 \r
-/** Function to manage CDC data transmission and reception to and from the host for the second CDC interface, which echoes back\r
- *  all data sent to it from the host.\r
- */\r
-TASK(CDC2_Task)\r
+void EVENT_USB_Connect(void)\r
 {\r
-       /* Select the Serial Rx Endpoint */\r
-       Endpoint_SelectEndpoint(CDC2_RX_EPNUM);\r
-       \r
-       /* Check to see if any data has been received */\r
-       if (Endpoint_IsOUTReceived())\r
-       {\r
-               /* Create a temp buffer big enough to hold the incoming endpoint packet */\r
-               uint8_t  Buffer[Endpoint_BytesInEndpoint()];\r
-               \r
-               /* Remember how large the incoming packet is */\r
-               uint16_t DataLength = Endpoint_BytesInEndpoint();\r
-       \r
-               /* Read in the incoming packet into the buffer */\r
-               Endpoint_Read_Stream_LE(&Buffer, DataLength);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);\r
+}\r
 \r
-               /* Finalize the stream transfer to send the last packet */\r
-               Endpoint_ClearOUT();\r
+void EVENT_USB_Disconnect(void)\r
+{\r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
+}\r
 \r
-               /* Select the Serial Tx Endpoint */\r
-               Endpoint_SelectEndpoint(CDC2_TX_EPNUM);\r
-               \r
-               /* Write the received data to the endpoint */\r
-               Endpoint_Write_Stream_LE(&Buffer, DataLength);\r
+void EVENT_USB_ConfigurationChanged(void)\r
+{\r
+       LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
 \r
-               /* Finalize the stream transfer to send the last packet */\r
-               Endpoint_ClearIN();\r
+       if (!(USB_CDC_ConfigureEndpoints(&VirtualSerial1_CDC_Interface)))\r
+         LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
 \r
-               /* Wait until the endpoint is ready for the next packet */\r
-               while (!(Endpoint_IsINReady()));\r
+       if (!(USB_CDC_ConfigureEndpoints(&VirtualSerial2_CDC_Interface)))\r
+         LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
+}\r
 \r
-               /* Send an empty packet to prevent host buffering */\r
-               Endpoint_ClearIN();\r
-       }\r
+void EVENT_USB_UnhandledControlPacket(void)\r
+{\r
+       USB_CDC_ProcessControlPacket(&VirtualSerial1_CDC_Interface);\r
+       USB_CDC_ProcessControlPacket(&VirtualSerial2_CDC_Interface);\r
 }\r
index 117af60..3c1e296 100644 (file)
 \r
                #include "Descriptors.h"\r
 \r
-               #include <LUFA/Version.h>                        // Library Version Information\r
-               #include <LUFA/Drivers/USB/USB.h>                // USB Functionality\r
-               #include <LUFA/Drivers/Board/Joystick.h>         // Joystick driver\r
-               #include <LUFA/Drivers/Board/LEDs.h>             // LEDs driver\r
-               #include <LUFA/Scheduler/Scheduler.h>            // Simple scheduler for task management\r
+               #include <LUFA/Version.h>\r
+               #include <LUFA/Drivers/Board/LEDs.h>\r
+               #include <LUFA/Drivers/Board/Joystick.h>\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/CDC.h>\r
 \r
        /* Macros: */\r
-               /** CDC Class specific request to get the current virtual serial port configuration settings. */\r
-               #define REQ_GetLineEncoding          0x21\r
-\r
-               /** CDC Class specific request to set the current virtual serial port configuration settings. */\r
-               #define REQ_SetLineEncoding          0x20\r
-\r
-               /** CDC Class specific request to set the current virtual serial port handshake line states. */\r
-               #define REQ_SetControlLineState      0x22\r
-\r
-       /* Type Defines: */\r
-               /** Type define for the virtual serial port line encoding settings, for storing the current USART configuration\r
-                *  as set by the host via a class specific request.\r
-                */\r
-               typedef struct\r
-               {\r
-                       uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */\r
-                       uint8_t  CharFormat; /**< Character format of the virtual serial port, a value from the\r
-                                             *   CDCDevice_CDC_LineCodingFormats_t enum\r
-                                             */\r
-                       uint8_t  ParityType; /**< Parity setting of the virtual serial port, a value from the\r
-                                             *   CDCDevice_LineCodingParity_t enum\r
-                                             */\r
-                       uint8_t  DataBits; /**< Bits of data per character of the virtual serial port */\r
-               } CDC_Line_Coding_t;\r
+               #define LEDMASK_USB_NOTREADY      LEDS_LED1\r
+               #define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)\r
+               #define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)\r
+               #define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)\r
                \r
-       /* Enums: */\r
-               /** Enum for the possible line encoding formats of a virtual serial port. */\r
-               enum CDCDevice_CDC_LineCodingFormats_t\r
-               {\r
-                       OneStopBit          = 0, /**< Each frame contains one stop bit */\r
-                       OneAndAHalfStopBits = 1, /**< Each frame contains one and a half stop bits */\r
-                       TwoStopBits         = 2, /**< Each frame contains two stop bits */\r
-               };\r
-               \r
-               /** Enum for the possible line encoding parity settings of a virtual serial port. */\r
-               enum CDCDevice_LineCodingParity_t\r
-               {\r
-                       Parity_None         = 0, /**< No parity bit mode on each frame */\r
-                       Parity_Odd          = 1, /**< Odd parity bit mode on each frame */\r
-                       Parity_Even         = 2, /**< Even parity bit mode on each frame */\r
-                       Parity_Mark         = 3, /**< Mark parity bit mode on each frame */\r
-                       Parity_Space        = 4, /**< Space parity bit mode on each frame */\r
-               };\r
-\r
-               /** Enum for the possible status codes for passing to the UpdateStatus() function. */\r
-               enum DualCDC_StatusCodes_t\r
-               {\r
-                       Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */\r
-                       Status_USBEnumerating = 1, /**< USB interface is enumerating */\r
-                       Status_USBReady       = 2, /**< USB interface is connected and ready */\r
-               };\r
-\r
-       /* Tasks: */\r
-               TASK(CDC1_Task);\r
-               TASK(CDC2_Task);\r
-\r
        /* Function Prototypes: */\r
+               void SetupHardware(void);\r
+               void CheckJoystickMovement(void);\r
+\r
                void EVENT_USB_Connect(void);\r
                void EVENT_USB_Disconnect(void);\r
                void EVENT_USB_ConfigurationChanged(void);\r
                void EVENT_USB_UnhandledControlPacket(void);\r
-\r
-               void UpdateStatus(uint8_t CurrentStatus);\r
+               void EVENT_USB_StartOfFrame(void);\r
                \r
 #endif\r
index 06d0e18..5fbda61 100644 (file)
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)\r
 SRC = $(TARGET).c                                                 \\r
          Descriptors.c                                               \\r
-         $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \\r
@@ -136,7 +135,7 @@ SRC = $(TARGET).c                                                 \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \\r
-         $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \\r
+         $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/CDC.c            \\r
 \r
 \r
 # List C++ source files here. (C dependencies are automatically generated.)\r
@@ -183,7 +182,7 @@ CSTANDARD = -std=gnu99
 \r
 # Place -D or -U options here for C sources\r
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)\r
-CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY\r
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY\r
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION\r
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"\r
 \r
index 0236870..bc4c68a 100644 (file)
 #define _DESCRIPTORS_H_\r
 \r
        /* Includes: */\r
-               #include <LUFA/Drivers/USB/USB.h>\r
-\r
                #include <avr/pgmspace.h>\r
 \r
-       /* Type Defines: */\r
-               /** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID\r
-                *  specification for details on the structure elements.\r
-                */\r
-               typedef struct\r
-               {\r
-                       USB_Descriptor_Header_t               Header;\r
-                               \r
-                       uint16_t                              HIDSpec;\r
-                       uint8_t                               CountryCode;\r
-               \r
-                       uint8_t                               TotalReportDescriptors;\r
-\r
-                       uint8_t                               HIDReportType;\r
-                       uint16_t                              HIDReportLength;\r
-               } USB_Descriptor_HID_t;\r
-\r
-               /** Type define for the data type used to store HID report descriptor elements. */\r
-               typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/HID.h>\r
 \r
+       /** Type Defines: */\r
                /** Type define for the device configuration descriptor structure. This must be defined in the\r
                 *  application code, as the configuration descriptor contains several sub-descriptors which\r
                 *  vary between devices, and which describe the device's usage to the host.\r
@@ -73,7 +55,7 @@
                USB_Descriptor_Endpoint_t             GenericINEndpoint;\r
                USB_Descriptor_Endpoint_t             GenericOUTEndpoint;\r
                } USB_Descriptor_Configuration_t;\r
-                                       \r
+\r
        /* Macros: */\r
                /** Endpoint number of the Generic HID reporting IN endpoint. */\r
                #define GENERIC_IN_EPNUM          1\r
                \r
                /** Size in bytes of the Generic HID reports (including report ID byte). */\r
                #define GENERIC_REPORT_SIZE       8\r
-\r
-               /** Descriptor header type value, to indicate a HID class HID descriptor. */\r
-               #define DTYPE_HID                 0x21\r
                \r
-               /** Descriptor header type value, to indicate a HID class HID report descriptor. */\r
-               #define DTYPE_Report              0x22\r
-\r
        /* Function Prototypes: */\r
                uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)\r
                                                                                        ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);\r
index 058d269..4dfb8e4 100644 (file)
   this software.\r
 */\r
 \r
-/** \file\r
- *\r
- *  Main source file for the GenericHID demo. This file contains the main tasks of the demo and\r
- *  is responsible for the initial application hardware configuration.\r
- */\r
-\r
 #include "GenericHID.h"\r
 \r
-/* Scheduler Task List */\r
-TASK_LIST\r
-{\r
-       { .Task = USB_USBTask          , .TaskStatus = TASK_STOP },\r
-       { .Task = USB_HID_Report       , .TaskStatus = TASK_STOP },\r
-};\r
+USB_ClassInfo_HID_t Generic_HID_Interface =\r
+       {\r
+               .InterfaceNumber         = 0,\r
 \r
-/** Static buffer to hold the last received report from the host, so that it can be echoed back in the next sent report */\r
-static uint8_t LastReceived[GENERIC_REPORT_SIZE];\r
+               .ReportINEndpointNumber  = GENERIC_IN_EPNUM,\r
+               .ReportINEndpointSize    = GENERIC_EPSIZE,\r
+               \r
+               .ReportOUTEndpointNumber = GENERIC_OUT_EPNUM,\r
+               .ReportOUTEndpointSize   = GENERIC_EPSIZE,\r
+               \r
+               .ReportBufferSize        = GENERIC_REPORT_SIZE,\r
 \r
+               .UsingReportProtocol     = true,\r
+       };\r
 \r
-/** Main program entry point. This routine configures the hardware required by the application, then\r
- *  starts the scheduler to run the USB management task.\r
- */\r
 int main(void)\r
 {\r
+       SetupHardware();\r
+       \r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
+       \r
+       for (;;)\r
+       {\r
+               USB_HID_USBTask(&Generic_HID_Interface);\r
+               USB_USBTask();\r
+       }\r
+}\r
+\r
+void SetupHardware(void)\r
+{\r
        /* Disable watchdog if enabled by bootloader/fuses */\r
        MCUSR &= ~(1 << WDRF);\r
        wdt_disable();\r
@@ -61,220 +69,45 @@ int main(void)
 \r
        /* Hardware Initialization */\r
        LEDs_Init();\r
-\r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
-\r
-       /* Initialize Scheduler so that it can be used */\r
-       Scheduler_Init();\r
-\r
-       /* Initialize USB Subsystem */\r
        USB_Init();\r
-       \r
-       /* Scheduling - routine never returns, so put this last in the main function */\r
-       Scheduler_Start();\r
 }\r
 \r
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and\r
- *  starts the library USB task to begin the enumeration and USB management process.\r
- */\r
 void EVENT_USB_Connect(void)\r
 {\r
-       /* Start USB management task */\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);\r
-\r
-       /* Indicate USB enumerating */\r
-       UpdateStatus(Status_USBEnumerating);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);\r
 }\r
 \r
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via\r
- *  the status LEDs and stops the USB management task.\r
- */\r
 void EVENT_USB_Disconnect(void)\r
 {\r
-       /* Stop running HID reporting and USB management tasks */\r
-       Scheduler_SetTaskMode(USB_HID_Report, TASK_STOP);\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);\r
-\r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
 }\r
 \r
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host sets the current configuration\r
- *  of the USB device after enumeration, and configures the generic HID device endpoints.\r
- */\r
 void EVENT_USB_ConfigurationChanged(void)\r
 {\r
-       /* Setup Generic IN Report Endpoint */\r
-       Endpoint_ConfigureEndpoint(GENERIC_IN_EPNUM, EP_TYPE_INTERRUPT,\r
-                                      ENDPOINT_DIR_IN, GENERIC_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
 \r
-       /* Setup Generic OUT Report Endpoint */\r
-       Endpoint_ConfigureEndpoint(GENERIC_OUT_EPNUM, EP_TYPE_INTERRUPT,\r
-                                      ENDPOINT_DIR_OUT, GENERIC_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
-\r
-       /* Indicate USB connected and ready */\r
-       UpdateStatus(Status_USBReady);\r
+       if (!(USB_HID_ConfigureEndpoints(&Generic_HID_Interface)))\r
+         LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
 }\r
 \r
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific\r
- *  control requests that are not handled internally by the USB library (including the HID commands, which are\r
- *  all issued via the control endpoint), so that they can be handled appropriately for the application.\r
- */\r
 void EVENT_USB_UnhandledControlPacket(void)\r
 {\r
-       /* Handle HID Class specific requests */\r
-       switch (USB_ControlRequest.bRequest)\r
-       {\r
-               case REQ_GetReport:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               uint8_t GenericData[GENERIC_REPORT_SIZE];\r
-\r
-                               Endpoint_ClearSETUP();\r
-       \r
-                               CreateGenericHIDReport(GenericData);\r
-\r
-                               /* Write the report data to the control endpoint */\r
-                               Endpoint_Write_Control_Stream_LE(&GenericData, sizeof(GenericData));\r
-\r
-                               /* Finalize the stream transfer to send the last packet or clear the host abort */\r
-                               Endpoint_ClearOUT();\r
-                       }\r
-               \r
-                       break;\r
-               case REQ_SetReport:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               uint8_t GenericData[GENERIC_REPORT_SIZE];\r
-\r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* Wait until the generic report has been sent by the host */\r
-                               while (!(Endpoint_IsOUTReceived()));\r
-\r
-                               Endpoint_Read_Control_Stream_LE(&GenericData, sizeof(GenericData));\r
-\r
-                               ProcessGenericHIDReport(GenericData);\r
-                       \r
-                               /* Clear the endpoint data */\r
-                               Endpoint_ClearOUT();\r
-\r
-                               /* Wait until the host is ready to receive the request confirmation */\r
-                               while (!(Endpoint_IsINReady()));\r
-                               \r
-                               /* Handshake the request by sending an empty IN packet */\r
-                               Endpoint_ClearIN();\r
-                       }\r
-                       \r
-                       break;\r
-       }\r
+       USB_HID_ProcessControlPacket(&Generic_HID_Interface);\r
 }\r
 \r
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to\r
- *  log to a serial port, or anything else that is suitable for status updates.\r
- *\r
- *  \param CurrentStatus  Current status of the system, from the GenericHID_StatusCodes_t enum\r
- */\r
-void UpdateStatus(uint8_t CurrentStatus)\r
+void EVENT_USB_StartOfFrame(void)\r
 {\r
-       uint8_t LEDMask = LEDS_NO_LEDS;\r
-       \r
-       /* Set the LED mask to the appropriate LED mask based on the given status code */\r
-       switch (CurrentStatus)\r
-       {\r
-               case Status_USBNotReady:\r
-                       LEDMask = (LEDS_LED1);\r
-                       break;\r
-               case Status_USBEnumerating:\r
-                       LEDMask = (LEDS_LED1 | LEDS_LED2);\r
-                       break;\r
-               case Status_USBReady:\r
-                       LEDMask = (LEDS_LED2 | LEDS_LED4);\r
-                       break;\r
-       }\r
-       \r
-       /* Set the board LEDs to the new LED mask */\r
-       LEDs_SetAllLEDs(LEDMask);\r
+       USB_HID_RegisterStartOfFrame(&Generic_HID_Interface);\r
 }\r
 \r
-/** Function to process the lest received report from the host.\r
- *\r
- *  \param DataArray  Pointer to a buffer where the last report data is stored\r
- */\r
-void ProcessGenericHIDReport(uint8_t* DataArray)\r
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)\r
 {\r
-       /*\r
-               This is where you need to process the reports being sent from the host to the device.\r
-               DataArray is an array holding the last report from the host. This function is called\r
-               each time the host has sent a report to the device.\r
-       */\r
+       // Create generic HID report here\r
        \r
-       for (uint8_t i = 0; i < GENERIC_REPORT_SIZE; i++)\r
-         LastReceived[i] = DataArray[i];\r
+       return 0;\r
 }\r
 \r
-/** Function to create the next report to send back to the host at the next reporting interval.\r
- *\r
- *  \param DataArray  Pointer to a buffer where the next report data should be stored\r
- */\r
-void CreateGenericHIDReport(uint8_t* DataArray)\r
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)\r
 {\r
-       /*\r
-               This is where you need to create reports to be sent to the host from the device. This\r
-               function is called each time the host is ready to accept a new report. DataArray is \r
-               an array to hold the report to the host.\r
-       */\r
-\r
-       for (uint8_t i = 0; i < GENERIC_REPORT_SIZE; i++)\r
-         DataArray[i] = LastReceived[i];\r
-}\r
-\r
-TASK(USB_HID_Report)\r
-{\r
-       /* Check if the USB system is connected to a host */\r
-       if (USB_IsConnected)\r
-       {\r
-               Endpoint_SelectEndpoint(GENERIC_OUT_EPNUM);\r
-               \r
-               /* Check to see if a packet has been sent from the host */\r
-               if (Endpoint_IsOUTReceived())\r
-               {\r
-                       /* Check to see if the packet contains data */\r
-                       if (Endpoint_IsReadWriteAllowed())\r
-                       {\r
-                               /* Create a temporary buffer to hold the read in report from the host */\r
-                               uint8_t GenericData[GENERIC_REPORT_SIZE];\r
-                               \r
-                               /* Read Generic Report Data */\r
-                               Endpoint_Read_Stream_LE(&GenericData, sizeof(GenericData));\r
-                               \r
-                               /* Process Generic Report Data */\r
-                               ProcessGenericHIDReport(GenericData);\r
-                       }\r
-\r
-                       /* Finalize the stream transfer to send the last packet */\r
-                       Endpoint_ClearOUT();\r
-               }       \r
-\r
-               Endpoint_SelectEndpoint(GENERIC_IN_EPNUM);\r
-               \r
-               /* Check to see if the host is ready to accept another packet */\r
-               if (Endpoint_IsINReady())\r
-               {\r
-                       /* Create a temporary buffer to hold the report to send to the host */\r
-                       uint8_t GenericData[GENERIC_REPORT_SIZE];\r
-                       \r
-                       /* Create Generic Report Data */\r
-                       CreateGenericHIDReport(GenericData);\r
-\r
-                       /* Write Generic Report Data */\r
-                       Endpoint_Write_Stream_LE(&GenericData, sizeof(GenericData));\r
-\r
-                       /* Finalize the stream transfer to send the last packet */\r
-                       Endpoint_ClearIN();\r
-               }\r
-       }\r
+       // Process received generic HID report here\r
 }\r
index 30354b7..2742643 100644 (file)
                \r
                #include "Descriptors.h"\r
 \r
-               #include <LUFA/Version.h>                    // Library Version Information\r
-               #include <LUFA/Scheduler/Scheduler.h>        // Simple scheduler for task management\r
-               #include <LUFA/Drivers/USB/USB.h>            // USB Functionality\r
-               #include <LUFA/Drivers/Board/LEDs.h>         // LEDs driver\r
-                       \r
-       /* Macros: */\r
-               /** HID Class specific request to get the next HID report from the device. */\r
-               #define REQ_GetReport      0x01\r
-\r
-               /** HID Class specific request to send the next HID report to the device. */\r
-               #define REQ_SetReport      0x09\r
-\r
-       /* Enums: */\r
-               /** Enum for the possible status codes for passing to the UpdateStatus() function. */\r
-               enum GenericHID_StatusCodes_t\r
-               {\r
-                       Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */\r
-                       Status_USBEnumerating = 1, /**< USB interface is enumerating */\r
-                       Status_USBReady       = 2, /**< USB interface is connected and ready */\r
-               };\r
+               #include <LUFA/Version.h>\r
+               #include <LUFA/Drivers/Board/LEDs.h>\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/HID.h>\r
 \r
-       /* Task Definitions: */\r
-               TASK(USB_HID_Report);\r
+       /* Macros: */\r
+               #define LEDMASK_USB_NOTREADY      LEDS_LED1\r
+               #define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)\r
+               #define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)\r
+               #define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)\r
 \r
        /* Function Prototypes: */\r
+               void SetupHardware(void);\r
+\r
                void EVENT_USB_Connect(void);\r
                void EVENT_USB_Disconnect(void);\r
                void EVENT_USB_ConfigurationChanged(void);\r
                void EVENT_USB_UnhandledControlPacket(void);\r
+               void EVENT_USB_StartOfFrame(void);\r
 \r
-               void UpdateStatus(uint8_t CurrentStatus);\r
-               void ProcessGenericHIDReport(uint8_t* DataArray);\r
-               void CreateGenericHIDReport(uint8_t* DataArray);\r
+               uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);\r
+               void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,\r
+                                                                  void* ReportData, uint16_t ReportSize);\r
                \r
 #endif\r
index 9c6c891..5cc4b4a 100644 (file)
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)\r
 SRC = $(TARGET).c                                                 \\r
          Descriptors.c                                               \\r
-         $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \\r
@@ -136,7 +135,7 @@ SRC = $(TARGET).c                                                 \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \\r
-         $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \\r
+         $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/HID.c            \\r
 \r
 \r
 # List C++ source files here. (C dependencies are automatically generated.)\r
@@ -183,7 +182,7 @@ CSTANDARD = -std=gnu99
 \r
 # Place -D or -U options here for C sources\r
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)\r
-CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY\r
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY\r
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION\r
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"\r
 \r
index 6121295..1241ad1 100644 (file)
 #define _DESCRIPTORS_H_\r
 \r
        /* Includes: */\r
-               #include <LUFA/Drivers/USB/USB.h>\r
-\r
                #include <avr/pgmspace.h>\r
 \r
-       /* Type Defines: */\r
-               /** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID\r
-                *  specification for details on the structure elements.\r
-                */\r
-               typedef struct\r
-               {\r
-                       USB_Descriptor_Header_t               Header;\r
-                               \r
-                       uint16_t                              HIDSpec;\r
-                       uint8_t                               CountryCode;\r
-               \r
-                       uint8_t                               TotalReportDescriptors;\r
-\r
-                       uint8_t                               HIDReportType;\r
-                       uint16_t                              HIDReportLength;\r
-               } USB_Descriptor_HID_t;\r
-\r
-               /** Type define for the data type used to store HID report descriptor elements. */\r
-               typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/HID.h>\r
 \r
+       /* Type Defines: */\r
                /** Type define for the device configuration descriptor structure. This must be defined in the\r
                 *  application code, as the configuration descriptor contains several sub-descriptors which\r
                 *  vary between devices, and which describe the device's usage to the host.\r
                /** Size in bytes of the Joystick HID reporting IN endpoint. */\r
                #define JOYSTICK_EPSIZE              8\r
 \r
-               /** Descriptor header type value, to indicate a HID class HID descriptor. */\r
-               #define DTYPE_HID                 0x21\r
-               \r
-               /** Descriptor header type value, to indicate a HID class HID report descriptor. */\r
-               #define DTYPE_Report              0x22\r
-\r
        /* Function Prototypes: */\r
                uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)\r
                                                                                        ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);\r
index 8c50a2c..e073a87 100644 (file)
   this software.\r
 */\r
 \r
-/** \file\r
- *\r
- *  Main source file for the Joystick demo. This file contains the main tasks of the demo and\r
- *  is responsible for the initial application hardware configuration.\r
- */\r
-\r
 #include "Joystick.h"\r
 \r
-/* Scheduler Task List */\r
-TASK_LIST\r
-{\r
-       { .Task = USB_USBTask          , .TaskStatus = TASK_STOP },\r
-       { .Task = USB_Joystick_Report  , .TaskStatus = TASK_STOP },\r
-};\r
+USB_ClassInfo_HID_t Joystick_HID_Interface =\r
+       {\r
+               .InterfaceNumber         = 0,\r
+\r
+               .ReportINEndpointNumber  = JOYSTICK_EPNUM,\r
+               .ReportINEndpointSize    = JOYSTICK_EPSIZE,\r
+               \r
+               .ReportBufferSize        = sizeof(USB_JoystickReport_Data_t),\r
+\r
+               .UsingReportProtocol     = true,\r
+       };\r
 \r
-/** Main program entry point. This routine configures the hardware required by the application, then\r
- *  starts the scheduler to run the application tasks.\r
- */\r
 int main(void)\r
 {\r
+       SetupHardware();\r
+       \r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
+       \r
+       for (;;)\r
+       {\r
+               USB_HID_USBTask(&Joystick_HID_Interface);\r
+               USB_USBTask();\r
+       }\r
+}\r
+\r
+void SetupHardware(void)\r
+{\r
        /* Disable watchdog if enabled by bootloader/fuses */\r
        MCUSR &= ~(1 << WDRF);\r
        wdt_disable();\r
@@ -59,188 +68,64 @@ int main(void)
        Joystick_Init();\r
        LEDs_Init();\r
        Buttons_Init();\r
-       \r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
-       \r
-       /* Initialize Scheduler so that it can be used */\r
-       Scheduler_Init();\r
-\r
-       /* Initialize USB Subsystem */\r
        USB_Init();\r
-\r
-       /* Scheduling - routine never returns, so put this last in the main function */\r
-       Scheduler_Start();\r
 }\r
 \r
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and\r
- *  starts the library USB task to begin the enumeration and USB management process.\r
- */\r
 void EVENT_USB_Connect(void)\r
 {\r
-       /* Start USB management task */\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);\r
-\r
-       /* Indicate USB enumerating */\r
-       UpdateStatus(Status_USBEnumerating);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);\r
 }\r
 \r
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via\r
- *  the status LEDs and stops the USB management and joystick reporting tasks.\r
- */\r
 void EVENT_USB_Disconnect(void)\r
 {\r
-       /* Stop running joystick reporting and USB management tasks */\r
-       Scheduler_SetTaskMode(USB_Joystick_Report, TASK_STOP);\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);\r
-\r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
 }\r
 \r
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration\r
- *  of the USB device after enumeration - the device endpoints are configured and the joystick reporting task started.\r
- */ \r
 void EVENT_USB_ConfigurationChanged(void)\r
 {\r
-       /* Setup Joystick Report Endpoint */\r
-       Endpoint_ConfigureEndpoint(JOYSTICK_EPNUM, EP_TYPE_INTERRUPT,\r
-                                      ENDPOINT_DIR_IN, JOYSTICK_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
 \r
-       /* Indicate USB connected and ready */\r
-       UpdateStatus(Status_USBReady);\r
-\r
-       /* Start joystick reporting task */\r
-       Scheduler_SetTaskMode(USB_Joystick_Report, TASK_RUN);\r
+       if (!(USB_HID_ConfigureEndpoints(&Joystick_HID_Interface)))\r
+         LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
 }\r
 \r
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific\r
- *  control requests that are not handled internally by the USB library (including the HID commands, which are\r
- *  all issued via the control endpoint), so that they can be handled appropriately for the application.\r
- */\r
 void EVENT_USB_UnhandledControlPacket(void)\r
 {\r
-       /* Handle HID Class specific requests */\r
-       switch (USB_ControlRequest.bRequest)\r
-       {\r
-               case REQ_GetReport:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               USB_JoystickReport_Data_t JoystickReportData;\r
-                               \r
-                               Endpoint_ClearSETUP();\r
-\r
-                               /* Create the next HID report to send to the host */                            \r
-                               GetNextReport(&JoystickReportData);\r
-                                       \r
-                               /* Write the report data to the control endpoint */\r
-                               Endpoint_Write_Control_Stream_LE(&JoystickReportData, sizeof(JoystickReportData));\r
-                               \r
-                               /* Finalize the stream transfer to send the last packet or clear the host abort */\r
-                               Endpoint_ClearOUT();\r
-                       }\r
-               \r
-                       break;\r
-       }\r
+       USB_HID_ProcessControlPacket(&Joystick_HID_Interface);\r
 }\r
 \r
-/** Fills the given HID report data structure with the next HID report to send to the host.\r
- *\r
- *  \param ReportData  Pointer to a HID report data structure to be filled\r
- *\r
- *  \return Boolean true if the new report differs from the last report, false otherwise\r
- */\r
-bool GetNextReport(USB_JoystickReport_Data_t* ReportData)\r
+void EVENT_USB_StartOfFrame(void)\r
 {\r
-       static uint8_t PrevJoyStatus    = 0;\r
-       static uint8_t PrevButtonStatus = 0;\r
-       uint8_t        JoyStatus_LCL    = Joystick_GetStatus();\r
-       uint8_t        ButtonStatus_LCL = Buttons_GetStatus();\r
-       bool           InputChanged     = false;\r
+       USB_HID_RegisterStartOfFrame(&Joystick_HID_Interface);\r
+}\r
 \r
-       /* Clear the report contents */\r
-       memset(ReportData, 0, sizeof(USB_JoystickReport_Data_t));\r
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)\r
+{\r
+       USB_JoystickReport_Data_t* JoystickReport = (USB_JoystickReport_Data_t*)ReportData;\r
+       \r
+       uint8_t JoyStatus_LCL    = Joystick_GetStatus();\r
+       uint8_t ButtonStatus_LCL = Buttons_GetStatus();\r
 \r
        if (JoyStatus_LCL & JOY_UP)\r
-         ReportData->Y = -100;\r
+         JoystickReport->Y = -100;\r
        else if (JoyStatus_LCL & JOY_DOWN)\r
-         ReportData->Y =  100;\r
+         JoystickReport->Y =  100;\r
 \r
        if (JoyStatus_LCL & JOY_RIGHT)\r
-         ReportData->X =  100;\r
+         JoystickReport->X =  100;\r
        else if (JoyStatus_LCL & JOY_LEFT)\r
-         ReportData->X = -100;\r
+         JoystickReport->X = -100;\r
 \r
        if (JoyStatus_LCL & JOY_PRESS)\r
-         ReportData->Button  = (1 << 1);\r
+         JoystickReport->Button  = (1 << 1);\r
          \r
        if (ButtonStatus_LCL & BUTTONS_BUTTON1)\r
-         ReportData->Button |= (1 << 0);\r
+         JoystickReport->Button |= (1 << 0);\r
          \r
-       /* Check if the new report is different to the previous report */\r
-       InputChanged = (uint8_t)(PrevJoyStatus ^ JoyStatus_LCL) | (uint8_t)(PrevButtonStatus ^ ButtonStatus_LCL);\r
-\r
-       /* Save the current joystick status for later comparison */\r
-       PrevJoyStatus    = JoyStatus_LCL;\r
-       PrevButtonStatus = ButtonStatus_LCL;\r
-\r
-       /* Return whether the new report is different to the previous report or not */\r
-       return InputChanged;\r
+       return sizeof(USB_JoystickReport_Data_t);\r
 }\r
 \r
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to\r
- *  log to a serial port, or anything else that is suitable for status updates.\r
- *\r
- *  \param CurrentStatus  Current status of the system, from the Joystick_StatusCodes_t enum\r
- */\r
-void UpdateStatus(uint8_t CurrentStatus)\r
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)\r
 {\r
-       uint8_t LEDMask = LEDS_NO_LEDS;\r
-       \r
-       /* Set the LED mask to the appropriate LED mask based on the given status code */\r
-       switch (CurrentStatus)\r
-       {\r
-               case Status_USBNotReady:\r
-                       LEDMask = (LEDS_LED1);\r
-                       break;\r
-               case Status_USBEnumerating:\r
-                       LEDMask = (LEDS_LED1 | LEDS_LED2);\r
-                       break;\r
-               case Status_USBReady:\r
-                       LEDMask = (LEDS_LED2 | LEDS_LED4);\r
-                       break;\r
-       }\r
-       \r
-       /* Set the board LEDs to the new LED mask */\r
-       LEDs_SetAllLEDs(LEDMask);\r
-}\r
-\r
-/** Function to manage HID report generation and transmission to the host. */\r
-TASK(USB_Joystick_Report)\r
-{\r
-       /* Check if the USB System is connected to a Host */\r
-       if (USB_IsConnected)\r
-       {\r
-               /* Select the Joystick Report Endpoint */\r
-               Endpoint_SelectEndpoint(JOYSTICK_EPNUM);\r
-\r
-               /* Check to see if the host is ready for another packet */\r
-               if (Endpoint_IsINReady())\r
-               {\r
-                       USB_JoystickReport_Data_t JoystickReportData;\r
-                       \r
-                       /* Create the next HID report to send to the host */\r
-                       GetNextReport(&JoystickReportData);\r
-               \r
-                       /* Write Joystick Report Data */\r
-                       Endpoint_Write_Stream_LE(&JoystickReportData, sizeof(JoystickReportData));\r
-\r
-                       /* Finalize the stream transfer to send the last packet */\r
-                       Endpoint_ClearIN();\r
-                       \r
-                       /* Clear the report data afterwards */\r
-                       memset(&JoystickReportData, 0, sizeof(JoystickReportData));\r
-               }\r
-       }\r
+       // Unused (but mandatory for the HID class driver) in this demo, since there are no Host->Device reports\r
 }\r
index 9763cad..461d0d0 100644 (file)
 \r
                #include "Descriptors.h"\r
 \r
-               #include <LUFA/Version.h>                    // Library Version Information\r
-               #include <LUFA/Drivers/USB/USB.h>            // USB Functionality\r
-               #include <LUFA/Drivers/Board/Joystick.h>     // Joystick driver\r
-               #include <LUFA/Drivers/Board/LEDs.h>         // LEDs driver\r
-               #include <LUFA/Drivers/Board/Buttons.h>      // Board Buttons driver\r
-               #include <LUFA/Scheduler/Scheduler.h>        // Simple scheduler for task management\r
-               \r
-       /* Task Definitions: */\r
-               TASK(USB_Joystick_Report);\r
-\r
-       /* Macros: */\r
-               /** HID Class specific request to get the next HID report from the device. */\r
-               #define REQ_GetReport   0x01\r
+               #include <LUFA/Version.h>\r
+               #include <LUFA/Drivers/Board/Joystick.h>\r
+               #include <LUFA/Drivers/Board/LEDs.h>\r
+               #include <LUFA/Drivers/Board/Buttons.h>\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/HID.h>\r
 \r
        /* Type Defines: */\r
                /** Type define for the joystick HID report structure, for creating and sending HID reports to the host PC.\r
                        uint8_t Button; /**< Bit mask of the currently pressed joystick buttons */\r
                } USB_JoystickReport_Data_t;\r
                        \r
-       /* Enums: */\r
-               /** Enum for the possible status codes for passing to the UpdateStatus() function. */\r
-               enum Joystick_StatusCodes_t\r
-               {\r
-                       Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */\r
-                       Status_USBEnumerating = 1, /**< USB interface is enumerating */\r
-                       Status_USBReady       = 2, /**< USB interface is connected and ready */\r
-               };\r
+       /* Macros: */\r
+               #define LEDMASK_USB_NOTREADY      LEDS_LED1\r
+               #define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)\r
+               #define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)\r
+               #define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)\r
 \r
        /* Function Prototypes: */\r
+               void SetupHardware(void);\r
+\r
                void EVENT_USB_Connect(void);\r
                void EVENT_USB_Disconnect(void);\r
                void EVENT_USB_ConfigurationChanged(void);\r
                void EVENT_USB_UnhandledControlPacket(void);\r
+               void EVENT_USB_StartOfFrame(void);\r
 \r
-               bool GetNextReport(USB_JoystickReport_Data_t* ReportData);\r
-               void UpdateStatus(uint8_t CurrentStatus);\r
+               uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);\r
+               void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,\r
+                                                                  void* ReportData, uint16_t ReportSize);\r
 \r
 #endif\r
index aaf69e8..826766c 100644 (file)
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)\r
 SRC = $(TARGET).c                                                 \\r
          Descriptors.c                                               \\r
-         $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \\r
@@ -136,7 +135,7 @@ SRC = $(TARGET).c                                                 \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \\r
-         $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \\r
+         $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/HID.c            \\r
 \r
 \r
 # List C++ source files here. (C dependencies are automatically generated.)\r
@@ -183,7 +182,7 @@ CSTANDARD = -std=gnu99
 \r
 # Place -D or -U options here for C sources\r
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)\r
-CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY\r
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY\r
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION\r
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"\r
 \r
index 92eb7b8..0a95ca0 100644 (file)
 #define _DESCRIPTORS_H_\r
 \r
        /* Includes: */\r
-               #include <LUFA/Drivers/USB/USB.h>\r
-\r
                #include <avr/pgmspace.h>\r
 \r
-       /* Type Defines: */\r
-               /** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID\r
-                *  specification for details on the structure elements.\r
-                */     \r
-               typedef struct\r
-               {\r
-                       USB_Descriptor_Header_t Header;\r
-                               \r
-                       uint16_t                HIDSpec;\r
-                       uint8_t                 CountryCode;\r
-               \r
-                       uint8_t                 TotalReportDescriptors;\r
-\r
-                       uint8_t                 HIDReportType;\r
-                       uint16_t                HIDReportLength;\r
-               } USB_Descriptor_HID_t;\r
-               \r
-               /** Type define for the data type used to store HID report descriptor elements. */\r
-               typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/HID.h>\r
 \r
+       /* Type Defines: */\r
                /** Type define for the device configuration descriptor structure. This must be defined in the\r
                 *  application code, as the configuration descriptor contains several sub-descriptors which\r
                 *  vary between devices, and which describe the device's usage to the host.\r
                /** Size in bytes of the Keyboard HID reporting IN and OUT endpoints. */                \r
                #define KEYBOARD_EPSIZE              8\r
 \r
-               /** Descriptor header type value, to indicate a HID class HID descriptor. */\r
-               #define DTYPE_HID                 0x21\r
-               \r
-               /** Descriptor header type value, to indicate a HID class HID report descriptor. */\r
-               #define DTYPE_Report              0x22\r
-\r
        /* Function Prototypes: */\r
                uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)\r
                                                                                        ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);\r
index 6abd193..d8893bf 100644 (file)
   arising out of or in connection with the use or performance of\r
   this software.\r
 */\r
-\r
-/** \file\r
- *\r
- *  Main source file for the Keyboard demo. This file contains the main tasks of the demo and\r
- *  is responsible for the initial application hardware configuration.\r
- */\r
  \r
 #include "Keyboard.h"\r
 \r
-/* Scheduler Task List */\r
-TASK_LIST\r
-{\r
-       { .Task = USB_USBTask          , .TaskStatus = TASK_STOP },     \r
-       { .Task = USB_Keyboard_Report  , .TaskStatus = TASK_STOP },\r
-};\r
-\r
-/* Global Variables */\r
-/** Indicates what report mode the host has requested, true for normal HID reporting mode, false for special boot\r
- *  protocol reporting mode.\r
- */\r
-bool UsingReportProtocol = true;\r
+USB_ClassInfo_HID_t Keyboard_HID_Interface =\r
+    {\r
+        .InterfaceNumber         = 0,\r
 \r
-/** Current Idle period. This is set by the host via a Set Idle HID class request to silence the device's reports\r
- *  for either the entire idle duration, or until the report status changes (e.g. the user presses a key).\r
- */\r
-uint16_t IdleCount = 500;\r
+        .ReportINEndpointNumber  = KEYBOARD_EPNUM,\r
+        .ReportINEndpointSize    = KEYBOARD_EPSIZE,\r
 \r
-/** Current Idle period remaining. When the IdleCount value is set, this tracks the remaining number of idle\r
- *  milliseconds. This is separate to the IdleCount timer and is incremented and compared as the host may request \r
- *  the current idle period via a Get Idle HID class request, thus its value must be preserved.\r
- */\r
-uint16_t IdleMSRemaining = 0;\r
+        .ReportOUTEndpointNumber = KEYBOARD_LEDS_EPNUM,\r
+        .ReportOUTEndpointSize   = KEYBOARD_EPSIZE,\r
+        \r
+               .ReportBufferSize        = sizeof(USB_KeyboardReport_Data_t),\r
 \r
+        .IdleCount               = 500,\r
+    };\r
 \r
-/** Main program entry point. This routine configures the hardware required by the application, then\r
- *  starts the scheduler to run the USB management task.\r
- */\r
 int main(void)\r
 {\r
-       /* Disable watchdog if enabled by bootloader/fuses */\r
-       MCUSR &= ~(1 << WDRF);\r
-       wdt_disable();\r
-\r
-       /* Disable clock division */\r
-       clock_prescale_set(clock_div_1);\r
-\r
-       /* Hardware Initialization */\r
-       Joystick_Init();\r
-       LEDs_Init();\r
-       \r
-       /* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */\r
-       OCR0A  = 0x7D;\r
-       TCCR0A = (1 << WGM01);\r
-       TCCR0B = ((1 << CS01) | (1 << CS00));\r
-       TIMSK0 = (1 << OCIE0A);\r
-\r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
-\r
-       /* Initialize Scheduler so that it can be used */\r
-       Scheduler_Init();\r
+    SetupHardware();\r
+\r
+    LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
+    \r
+    for (;;)\r
+    {\r
+        USB_HID_USBTask(&Keyboard_HID_Interface);\r
+        USB_USBTask();\r
+    }\r
+}\r
 \r
-       /* Initialize USB Subsystem */\r
-       USB_Init();\r
-       \r
-       /* Scheduling - routine never returns, so put this last in the main function */\r
-       Scheduler_Start();\r
+void SetupHardware()\r
+{\r
+    /* Disable watchdog if enabled by bootloader/fuses */\r
+    MCUSR &= ~(1 << WDRF);\r
+    wdt_disable();\r
+\r
+    /* Disable clock division */\r
+    clock_prescale_set(clock_div_1);\r
+\r
+    /* Hardware Initialization */\r
+    Joystick_Init();\r
+    LEDs_Init();\r
+    Buttons_Init();\r
+    USB_Init();\r
 }\r
 \r
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and\r
- *  starts the library USB task to begin the enumeration and USB management process.\r
- */\r
 void EVENT_USB_Connect(void)\r
 {\r
-       /* Start USB management task */\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);\r
-\r
-       /* Indicate USB enumerating */\r
-       UpdateStatus(Status_USBEnumerating);\r
-\r
-       /* Default to report protocol on connect */\r
-       UsingReportProtocol = true;\r
+    LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);\r
 }\r
 \r
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via\r
- *  the status LEDs.\r
- */\r
 void EVENT_USB_Disconnect(void)\r
 {\r
-       /* Stop running keyboard reporting and USB management tasks */\r
-       Scheduler_SetTaskMode(USB_Keyboard_Report, TASK_STOP);\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);\r
-       \r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
+    LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
 }\r
 \r
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host sets the current configuration\r
- *  of the USB device after enumeration, and configures the keyboard device endpoints.\r
- */\r
 void EVENT_USB_ConfigurationChanged(void)\r
 {\r
-       /* Setup Keyboard Keycode Report Endpoint */\r
-       Endpoint_ConfigureEndpoint(KEYBOARD_EPNUM, EP_TYPE_INTERRUPT,\r
-                                      ENDPOINT_DIR_IN, KEYBOARD_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
-\r
-       /* Setup Keyboard LED Report Endpoint */\r
-       Endpoint_ConfigureEndpoint(KEYBOARD_LEDS_EPNUM, EP_TYPE_INTERRUPT,\r
-                                      ENDPOINT_DIR_OUT, KEYBOARD_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
+    LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
 \r
-       /* Indicate USB connected and ready */\r
-       UpdateStatus(Status_USBReady);\r
-\r
-       /* Start running keyboard reporting task */\r
-       Scheduler_SetTaskMode(USB_Keyboard_Report, TASK_RUN);\r
+    if (!(USB_HID_ConfigureEndpoints(&Keyboard_HID_Interface)))\r
+      LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
 }\r
 \r
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific\r
- *  control requests that are not handled internally by the USB library (including the HID commands, which are\r
- *  all issued via the control endpoint), so that they can be handled appropriately for the application.\r
- */\r
 void EVENT_USB_UnhandledControlPacket(void)\r
 {\r
-       /* Handle HID Class specific requests */\r
-       switch (USB_ControlRequest.bRequest)\r
-       {\r
-               case REQ_GetReport:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               USB_KeyboardReport_Data_t KeyboardReportData;\r
-\r
-                               Endpoint_ClearSETUP();\r
-       \r
-                               /* Create the next keyboard report for transmission to the host */\r
-                               CreateKeyboardReport(&KeyboardReportData);\r
-\r
-                               /* Write the report data to the control endpoint */\r
-                               Endpoint_Write_Control_Stream_LE(&KeyboardReportData, sizeof(KeyboardReportData));\r
-                               \r
-                               /* Finalize the stream transfer to send the last packet or clear the host abort */\r
-                               Endpoint_ClearOUT();\r
-                       }\r
-               \r
-                       break;\r
-               case REQ_SetReport:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* Wait until the LED report has been sent by the host */\r
-                               while (!(Endpoint_IsOUTReceived()));\r
-\r
-                               /* Read in the LED report from the host */\r
-                               uint8_t LEDStatus = Endpoint_Read_Byte();\r
-\r
-                               /* Process the incoming LED report */\r
-                               ProcessLEDReport(LEDStatus);\r
-                       \r
-                               /* Clear the endpoint data */\r
-                               Endpoint_ClearOUT();\r
-\r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsINReady()));\r
-                               Endpoint_ClearIN();\r
-                       }\r
-                       \r
-                       break;\r
-               case REQ_GetProtocol:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* Write the current protocol flag to the host */\r
-                               Endpoint_Write_Byte(UsingReportProtocol);\r
-                               \r
-                               /* Send the flag to the host */\r
-                               Endpoint_ClearIN();\r
-\r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsOUTReceived()));\r
-                               Endpoint_ClearOUT();\r
-                       }\r
-                       \r
-                       break;\r
-               case REQ_SetProtocol:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               Endpoint_ClearSETUP();\r
-\r
-                               /* Set or clear the flag depending on what the host indicates that the current Protocol should be */\r
-                               UsingReportProtocol = (USB_ControlRequest.wValue != 0);\r
-\r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsINReady()));\r
-                               Endpoint_ClearIN();\r
-                       }\r
-                       \r
-                       break;\r
-               case REQ_SetIdle:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* Get idle period in MSB */\r
-                               IdleCount = (USB_ControlRequest.wValue >> 8);\r
-                               \r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsINReady()));\r
-                               Endpoint_ClearIN();\r
-                       }\r
-                       \r
-                       break;\r
-               case REQ_GetIdle:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {               \r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* Write the current idle duration to the host */\r
-                               Endpoint_Write_Byte(IdleCount);\r
-                               \r
-                               /* Send the flag to the host */\r
-                               Endpoint_ClearIN();\r
-\r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsOUTReceived()));\r
-                               Endpoint_ClearOUT();\r
-                       }\r
-\r
-                       break;\r
-       }\r
+    USB_HID_ProcessControlPacket(&Keyboard_HID_Interface);\r
 }\r
 \r
-/** ISR for the timer 0 compare vector. This ISR fires once each millisecond, and increments the\r
- *  scheduler elapsed idle period counter when the host has set an idle period.\r
- */\r
-ISR(TIMER0_COMPA_vect, ISR_BLOCK)\r
+void EVENT_USB_StartOfFrame(void)\r
 {\r
-       /* One millisecond has elapsed, decrement the idle time remaining counter if it has not already elapsed */\r
-       if (IdleMSRemaining)\r
-         IdleMSRemaining--;\r
-}\r
-\r
-/** Fills the given HID report data structure with the next HID report to send to the host.\r
- *\r
- *  \param ReportData  Pointer to a HID report data structure to be filled\r
- */\r
-void CreateKeyboardReport(USB_KeyboardReport_Data_t* ReportData)\r
-{\r
-       uint8_t JoyStatus_LCL = Joystick_GetStatus();\r
-\r
-       /* Clear the report contents */\r
-       memset(ReportData, 0, sizeof(USB_KeyboardReport_Data_t));\r
-\r
-       if (JoyStatus_LCL & JOY_UP)\r
-         ReportData->KeyCode[0] = 0x04; // A\r
-       else if (JoyStatus_LCL & JOY_DOWN)\r
-         ReportData->KeyCode[0] = 0x05; // B\r
-\r
-       if (JoyStatus_LCL & JOY_LEFT)\r
-         ReportData->KeyCode[0] = 0x06; // C\r
-       else if (JoyStatus_LCL & JOY_RIGHT)\r
-         ReportData->KeyCode[0] = 0x07; // D\r
-\r
-       if (JoyStatus_LCL & JOY_PRESS)\r
-         ReportData->KeyCode[0] = 0x08; // E\r
-}\r
-\r
-/** Processes a received LED report, and updates the board LEDs states to match.\r
- *\r
- *  \param LEDReport  LED status report from the host\r
- */\r
-void ProcessLEDReport(uint8_t LEDReport)\r
-{\r
-       uint8_t LEDMask = LEDS_LED2;\r
-       \r
-       if (LEDReport & 0x01) // NUM Lock\r
-         LEDMask |= LEDS_LED1;\r
-       \r
-       if (LEDReport & 0x02) // CAPS Lock\r
-         LEDMask |= LEDS_LED3;\r
-\r
-       if (LEDReport & 0x04) // SCROLL Lock\r
-         LEDMask |= LEDS_LED4;\r
-\r
-       /* Set the status LEDs to the current Keyboard LED status */\r
-       LEDs_SetAllLEDs(LEDMask);\r
-}\r
-\r
-/** Sends the next HID report to the host, via the keyboard data endpoint. */\r
-void SendNextReport(void)\r
-{\r
-       static USB_KeyboardReport_Data_t PrevKeyboardReportData;\r
-       USB_KeyboardReport_Data_t        KeyboardReportData;\r
-       bool                             SendReport = true;\r
-       \r
-       /* Create the next keyboard report for transmission to the host */\r
-       CreateKeyboardReport(&KeyboardReportData);\r
-       \r
-       /* Check to see if the report data has changed - if so a report MUST be sent */\r
-       SendReport = (memcmp(&PrevKeyboardReportData, &KeyboardReportData, sizeof(USB_KeyboardReport_Data_t)) != 0);\r
-       \r
-       /* Save the current report data for later comparison to check for changes */\r
-       PrevKeyboardReportData = KeyboardReportData;\r
-       \r
-       /* Check if the idle period is set and has elapsed */\r
-       if ((IdleCount != HID_IDLE_CHANGESONLY) && (!(IdleMSRemaining)))\r
-       {\r
-               /* Reset the idle time remaining counter, must multiply by 4 to get the duration in milliseconds */\r
-               IdleMSRemaining = (IdleCount << 2);\r
-               \r
-               /* Idle period is set and has elapsed, must send a report to the host */\r
-               SendReport = true;\r
-       }\r
-       \r
-       /* Select the Keyboard Report Endpoint */\r
-       Endpoint_SelectEndpoint(KEYBOARD_EPNUM);\r
-\r
-       /* Check if Keyboard Endpoint Ready for Read/Write and if we should send a new report */\r
-       if (Endpoint_IsReadWriteAllowed() && SendReport)\r
-       {\r
-               /* Write Keyboard Report Data */\r
-               Endpoint_Write_Stream_LE(&KeyboardReportData, sizeof(KeyboardReportData));\r
-               \r
-               /* Finalize the stream transfer to send the last packet */\r
-               Endpoint_ClearIN();\r
-       }\r
-}\r
-\r
-/** Reads the next LED status report from the host from the LED data endpoint, if one has been sent. */\r
-void ReceiveNextReport(void)\r
-{\r
-       /* Select the Keyboard LED Report Endpoint */\r
-       Endpoint_SelectEndpoint(KEYBOARD_LEDS_EPNUM);\r
-\r
-       /* Check if Keyboard LED Endpoint contains a packet */\r
-       if (Endpoint_IsOUTReceived())\r
-       {\r
-               /* Check to see if the packet contains data */\r
-               if (Endpoint_IsReadWriteAllowed())\r
-               {\r
-                       /* Read in the LED report from the host */\r
-                       uint8_t LEDReport = Endpoint_Read_Byte();\r
-\r
-                       /* Process the read LED report from the host */\r
-                       ProcessLEDReport(LEDReport);\r
-               }\r
-\r
-               /* Handshake the OUT Endpoint - clear endpoint and ready for next report */\r
-               Endpoint_ClearOUT();\r
-       }\r
+    USB_HID_RegisterStartOfFrame(&Keyboard_HID_Interface);\r
 }\r
 \r
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to\r
- *  log to a serial port, or anything else that is suitable for status updates.\r
- *\r
- *  \param CurrentStatus  Current status of the system, from the Keyboard_StatusCodes_t enum\r
- */\r
-void UpdateStatus(uint8_t CurrentStatus)\r
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)\r
 {\r
-       uint8_t LEDMask = LEDS_NO_LEDS;\r
-       \r
-       /* Set the LED mask to the appropriate LED mask based on the given status code */\r
-       switch (CurrentStatus)\r
-       {\r
-               case Status_USBNotReady:\r
-                       LEDMask = (LEDS_LED1);\r
-                       break;\r
-               case Status_USBEnumerating:\r
-                       LEDMask = (LEDS_LED1 | LEDS_LED2);\r
-                       break;\r
-               case Status_USBReady:\r
-                       LEDMask = (LEDS_LED2 | LEDS_LED4);\r
-                       break;\r
-       }\r
-       \r
-       /* Set the board LEDs to the new LED mask */\r
-       LEDs_SetAllLEDs(LEDMask);\r
+    USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;\r
+    \r
+    uint8_t JoyStatus_LCL    = Joystick_GetStatus();\r
+    uint8_t ButtonStatus_LCL = Buttons_GetStatus();\r
+\r
+    if (JoyStatus_LCL & JOY_UP)\r
+      KeyboardReport->KeyCode[0] = 0x04; // A\r
+    else if (JoyStatus_LCL & JOY_DOWN)\r
+      KeyboardReport->KeyCode[0] = 0x05; // B\r
+\r
+    if (JoyStatus_LCL & JOY_LEFT)\r
+      KeyboardReport->KeyCode[0] = 0x06; // C\r
+    else if (JoyStatus_LCL & JOY_RIGHT)\r
+      KeyboardReport->KeyCode[0] = 0x07; // D\r
+\r
+    if (JoyStatus_LCL & JOY_PRESS)\r
+      KeyboardReport->KeyCode[0] = 0x08; // E\r
+      \r
+    if (ButtonStatus_LCL & BUTTONS_BUTTON1)\r
+      KeyboardReport->KeyCode[0] = 0x09; // F\r
+      \r
+    return sizeof(USB_KeyboardReport_Data_t);\r
 }\r
 \r
-/** Function to manage HID report generation and transmission to the host, when in report mode. */\r
-TASK(USB_Keyboard_Report)\r
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)\r
 {\r
-       /* Check if the USB system is connected to a host */\r
-       if (USB_IsConnected)\r
-       {\r
-               /* Send the next keypress report to the host */\r
-               SendNextReport();\r
-               \r
-               /* Process the LED report sent from the host */\r
-               ReceiveNextReport();\r
-       }\r
+    uint8_t  LEDMask   = LEDS_NO_LEDS;\r
+    uint8_t* LEDReport = (uint8_t*)ReportData;\r
+\r
+    if (*LEDReport & 0x01) // NUM Lock\r
+      LEDMask |= LEDS_LED1;\r
+    \r
+    if (*LEDReport & 0x02) // CAPS Lock\r
+      LEDMask |= LEDS_LED3;\r
+\r
+    if (*LEDReport & 0x04) // SCROLL Lock\r
+      LEDMask |= LEDS_LED4;\r
+      \r
+    LEDs_SetAllLEDs(LEDMask);\r
 }\r
index c4ed6e0..eeb7be9 100644 (file)
 \r
                #include "Descriptors.h"\r
 \r
-               #include <LUFA/Version.h>                    // Library Version Information\r
-               #include <LUFA/Scheduler/Scheduler.h>        // Simple scheduler for task management\r
-               #include <LUFA/Drivers/USB/USB.h>            // USB Functionality\r
-               #include <LUFA/Drivers/Board/Joystick.h>     // Joystick driver\r
-               #include <LUFA/Drivers/Board/LEDs.h>         // LEDs driver\r
-\r
-       /* Macros: */\r
-               /** Idle period indicating that reports should be sent only when the inputs have changed */\r
-               #define HID_IDLE_CHANGESONLY   0\r
-\r
-               /** HID Class specific request to get the next HID report from the device. */\r
-               #define REQ_GetReport          0x01\r
-\r
-               /** HID Class specific request to get the idle timeout period of the device. */\r
-               #define REQ_GetIdle            0x02\r
-\r
-               /** HID Class specific request to send the next HID report to the device. */\r
-               #define REQ_SetReport          0x09\r
-\r
-               /** HID Class specific request to set the idle timeout period of the device. */\r
-               #define REQ_SetIdle            0x0A\r
-\r
-               /** HID Class specific request to get the current HID protocol in use, either report or boot. */\r
-               #define REQ_GetProtocol        0x03\r
-\r
-               /** HID Class specific request to set the current HID protocol in use, either report or boot. */\r
-               #define REQ_SetProtocol        0x0B\r
-               \r
-       /* Task Definitions: */\r
-               TASK(USB_Keyboard_Report);\r
+               #include <LUFA/Version.h>\r
+               #include <LUFA/Drivers/Board/Joystick.h>\r
+               #include <LUFA/Drivers/Board/LEDs.h>\r
+               #include <LUFA/Drivers/Board/Buttons.h>\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/HID.h>\r
 \r
        /* Type Defines: */\r
                /** Type define for the keyboard HID report structure, for creating and sending HID reports to the host PC.\r
                        uint8_t KeyCode[6]; /**< Array of up to six simultaneous key codes of pressed keys */\r
                } USB_KeyboardReport_Data_t;\r
                        \r
-       /* Enums: */\r
-               /** Enum for the possible status codes for passing to the UpdateStatus() function. */\r
-               enum Keyboard_StatusCodes_t\r
-               {\r
-                       Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */\r
-                       Status_USBEnumerating = 1, /**< USB interface is enumerating */\r
-                       Status_USBReady       = 2, /**< USB interface is connected and ready */\r
-               };\r
+       /* Macros: */\r
+               #define LEDMASK_USB_NOTREADY      LEDS_LED1\r
+               #define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)\r
+               #define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)\r
+               #define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)\r
                \r
        /* Function Prototypes: */\r
+               void SetupHardware(void);\r
+\r
                void EVENT_USB_Connect(void);\r
                void EVENT_USB_Disconnect(void);\r
                void EVENT_USB_ConfigurationChanged(void);\r
                void EVENT_USB_UnhandledControlPacket(void);\r
+               void EVENT_USB_StartOfFrame(void);\r
 \r
-               void CreateKeyboardReport(USB_KeyboardReport_Data_t* ReportData);\r
-               void ProcessLEDReport(uint8_t LEDReport);\r
-               void SendNextReport(void);\r
-               void ReceiveNextReport(void);\r
-               void UpdateStatus(uint8_t CurrentStatus);\r
+               uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);\r
+               void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,\r
+                                                                  void* ReportData, uint16_t ReportSize);\r
 \r
 #endif\r
index 88e4de0..98cda2f 100644 (file)
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)\r
 SRC = $(TARGET).c                                                 \\r
          Descriptors.c                                               \\r
-         $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \\r
@@ -136,7 +135,7 @@ SRC = $(TARGET).c                                                 \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \\r
-         $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \\r
+         $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/HID.c            \\r
 \r
 \r
 # List C++ source files here. (C dependencies are automatically generated.)\r
@@ -183,7 +182,7 @@ CSTANDARD = -std=gnu99
 \r
 # Place -D or -U options here for C sources\r
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)\r
-CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY\r
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY\r
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION\r
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"\r
 \r
index 43c345a..152e511 100644 (file)
 #define _DESCRIPTORS_H_\r
 \r
        /* Includes: */\r
-               #include <LUFA/Drivers/USB/USB.h>\r
-\r
                #include <avr/pgmspace.h>\r
 \r
-       /* Type Defines: */\r
-               /** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID\r
-                *  specification for details on the structure elements.\r
-                */\r
-               typedef struct\r
-               {\r
-                       USB_Descriptor_Header_t               Header;\r
-                               \r
-                       uint16_t                              HIDSpec;\r
-                       uint8_t                               CountryCode;\r
-               \r
-                       uint8_t                               TotalReportDescriptors;\r
-\r
-                       uint8_t                               HIDReportType;\r
-                       uint16_t                              HIDReportLength;\r
-               } USB_Descriptor_HID_t;\r
-\r
-               /** Type define for the data type used to store HID report descriptor elements. */\r
-               typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/HID.h>\r
 \r
+       /* Type Defines: */\r
                /** Type define for the device configuration descriptor structure. This must be defined in the\r
                 *  application code, as the configuration descriptor contains several sub-descriptors which\r
                 *  vary between devices, and which describe the device's usage to the host.\r
                /** Size in bytes of each of the HID reporting IN and OUT endpoints. */\r
                #define HID_EPSIZE                8\r
 \r
-               /** Descriptor header type value, to indicate a HID class HID descriptor. */\r
-               #define DTYPE_HID                 0x21\r
-               \r
-               /** Descriptor header type value, to indicate a HID class HID report descriptor. */\r
-               #define DTYPE_Report              0x22\r
-\r
        /* Function Prototypes: */\r
                uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)\r
                                                                                        ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);\r
index 25d633e..8f6a573 100644 (file)
   arising out of or in connection with the use or performance of\r
   this software.\r
 */\r
-\r
-/** \file\r
- *\r
- *  Main source file for the KeyboardMouse demo. This file contains the main tasks of the demo and\r
- *  is responsible for the initial application hardware configuration.\r
- */\r
  \r
 #include "KeyboardMouse.h"\r
 \r
-/* Scheduler Task List */\r
-TASK_LIST\r
-{\r
-       { .Task = USB_USBTask               , .TaskStatus = TASK_STOP },\r
-       { .Task = USB_Mouse                 , .TaskStatus = TASK_RUN  },\r
-       { .Task = USB_Keyboard              , .TaskStatus = TASK_RUN  },\r
-};\r
+USB_ClassInfo_HID_t Keyboard_HID_Interface =\r
+       {\r
+               .InterfaceNumber         = 0,\r
+\r
+               .ReportINEndpointNumber  = KEYBOARD_IN_EPNUM,\r
+               .ReportINEndpointSize    = HID_EPSIZE,\r
+\r
+               .ReportOUTEndpointNumber = KEYBOARD_OUT_EPNUM,\r
+               .ReportOUTEndpointSize   = HID_EPSIZE,\r
+               \r
+               .ReportBufferSize        = sizeof(USB_KeyboardReport_Data_t),\r
+\r
+               .IdleCount               = 500,\r
+       };\r
+       \r
+USB_ClassInfo_HID_t Mouse_HID_Interface =\r
+       {\r
+               .InterfaceNumber         = 0,\r
 \r
-/* Global Variables */\r
-/** Global structure to hold the current keyboard interface HID report, for transmission to the host */\r
-USB_KeyboardReport_Data_t KeyboardReportData;\r
+               .ReportINEndpointNumber  = MOUSE_IN_EPNUM,\r
+               .ReportINEndpointSize    = HID_EPSIZE,\r
 \r
-/** Global structure to hold the current mouse interface HID report, for transmission to the host */\r
-USB_MouseReport_Data_t    MouseReportData;\r
+               .ReportBufferSize        = sizeof(USB_MouseReport_Data_t),\r
 \r
-/** Main program entry point. This routine configures the hardware required by the application, then\r
- *  starts the scheduler to run the USB management task.\r
- */\r
+               .ReportOUTEndpointNumber = 0,\r
+               .ReportOUTEndpointSize   = 0,\r
+       };\r
+       \r
 int main(void)\r
 {\r
+       SetupHardware();\r
+\r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
+\r
+       for (;;)\r
+       {\r
+               USB_HID_USBTask(&Keyboard_HID_Interface);\r
+               USB_HID_USBTask(&Mouse_HID_Interface);\r
+               USB_USBTask();\r
+       }\r
+}\r
+\r
+void SetupHardware()\r
+{\r
        /* Disable watchdog if enabled by bootloader/fuses */\r
        MCUSR &= ~(1 << WDRF);\r
        wdt_disable();\r
@@ -67,284 +85,111 @@ int main(void)
        /* Hardware Initialization */\r
        Joystick_Init();\r
        LEDs_Init();\r
-       \r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
-       \r
-       /* Initialize Scheduler so that it can be used */\r
-       Scheduler_Init();\r
-\r
-       /* Initialize USB Subsystem */\r
-       USB_Init();\r
-       \r
-       /* Scheduling - routine never returns, so put this last in the main function */\r
-       Scheduler_Start();\r
+       USB_Init();     \r
 }\r
 \r
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and\r
- *  starts the library USB task to begin the enumeration and USB management process.\r
- */\r
 void EVENT_USB_Connect(void)\r
 {\r
-       /* Start USB management task */\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);\r
-\r
-       /* Indicate USB enumerating */\r
-       UpdateStatus(Status_USBEnumerating);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);\r
 }\r
 \r
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via\r
- *  the status LEDs and stops the USB management task.\r
- */\r
 void EVENT_USB_Disconnect(void)\r
 {\r
-       /* Stop running HID reporting and USB management tasks */\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);\r
-\r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
 }\r
 \r
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host sets the current configuration\r
- *  of the USB device after enumeration, and configures the keyboard and mouse device endpoints.\r
- */\r
 void EVENT_USB_ConfigurationChanged(void)\r
 {\r
-       /* Setup Keyboard Report Endpoint */\r
-       Endpoint_ConfigureEndpoint(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT,\r
-                                      ENDPOINT_DIR_IN, HID_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
-\r
-       /* Setup Keyboard LED Report Endpoint */\r
-       Endpoint_ConfigureEndpoint(KEYBOARD_OUT_EPNUM, EP_TYPE_INTERRUPT,\r
-                                      ENDPOINT_DIR_OUT, HID_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
 \r
-       /* Setup Mouse Report Endpoint */\r
-       Endpoint_ConfigureEndpoint(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT,\r
-                                      ENDPOINT_DIR_IN, HID_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
-\r
-       /* Indicate USB connected and ready */\r
-       UpdateStatus(Status_USBReady);\r
+       if (!(USB_HID_ConfigureEndpoints(&Keyboard_HID_Interface)))\r
+         LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
+       \r
+       if (!(USB_HID_ConfigureEndpoints(&Mouse_HID_Interface)))\r
+         LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
 }\r
 \r
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific\r
- *  control requests that are not handled internally by the USB library (including the HID commands, which are\r
- *  all issued via the control endpoint), so that they can be handled appropriately for the application.\r
- */\r
 void EVENT_USB_UnhandledControlPacket(void)\r
 {\r
-       uint8_t* ReportData;\r
-       uint8_t  ReportSize;\r
-\r
-       /* Handle HID Class specific requests */\r
-       switch (USB_ControlRequest.bRequest)\r
-       {\r
-               case REQ_GetReport:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               Endpoint_ClearSETUP();\r
-       \r
-                               /* Determine if it is the mouse or the keyboard data that is being requested */\r
-                               if (!(USB_ControlRequest.wIndex))\r
-                               {\r
-                                       ReportData = (uint8_t*)&KeyboardReportData;\r
-                                       ReportSize = sizeof(KeyboardReportData);\r
-                               }\r
-                               else\r
-                               {\r
-                                       ReportData = (uint8_t*)&MouseReportData;\r
-                                       ReportSize = sizeof(MouseReportData);\r
-                               }\r
-\r
-                               /* Write the report data to the control endpoint */\r
-                               Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);\r
-\r
-                               /* Clear the report data afterwards */\r
-                               memset(ReportData, 0, ReportSize);\r
-                               \r
-                               /* Finalize the stream transfer to send the last packet or clear the host abort */\r
-                               Endpoint_ClearOUT();\r
-                       }\r
-               \r
-                       break;\r
-               case REQ_SetReport:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* Wait until the LED report has been sent by the host */\r
-                               while (!(Endpoint_IsOUTReceived()));\r
-\r
-                               /* Read in the LED report from the host */\r
-                               uint8_t LEDStatus = Endpoint_Read_Byte();\r
-                               uint8_t LEDMask   = LEDS_LED2;\r
-                               \r
-                               if (LEDStatus & 0x01) // NUM Lock\r
-                                 LEDMask |= LEDS_LED1;\r
-                               \r
-                               if (LEDStatus & 0x02) // CAPS Lock\r
-                                 LEDMask |= LEDS_LED3;\r
-\r
-                               if (LEDStatus & 0x04) // SCROLL Lock\r
-                                 LEDMask |= LEDS_LED4;\r
-\r
-                               /* Set the status LEDs to the current HID LED status */\r
-                               LEDs_SetAllLEDs(LEDMask);\r
-\r
-                               /* Clear the endpoint data */\r
-                               Endpoint_ClearOUT();\r
-\r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsINReady()));\r
-                               Endpoint_ClearIN();\r
-                       }\r
-                       \r
-                       break;\r
-       }\r
+       USB_HID_ProcessControlPacket(&Keyboard_HID_Interface);\r
+       USB_HID_ProcessControlPacket(&Mouse_HID_Interface);\r
 }\r
 \r
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to\r
- *  log to a serial port, or anything else that is suitable for status updates.\r
- *\r
- *  \param CurrentStatus  Current status of the system, from the KeyboardMouse_StatusCodes_t enum\r
- */\r
-void UpdateStatus(uint8_t CurrentStatus)\r
+void EVENT_USB_StartOfFrame(void)\r
 {\r
-       uint8_t LEDMask = LEDS_NO_LEDS;\r
-       \r
-       /* Set the LED mask to the appropriate LED mask based on the given status code */\r
-       switch (CurrentStatus)\r
-       {\r
-               case Status_USBNotReady:\r
-                       LEDMask = (LEDS_LED1);\r
-                       break;\r
-               case Status_USBEnumerating:\r
-                       LEDMask = (LEDS_LED1 | LEDS_LED2);\r
-                       break;\r
-               case Status_USBReady:\r
-                       LEDMask = (LEDS_LED2 | LEDS_LED4);\r
-                       break;\r
-       }\r
-       \r
-       /* Set the board LEDs to the new LED mask */\r
-       LEDs_SetAllLEDs(LEDMask);\r
+       USB_HID_RegisterStartOfFrame(&Keyboard_HID_Interface);\r
+       USB_HID_RegisterStartOfFrame(&Mouse_HID_Interface);\r
 }\r
 \r
-/** Keyboard task. This generates the next keyboard HID report for the host, and transmits it via the\r
- *  keyboard IN endpoint when the host is ready for more data. Additionally, it processes host LED status\r
- *  reports sent to the device via the keyboard OUT reporting endpoint.\r
- */\r
-TASK(USB_Keyboard)\r
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)\r
 {\r
-       uint8_t JoyStatus_LCL = Joystick_GetStatus();\r
+       uint8_t JoyStatus_LCL    = Joystick_GetStatus();\r
+       uint8_t ButtonStatus_LCL = Buttons_GetStatus();\r
 \r
-       /* Check if board button is not pressed, if so mouse mode enabled */\r
-       if (!(Buttons_GetStatus() & BUTTONS_BUTTON1))\r
+       if (HIDInterfaceInfo == &Keyboard_HID_Interface)\r
        {\r
+               USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;\r
+               \r
+               /* If first board button not being held down, no keyboard report */\r
+               if (!(ButtonStatus_LCL & BUTTONS_BUTTON1))\r
+                 return 0;\r
+               \r
                if (JoyStatus_LCL & JOY_UP)\r
-                 KeyboardReportData.KeyCode[0] = 0x04; // A\r
+                 KeyboardReport->KeyCode[0] = 0x04; // A\r
                else if (JoyStatus_LCL & JOY_DOWN)\r
-                 KeyboardReportData.KeyCode[0] = 0x05; // B\r
+                 KeyboardReport->KeyCode[0] = 0x05; // B\r
 \r
                if (JoyStatus_LCL & JOY_LEFT)\r
-                 KeyboardReportData.KeyCode[0] = 0x06; // C\r
+                 KeyboardReport->KeyCode[0] = 0x06; // C\r
                else if (JoyStatus_LCL & JOY_RIGHT)\r
-                 KeyboardReportData.KeyCode[0] = 0x07; // D\r
+                 KeyboardReport->KeyCode[0] = 0x07; // D\r
 \r
                if (JoyStatus_LCL & JOY_PRESS)\r
-                 KeyboardReportData.KeyCode[0] = 0x08; // E\r
+                 KeyboardReport->KeyCode[0] = 0x08; // E\r
+                 \r
+               return sizeof(USB_KeyboardReport_Data_t);\r
        }\r
-       \r
-       /* Check if the USB system is connected to a host and report protocol mode is enabled */\r
-       if (USB_IsConnected)\r
+       else\r
        {\r
-               /* Select the Keyboard Report Endpoint */\r
-               Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);\r
-\r
-               /* Check if Keyboard Endpoint Ready for Read/Write */\r
-               if (Endpoint_IsReadWriteAllowed())\r
-               {\r
-                       /* Write Keyboard Report Data */\r
-                       Endpoint_Write_Stream_LE(&KeyboardReportData, sizeof(KeyboardReportData));\r
-\r
-                       /* Finalize the stream transfer to send the last packet */\r
-                       Endpoint_ClearIN();\r
-\r
-                       /* Clear the report data afterwards */\r
-                       memset(&KeyboardReportData, 0, sizeof(KeyboardReportData));\r
-               }\r
+               USB_MouseReport_Data_t* MouseReport = (USB_MouseReport_Data_t*)ReportData;\r
 \r
-               /* Select the Keyboard LED Report Endpoint */\r
-               Endpoint_SelectEndpoint(KEYBOARD_OUT_EPNUM);\r
-\r
-               /* Check if Keyboard LED Endpoint Ready for Read/Write */\r
-               if (Endpoint_IsReadWriteAllowed())\r
-               {               \r
-                       /* Read in the LED report from the host */\r
-                       uint8_t LEDStatus = Endpoint_Read_Byte();\r
-                       uint8_t LEDMask   = LEDS_LED2;\r
-                       \r
-                       if (LEDStatus & 0x01) // NUM Lock\r
-                         LEDMask |= LEDS_LED1;\r
-                       \r
-                       if (LEDStatus & 0x02) // CAPS Lock\r
-                         LEDMask |= LEDS_LED3;\r
-\r
-                       if (LEDStatus & 0x04) // SCROLL Lock\r
-                         LEDMask |= LEDS_LED4;\r
-\r
-                       /* Set the status LEDs to the current Keyboard LED status */\r
-                       LEDs_SetAllLEDs(LEDMask);\r
-\r
-                       /* Handshake the OUT Endpoint - clear endpoint and ready for next report */\r
-                       Endpoint_ClearOUT();\r
-               }\r
-       }\r
-}\r
-\r
-/** Mouse task. This generates the next mouse HID report for the host, and transmits it via the\r
- *  mouse IN endpoint when the host is ready for more data.\r
- */\r
-TASK(USB_Mouse)\r
-{\r
-       uint8_t JoyStatus_LCL = Joystick_GetStatus();\r
-\r
-       /* Check if board button is pressed, if so mouse mode enabled */\r
-       if (Buttons_GetStatus() & BUTTONS_BUTTON1)\r
-       {\r
+               /* If first board button being held down, no mouse report */\r
+               if (ButtonStatus_LCL & BUTTONS_BUTTON1)\r
+                 return 0;\r
+                 \r
                if (JoyStatus_LCL & JOY_UP)\r
-                 MouseReportData.Y =  1;\r
+                 MouseReport->Y = -1;\r
                else if (JoyStatus_LCL & JOY_DOWN)\r
-                 MouseReportData.Y = -1;\r
+                 MouseReport->Y =  1;\r
 \r
                if (JoyStatus_LCL & JOY_RIGHT)\r
-                 MouseReportData.X =  1;\r
+                 MouseReport->X =  1;\r
                else if (JoyStatus_LCL & JOY_LEFT)\r
-                 MouseReportData.X = -1;\r
+                 MouseReport->X = -1;\r
 \r
                if (JoyStatus_LCL & JOY_PRESS)\r
-                 MouseReportData.Button  = (1 << 0);\r
+                 MouseReport->Button  = (1 << 0);\r
+               \r
+               return sizeof(USB_MouseReport_Data_t);          \r
        }\r
+}\r
 \r
-       /* Check if the USB system is connected to a host and report protocol mode is enabled */\r
-       if (USB_IsConnected)\r
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)\r
+{\r
+       if (HIDInterfaceInfo == &Keyboard_HID_Interface)\r
        {\r
-               /* Select the Mouse Report Endpoint */\r
-               Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);\r
-\r
-               /* Check if Mouse Endpoint Ready for Read/Write */\r
-               if (Endpoint_IsReadWriteAllowed())\r
-               {\r
-                       /* Write Mouse Report Data */\r
-                       Endpoint_Write_Stream_LE(&MouseReportData, sizeof(MouseReportData));\r
+               uint8_t  LEDMask   = LEDS_NO_LEDS;\r
+               uint8_t* LEDReport = (uint8_t*)ReportData;\r
 \r
-                       /* Finalize the stream transfer to send the last packet */\r
-                       Endpoint_ClearIN();\r
+               if (*LEDReport & 0x01) // NUM Lock\r
+                 LEDMask |= LEDS_LED1;\r
+               \r
+               if (*LEDReport & 0x02) // CAPS Lock\r
+                 LEDMask |= LEDS_LED3;\r
 \r
-                       /* Clear the report data afterwards */\r
-                       memset(&MouseReportData, 0, sizeof(MouseReportData));\r
-               }\r
+               if (*LEDReport & 0x04) // SCROLL Lock\r
+                 LEDMask |= LEDS_LED4;\r
+                 \r
+               LEDs_SetAllLEDs(LEDMask);\r
        }\r
-}\r
+}
\ No newline at end of file
index e3f9434..a5c3c5d 100644 (file)
 \r
                #include "Descriptors.h"\r
 \r
-               #include <LUFA/Version.h>                    // Library Version Information\r
-               #include <LUFA/Drivers/USB/USB.h>            // USB Functionality\r
-               #include <LUFA/Drivers/Board/Joystick.h>     // Joystick driver\r
-               #include <LUFA/Drivers/Board/LEDs.h>         // LEDs driver\r
-               #include <LUFA/Drivers/Board/Buttons.h>      // Board Buttons driver\r
-               #include <LUFA/Scheduler/Scheduler.h>        // Simple scheduler for task management\r
-               \r
-       /* Task Definitions: */\r
-               TASK(USB_Keyboard);\r
-               TASK(USB_Mouse);\r
+               #include <LUFA/Version.h>\r
+               #include <LUFA/Drivers/Board/Joystick.h>\r
+               #include <LUFA/Drivers/Board/LEDs.h>\r
+               #include <LUFA/Drivers/Board/Buttons.h>\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/HID.h>\r
 \r
-       /* Enums: */\r
-               /** Enum for the possible status codes for passing to the UpdateStatus() function. */\r
-               enum KeyboardMouse_StatusCodes_t\r
-               {\r
-                       Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */\r
-                       Status_USBEnumerating = 1, /**< USB interface is enumerating */\r
-                       Status_USBReady       = 2, /**< USB interface is connected and ready */\r
-               };\r
-               \r
        /* Macros: */\r
-               /** HID Class specific request to get the next HID report from the device. */\r
-               #define REQ_GetReport      0x01\r
-\r
-               /** HID Class specific request to send the next HID report to the device. */\r
-               #define REQ_SetReport      0x09\r
-\r
-               /** HID Class specific request to get the current HID protocol in use, either report or boot. */\r
-               #define REQ_GetProtocol    0x03\r
-\r
-               /** HID Class specific request to set the current HID protocol in use, either report or boot. */\r
-               #define REQ_SetProtocol    0x0B\r
+               #define LEDMASK_USB_NOTREADY      LEDS_LED1\r
+               #define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)\r
+               #define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)\r
+               #define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)\r
                \r
        /* Type Defines: */\r
                /** Type define for the keyboard HID report structure, for creating and sending HID reports to the host PC.\r
                } USB_MouseReport_Data_t;\r
                        \r
        /* Function Prototypes: */\r
+               void SetupHardware(void);\r
+\r
                void EVENT_USB_Connect(void);\r
                void EVENT_USB_Disconnect(void);\r
                void EVENT_USB_ConfigurationChanged(void);\r
                void EVENT_USB_UnhandledControlPacket(void);\r
+               void EVENT_USB_StartOfFrame(void);\r
 \r
-               void UpdateStatus(uint8_t CurrentStatus);\r
+               uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);\r
+               void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,\r
+                                                                  void* ReportData, uint16_t ReportSize);\r
                \r
 #endif\r
index c6b34d9..ddad7d2 100644 (file)
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)\r
 SRC = $(TARGET).c                                                 \\r
          Descriptors.c                                               \\r
-         $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \\r
@@ -136,7 +135,7 @@ SRC = $(TARGET).c                                                 \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \\r
-         $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \\r
+         $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/HID.c            \\r
 \r
 \r
 # List C++ source files here. (C dependencies are automatically generated.)\r
@@ -183,7 +182,7 @@ CSTANDARD = -std=gnu99
 \r
 # Place -D or -U options here for C sources\r
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)\r
-CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY\r
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY\r
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION\r
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"\r
 \r
index 18fc3b1..485cdc7 100644 (file)
@@ -183,7 +183,7 @@ CSTANDARD = -std=gnu99
 \r
 # Place -D or -U options here for C sources\r
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)\r
-CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY\r
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY\r
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION\r
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"\r
 \r
index 4b62419..87edef1 100644 (file)
@@ -46,7 +46,7 @@
  *  \param BlockAddress  Data block starting address for the write sequence\r
  *  \param TotalBlocks   Number of blocks of data to write\r
  */\r
-void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks)\r
+void DataflashManager_WriteBlocks(USB_ClassInfo_MS_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks)\r
 {\r
        uint16_t CurrDFPage          = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);\r
        uint16_t CurrDFPageByte      = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);\r
@@ -142,7 +142,7 @@ void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlo
                        BytesInBlockDiv16++;\r
 \r
                        /* Check if the current command is being aborted by the host */\r
-                       if (IsMassStoreReset)\r
+                       if (MSInterfaceInfo->IsMassStoreReset)\r
                          return;                       \r
                }\r
                        \r
@@ -171,7 +171,7 @@ void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlo
  *  \param BlockAddress  Data block starting address for the read sequence\r
  *  \param TotalBlocks   Number of blocks of data to read\r
  */\r
-void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks)\r
+void DataflashManager_ReadBlocks(USB_ClassInfo_MS_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks)\r
 {\r
        uint16_t CurrDFPage          = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);\r
        uint16_t CurrDFPageByte      = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);\r
@@ -250,7 +250,7 @@ void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBloc
                        BytesInBlockDiv16++;\r
 \r
                        /* Check if the current command is being aborted by the host */\r
-                       if (IsMassStoreReset)\r
+                       if (MSInterfaceInfo->IsMassStoreReset)\r
                          return;\r
                }\r
                \r
@@ -341,11 +341,7 @@ void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t Tota
                        CurrDFPageByteDiv16++;\r
 \r
                        /* Increment the block 16 byte block counter */\r
-                       BytesInBlockDiv16++;\r
-\r
-                       /* Check if the current command is being aborted by the host */\r
-                       if (IsMassStoreReset)\r
-                         return;                       \r
+                       BytesInBlockDiv16++;            \r
                }\r
                        \r
                /* Decrement the blocks remaining counter and reset the sub block counter */\r
@@ -421,10 +417,6 @@ void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t Total
                        \r
                        /* Increment the block 16 byte block counter */\r
                        BytesInBlockDiv16++;\r
-\r
-                       /* Check if the current command is being aborted by the host */\r
-                       if (IsMassStoreReset)\r
-                         return;\r
                }\r
                \r
                /* Decrement the blocks remaining counter */\r
index 1332fd3..b828051 100644 (file)
@@ -64,8 +64,8 @@
                #define VIRTUAL_MEMORY_BLOCKS               (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE)\r
                \r
        /* Function Prototypes: */\r
-               void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks);\r
-               void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks);\r
+               void DataflashManager_WriteBlocks(USB_ClassInfo_MS_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks);\r
+               void DataflashManager_ReadBlocks(USB_ClassInfo_MS_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks);\r
                void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,\r
                                                      uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);\r
                void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,\r
index 5993a54..8f3167a 100644 (file)
@@ -84,37 +84,37 @@ SCSI_Request_Sense_Response_t SenseData =
  *  to the appropriate SCSI command handling routine if the issued command is supported by the device, else it returns\r
  *  a command failure due to a ILLEGAL REQUEST.\r
  */\r
-void SCSI_DecodeSCSICommand(void)\r
+bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_t* MSInterfaceInfo)\r
 {\r
        bool CommandSuccess = false;\r
 \r
        /* Run the appropriate SCSI command hander function based on the passed command */\r
-       switch (CommandBlock.SCSICommandData[0])\r
+       switch (MSInterfaceInfo->CommandBlock.SCSICommandData[0])\r
        {\r
                case SCSI_CMD_INQUIRY:\r
-                       CommandSuccess = SCSI_Command_Inquiry();                        \r
+                       CommandSuccess = SCSI_Command_Inquiry(MSInterfaceInfo);                 \r
                        break;\r
                case SCSI_CMD_REQUEST_SENSE:\r
-                       CommandSuccess = SCSI_Command_Request_Sense();\r
+                       CommandSuccess = SCSI_Command_Request_Sense(MSInterfaceInfo);\r
                        break;\r
                case SCSI_CMD_READ_CAPACITY_10:\r
-                       CommandSuccess = SCSI_Command_Read_Capacity_10();                       \r
+                       CommandSuccess = SCSI_Command_Read_Capacity_10(MSInterfaceInfo);                        \r
                        break;\r
                case SCSI_CMD_SEND_DIAGNOSTIC:\r
-                       CommandSuccess = SCSI_Command_Send_Diagnostic();\r
+                       CommandSuccess = SCSI_Command_Send_Diagnostic(MSInterfaceInfo);\r
                        break;\r
                case SCSI_CMD_WRITE_10:\r
-                       CommandSuccess = SCSI_Command_ReadWrite_10(DATA_WRITE);\r
+                       CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_WRITE);\r
                        break;\r
                case SCSI_CMD_READ_10:\r
-                       CommandSuccess = SCSI_Command_ReadWrite_10(DATA_READ);\r
+                       CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_READ);\r
                        break;\r
                case SCSI_CMD_TEST_UNIT_READY:\r
                case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:\r
                case SCSI_CMD_VERIFY_10:\r
                        /* These commands should just succeed, no handling required */\r
                        CommandSuccess = true;\r
-                       CommandBlock.DataTransferLength = 0;\r
+                       MSInterfaceInfo->CommandBlock.DataTransferLength = 0;\r
                        break;\r
                default:\r
                        /* Update the SENSE key to reflect the invalid command */\r
@@ -123,22 +123,18 @@ void SCSI_DecodeSCSICommand(void)
                                   SCSI_ASENSEQ_NO_QUALIFIER);\r
                        break;\r
        }\r
-       \r
+\r
        /* Check if command was successfully processed */\r
        if (CommandSuccess)\r
        {\r
-               /* Command succeeded - set the CSW status and update the SENSE key */\r
-               CommandStatus.Status = Command_Pass;\r
-               \r
                SCSI_SET_SENSE(SCSI_SENSE_KEY_GOOD,\r
                               SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,\r
-                              SCSI_ASENSEQ_NO_QUALIFIER);                                         \r
-       }\r
-       else\r
-       {\r
-               /* Command failed - set the CSW status - failed command function updates the SENSE key */\r
-               CommandStatus.Status = Command_Fail;\r
+                              SCSI_ASENSEQ_NO_QUALIFIER);\r
+               \r
+               return true;\r
        }\r
+\r
+       return false;\r
 }\r
 \r
 /** Command processing for an issued SCSI INQUIRY command. This command returns information about the device's features\r
@@ -146,16 +142,16 @@ void SCSI_DecodeSCSICommand(void)
  *\r
  *  \return Boolean true if the command completed successfully, false otherwise.\r
  */\r
-static bool SCSI_Command_Inquiry(void)\r
+static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_t* MSInterfaceInfo)\r
 {\r
-       uint16_t AllocationLength  = (((uint16_t)CommandBlock.SCSICommandData[3] << 8) |\r
-                                                CommandBlock.SCSICommandData[4]);\r
+       uint16_t AllocationLength  = (((uint16_t)MSInterfaceInfo->CommandBlock.SCSICommandData[3] << 8) |\r
+                                                MSInterfaceInfo->CommandBlock.SCSICommandData[4]);\r
        uint16_t BytesTransferred  = (AllocationLength < sizeof(InquiryData))? AllocationLength :\r
                                                                               sizeof(InquiryData);\r
 \r
        /* Only the standard INQUIRY data is supported, check if any optional INQUIRY bits set */\r
-       if ((CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) ||\r
-            CommandBlock.SCSICommandData[2])\r
+       if ((MSInterfaceInfo->CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) ||\r
+            MSInterfaceInfo->CommandBlock.SCSICommandData[2])\r
        {\r
                /* Optional but unsupported bits set - update the SENSE key and fail the request */\r
                SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,\r
@@ -164,20 +160,19 @@ static bool SCSI_Command_Inquiry(void)
 \r
                return false;\r
        }\r
-\r
-       /* Write the INQUIRY data to the endpoint */\r
-       Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, StreamCallback_AbortOnMassStoreReset);\r
+       \r
+       Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, NO_STREAM_CALLBACK);\r
 \r
        uint8_t PadBytes[AllocationLength - BytesTransferred];\r
        \r
        /* Pad out remaining bytes with 0x00 */\r
-       Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), StreamCallback_AbortOnMassStoreReset);\r
+       Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK);\r
 \r
        /* Finalize the stream transfer to send the last packet */\r
        Endpoint_ClearIN();\r
 \r
        /* Succeed the command and update the bytes transferred counter */\r
-       CommandBlock.DataTransferLength -= BytesTransferred;\r
+       MSInterfaceInfo->CommandBlock.DataTransferLength -= BytesTransferred;\r
        \r
        return true;\r
 }\r
@@ -187,24 +182,19 @@ static bool SCSI_Command_Inquiry(void)
  *\r
  *  \return Boolean true if the command completed successfully, false otherwise.\r
  */\r
-static bool SCSI_Command_Request_Sense(void)\r
+static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_t* MSInterfaceInfo)\r
 {\r
-       uint8_t  AllocationLength = CommandBlock.SCSICommandData[4];\r
+       uint8_t  AllocationLength = MSInterfaceInfo->CommandBlock.SCSICommandData[4];\r
        uint8_t  BytesTransferred = (AllocationLength < sizeof(SenseData))? AllocationLength : sizeof(SenseData);\r
        \r
-       /* Send the SENSE data - this indicates to the host the status of the last command */\r
-       Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, StreamCallback_AbortOnMassStoreReset);\r
-       \r
        uint8_t PadBytes[AllocationLength - BytesTransferred];\r
-       \r
-       /* Pad out remaining bytes with 0x00 */\r
-       Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), StreamCallback_AbortOnMassStoreReset);\r
 \r
-       /* Finalize the stream transfer to send the last packet */\r
+       Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NO_STREAM_CALLBACK);\r
+       Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK);\r
        Endpoint_ClearIN();\r
 \r
        /* Succeed the command and update the bytes transferred counter */\r
-       CommandBlock.DataTransferLength -= BytesTransferred;\r
+       MSInterfaceInfo->CommandBlock.DataTransferLength -= BytesTransferred;\r
 \r
        return true;\r
 }\r
@@ -214,23 +204,17 @@ static bool SCSI_Command_Request_Sense(void)
  *\r
  *  \return Boolean true if the command completed successfully, false otherwise.\r
  */\r
-static bool SCSI_Command_Read_Capacity_10(void)\r
+static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_t* MSInterfaceInfo)\r
 {\r
-       /* Send the total number of logical blocks in the current LUN */\r
-       Endpoint_Write_DWord_BE(LUN_MEDIA_BLOCKS - 1);\r
+       uint32_t TotalLUNs      = (LUN_MEDIA_BLOCKS - 1);\r
+       uint32_t MediaBlockSize = VIRTUAL_MEMORY_BLOCK_SIZE;\r
 \r
-       /* Send the logical block size of the device (must be 512 bytes) */\r
-       Endpoint_Write_DWord_BE(VIRTUAL_MEMORY_BLOCK_SIZE);\r
-\r
-       /* Check if the current command is being aborted by the host */\r
-       if (IsMassStoreReset)\r
-         return false;\r
-\r
-       /* Send the endpoint data packet to the host */\r
+       Endpoint_Write_Stream_BE(&TotalLUNs, sizeof(TotalLUNs), NO_STREAM_CALLBACK);\r
+       Endpoint_Write_Stream_BE(&MediaBlockSize, sizeof(MediaBlockSize), NO_STREAM_CALLBACK);\r
        Endpoint_ClearIN();\r
-\r
+       \r
        /* Succeed the command and update the bytes transferred counter */\r
-       CommandBlock.DataTransferLength -= 8;\r
+       MSInterfaceInfo->CommandBlock.DataTransferLength -= 8;\r
        \r
        return true;\r
 }\r
@@ -241,12 +225,12 @@ static bool SCSI_Command_Read_Capacity_10(void)
  *\r
  *  \return Boolean true if the command completed successfully, false otherwise.\r
  */\r
-static bool SCSI_Command_Send_Diagnostic(void)\r
+static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_t* MSInterfaceInfo)\r
 {\r
        uint8_t ReturnByte;\r
 \r
        /* Check to see if the SELF TEST bit is not set */\r
-       if (!(CommandBlock.SCSICommandData[1] & (1 << 2)))\r
+       if (!(MSInterfaceInfo->CommandBlock.SCSICommandData[1] & (1 << 2)))\r
        {\r
                /* Only self-test supported - update SENSE key and fail the command */\r
                SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,\r
@@ -293,7 +277,7 @@ static bool SCSI_Command_Send_Diagnostic(void)
        #endif\r
        \r
        /* Succeed the command and update the bytes transferred counter */\r
-       CommandBlock.DataTransferLength = 0;\r
+       MSInterfaceInfo->CommandBlock.DataTransferLength = 0;\r
        \r
        return true;\r
 }\r
@@ -306,20 +290,20 @@ static bool SCSI_Command_Send_Diagnostic(void)
  *\r
  *  \return Boolean true if the command completed successfully, false otherwise.\r
  */\r
-static bool SCSI_Command_ReadWrite_10(const bool IsDataRead)\r
+static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_t* MSInterfaceInfo, const bool IsDataRead)\r
 {\r
        uint32_t BlockAddress;\r
        uint16_t TotalBlocks;\r
        \r
        /* Load in the 32-bit block address (SCSI uses big-endian, so have to do it byte-by-byte) */\r
-       ((uint8_t*)&BlockAddress)[3] = CommandBlock.SCSICommandData[2];\r
-       ((uint8_t*)&BlockAddress)[2] = CommandBlock.SCSICommandData[3];\r
-       ((uint8_t*)&BlockAddress)[1] = CommandBlock.SCSICommandData[4];\r
-       ((uint8_t*)&BlockAddress)[0] = CommandBlock.SCSICommandData[5];\r
+       ((uint8_t*)&BlockAddress)[3] = MSInterfaceInfo->CommandBlock.SCSICommandData[2];\r
+       ((uint8_t*)&BlockAddress)[2] = MSInterfaceInfo->CommandBlock.SCSICommandData[3];\r
+       ((uint8_t*)&BlockAddress)[1] = MSInterfaceInfo->CommandBlock.SCSICommandData[4];\r
+       ((uint8_t*)&BlockAddress)[0] = MSInterfaceInfo->CommandBlock.SCSICommandData[5];\r
 \r
        /* Load in the 16-bit total blocks (SCSI uses big-endian, so have to do it byte-by-byte) */\r
-       ((uint8_t*)&TotalBlocks)[1]  = CommandBlock.SCSICommandData[7];\r
-       ((uint8_t*)&TotalBlocks)[0]  = CommandBlock.SCSICommandData[8];\r
+       ((uint8_t*)&TotalBlocks)[1]  = MSInterfaceInfo->CommandBlock.SCSICommandData[7];\r
+       ((uint8_t*)&TotalBlocks)[0]  = MSInterfaceInfo->CommandBlock.SCSICommandData[8];\r
        \r
        /* Check if the block address is outside the maximum allowable value for the LUN */\r
        if (BlockAddress >= LUN_MEDIA_BLOCKS)\r
@@ -334,17 +318,17 @@ static bool SCSI_Command_ReadWrite_10(const bool IsDataRead)
 \r
        #if (TOTAL_LUNS > 1)\r
        /* Adjust the given block address to the real media address based on the selected LUN */\r
-       BlockAddress += ((uint32_t)CommandBlock.LUN * LUN_MEDIA_BLOCKS);\r
+       BlockAddress += ((uint32_t)MSInterfaceInfo->CommandBlock.LUN * LUN_MEDIA_BLOCKS);\r
        #endif\r
        \r
        /* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */\r
        if (IsDataRead == DATA_READ)\r
-         DataflashManager_ReadBlocks(BlockAddress, TotalBlocks);\r
+         DataflashManager_ReadBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);\r
        else\r
-         DataflashManager_WriteBlocks(BlockAddress, TotalBlocks);\r
+         DataflashManager_WriteBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);\r
 \r
        /* Update the bytes transferred counter and succeed the command */\r
-       CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);\r
+       MSInterfaceInfo->CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);\r
        \r
        return true;\r
 }\r
index d7693ca..3fd751d 100644 (file)
@@ -40,9 +40,8 @@
                #include <avr/io.h>\r
                #include <avr/pgmspace.h>\r
 \r
-               #include <LUFA/Common/Common.h>              // Function Attribute, Atomic, Debug and ISR Macros\r
-               #include <LUFA/Drivers/USB/USB.h>            // USB Functionality\r
-               #include <LUFA/Drivers/Board/LEDs.h>         // LEDs driver\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/MassStorage.h>\r
 \r
                #include "MassStorage.h"\r
                #include "Descriptors.h"\r
                                                                   SenseData.AdditionalSenseQualifier = aqual; }MACROE\r
 \r
                /** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be read from the storage medium. */\r
-               #define DATA_READ      true\r
+               #define DATA_READ           true\r
 \r
                /** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be written to the storage medium. */\r
-               #define DATA_WRITE     false\r
+               #define DATA_WRITE          false\r
 \r
                /** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a Block Media device. */\r
-               #define DEVICE_TYPE_BLOCK 0x00\r
+               #define DEVICE_TYPE_BLOCK   0x00\r
                \r
                /** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a CD-ROM device. */\r
-               #define DEVICE_TYPE_CDROM 0x05\r
+               #define DEVICE_TYPE_CDROM   0x05\r
 \r
        /* Type Defines: */\r
                /** Type define for a SCSI response structure to a SCSI INQUIRY command. For details of the\r
                } SCSI_Request_Sense_Response_t;\r
                \r
        /* Function Prototypes: */\r
-               void SCSI_DecodeSCSICommand(void);\r
+               bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_t* MSInterfaceInfo);\r
                \r
                #if defined(INCLUDE_FROM_SCSI_C)\r
-                       static bool SCSI_Command_Inquiry(void);\r
-                       static bool SCSI_Command_Request_Sense(void);\r
-                       static bool SCSI_Command_Read_Capacity_10(void);\r
-                       static bool SCSI_Command_Send_Diagnostic(void);\r
-                       static bool SCSI_Command_ReadWrite_10(const bool IsDataRead);\r
+                       static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_t* MSInterfaceInfo);\r
+                       static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_t* MSInterfaceInfo);\r
+                       static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_t* MSInterfaceInfo);\r
+                       static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_t* MSInterfaceInfo);\r
+                       static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_t* MSInterfaceInfo, const bool IsDataRead);\r
                #endif\r
                \r
 #endif\r
index 72a2302..8e2b9f4 100644 (file)
   this software.\r
 */\r
 \r
-/** \file\r
- *\r
- *  Main source file for the Mass Storage demo. This file contains the main tasks of the demo and\r
- *  is responsible for the initial application hardware configuration.\r
- */\r
-\r
-#define  INCLUDE_FROM_MASSSTORAGE_C\r
 #include "MassStorage.h"\r
 \r
-/* Scheduler Task List */\r
-TASK_LIST\r
-{\r
-       { .Task = USB_MassStorage      , .TaskStatus = TASK_STOP },\r
-};\r
+USB_ClassInfo_MS_t Disk_MS_Interface =\r
+       {\r
+               .InterfaceNumber        = 0,\r
 \r
-/* Global Variables */\r
-/** Structure to hold the latest Command Block Wrapper issued by the host, containing a SCSI command to execute. */\r
-CommandBlockWrapper_t  CommandBlock;\r
+               .DataINEndpointNumber   = MASS_STORAGE_IN_EPNUM,\r
+               .DataINEndpointSize     = MASS_STORAGE_IO_EPSIZE,\r
 \r
-/** Structure to hold the latest Command Status Wrapper to return to the host, containing the status of the last issued command. */\r
-CommandStatusWrapper_t CommandStatus = { .Signature = CSW_SIGNATURE };\r
+               .DataOUTEndpointNumber  = MASS_STORAGE_OUT_EPNUM,\r
+               .DataOUTEndpointSize    = MASS_STORAGE_IO_EPSIZE,\r
 \r
-/** Flag to asynchronously abort any in-progress data transfers upon the reception of a mass storage reset command. */\r
-volatile bool          IsMassStoreReset = false;\r
+               .TotalLUNs              = TOTAL_LUNS,\r
+       };\r
 \r
-/** Main program entry point. This routine configures the hardware required by the application, then\r
- *  starts the scheduler to run the application tasks.\r
- */\r
 int main(void)\r
 {\r
+       SetupHardware();\r
+\r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
+\r
+       for (;;)\r
+       {\r
+               USB_MS_USBTask(&Disk_MS_Interface);\r
+               USB_USBTask();\r
+       }\r
+}\r
+\r
+void SetupHardware(void)\r
+{\r
        /* Disable watchdog if enabled by bootloader/fuses */\r
        MCUSR &= ~(1 << WDRF);\r
        wdt_disable();\r
@@ -68,303 +68,42 @@ int main(void)
        /* Hardware Initialization */\r
        LEDs_Init();\r
        Dataflash_Init(SPI_SPEED_FCPU_DIV_2);\r
+       USB_Init();\r
 \r
        /* Clear Dataflash sector protections, if enabled */\r
        DataflashManager_ResetDataflashProtections();\r
-       \r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
-       \r
-       /* Initialize Scheduler so that it can be used */\r
-       Scheduler_Init();\r
-\r
-       /* Initialize USB Subsystem */\r
-       USB_Init();\r
-\r
-       /* Scheduling - routine never returns, so put this last in the main function */\r
-       Scheduler_Start();\r
 }\r
 \r
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs. */\r
 void EVENT_USB_Connect(void)\r
 {\r
-       /* Indicate USB enumerating */\r
-       UpdateStatus(Status_USBEnumerating);\r
-       \r
-       /* Reset the MSReset flag upon connection */\r
-       IsMassStoreReset = false;\r
+       LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);\r
 }\r
 \r
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via\r
- *  the status LEDs and stops the Mass Storage management task.\r
- */\r
 void EVENT_USB_Disconnect(void)\r
 {\r
-       /* Stop running mass storage task */\r
-       Scheduler_SetTaskMode(USB_MassStorage, TASK_STOP);\r
-\r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
 }\r
 \r
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration\r
- *  of the USB device after enumeration - the device endpoints are configured and the Mass Storage management task started.\r
- */\r
 void EVENT_USB_ConfigurationChanged(void)\r
 {\r
-       /* Setup Mass Storage In and Out Endpoints */\r
-       Endpoint_ConfigureEndpoint(MASS_STORAGE_IN_EPNUM, EP_TYPE_BULK,\r
-                                      ENDPOINT_DIR_IN, MASS_STORAGE_IO_EPSIZE,\r
-                                  ENDPOINT_BANK_DOUBLE);\r
-\r
-       Endpoint_ConfigureEndpoint(MASS_STORAGE_OUT_EPNUM, EP_TYPE_BULK,\r
-                                      ENDPOINT_DIR_OUT, MASS_STORAGE_IO_EPSIZE,\r
-                                  ENDPOINT_BANK_DOUBLE);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
 \r
-       /* Indicate USB connected and ready */\r
-       UpdateStatus(Status_USBReady);\r
-       \r
-       /* Start mass storage task */\r
-       Scheduler_SetTaskMode(USB_MassStorage, TASK_RUN);\r
+       if (!(USB_MS_ConfigureEndpoints(&Disk_MS_Interface)))\r
+         LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
 }\r
 \r
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific\r
- *  control requests that are not handled internally by the USB library (including the Mass Storage class-specific\r
- *  requests) so that they can be handled appropriately for the application.\r
- */\r
 void EVENT_USB_UnhandledControlPacket(void)\r
 {\r
-       /* Process UFI specific control requests */\r
-       switch (USB_ControlRequest.bRequest)\r
-       {\r
-               case REQ_MassStorageReset:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               Endpoint_ClearSETUP();\r
-\r
-                               /* Indicate that the current transfer should be aborted */\r
-                               IsMassStoreReset = true;                        \r
-\r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsINReady()));\r
-                               Endpoint_ClearIN();\r
-                       }\r
-\r
-                       break;\r
-               case REQ_GetMaxLUN:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               Endpoint_ClearSETUP();\r
-\r
-                               /* Indicate to the host the number of supported LUNs (virtual disks) on the device */\r
-                               Endpoint_Write_Byte(TOTAL_LUNS - 1);\r
-                               \r
-                               Endpoint_ClearIN();\r
-                               \r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsOUTReceived()));\r
-                               Endpoint_ClearOUT();\r
-                       }\r
-                       \r
-                       break;\r
-       }\r
-}\r
-\r
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to\r
- *  log to a serial port, or anything else that is suitable for status updates.\r
- *\r
- *  \param CurrentStatus  Current status of the system, from the MassStorage_StatusCodes_t enum\r
- */\r
-void UpdateStatus(uint8_t CurrentStatus)\r
-{\r
-       uint8_t LEDMask = LEDS_NO_LEDS;\r
-       \r
-       /* Set the LED mask to the appropriate LED mask based on the given status code */\r
-       switch (CurrentStatus)\r
-       {\r
-               case Status_USBNotReady:\r
-                       LEDMask = (LEDS_LED1);\r
-                       break;\r
-               case Status_USBEnumerating:\r
-                       LEDMask = (LEDS_LED1 | LEDS_LED2);\r
-                       break;\r
-               case Status_USBReady:\r
-                       LEDMask = (LEDS_LED2 | LEDS_LED4);\r
-                       break;\r
-               case Status_CommandBlockError:\r
-                       LEDMask = (LEDS_LED1);\r
-                       break;\r
-               case Status_ProcessingCommandBlock:\r
-                       LEDMask = (LEDS_LED1 | LEDS_LED2);\r
-                       break;\r
-       }\r
-       \r
-       /* Set the board LEDs to the new LED mask */\r
-       LEDs_SetAllLEDs(LEDMask);\r
-}\r
-\r
-/** Task to manage the Mass Storage interface, reading in Command Block Wrappers from the host, processing the SCSI commands they\r
- *  contain, and returning Command Status Wrappers back to the host to indicate the success or failure of the last issued command.\r
- */\r
-TASK(USB_MassStorage)\r
-{\r
-       /* Check if the USB System is connected to a Host */\r
-       if (USB_IsConnected)\r
-       {\r
-               /* Select the Data Out Endpoint */\r
-               Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);\r
-               \r
-               /* Check to see if a command from the host has been issued */\r
-               if (Endpoint_IsReadWriteAllowed())\r
-               {       \r
-                       /* Indicate busy */\r
-                       UpdateStatus(Status_ProcessingCommandBlock);\r
-\r
-                       /* Process sent command block from the host */\r
-                       if (ReadInCommandBlock())\r
-                       {\r
-                               /* Check direction of command, select Data IN endpoint if data is from the device */\r
-                               if (CommandBlock.Flags & COMMAND_DIRECTION_DATA_IN)\r
-                                 Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);\r
-\r
-                               /* Decode the received SCSI command */\r
-                               SCSI_DecodeSCSICommand();\r
-\r
-                               /* Load in the CBW tag into the CSW to link them together */\r
-                               CommandStatus.Tag = CommandBlock.Tag;\r
-\r
-                               /* Load in the data residue counter into the CSW */\r
-                               CommandStatus.DataTransferResidue = CommandBlock.DataTransferLength;\r
-\r
-                               /* Stall the selected data pipe if command failed (if data is still to be transferred) */\r
-                               if ((CommandStatus.Status == Command_Fail) && (CommandStatus.DataTransferResidue))\r
-                                 Endpoint_StallTransaction();\r
-\r
-                               /* Return command status block to the host */\r
-                               ReturnCommandStatus();\r
-                               \r
-                               /* Check if a Mass Storage Reset occurred */\r
-                               if (IsMassStoreReset)\r
-                               {\r
-                                       /* Reset the data endpoint banks */\r
-                                       Endpoint_ResetFIFO(MASS_STORAGE_OUT_EPNUM);\r
-                                       Endpoint_ResetFIFO(MASS_STORAGE_IN_EPNUM);\r
-                                       \r
-                                       Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);\r
-                                       Endpoint_ClearStall();\r
-                                       Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);\r
-                                       Endpoint_ClearStall();\r
-\r
-                                       /* Clear the abort transfer flag */\r
-                                       IsMassStoreReset = false;\r
-                               }\r
-\r
-                               /* Indicate ready */\r
-                               UpdateStatus(Status_USBReady);\r
-                       }\r
-                       else\r
-                       {\r
-                               /* Indicate error reading in the command block from the host */\r
-                               UpdateStatus(Status_CommandBlockError);\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-/** Function to read in a command block from the host, via the bulk data OUT endpoint. This function reads in the next command block\r
- *  if one has been issued, and performs validation to ensure that the block command is valid.\r
- *\r
- *  \return Boolean true if a valid command block has been read in from the endpoint, false otherwise\r
- */\r
-static bool ReadInCommandBlock(void)\r
-{\r
-       /* Select the Data Out endpoint */\r
-       Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);\r
-\r
-       /* Read in command block header */\r
-       Endpoint_Read_Stream_LE(&CommandBlock, (sizeof(CommandBlock) - sizeof(CommandBlock.SCSICommandData)),\r
-                               StreamCallback_AbortOnMassStoreReset);\r
-\r
-       /* Check if the current command is being aborted by the host */\r
-       if (IsMassStoreReset)\r
-         return false;\r
-\r
-       /* Verify the command block - abort if invalid */\r
-       if ((CommandBlock.Signature != CBW_SIGNATURE) ||\r
-           (CommandBlock.LUN >= TOTAL_LUNS) ||\r
-               (CommandBlock.SCSICommandLength > MAX_SCSI_COMMAND_LENGTH))\r
-       {\r
-               /* Stall both data pipes until reset by host */\r
-               Endpoint_StallTransaction();\r
-               Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);\r
-               Endpoint_StallTransaction();\r
-               \r
-               return false;\r
-       }\r
-\r
-       /* Read in command block command data */\r
-       Endpoint_Read_Stream_LE(&CommandBlock.SCSICommandData,\r
-                               CommandBlock.SCSICommandLength,\r
-                               StreamCallback_AbortOnMassStoreReset);\r
-         \r
-       /* Check if the current command is being aborted by the host */\r
-       if (IsMassStoreReset)\r
-         return false;\r
-\r
-       /* Finalize the stream transfer to send the last packet */\r
-       Endpoint_ClearOUT();\r
-       \r
-       return true;\r
+       USB_MS_ProcessControlPacket(&Disk_MS_Interface);\r
 }\r
 \r
-/** Returns the filled Command Status Wrapper back to the host via the bulk data IN endpoint, waiting for the host to clear any\r
- *  stalled data endpoints as needed.\r
- */\r
-static void ReturnCommandStatus(void)\r
+bool CALLBACK_USB_MS_SCSICommandReceived(USB_ClassInfo_MS_t* MSInterfaceInfo)\r
 {\r
-       /* Select the Data Out endpoint */\r
-       Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);\r
-\r
-       /* While data pipe is stalled, wait until the host issues a control request to clear the stall */\r
-       while (Endpoint_IsStalled())\r
-       {\r
-               /* Check if the current command is being aborted by the host */\r
-               if (IsMassStoreReset)\r
-                 return;\r
-       }\r
-\r
-       /* Select the Data In endpoint */\r
-       Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);\r
-\r
-       /* While data pipe is stalled, wait until the host issues a control request to clear the stall */\r
-       while (Endpoint_IsStalled())\r
-       {\r
-               /* Check if the current command is being aborted by the host */\r
-               if (IsMassStoreReset)\r
-                 return;\r
-       }\r
+       bool CommandSuccess;\r
        \r
-       /* Write the CSW to the endpoint */\r
-       Endpoint_Write_Stream_LE(&CommandStatus, sizeof(CommandStatus),\r
-                                 StreamCallback_AbortOnMassStoreReset);\r
-       \r
-       /* Check if the current command is being aborted by the host */\r
-       if (IsMassStoreReset)\r
-         return;\r
-\r
-       /* Finalize the stream transfer to send the last packet */\r
-       Endpoint_ClearIN();\r
-}\r
-\r
-/** Stream callback function for the Endpoint stream read and write functions. This callback will abort the current stream transfer\r
- *  if a Mass Storage Reset request has been issued to the control endpoint.\r
- */\r
-uint8_t StreamCallback_AbortOnMassStoreReset(void)\r
-{      \r
-       /* Abort if a Mass Storage reset command was received */\r
-       if (IsMassStoreReset)\r
-         return STREAMCALLBACK_Abort;\r
+       LEDs_SetAllLEDs(LEDMASK_USB_BUSY);\r
+       CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
        \r
-       /* Continue with the current stream operation */\r
-       return STREAMCALLBACK_Continue;\r
+       return CommandSuccess;\r
 }\r
index cbd3cd9..a50edac 100644 (file)
                #include "Lib/SCSI.h"\r
                #include "Lib/DataflashManager.h"\r
 \r
-               #include <LUFA/Version.h>                    // Library Version Information\r
-               #include <LUFA/Drivers/USB/USB.h>            // USB Functionality\r
-               #include <LUFA/Drivers/Board/LEDs.h>         // LEDs driver\r
-               #include <LUFA/Drivers/Board/Dataflash.h>    // Dataflash chip driver\r
-               #include <LUFA/Scheduler/Scheduler.h>        // Simple scheduler for task management\r
+               #include <LUFA/Version.h>\r
+               #include <LUFA/Drivers/Board/Joystick.h>\r
+               #include <LUFA/Drivers/Board/LEDs.h>\r
+               #include <LUFA/Drivers/Board/Buttons.h>\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/MassStorage.h>
 \r
        /* Macros: */\r
-               /** Mass Storage Class specific request to reset the Mass Storage interface, ready for the next command. */\r
-               #define REQ_MassStorageReset       0xFF\r
-\r
-               /** Mass Storage Class specific request to retrieve the total number of Logical Units (drives) in the SCSI device. */\r
-               #define REQ_GetMaxLUN              0xFE\r
-\r
-               /** Maximum length of a SCSI command which can be issued by the device or host in a Mass Storage bulk wrapper. */\r
-               #define MAX_SCSI_COMMAND_LENGTH    16\r
+               #define LEDMASK_USB_NOTREADY      LEDS_LED1\r
+               #define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)\r
+               #define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)\r
+               #define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)\r
+               #define LEDMASK_USB_BUSY          LEDS_LED2\r
                \r
-               /** Total number of Logical Units (drives) in the device. The total device capacity is shared equally between\r
-                *  each drive - this can be set to any positive non-zero amount.\r
-                */\r
-               #define TOTAL_LUNS                 2\r
+               #define TOTAL_LUNS                2\r
                \r
                /** Blocks in each LUN, calculated from the total capacity divided by the total number of Logical Units in the device. */\r
-               #define LUN_MEDIA_BLOCKS           (VIRTUAL_MEMORY_BLOCKS / TOTAL_LUNS)    \r
-               \r
-               /** Magic signature for a Command Block Wrapper used in the Mass Storage Bulk-Only transport protocol. */\r
-               #define CBW_SIGNATURE              0x43425355UL\r
-\r
-               /** Magic signature for a Command Status Wrapper used in the Mass Storage Bulk-Only transport protocol. */\r
-               #define CSW_SIGNATURE              0x53425355UL\r
-               \r
-               /** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from host-to-device. */\r
-               #define COMMAND_DIRECTION_DATA_OUT (0 << 7)\r
-\r
-               /** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from device-to-host. */\r
-               #define COMMAND_DIRECTION_DATA_IN  (1 << 7)\r
-\r
-       /* Type defines: */\r
-               /** Type define for a Command Block Wrapper, used in the Mass Storage Bulk-Only Transport protocol. */\r
-               typedef struct\r
-               {\r
-                       uint32_t Signature; /**< Command block signature, must be CBW_SIGNATURE to indicate a valid Command Block */\r
-                       uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper */\r
-                       uint32_t DataTransferLength; /** Length of the optional data portion of the issued command, in bytes */\r
-                       uint8_t  Flags; /**< Command block flags, indicating command data direction */\r
-                       uint8_t  LUN; /**< Logical Unit number this command is issued to */\r
-                       uint8_t  SCSICommandLength; /**< Length of the issued SCSI command within the SCSI command data array */\r
-                       uint8_t  SCSICommandData[MAX_SCSI_COMMAND_LENGTH]; /**< Issued SCSI command in the Command Block */\r
-               } CommandBlockWrapper_t;\r
-               \r
-               /** Type define for a Command Status Wrapper, used in the Mass Storage Bulk-Only Transport protocol. */\r
-               typedef struct\r
-               {\r
-                       uint32_t Signature; /**< Status block signature, must be CSW_SIGNATURE to indicate a valid Command Status */\r
-                       uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper */\r
-                       uint32_t DataTransferResidue; /**< Number of bytes of data not processed in the SCSI command */\r
-                       uint8_t  Status; /**< Status code of the issued command - a value from the MassStorage_CommandStatusCodes_t enum */\r
-               } CommandStatusWrapper_t;\r
-               \r
-       /* Enums: */\r
-               /** Enum for the possible command status wrapper return status codes. */\r
-               enum MassStorage_CommandStatusCodes_t\r
-               {\r
-                       Command_Pass = 0, /**< Command completed with no error */\r
-                       Command_Fail = 1, /**< Command failed to complete - host may check the exact error via a SCSI REQUEST SENSE command */\r
-                       Phase_Error  = 2  /**< Command failed due to being invalid in the current phase */\r
-               };\r
-\r
-               /** Enum for the possible status codes for passing to the UpdateStatus() function. */\r
-               enum MassStorage_StatusCodes_t\r
-               {\r
-                       Status_USBNotReady            = 0, /**< USB is not ready (disconnected from a USB host) */\r
-                       Status_USBEnumerating         = 1, /**< USB interface is enumerating */\r
-                       Status_USBReady               = 2, /**< USB interface is connected and ready */\r
-                       Status_CommandBlockError      = 3, /**< Processing a SCSI command block from the host */\r
-                       Status_ProcessingCommandBlock = 4, /**< Error during the processing of a SCSI command block from the host */\r
-               };\r
-               \r
-       /* Global Variables: */\r
-               extern CommandBlockWrapper_t  CommandBlock;\r
-               extern CommandStatusWrapper_t CommandStatus;\r
-               extern volatile bool          IsMassStoreReset;\r
-\r
-       /* Task Definitions: */\r
-               TASK(USB_MassStorage);\r
+               #define LUN_MEDIA_BLOCKS         (VIRTUAL_MEMORY_BLOCKS / TOTAL_LUNS)\r
                \r
        /* Function Prototypes: */\r
+               void SetupHardware(void);\r
+\r
                void EVENT_USB_Connect(void);\r
                void EVENT_USB_Disconnect(void);\r
                void EVENT_USB_ConfigurationChanged(void);\r
                void EVENT_USB_UnhandledControlPacket(void);\r
 \r
-               void UpdateStatus(uint8_t CurrentStatus);\r
-\r
-               #if defined(INCLUDE_FROM_MASSSTORAGE_C)\r
-                       static bool ReadInCommandBlock(void);\r
-                       static void ReturnCommandStatus(void);\r
-               #endif\r
-\r
-               uint8_t StreamCallback_AbortOnMassStoreReset(void);\r
+               bool CALLBACK_USB_MS_SCSICommandReceived(USB_ClassInfo_MS_t* MSInterfaceInfo);\r
 \r
 #endif\r
index 93f8957..c4adfc9 100644 (file)
@@ -127,7 +127,6 @@ SRC = $(TARGET).c                                                 \
          Descriptors.c                                               \\r
          Lib/SCSI.c                                                  \\r
          Lib/DataflashManager.c                                      \\r
-         $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \\r
@@ -138,7 +137,7 @@ SRC = $(TARGET).c                                                 \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \\r
-         $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \\r
+         $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/MassStorage.c    \\r
 \r
 \r
 # List C++ source files here. (C dependencies are automatically generated.)\r
@@ -188,7 +187,6 @@ CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)
 CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY\r
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION\r
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"\r
-CDEFS += -DINTERRUPT_CONTROL_ENDPOINT\r
 \r
 \r
 # Place -D or -U options here for ASM sources\r
index 883ef31..ef3215c 100644 (file)
 #define _DESCRIPTORS_H_\r
 \r
        /* Includes: */\r
-               #include <LUFA/Drivers/USB/USB.h>\r
-\r
                #include <avr/pgmspace.h>\r
 \r
-       /* Type Defines: */\r
-               /** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID\r
-                *  specification for details on the structure elements.\r
-                */\r
-               typedef struct\r
-               {\r
-                       USB_Descriptor_Header_t Header;\r
-                               \r
-                       uint16_t                HIDSpec;\r
-                       uint8_t                 CountryCode;\r
-               \r
-                       uint8_t                 TotalReportDescriptors;\r
-\r
-                       uint8_t                 HIDReportType;\r
-                       uint16_t                HIDReportLength;\r
-               } USB_Descriptor_HID_t;\r
-\r
-               /** Type define for the data type used to store HID report descriptor elements. */\r
-               typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/HID.h>\r
 \r
+       /* Type Defines: */\r
                /** Type define for the device configuration descriptor structure. This must be defined in the\r
                 *  application code, as the configuration descriptor contains several sub-descriptors which\r
                 *  vary between devices, and which describe the device's usage to the host.\r
                /** Size in bytes of the Mouse HID reporting IN endpoint. */\r
                #define MOUSE_EPSIZE              8\r
 \r
-               /** Descriptor header type value, to indicate a HID class HID descriptor. */\r
-               #define DTYPE_HID                 0x21\r
-               \r
-               /** Descriptor header type value, to indicate a HID class HID report descriptor. */\r
-               #define DTYPE_Report              0x22\r
-\r
        /* Function Prototypes: */\r
                uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)\r
                                                                                        ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);\r
index 32b12fc..57c1aa1 100644 (file)
   arising out of or in connection with the use or performance of\r
   this software.\r
 */\r
-\r
-/** \file\r
- *\r
- *  Main source file for the Mouse demo. This file contains the main tasks of the demo and\r
- *  is responsible for the initial application hardware configuration.\r
- */\r
  \r
 #include "Mouse.h"\r
 \r
-/* Scheduler Task List */\r
-TASK_LIST\r
-{\r
-       { .Task = USB_USBTask          , .TaskStatus = TASK_STOP },\r
-       { .Task = USB_Mouse_Report     , .TaskStatus = TASK_STOP },\r
-};\r
+USB_ClassInfo_HID_t Mouse_HID_Interface =\r
+       {\r
+               .InterfaceNumber         = 0,\r
 \r
-/* Global Variables */\r
-/** Indicates what report mode the host has requested, true for normal HID reporting mode, false for special boot\r
- *  protocol reporting mode.\r
- */\r
-bool UsingReportProtocol = true;\r
+               .ReportINEndpointNumber  = MOUSE_EPNUM,\r
+               .ReportINEndpointSize    = MOUSE_EPSIZE,\r
 \r
-/** Current Idle period. This is set by the host via a Set Idle HID class request to silence the device's reports\r
- *  for either the entire idle duration, or until the report status changes (e.g. the user moves the mouse).\r
- */\r
-uint16_t IdleCount = HID_IDLE_CHANGESONLY;\r
+               .ReportBufferSize        = sizeof(USB_MouseReport_Data_t),\r
+       };\r
 \r
-/** Current Idle period remaining. When the IdleCount value is set, this tracks the remaining number of idle\r
- *  milliseconds. This is separate to the IdleCount timer and is incremented and compared as the host may request \r
- *  the current idle period via a Get Idle HID class request, thus its value must be preserved.\r
- */\r
-uint16_t IdleMSRemaining = 0;\r
+int main(void)\r
+{      \r
+       SetupHardware();\r
+       \r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
 \r
+       for (;;)\r
+       {\r
+               USB_HID_USBTask(&Mouse_HID_Interface);\r
+               USB_USBTask();\r
+       }\r
+}\r
 \r
-/** Main program entry point. This routine configures the hardware required by the application, then\r
- *  starts the scheduler to run the application tasks.\r
- */\r
-int main(void)\r
+void SetupHardware(void)\r
 {\r
        /* Disable watchdog if enabled by bootloader/fuses */\r
        MCUSR &= ~(1 << WDRF);\r
@@ -77,284 +66,64 @@ int main(void)
        Joystick_Init();\r
        LEDs_Init();\r
        Buttons_Init();\r
-       \r
-       /* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */\r
-       OCR0A  = 0x7D;\r
-       TCCR0A = (1 << WGM01);\r
-       TCCR0B = ((1 << CS01) | (1 << CS00));\r
-       TIMSK0 = (1 << OCIE0A);\r
-\r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
-       \r
-       /* Initialize Scheduler so that it can be used */\r
-       Scheduler_Init();\r
-\r
-       /* Initialize USB Subsystem */\r
        USB_Init();\r
-\r
-       /* Scheduling - routine never returns, so put this last in the main function */\r
-       Scheduler_Start();\r
 }\r
 \r
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and\r
- *  starts the library USB task to begin the enumeration and USB management process.\r
- */\r
 void EVENT_USB_Connect(void)\r
 {\r
-       /* Start USB management task */\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);\r
-       \r
-       /* Indicate USB enumerating */\r
-       UpdateStatus(Status_USBEnumerating);\r
-\r
-       /* Default to report protocol on connect */\r
-       UsingReportProtocol = true;\r
+       LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);\r
 }\r
 \r
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via\r
- *  the status LEDs and stops the USB management and Mouse reporting tasks.\r
- */\r
 void EVENT_USB_Disconnect(void)\r
 {\r
-       /* Stop running mouse reporting and USB management tasks */\r
-       Scheduler_SetTaskMode(USB_Mouse_Report, TASK_STOP);\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);\r
-\r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
 }\r
 \r
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host sets the current configuration\r
- *  of the USB device after enumeration - the device endpoints are configured and the mouse reporting task started.\r
- */ \r
 void EVENT_USB_ConfigurationChanged(void)\r
 {\r
-       /* Setup Mouse Report Endpoint */\r
-       Endpoint_ConfigureEndpoint(MOUSE_EPNUM, EP_TYPE_INTERRUPT,\r
-                                      ENDPOINT_DIR_IN, MOUSE_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
-\r
-       /* Indicate USB connected and ready */\r
-       UpdateStatus(Status_USBReady);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
 \r
-       /* Start running mouse reporting task */\r
-       Scheduler_SetTaskMode(USB_Mouse_Report, TASK_RUN);\r
+       if (!(USB_HID_ConfigureEndpoints(&Mouse_HID_Interface)))\r
+         LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
 }\r
 \r
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific\r
- *  control requests that are not handled internally by the USB library (including the HID commands, which are\r
- *  all issued via the control endpoint), so that they can be handled appropriately for the application.\r
- */\r
 void EVENT_USB_UnhandledControlPacket(void)\r
 {\r
-       /* Handle HID Class specific requests */\r
-       switch (USB_ControlRequest.bRequest)\r
-       {\r
-               case REQ_GetReport:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               USB_MouseReport_Data_t MouseReportData;\r
-\r
-                               Endpoint_ClearSETUP();\r
-\r
-                               /* Create the next mouse report for transmission to the host */\r
-                               CreateMouseReport(&MouseReportData);\r
-       \r
-                               /* Write the report data to the control endpoint */\r
-                               Endpoint_Write_Control_Stream_LE(&MouseReportData, sizeof(MouseReportData));\r
-                               \r
-                               /* Clear the report data afterwards */\r
-                               memset(&MouseReportData, 0, sizeof(MouseReportData));\r
-\r
-                               /* Finalize the stream transfer to send the last packet or clear the host abort */\r
-                               Endpoint_ClearOUT();\r
-                       }\r
-               \r
-                       break;\r
-               case REQ_GetProtocol:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* Write the current protocol flag to the host */\r
-                               Endpoint_Write_Byte(UsingReportProtocol);\r
-                               \r
-                               /* Send the flag to the host */\r
-                               Endpoint_ClearIN();\r
-\r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsOUTReceived()));\r
-                               Endpoint_ClearOUT();\r
-                       }\r
-                       \r
-                       break;\r
-               case REQ_SetProtocol:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* Set or clear the flag depending on what the host indicates that the current Protocol should be */\r
-                               UsingReportProtocol = (USB_ControlRequest.wValue != 0);\r
-                               \r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsINReady()));\r
-                               Endpoint_ClearIN();\r
-                       }\r
-                       \r
-                       break;\r
-               case REQ_SetIdle:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* Get idle period in MSB */\r
-                               IdleCount = (USB_ControlRequest.wValue >> 8);\r
-                               \r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsINReady()));\r
-                               Endpoint_ClearIN();\r
-                       }\r
-                       \r
-                       break;\r
-               case REQ_GetIdle:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {               \r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* Write the current idle duration to the host */\r
-                               Endpoint_Write_Byte(IdleCount);\r
-                               \r
-                               /* Send the flag to the host */\r
-                               Endpoint_ClearIN();\r
-\r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsOUTReceived()));\r
-                               Endpoint_ClearOUT();\r
-                       }\r
-\r
-                       break;\r
-       }\r
+       USB_HID_ProcessControlPacket(&Mouse_HID_Interface);\r
 }\r
 \r
-/** ISR for the timer 0 compare vector. This ISR fires once each millisecond, and increments the\r
- *  scheduler elapsed idle period counter when the host has set an idle period.\r
- */\r
-ISR(TIMER0_COMPA_vect, ISR_BLOCK)\r
+void EVENT_USB_StartOfFrame(void)\r
 {\r
-       /* One millisecond has elapsed, decrement the idle time remaining counter if it has not already elapsed */\r
-       if (IdleMSRemaining)\r
-         IdleMSRemaining--;\r
+       USB_HID_RegisterStartOfFrame(&Mouse_HID_Interface);\r
 }\r
 \r
-/** Fills the given HID report data structure with the next HID report to send to the host.\r
- *\r
- *  \param ReportData  Pointer to a HID report data structure to be filled\r
- */\r
-void CreateMouseReport(USB_MouseReport_Data_t* ReportData)\r
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)\r
 {\r
+       USB_MouseReport_Data_t* MouseReport = (USB_MouseReport_Data_t*)ReportData;\r
+               \r
        uint8_t JoyStatus_LCL    = Joystick_GetStatus();\r
        uint8_t ButtonStatus_LCL = Buttons_GetStatus();\r
-       \r
-       /* Clear the report contents */\r
-       memset(ReportData, 0, sizeof(USB_MouseReport_Data_t));\r
 \r
        if (JoyStatus_LCL & JOY_UP)\r
-         ReportData->Y = -1;\r
+         MouseReport->Y = -1;\r
        else if (JoyStatus_LCL & JOY_DOWN)\r
-         ReportData->Y =  1;\r
+         MouseReport->Y =  1;\r
 \r
        if (JoyStatus_LCL & JOY_RIGHT)\r
-         ReportData->X =  1;\r
+         MouseReport->X =  1;\r
        else if (JoyStatus_LCL & JOY_LEFT)\r
-         ReportData->X = -1;\r
+         MouseReport->X = -1;\r
 \r
        if (JoyStatus_LCL & JOY_PRESS)\r
-         ReportData->Button  = (1 << 0);\r
+         MouseReport->Button  = (1 << 0);\r
          \r
        if (ButtonStatus_LCL & BUTTONS_BUTTON1)\r
-         ReportData->Button |= (1 << 1);\r
-}\r
-\r
-/** Sends the next HID report to the host, via the keyboard data endpoint. */\r
-void SendNextReport(void)\r
-{\r
-       static USB_MouseReport_Data_t PrevMouseReportData;\r
-       USB_MouseReport_Data_t        MouseReportData;\r
-       bool                          SendReport;\r
-       \r
-       /* Create the next mouse report for transmission to the host */\r
-       CreateMouseReport(&MouseReportData);\r
-       \r
-       /* Check to see if the report data has changed - if so a report MUST be sent */\r
-       SendReport = (memcmp(&PrevMouseReportData, &MouseReportData, sizeof(USB_MouseReport_Data_t)) != 0);\r
-       \r
-       /* Override the check if the Y or X values are non-zero - we want continuous movement while the joystick\r
-        * is being held down (via continuous reports), otherwise the cursor will only move once per joystick toggle */\r
-       if ((MouseReportData.Y != 0) || (MouseReportData.X != 0))\r
-         SendReport = true;\r
-       \r
-       /* Save the current report data for later comparison to check for changes */\r
-       PrevMouseReportData = MouseReportData;\r
-       \r
-       /* Check if the idle period is set and has elapsed */\r
-       if ((IdleCount != HID_IDLE_CHANGESONLY) && (!(IdleMSRemaining)))\r
-       {\r
-               /* Reset the idle time remaining counter, must multiply by 4 to get the duration in milliseconds */\r
-               IdleMSRemaining = (IdleCount << 2);\r
-               \r
-               /* Idle period is set and has elapsed, must send a report to the host */\r
-               SendReport = true;\r
-       }\r
+         MouseReport->Button |= (1 << 1);\r
        \r
-       /* Select the Mouse Report Endpoint */\r
-       Endpoint_SelectEndpoint(MOUSE_EPNUM);\r
-\r
-       /* Check if Mouse Endpoint Ready for Read/Write and if we should send a new report */\r
-       if (Endpoint_IsReadWriteAllowed() && SendReport)\r
-       {\r
-               /* Write Mouse Report Data */\r
-               Endpoint_Write_Stream_LE(&MouseReportData, sizeof(MouseReportData));\r
-               \r
-               /* Finalize the stream transfer to send the last packet */\r
-               Endpoint_ClearIN();\r
-       }\r
+       return sizeof(USB_MouseReport_Data_t);\r
 }\r
 \r
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to\r
- *  log to a serial port, or anything else that is suitable for status updates.\r
- *\r
- *  \param CurrentStatus  Current status of the system, from the Mouse_StatusCodes_t enum\r
- */\r
-void UpdateStatus(uint8_t CurrentStatus)\r
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)\r
 {\r
-       uint8_t LEDMask = LEDS_NO_LEDS;\r
-       \r
-       /* Set the LED mask to the appropriate LED mask based on the given status code */\r
-       switch (CurrentStatus)\r
-       {\r
-               case Status_USBNotReady:\r
-                       LEDMask = (LEDS_LED1);\r
-                       break;\r
-               case Status_USBEnumerating:\r
-                       LEDMask = (LEDS_LED1 | LEDS_LED2);\r
-                       break;\r
-               case Status_USBReady:\r
-                       LEDMask = (LEDS_LED2 | LEDS_LED4);\r
-                       break;\r
-       }\r
-       \r
-       /* Set the board LEDs to the new LED mask */\r
-       LEDs_SetAllLEDs(LEDMask);\r
-}\r
-\r
-/** Task to manage HID report generation and transmission to the host, when in report mode. */\r
-TASK(USB_Mouse_Report)\r
-{\r
-       /* Check if the USB system is connected to a host */\r
-       if (USB_IsConnected)\r
-       {\r
-               /* Send the next mouse report to the host */\r
-               SendNextReport();\r
-       }\r
+       // Unused (but mandatory for the HID class driver) in this demo, since there are no Host->Device reports\r
 }\r
index 65879da..5c80495 100644 (file)
                \r
                #include "Descriptors.h"\r
 \r
-               #include <LUFA/Version.h>                    // Library Version Information\r
-               #include <LUFA/Drivers/USB/USB.h>            // USB Functionality\r
-               #include <LUFA/Drivers/Board/Joystick.h>     // Joystick driver\r
-               #include <LUFA/Drivers/Board/LEDs.h>         // LEDs driver\r
-               #include <LUFA/Drivers/Board/Buttons.h>      // Board Buttons driver\r
-               #include <LUFA/Scheduler/Scheduler.h>        // Simple scheduler for task management\r
-               \r
-       /* Task Definitions: */\r
-               TASK(USB_Mouse_Report);\r
-\r
-       /* Macros: */\r
-               /** Idle period indicating that reports should be sent only when the inputs have changed */\r
-               #define HID_IDLE_CHANGESONLY 0\r
-       \r
-               /** HID Class specific request to get the next HID report from the device. */\r
-               #define REQ_GetReport        0x01\r
-\r
-               /** HID Class specific request to get the idle timeout period of the device. */\r
-               #define REQ_GetIdle          0x02\r
-\r
-               /** HID Class specific request to send the next HID report to the device. */\r
-               #define REQ_SetReport        0x09\r
-\r
-               /** HID Class specific request to set the idle timeout period of the device. */\r
-               #define REQ_SetIdle          0x0A\r
-\r
-               /** HID Class specific request to get the current HID protocol in use, either report or boot. */\r
-               #define REQ_GetProtocol      0x03\r
-\r
-               /** HID Class specific request to set the current HID protocol in use, either report or boot. */\r
-               #define REQ_SetProtocol      0x0B\r
+               #include <LUFA/Version.h>\r
+               #include <LUFA/Drivers/Board/Joystick.h>\r
+               #include <LUFA/Drivers/Board/LEDs.h>\r
+               #include <LUFA/Drivers/Board/Buttons.h>\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/HID.h>\r
 \r
        /* Type Defines: */\r
                /** Type define for the mouse HID report structure, for creating and sending HID reports to the host PC.\r
                        int8_t  Y; /**< Current mouse delta Y movement, as a signed 8-bit integer */\r
                } USB_MouseReport_Data_t;\r
                \r
-       /* Enums: */\r
-               /** Enum for the possible status codes for passing to the UpdateStatus() function. */\r
-               enum Mouse_StatusCodes_t\r
-               {\r
-                       Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */\r
-                       Status_USBEnumerating = 1, /**< USB interface is enumerating */\r
-                       Status_USBReady       = 2, /**< USB interface is connected and ready */\r
-               };\r
+       /* Macros: */\r
+               #define LEDMASK_USB_NOTREADY      LEDS_LED1\r
+               #define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)\r
+               #define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)\r
+               #define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)\r
                        \r
        /* Function Prototypes: */\r
+               void SetupHardware(void);\r
+\r
                void EVENT_USB_Connect(void);\r
                void EVENT_USB_Disconnect(void);\r
                void EVENT_USB_ConfigurationChanged(void);\r
                void EVENT_USB_UnhandledControlPacket(void);\r
+               void EVENT_USB_StartOfFrame(void);\r
 \r
-               void CreateMouseReport(USB_MouseReport_Data_t* ReportData);\r
-               void UpdateStatus(uint8_t CurrentStatus);\r
+               uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);\r
+               void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,\r
+                                                                  void* ReportData, uint16_t ReportSize);\r
 \r
 #endif\r
index 632bf91..4c18f9d 100644 (file)
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)\r
 SRC = $(TARGET).c                                                 \\r
          Descriptors.c                                               \\r
-         $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \\r
@@ -136,7 +135,7 @@ SRC = $(TARGET).c                                                 \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \\r
-         $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \\r
+         $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/HID.c            \\r
  \r
 # List C++ source files here. (C dependencies are automatically generated.)\r
 CPPSRC = \r
@@ -182,7 +181,7 @@ CSTANDARD = -std=gnu99
 \r
 # Place -D or -U options here for C sources\r
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)\r
-CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY\r
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY\r
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION\r
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"\r
 \r
index 8551df8..f05d8f0 100644 (file)
@@ -38,9 +38,7 @@
 \r
        /* Includes: */\r
                #include <avr/io.h>\r
-               #include <string.h>\r
-               \r
-               #include <LUFA/Scheduler/Scheduler.h>\r
+               #include <string.h>
                \r
                #include "EthernetProtocols.h"\r
                #include "Ethernet.h"\r
index 3d34f71..57380a0 100644 (file)
 #include "Ethernet.h"\r
 \r
 /* Global Variables: */\r
-/** Ethernet Frame buffer structure, to hold the incoming Ethernet frame from the host. */\r
-Ethernet_Frame_Info_t FrameIN;\r
-\r
-/** Ethernet Frame buffer structure, to hold the outgoing Ethernet frame to the host. */\r
-Ethernet_Frame_Info_t FrameOUT;\r
-\r
 /** Constant for convenience when checking against or setting a MAC address to the virtual server MAC address. */\r
 const MAC_Address_t ServerMACAddress    = {SERVER_MAC_ADDRESS};\r
 \r
@@ -63,31 +57,31 @@ const IP_Address_t  ClientIPAddress     = {CLIENT_IP_ADDRESS};
 /** Processes an incoming Ethernet frame, and writes the appropriate response to the output Ethernet\r
  *  frame buffer if the sub protocol handlers create a valid response.\r
  */\r
-void Ethernet_ProcessPacket(void)\r
+void Ethernet_ProcessPacket(Ethernet_Frame_Info_t* FrameIN, Ethernet_Frame_Info_t* FrameOUT)\r
 {\r
-       DecodeEthernetFrameHeader(FrameIN.FrameData);\r
+       DecodeEthernetFrameHeader(FrameIN->FrameData);\r
 \r
        /* Cast the incoming Ethernet frame to the Ethernet header type */\r
-       Ethernet_Frame_Header_t* FrameINHeader  = (Ethernet_Frame_Header_t*)&FrameIN.FrameData;\r
-       Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT.FrameData;\r
+       Ethernet_Frame_Header_t* FrameINHeader  = (Ethernet_Frame_Header_t*)&FrameIN->FrameData;\r
+       Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT->FrameData;\r
        \r
        int16_t                  RetSize        = NO_RESPONSE;\r
        \r
        /* Ensure frame is addressed to either all (broadcast) or the virtual webserver, and is a type II frame */\r
        if ((MAC_COMPARE(&FrameINHeader->Destination, &ServerMACAddress) ||\r
-            MAC_COMPARE(&FrameINHeader->Destination, &BroadcastMACAddress)) &&\r
-               (SwapEndian_16(FrameIN.FrameLength) > ETHERNET_VER2_MINSIZE))\r
+            MAC_COMPARE(&FrameINHeader->Destination, &BroadcastMACAddress)))\r
        {\r
                /* Process the packet depending on its protocol */\r
                switch (SwapEndian_16(FrameINHeader->EtherType))\r
                {\r
                        case ETHERTYPE_ARP:\r
-                               RetSize = ARP_ProcessARPPacket(&FrameIN.FrameData[sizeof(Ethernet_Frame_Header_t)],\r
-                                                              &FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)]);\r
+                               RetSize = ARP_ProcessARPPacket(&FrameIN->FrameData[sizeof(Ethernet_Frame_Header_t)],\r
+                                                              &FrameOUT->FrameData[sizeof(Ethernet_Frame_Header_t)]);\r
                                break;          \r
                        case ETHERTYPE_IPV4:\r
-                               RetSize = IP_ProcessIPPacket(&FrameIN.FrameData[sizeof(Ethernet_Frame_Header_t)],\r
-                                                            &FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)]);\r
+                               RetSize = IP_ProcessIPPacket(FrameIN,\r
+                                                            &FrameIN->FrameData[sizeof(Ethernet_Frame_Header_t)],\r
+                                                            &FrameOUT->FrameData[sizeof(Ethernet_Frame_Header_t)]);\r
                                break;\r
                }\r
                \r
@@ -100,8 +94,8 @@ void Ethernet_ProcessPacket(void)
                        FrameOUTHeader->EtherType       = FrameINHeader->EtherType;\r
                        \r
                        /* Set the response length in the buffer and indicate that a response is ready to be sent */\r
-                       FrameOUT.FrameLength            = (sizeof(Ethernet_Frame_Header_t) + RetSize);\r
-                       FrameOUT.FrameInBuffer          = true;\r
+                       FrameOUT->FrameLength           = (sizeof(Ethernet_Frame_Header_t) + RetSize);\r
+                       FrameOUT->FrameInBuffer         = true;\r
                }\r
        }\r
 \r
@@ -109,7 +103,7 @@ void Ethernet_ProcessPacket(void)
        if (RetSize != NO_PROCESS)\r
        {\r
                /* Clear the frame buffer */\r
-               FrameIN.FrameInBuffer = false;\r
+               FrameIN->FrameInBuffer = false;\r
        }\r
 }\r
 \r
index b360f07..b300252 100644 (file)
@@ -39,6 +39,8 @@
        /* Includes: */\r
                #include <avr/io.h>\r
                #include <string.h>\r
+               \r
+               #include <LUFA/Drivers/USB/Class/Device/RNDIS.h>\r
 \r
                #include "EthernetProtocols.h"\r
                #include "ProtocolDecoders.h"\r
@@ -50,6 +52,9 @@
                #include "IP.h"\r
                \r
        /* Macros: */\r
+               /** Physical MAC address of the USB RNDIS network adapter */\r
+               #define ADAPTER_MAC_ADDRESS              {0x00, 0x02, 0x00, 0x02, 0x00, 0x02}           \r
+\r
                /** Physical MAC address of the virtual server on the network */\r
                #define SERVER_MAC_ADDRESS               {0x00, 0x01, 0x00, 0x01, 0x00, 0x01}           \r
 \r
                 *  \return True if the addresses match, false otherwise\r
                 */\r
                #define MAC_COMPARE(MAC1, MAC2)          (memcmp(MAC1, MAC2, sizeof(MAC_Address_t)) == 0)\r
-\r
-               /** Maximum size of an incoming or outgoing Ethernet frame in bytes */\r
-               #define ETHERNET_FRAME_SIZE_MAX          1500\r
-               \r
-               /** Minimum size of an Ethernet packet in bytes, to conform to the Ethernet V2 packet standard */\r
-               #define ETHERNET_VER2_MINSIZE            0x0600\r
                \r
                /** Return value for all sub protocol handling routines, indicating that no response packet has been generated */\r
                #define NO_RESPONSE                      0              \r
                #define NO_PROCESS                       -1\r
 \r
        /* Type Defines: */\r
-               /** Type define for an Ethernet frame buffer. */\r
-               typedef struct\r
-               {\r
-                       uint8_t       FrameData[ETHERNET_FRAME_SIZE_MAX]; /**< Ethernet frame contents */\r
-                       uint16_t      FrameLength; /**< Length in bytes of the Ethernet frame stored in the buffer */\r
-                       bool          FrameInBuffer; /**< Indicates if a frame is currently stored in the buffer */\r
-               } Ethernet_Frame_Info_t;\r
-\r
                /** Type define for an Ethernet frame header */\r
                typedef struct\r
                {\r
                } Ethernet_Frame_Header_t;\r
                \r
        /* External Variables: */\r
-               extern Ethernet_Frame_Info_t FrameIN;\r
-               extern Ethernet_Frame_Info_t FrameOUT;\r
-\r
                extern const MAC_Address_t ServerMACAddress;\r
                extern const IP_Address_t  ServerIPAddress;\r
                extern const MAC_Address_t BroadcastMACAddress;\r
                extern const IP_Address_t  ClientIPAddress;\r
                \r
        /* Function Prototypes: */\r
-               void     Ethernet_ProcessPacket(void);\r
+               void     Ethernet_ProcessPacket(Ethernet_Frame_Info_t* FrameIN, Ethernet_Frame_Info_t* FrameOUT);\r
                uint16_t Ethernet_Checksum16(void* Data, uint16_t Bytes);\r
                \r
 #endif\r
index 3ff3433..1ec5961 100644 (file)
                #define PROTOCOL_OSPF                    89\r
                #define PROTOCOL_SCTP                    132\r
 \r
-       /* Type Defines: */\r
-               /** Type define for a physical MAC address of a device on a network */\r
-               typedef struct\r
-               {\r
-                       uint8_t       Octets[6]; /**< Individual bytes of a MAC address */\r
-               } MAC_Address_t;\r
-               \r
+       /* Type Defines: */             \r
                /** Type define for a protocol IP address of a device on a network */\r
                typedef struct\r
                {\r
index da4ffcf..ba6e1db 100644 (file)
@@ -45,7 +45,7 @@
  *\r
  *  \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise\r
  */\r
-int16_t ICMP_ProcessICMPPacket(void* InDataStart, void* OutDataStart)\r
+int16_t ICMP_ProcessICMPPacket(Ethernet_Frame_Info_t* FrameIN, void* InDataStart, void* OutDataStart)\r
 {\r
        ICMP_Header_t* ICMPHeaderIN  = (ICMP_Header_t*)InDataStart;\r
        ICMP_Header_t* ICMPHeaderOUT = (ICMP_Header_t*)OutDataStart;\r
@@ -62,7 +62,7 @@ int16_t ICMP_ProcessICMPPacket(void* InDataStart, void* OutDataStart)
                ICMPHeaderOUT->Id       = ICMPHeaderIN->Id;\r
                ICMPHeaderOUT->Sequence = ICMPHeaderIN->Sequence;\r
                \r
-               uint16_t DataSize = FrameIN.FrameLength - ((((uint16_t)InDataStart + sizeof(ICMP_Header_t)) - (uint16_t)FrameIN.FrameData));\r
+               uint16_t DataSize = FrameIN->FrameLength - ((((uint16_t)InDataStart + sizeof(ICMP_Header_t)) - (uint16_t)FrameIN->FrameData));\r
                \r
                /* Copy the remaining payload to the response - echo requests should echo back any sent data */\r
                memcpy(&((uint8_t*)OutDataStart)[sizeof(ICMP_Header_t)],\r
index b20a557..56749c0 100644 (file)
@@ -75,6 +75,6 @@
                } ICMP_Header_t;\r
                \r
        /* Function Prototypes: */\r
-               int16_t ICMP_ProcessICMPPacket(void* InDataStart, void* OutDataStart);\r
+               int16_t ICMP_ProcessICMPPacket(Ethernet_Frame_Info_t* FrameIN, void* InDataStart, void* OutDataStart);\r
 \r
 #endif\r
index 8fb0b44..0850045 100644 (file)
@@ -46,7 +46,7 @@
  *           response was generated, NO_PROCESS if the packet processing was deferred until the\r
  *           next Ethernet packet handler iteration\r
  */\r
-int16_t IP_ProcessIPPacket(void* InDataStart, void* OutDataStart)\r
+int16_t IP_ProcessIPPacket(Ethernet_Frame_Info_t* FrameIN, void* InDataStart, void* OutDataStart)\r
 {\r
        DecodeIPHeader(InDataStart);\r
 \r
@@ -69,7 +69,8 @@ int16_t IP_ProcessIPPacket(void* InDataStart, void* OutDataStart)
        switch (IPHeaderIN->Protocol)\r
        {\r
                case PROTOCOL_ICMP:\r
-                       RetSize = ICMP_ProcessICMPPacket(&((uint8_t*)InDataStart)[HeaderLengthBytes],\r
+                       RetSize = ICMP_ProcessICMPPacket(FrameIN,\r
+                                                        &((uint8_t*)InDataStart)[HeaderLengthBytes],\r
                                                         &((uint8_t*)OutDataStart)[sizeof(IP_Header_t)]);\r
                        break;\r
                case PROTOCOL_TCP:\r
index fc1a46a..f77c772 100644 (file)
@@ -88,6 +88,6 @@
                } IP_Header_t;\r
                \r
        /* Function Prototypes: */\r
-               int16_t IP_ProcessIPPacket(void* InDataStart, void* OutDataStart);\r
+               int16_t IP_ProcessIPPacket(Ethernet_Frame_Info_t* FrameIN, void* InDataStart, void* OutDataStart);\r
 \r
 #endif\r
diff --git a/Demos/Device/RNDISEthernet/Lib/RNDIS.c b/Demos/Device/RNDISEthernet/Lib/RNDIS.c
deleted file mode 100644 (file)
index c5202bc..0000000
+++ /dev/null
@@ -1,394 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  RNDIS command handler functions. This handles RNDIS commands according to\r
- *  the Microsoft RNDIS specification, creating a USB Ethernet network adapter.\r
- */\r
\r
-#define  INCLUDE_FROM_RNDIS_C\r
-#include "RNDIS.h"\r
-\r
-/* Global Variables: */\r
-/** Physical MAC address of the network adapter, which becomes the MAC address of the host for packets sent to the adapter. */\r
-static MAC_Address_t  PROGMEM AdapterMACAddress          = {ADAPTER_MAC_ADDRESS};\r
-\r
-/** Vendor description of the adapter. This is overridden by the INF file required to install the appropriate RNDIS drivers for\r
- *  the device, but may still be used by the OS in some circumstances.\r
- */\r
-static char           PROGMEM AdapterVendorDescription[] = "LUFA RNDIS Adapter";\r
-\r
-/** List of RNDIS OID commands supported by this adapter. */\r
-static const uint32_t PROGMEM AdapterSupportedOIDList[]  =\r
-                                                       {\r
-                                                               OID_GEN_SUPPORTED_LIST,\r
-                                                               OID_GEN_PHYSICAL_MEDIUM,\r
-                                                               OID_GEN_HARDWARE_STATUS,\r
-                                                               OID_GEN_MEDIA_SUPPORTED,\r
-                                                               OID_GEN_MEDIA_IN_USE,\r
-                                                               OID_GEN_MAXIMUM_FRAME_SIZE,\r
-                                                               OID_GEN_MAXIMUM_TOTAL_SIZE,\r
-                                                               OID_GEN_LINK_SPEED,\r
-                                                               OID_GEN_TRANSMIT_BLOCK_SIZE,\r
-                                                               OID_GEN_RECEIVE_BLOCK_SIZE,\r
-                                                               OID_GEN_VENDOR_ID,\r
-                                                               OID_GEN_VENDOR_DESCRIPTION,\r
-                                                               OID_GEN_CURRENT_PACKET_FILTER,\r
-                                                               OID_GEN_MAXIMUM_TOTAL_SIZE,\r
-                                                               OID_GEN_MEDIA_CONNECT_STATUS,\r
-                                                               OID_GEN_XMIT_OK,\r
-                                                               OID_GEN_RCV_OK,\r
-                                                               OID_GEN_XMIT_ERROR,\r
-                                                               OID_GEN_RCV_ERROR,\r
-                                                               OID_GEN_RCV_NO_BUFFER,\r
-                                                               OID_802_3_PERMANENT_ADDRESS,\r
-                                                               OID_802_3_CURRENT_ADDRESS,\r
-                                                               OID_802_3_MULTICAST_LIST,\r
-                                                               OID_802_3_MAXIMUM_LIST_SIZE,\r
-                                                               OID_802_3_RCV_ERROR_ALIGNMENT,\r
-                                                               OID_802_3_XMIT_ONE_COLLISION,\r
-                                                               OID_802_3_XMIT_MORE_COLLISIONS,\r
-                                                       };\r
-\r
-/** Buffer for RNDIS messages (as distinct from Ethernet frames sent through the adapter. This must be big enough to hold the entire\r
- *  Supported OID list, plus the response header. The buffer is half-duplex, and is written to as it is read to save on SRAM - for this\r
- *  reason, care must be taken when constructing RNDIS responses that unread data is not overwritten when writing in responses.\r
- */\r
-uint8_t                 RNDISMessageBuffer[sizeof(AdapterSupportedOIDList) + sizeof(RNDIS_QUERY_CMPLT_t)];\r
-\r
-/** Pointer to the RNDIS message header at the top of the RNDIS message buffer, for convenience. */\r
-RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISMessageBuffer;\r
-\r
-/** Indicates if a RNDIS message response is ready to be sent back to the host. */\r
-bool                    ResponseReady               = false;\r
-\r
-/** Current RNDIS adapter state, a value from the RNDIS_States_t enum. */\r
-uint8_t                 CurrRNDISState              = RNDIS_Uninitialized;\r
-\r
-/** Current Ethernet packet filter mask. This is non-zero when the adapter is initialized, or zero when disabled. */\r
-uint32_t                CurrPacketFilter            = 0;                                                       \r
-\r
-\r
-/** Processes the RNDIS message received by the host and stored in the RNDISMessageBuffer global buffer. If a response is\r
- *  created, the ResponseReady global is updated so that the response is written back to the host upon request.\r
- */\r
-void ProcessRNDISControlMessage(void)\r
-{\r
-       /* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of\r
-                this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */\r
-\r
-       switch (MessageHeader->MessageType)\r
-       {\r
-               case REMOTE_NDIS_INITIALIZE_MSG:\r
-                       /* Initialize the adapter - return information about the supported RNDIS version and buffer sizes */\r
-\r
-                       ResponseReady = true;\r
-                       \r
-                       RNDIS_INITIALIZE_MSG_t*   INITIALIZE_Message  = (RNDIS_INITIALIZE_MSG_t*)&RNDISMessageBuffer;\r
-                       RNDIS_INITIALIZE_CMPLT_t* INITIALIZE_Response = (RNDIS_INITIALIZE_CMPLT_t*)&RNDISMessageBuffer;\r
-                       \r
-                       INITIALIZE_Response->MessageType           = REMOTE_NDIS_INITIALIZE_CMPLT;\r
-                       INITIALIZE_Response->MessageLength         = sizeof(RNDIS_INITIALIZE_CMPLT_t);\r
-                       INITIALIZE_Response->RequestId             = INITIALIZE_Message->RequestId;\r
-                       INITIALIZE_Response->Status                = REMOTE_NDIS_STATUS_SUCCESS;\r
-                       \r
-                       INITIALIZE_Response->MajorVersion          = REMOTE_NDIS_VERSION_MAJOR;\r
-                       INITIALIZE_Response->MinorVersion          = REMOTE_NDIS_VERSION_MINOR;                 \r
-                       INITIALIZE_Response->DeviceFlags           = REMOTE_NDIS_DF_CONNECTIONLESS;\r
-                       INITIALIZE_Response->Medium                = REMOTE_NDIS_MEDIUM_802_3;\r
-                       INITIALIZE_Response->MaxPacketsPerTransfer = 1;\r
-                       INITIALIZE_Response->MaxTransferSize       = (sizeof(RNDIS_PACKET_MSG_t) + ETHERNET_FRAME_SIZE_MAX);\r
-                       INITIALIZE_Response->PacketAlignmentFactor = 0;\r
-                       INITIALIZE_Response->AFListOffset          = 0;\r
-                       INITIALIZE_Response->AFListSize            = 0;\r
-                       \r
-                       CurrRNDISState = RNDIS_Initialized;\r
-               \r
-                       break;\r
-               case REMOTE_NDIS_HALT_MSG:\r
-                       /* Halt the adapter, reset the adapter state - note that no response should be returned when completed */\r
-\r
-                       ResponseReady = false;\r
-                       MessageHeader->MessageLength = 0;\r
-\r
-                       CurrRNDISState = RNDIS_Uninitialized;\r
-\r
-                       break;\r
-               case REMOTE_NDIS_QUERY_MSG:\r
-                       /* Request for information about a parameter about the adapter, specified as an OID token */\r
-\r
-                       ResponseReady = true;\r
-                                               \r
-                       RNDIS_QUERY_MSG_t*   QUERY_Message  = (RNDIS_QUERY_MSG_t*)&RNDISMessageBuffer;\r
-                       RNDIS_QUERY_CMPLT_t* QUERY_Response = (RNDIS_QUERY_CMPLT_t*)&RNDISMessageBuffer;\r
-                       uint32_t             Query_Oid      = QUERY_Message->Oid;\r
-                                               \r
-                       void*     QueryData                 = &RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +\r
-                                                                                 QUERY_Message->InformationBufferOffset];\r
-                       void*     ResponseData              = &RNDISMessageBuffer[sizeof(RNDIS_QUERY_CMPLT_t)];         \r
-                       uint16_t  ResponseSize;\r
-\r
-                       QUERY_Response->MessageType         = REMOTE_NDIS_QUERY_CMPLT;\r
-                       QUERY_Response->MessageLength       = sizeof(RNDIS_QUERY_CMPLT_t);\r
-                                               \r
-                       if (ProcessNDISQuery(Query_Oid, QueryData, QUERY_Message->InformationBufferLength,\r
-                                            ResponseData, &ResponseSize))\r
-                       {\r
-                               QUERY_Response->Status                  = REMOTE_NDIS_STATUS_SUCCESS;\r
-                               QUERY_Response->MessageLength          += ResponseSize;\r
-                                                       \r
-                               QUERY_Response->InformationBufferLength = ResponseSize;\r
-                               QUERY_Response->InformationBufferOffset = (sizeof(RNDIS_QUERY_CMPLT_t) - sizeof(RNDIS_Message_Header_t));\r
-                       }\r
-                       else\r
-                       {                               \r
-                               QUERY_Response->Status                  = REMOTE_NDIS_STATUS_NOT_SUPPORTED;\r
-\r
-                               QUERY_Response->InformationBufferLength = 0;\r
-                               QUERY_Response->InformationBufferOffset = 0;\r
-                       }\r
-                       \r
-                       break;\r
-               case REMOTE_NDIS_SET_MSG:\r
-                       /* Request to set a parameter of the adapter, specified as an OID token */\r
-               \r
-                       ResponseReady = true;\r
-                       \r
-                       RNDIS_SET_MSG_t*   SET_Message  = (RNDIS_SET_MSG_t*)&RNDISMessageBuffer;\r
-                       RNDIS_SET_CMPLT_t* SET_Response = (RNDIS_SET_CMPLT_t*)&RNDISMessageBuffer;\r
-                       uint32_t           SET_Oid      = SET_Message->Oid;\r
-\r
-                       SET_Response->MessageType       = REMOTE_NDIS_SET_CMPLT;\r
-                       SET_Response->MessageLength     = sizeof(RNDIS_SET_CMPLT_t);\r
-                       SET_Response->RequestId         = SET_Message->RequestId;\r
-\r
-                       void* SetData                   = &RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +\r
-                                                                             SET_Message->InformationBufferOffset];\r
-                                               \r
-                       if (ProcessNDISSet(SET_Oid, SetData, SET_Message->InformationBufferLength))\r
-                         SET_Response->Status        = REMOTE_NDIS_STATUS_SUCCESS;\r
-                       else\r
-                         SET_Response->Status        = REMOTE_NDIS_STATUS_NOT_SUPPORTED;\r
-\r
-                       break;\r
-               case REMOTE_NDIS_RESET_MSG:\r
-                       /* Soft reset the adapter */\r
-               \r
-                       ResponseReady = true;\r
-                       \r
-                       RNDIS_RESET_CMPLT_t* RESET_Response = (RNDIS_RESET_CMPLT_t*)&RNDISMessageBuffer;\r
-\r
-                       RESET_Response->MessageType         = REMOTE_NDIS_RESET_CMPLT;\r
-                       RESET_Response->MessageLength       = sizeof(RNDIS_RESET_CMPLT_t);\r
-                       RESET_Response->Status              = REMOTE_NDIS_STATUS_SUCCESS;\r
-                       RESET_Response->AddressingReset     = 0;\r
-\r
-                       break;\r
-               case REMOTE_NDIS_KEEPALIVE_MSG:\r
-                       /* Keep alive message sent to the adapter every 5 seconds when idle to ensure it is still responding */\r
-               \r
-                       ResponseReady = true;\r
-                       \r
-                       RNDIS_KEEPALIVE_MSG_t*   KEEPALIVE_Message  = (RNDIS_KEEPALIVE_MSG_t*)&RNDISMessageBuffer;\r
-                       RNDIS_KEEPALIVE_CMPLT_t* KEEPALIVE_Response = (RNDIS_KEEPALIVE_CMPLT_t*)&RNDISMessageBuffer;\r
-\r
-                       KEEPALIVE_Response->MessageType     = REMOTE_NDIS_KEEPALIVE_CMPLT;\r
-                       KEEPALIVE_Response->MessageLength   = sizeof(RNDIS_KEEPALIVE_CMPLT_t);\r
-                       KEEPALIVE_Response->RequestId       = KEEPALIVE_Message->RequestId;\r
-                       KEEPALIVE_Response->Status          = REMOTE_NDIS_STATUS_SUCCESS;\r
-                       \r
-                       break;\r
-       }\r
-}\r
-\r
-/** Processes RNDIS query commands, retrieving information from the adapter and reporting it back to the host. The requested\r
- *  parameter is given as an OID value.\r
- *\r
- *  \param OId           OId value of the parameter being queried\r
- *  \param QueryData     Pointer to any extra query data being sent by the host to the device inside the RNDIS message buffer\r
- *  \param QuerySize     Size in bytes of the extra query data being sent by the host\r
- *  \param ResponseData  Pointer to the start of the query response inside the RNDIS message buffer\r
- *  \param ResponseSize  Pointer to the size in bytes of the response data being sent to the host\r
- *\r
- *  \return Boolean true if the query was handled, false otherwise\r
- */\r
-static bool ProcessNDISQuery(uint32_t OId, void* QueryData, uint16_t QuerySize,\r
-                             void* ResponseData, uint16_t* ResponseSize)\r
-{\r
-       /* Handler for REMOTE_NDIS_QUERY_MSG messages */\r
-\r
-       switch (OId)\r
-       {\r
-               case OID_GEN_SUPPORTED_LIST:\r
-                       *ResponseSize = sizeof(AdapterSupportedOIDList);\r
-                       \r
-                       /* Copy the list of supported NDIS OID tokens to the response buffer */\r
-                       memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList));\r
-                       \r
-                       return true;\r
-               case OID_GEN_PHYSICAL_MEDIUM:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Indicate that the device is a true ethernet link */\r
-                       *((uint32_t*)ResponseData) = 0;\r
-                       \r
-                       return true;\r
-               case OID_GEN_HARDWARE_STATUS:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Always indicate hardware ready */\r
-                       *((uint32_t*)ResponseData) = NdisHardwareStatusReady;\r
-                       \r
-                       return true;\r
-               case OID_GEN_MEDIA_SUPPORTED:\r
-               case OID_GEN_MEDIA_IN_USE:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Indicate 802.3 (Ethernet) supported by the adapter */\r
-                       *((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIUM_802_3;\r
-                       \r
-                       return true;\r
-               case OID_GEN_VENDOR_ID:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */\r
-                       *((uint32_t*)ResponseData) = 0x00FFFFFF;\r
-                       \r
-                       return true;\r
-               case OID_GEN_MAXIMUM_FRAME_SIZE:\r
-               case OID_GEN_TRANSMIT_BLOCK_SIZE:\r
-               case OID_GEN_RECEIVE_BLOCK_SIZE:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Indicate that the maximum frame size is the size of the ethernet frame buffer */\r
-                       *((uint32_t*)ResponseData) = ETHERNET_FRAME_SIZE_MAX;\r
-                       \r
-                       return true;\r
-               case OID_GEN_VENDOR_DESCRIPTION:\r
-                       *ResponseSize = sizeof(AdapterVendorDescription);\r
-                       \r
-                       /* Copy vendor description string to the response buffer */\r
-                       memcpy_P(ResponseData, AdapterVendorDescription, sizeof(AdapterVendorDescription));\r
-                       \r
-                       return true;\r
-               case OID_GEN_MEDIA_CONNECT_STATUS:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Always indicate that the adapter is connected to a network */\r
-                       *((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIA_STATE_CONNECTED;\r
-                       \r
-                       return true;\r
-               case OID_GEN_LINK_SPEED:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Indicate 10Mb/s link speed */\r
-                       *((uint32_t*)ResponseData) = 100000;\r
-\r
-                       return true;\r
-               case OID_802_3_PERMANENT_ADDRESS:\r
-               case OID_802_3_CURRENT_ADDRESS:\r
-                       *ResponseSize = sizeof(MAC_Address_t);\r
-                       \r
-                       /* Copy over the fixed adapter MAC to the response buffer */\r
-                       memcpy_P(ResponseData, &AdapterMACAddress, sizeof(MAC_Address_t));\r
-\r
-                       return true;\r
-               case OID_802_3_MAXIMUM_LIST_SIZE:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Indicate only one multicast address supported */\r
-                       *((uint32_t*)ResponseData) = 1;\r
-               \r
-                       return true;\r
-               case OID_GEN_CURRENT_PACKET_FILTER:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Indicate the current packet filter mask */\r
-                       *((uint32_t*)ResponseData) = CurrPacketFilter;\r
-               \r
-                       return true;                    \r
-               case OID_GEN_XMIT_OK:\r
-               case OID_GEN_RCV_OK:\r
-               case OID_GEN_XMIT_ERROR:\r
-               case OID_GEN_RCV_ERROR:\r
-               case OID_GEN_RCV_NO_BUFFER:\r
-               case OID_802_3_RCV_ERROR_ALIGNMENT:\r
-               case OID_802_3_XMIT_ONE_COLLISION:\r
-               case OID_802_3_XMIT_MORE_COLLISIONS:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Unused statistic OIDs - always return 0 for each */\r
-                       *((uint32_t*)ResponseData) = 0;\r
-               \r
-                       return true;\r
-               case OID_GEN_MAXIMUM_TOTAL_SIZE:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */\r
-                       *((uint32_t*)ResponseData) = (sizeof(RNDISMessageBuffer) + ETHERNET_FRAME_SIZE_MAX);\r
-               \r
-                       return true;\r
-               default:\r
-                       return false;\r
-       }\r
-}\r
-\r
-/** Processes RNDIS set commands, setting adapter parameters to values given by the host. The requested parameter is given \r
- *  as an OID value.\r
- *\r
- *  \param OId      OId value of the parameter being set\r
- *  \param SetData  Pointer to the parameter value in the RNDIS message buffer\r
- *  \param SetSize  Size in bytes of the parameter value being sent by the host\r
- *\r
- *  \return Boolean true if the set was handled, false otherwise\r
- */\r
-static bool ProcessNDISSet(uint32_t OId, void* SetData, uint16_t SetSize)\r
-{\r
-       /* Handler for REMOTE_NDIS_SET_MSG messages */\r
-\r
-       switch (OId)\r
-       {\r
-               case OID_GEN_CURRENT_PACKET_FILTER:\r
-                       /* Save the packet filter mask in case the host queries it again later */\r
-                       CurrPacketFilter = *((uint32_t*)SetData);\r
-               \r
-                       /* Set the RNDIS state to initialized if the packet filter is non-zero */\r
-                       CurrRNDISState = ((CurrPacketFilter) ? RNDIS_Data_Initialized : RNDIS_Data_Initialized);\r
-                       \r
-                       return true;\r
-               case OID_802_3_MULTICAST_LIST:\r
-                       /* Do nothing - throw away the value from the host as it is unused */\r
-               \r
-                       return true;\r
-               default:\r
-                       return false;\r
-       }\r
-}\r
diff --git a/Demos/Device/RNDISEthernet/Lib/RNDIS.h b/Demos/Device/RNDISEthernet/Lib/RNDIS.h
deleted file mode 100644 (file)
index 88c9a9e..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Header file for RNDIS.c.\r
- */\r
-\r
-#ifndef _RNDIS_H_\r
-#define _RNDIS_H_\r
-\r
-       /* Includes: */\r
-               #include <avr/io.h>\r
-               #include <stdbool.h>\r
-               \r
-               #include "RNDISEthernet.h"\r
-               #include "RNDISConstants.h"\r
-               #include "Ethernet.h"\r
-\r
-       /* Macros: */\r
-               /** Physical MAC Address of the USB network adapter */\r
-               #define ADAPTER_MAC_ADDRESS                   {0x02, 0x00, 0x02, 0x00, 0x02, 0x00}\r
-       \r
-               /** Implemented RNDIS Version Major */\r
-               #define REMOTE_NDIS_VERSION_MAJOR             0x01\r
-\r
-               /** Implemented RNDIS Version Minor */\r
-               #define REMOTE_NDIS_VERSION_MINOR             0x00\r
-       \r
-               /** RNDIS request to issue a host-to-device NDIS command */\r
-               #define REQ_SendEncapsulatedCommand           0x00\r
-\r
-               /** RNDIS request to issue a device-to-host NDIS response */\r
-               #define REQ_GetEncapsulatedResponse           0x01\r
-               \r
-       /* Enums: */\r
-               /** Enum for the possible NDIS adapter states. */\r
-               enum RNDIS_States_t\r
-               {\r
-                       RNDIS_Uninitialized    = 0, /**< Adapter currently uninitialized */\r
-                       RNDIS_Initialized      = 1, /**< Adapter currently initialized but not ready for data transfers */\r
-                       RNDIS_Data_Initialized = 2, /**< Adapter currently initialized and ready for data transfers */\r
-               };\r
-\r
-               /** Enum for the NDIS hardware states */\r
-               enum NDIS_Hardware_Status_t\r
-               {\r
-                       NdisHardwareStatusReady, /**< Hardware Ready to accept commands from the host */\r
-                       NdisHardwareStatusInitializing, /**< Hardware busy initializing */\r
-                       NdisHardwareStatusReset, /**< Hardware reset */\r
-                       NdisHardwareStatusClosing, /**< Hardware currently closing */\r
-                       NdisHardwareStatusNotReady /**< Hardware not ready to accept commands from the host */\r
-               };\r
-\r
-       /* Type Defines: */\r
-               /** Type define for a RNDIS message header, sent before RNDIS messages */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType; /**< RNDIS message type, a REMOTE_NDIS_*_MSG constant */\r
-                       uint32_t MessageLength; /**< Total length of the RNDIS message, in bytes */\r
-               } RNDIS_Message_Header_t;\r
-\r
-               /** Type define for a RNDIS packet message, used to encapsulate Ethernet packets sent to and from the adapter */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType;\r
-                       uint32_t MessageLength;\r
-                       uint32_t DataOffset;\r
-                       uint32_t DataLength;\r
-                       uint32_t OOBDataOffset;\r
-                       uint32_t OOBDataLength;\r
-                       uint32_t NumOOBDataElements;\r
-                       uint32_t PerPacketInfoOffset;\r
-                       uint32_t PerPacketInfoLength;\r
-                       uint32_t VcHandle;\r
-                       uint32_t Reserved;\r
-               } RNDIS_PACKET_MSG_t;\r
-       \r
-               /** Type define for a RNDIS Initialize command message */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType;\r
-                       uint32_t MessageLength;\r
-                       uint32_t RequestId;\r
-                       \r
-                       uint32_t MajorVersion;\r
-                       uint32_t MinorVersion;\r
-                       uint32_t MaxTransferSize;\r
-               } RNDIS_INITIALIZE_MSG_t;\r
-               \r
-               /** Type define for a RNDIS Initialize complete response message */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType;\r
-                       uint32_t MessageLength;\r
-                       uint32_t RequestId;\r
-                       uint32_t Status;\r
-                       \r
-                       uint32_t MajorVersion;\r
-                       uint32_t MinorVersion;\r
-                       uint32_t DeviceFlags;\r
-                       uint32_t Medium;\r
-                       uint32_t MaxPacketsPerTransfer;\r
-                       uint32_t MaxTransferSize;\r
-                       uint32_t PacketAlignmentFactor;\r
-                       uint32_t AFListOffset;\r
-                       uint32_t AFListSize;\r
-               } RNDIS_INITIALIZE_CMPLT_t;\r
-               \r
-               /** Type define for a RNDIS Keepalive command message */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType;\r
-                       uint32_t MessageLength;\r
-                       uint32_t RequestId;\r
-               } RNDIS_KEEPALIVE_MSG_t;\r
-\r
-               /** Type define for a RNDIS Keepalive complete message */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType;\r
-                       uint32_t MessageLength;\r
-                       uint32_t RequestId;\r
-                       uint32_t Status;\r
-               } RNDIS_KEEPALIVE_CMPLT_t;\r
-\r
-               /** Type define for a RNDIS Reset complete message */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType;\r
-                       uint32_t MessageLength;\r
-                       uint32_t Status;\r
-\r
-                       uint32_t AddressingReset;\r
-               } RNDIS_RESET_CMPLT_t;\r
-               \r
-               /** Type define for a RNDIS Set command message */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType;\r
-                       uint32_t MessageLength;\r
-                       uint32_t RequestId;\r
-                       \r
-                       uint32_t Oid;\r
-                       uint32_t InformationBufferLength;\r
-                       uint32_t InformationBufferOffset;\r
-                       uint32_t DeviceVcHandle;\r
-               } RNDIS_SET_MSG_t;\r
-\r
-               /** Type define for a RNDIS Set complete response message */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType;\r
-                       uint32_t MessageLength;\r
-                       uint32_t RequestId;\r
-                       uint32_t Status;\r
-               } RNDIS_SET_CMPLT_t;\r
-               \r
-               /** Type define for a RNDIS Query command message */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType;\r
-                       uint32_t MessageLength;\r
-                       uint32_t RequestId;\r
-                       \r
-                       uint32_t Oid;\r
-                       uint32_t InformationBufferLength;\r
-                       uint32_t InformationBufferOffset;\r
-                       uint32_t DeviceVcHandle;\r
-               } RNDIS_QUERY_MSG_t;\r
-               \r
-               /** Type define for a RNDIS Query complete response message */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType;\r
-                       uint32_t MessageLength;\r
-                       uint32_t RequestId;\r
-                       uint32_t Status;\r
-                       \r
-                       uint32_t InformationBufferLength;\r
-                       uint32_t InformationBufferOffset;\r
-               } RNDIS_QUERY_CMPLT_t;\r
-               \r
-       /* External Variables: */\r
-               extern uint8_t                 RNDISMessageBuffer[];\r
-               extern RNDIS_Message_Header_t* MessageHeader;\r
-               extern bool                    ResponseReady;\r
-               extern uint8_t                 CurrRNDISState;\r
-\r
-       /* Function Prototypes: */\r
-               void ProcessRNDISControlMessage(void);\r
-\r
-               #if defined(INCLUDE_FROM_RNDIS_C)\r
-                       static bool ProcessNDISQuery(uint32_t OId, void* QueryData, uint16_t QuerySize,\r
-                                                                                void* ResponseData, uint16_t* ResponseSize);\r
-                       static bool ProcessNDISSet(uint32_t OId, void* SetData, uint16_t SetSize);      \r
-               #endif\r
-               \r
-#endif\r
diff --git a/Demos/Device/RNDISEthernet/Lib/RNDISConstants.h b/Demos/Device/RNDISEthernet/Lib/RNDISConstants.h
deleted file mode 100644 (file)
index ad66f62..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  RNDIS specification related constants. For more information on these\r
- *  constants, please refer to the Microsoft RNDIS specification.\r
- */\r
\r
-#ifndef _RNDIS_CONSTANTS_H_\r
-#define _RNDIS_CONSTANTS_H_\r
-\r
-       /* Macros: */\r
-               #define REMOTE_NDIS_PACKET_MSG                0x00000001UL\r
-               #define REMOTE_NDIS_INITIALIZE_MSG            0x00000002UL\r
-               #define REMOTE_NDIS_HALT_MSG                  0x00000003UL\r
-               #define REMOTE_NDIS_QUERY_MSG                 0x00000004UL\r
-               #define REMOTE_NDIS_SET_MSG                   0x00000005UL\r
-               #define REMOTE_NDIS_RESET_MSG                 0x00000006UL\r
-               #define REMOTE_NDIS_INDICATE_STATUS_MSG       0x00000007UL\r
-               #define REMOTE_NDIS_KEEPALIVE_MSG             0x00000008UL\r
-\r
-               #define REMOTE_NDIS_INITIALIZE_CMPLT          0x80000002UL\r
-               #define REMOTE_NDIS_QUERY_CMPLT               0x80000004UL\r
-               #define REMOTE_NDIS_SET_CMPLT                 0x80000005UL\r
-               #define REMOTE_NDIS_RESET_CMPLT               0x80000006UL\r
-               #define REMOTE_NDIS_KEEPALIVE_CMPLT           0x80000008UL\r
-               \r
-               #define REMOTE_NDIS_STATUS_SUCCESS            0x00000000UL\r
-               #define REMOTE_NDIS_STATUS_FAILURE            0xC0000001UL\r
-               #define REMOTE_NDIS_STATUS_INVALID_DATA       0xC0010015UL\r
-               #define REMOTE_NDIS_STATUS_NOT_SUPPORTED      0xC00000BBUL\r
-               #define REMOTE_NDIS_STATUS_MEDIA_CONNECT      0x4001000BUL\r
-               #define REMOTE_NDIS_STATUS_MEDIA_DISCONNECT   0x4001000CUL\r
-               \r
-               #define REMOTE_NDIS_MEDIA_STATE_CONNECTED     0x00000000UL\r
-               #define REMOTE_NDIS_MEDIA_STATE_DISCONNECTED  0x00000001UL\r
-               \r
-               #define REMOTE_NDIS_MEDIUM_802_3              0x00000000UL\r
-               \r
-               #define REMOTE_NDIS_DF_CONNECTIONLESS         0x00000001UL\r
-               #define REMOTE_NDIS_DF_CONNECTION_ORIENTED    0x00000002UL\r
-               \r
-               #define OID_GEN_SUPPORTED_LIST                0x00010101UL\r
-               #define OID_GEN_HARDWARE_STATUS               0x00010102UL\r
-               #define OID_GEN_MEDIA_SUPPORTED               0x00010103UL\r
-               #define OID_GEN_MEDIA_IN_USE                  0x00010104UL\r
-               #define OID_GEN_MAXIMUM_FRAME_SIZE            0x00010106UL\r
-               #define OID_GEN_MAXIMUM_TOTAL_SIZE            0x00010111UL\r
-               #define OID_GEN_LINK_SPEED                    0x00010107UL\r
-               #define OID_GEN_TRANSMIT_BLOCK_SIZE           0x0001010AUL\r
-               #define OID_GEN_RECEIVE_BLOCK_SIZE            0x0001010BUL\r
-               #define OID_GEN_VENDOR_ID                     0x0001010CUL\r
-               #define OID_GEN_VENDOR_DESCRIPTION            0x0001010DUL\r
-               #define OID_GEN_CURRENT_PACKET_FILTER         0x0001010EUL\r
-               #define OID_GEN_MAXIMUM_TOTAL_SIZE            0x00010111UL\r
-               #define OID_GEN_MEDIA_CONNECT_STATUS          0x00010114UL\r
-               #define OID_GEN_PHYSICAL_MEDIUM               0x00010202UL\r
-               #define OID_GEN_XMIT_OK                       0x00020101UL\r
-               #define OID_GEN_RCV_OK                        0x00020102UL\r
-               #define OID_GEN_XMIT_ERROR                    0x00020103UL\r
-               #define OID_GEN_RCV_ERROR                     0x00020104UL\r
-               #define OID_GEN_RCV_NO_BUFFER                 0x00020105UL\r
-               #define OID_802_3_PERMANENT_ADDRESS           0x01010101UL\r
-               #define OID_802_3_CURRENT_ADDRESS             0x01010102UL\r
-               #define OID_802_3_MULTICAST_LIST              0x01010103UL\r
-               #define OID_802_3_MAXIMUM_LIST_SIZE           0x01010104UL\r
-               #define OID_802_3_RCV_ERROR_ALIGNMENT         0x01020101UL\r
-               #define OID_802_3_XMIT_ONE_COLLISION          0x01020102UL\r
-               #define OID_802_3_XMIT_MORE_COLLISIONS        0x01020103UL\r
-\r
-#endif\r
index f259aad..1ebd154 100644 (file)
@@ -56,7 +56,7 @@ TCP_ConnectionState_t  ConnectionStateTable[MAX_TCP_CONNECTIONS];
  *  level. If an application produces a response, this task constructs the appropriate Ethernet frame and places it into the Ethernet OUT\r
  *  buffer for later transmission.\r
  */\r
-TASK(TCP_Task)\r
+void TCP_TCPTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)\r
 {\r
        /* Task to hand off TCP packets to and from the listening applications. */\r
 \r
@@ -76,7 +76,7 @@ TASK(TCP_Task)
        }\r
        \r
        /* Bail out early if there is already a frame waiting to be sent in the Ethernet OUT buffer */\r
-       if (FrameOUT.FrameInBuffer)\r
+       if (RNDISInterfaceInfo->FrameOUT.FrameInBuffer)\r
          return;\r
        \r
        /* Send response packets from each application as the TCP packet buffers are filled by the applications */\r
@@ -86,13 +86,13 @@ TASK(TCP_Task)
                if ((ConnectionStateTable[CSTableEntry].Info.Buffer.Direction == TCP_PACKETDIR_OUT) &&\r
                    (ConnectionStateTable[CSTableEntry].Info.Buffer.Ready))\r
                {\r
-                       Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT.FrameData;\r
-                       IP_Header_t*             IPHeaderOUT    = (IP_Header_t*)&FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)];\r
-                       TCP_Header_t*            TCPHeaderOUT   = (TCP_Header_t*)&FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +\r
-                                                                                                    sizeof(IP_Header_t)];                                              \r
-                       void*                    TCPDataOUT     = &FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +\r
-                                                                                     sizeof(IP_Header_t) +\r
-                                                                                     sizeof(TCP_Header_t)];\r
+                       Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&RNDISInterfaceInfo->FrameOUT.FrameData;\r
+                       IP_Header_t*    IPHeaderOUT  = (IP_Header_t*)&RNDISInterfaceInfo->FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)];\r
+                       TCP_Header_t*   TCPHeaderOUT = (TCP_Header_t*)&RNDISInterfaceInfo->FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +\r
+                                                                                                             sizeof(IP_Header_t)];                                             \r
+                       void*           TCPDataOUT     = &RNDISInterfaceInfo->FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +\r
+                                                                                                sizeof(IP_Header_t) +\r
+                                                                                                sizeof(TCP_Header_t)];\r
 \r
                        uint16_t PacketSize = ConnectionStateTable[CSTableEntry].Info.Buffer.Length;\r
 \r
@@ -145,8 +145,8 @@ TASK(TCP_Task)
                        PacketSize += sizeof(Ethernet_Frame_Header_t);\r
 \r
                        /* Set the response length in the buffer and indicate that a response is ready to be sent */\r
-                       FrameOUT.FrameLength            = PacketSize;\r
-                       FrameOUT.FrameInBuffer          = true;\r
+                       RNDISInterfaceInfo->FrameOUT.FrameLength   = PacketSize;\r
+                       RNDISInterfaceInfo->FrameOUT.FrameInBuffer = true;\r
                        \r
                        ConnectionStateTable[CSTableEntry].Info.Buffer.Ready = false;\r
                        \r
index d4b72a5..3448245 100644 (file)
@@ -38,9 +38,7 @@
 \r
        /* Includes: */\r
                #include <avr/io.h>\r
-               #include <stdbool.h>\r
-               \r
-               #include <LUFA/Scheduler/Scheduler.h>\r
+               #include <stdbool.h>
                \r
                #include "EthernetProtocols.h"\r
                #include "Ethernet.h"\r
                        uint16_t               Checksum; /**< TCP checksum */\r
                        uint16_t               UrgentPointer; /**< Urgent data pointer */\r
                } TCP_Header_t;\r
-\r
-       /* Tasks: */\r
-               TASK(TCP_Task);\r
                \r
        /* External Variables: */\r
                TCP_PortState_t PortStateTable[MAX_OPEN_TCP_PORTS];\r
 \r
        /* Function Prototypes: */\r
+               void                  TCP_TCPTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);\r
                void                  TCP_Init(void);\r
                bool                  TCP_SetPortState(uint16_t Port, uint8_t State, void (*Handler)(TCP_ConnectionState_t*, TCP_ConnectionBuffer_t*));\r
                uint8_t               TCP_GetPortState(uint16_t Port);\r
index b046f78..3246cd8 100644 (file)
   this software.\r
 */\r
 \r
-/** \file\r
- *\r
- *  Main source file for the RNDISEthernet demo. This file contains the main tasks of the demo and\r
- *  is responsible for the initial application hardware configuration.\r
- */\r
-\r
 #include "RNDISEthernet.h"\r
 \r
-/* Scheduler Task List */\r
-TASK_LIST\r
-{\r
-       { .Task = USB_USBTask          , .TaskStatus = TASK_STOP },\r
-       { .Task = Ethernet_Task        , .TaskStatus = TASK_STOP },\r
-       { .Task = TCP_Task             , .TaskStatus = TASK_STOP },\r
-       { .Task = RNDIS_Task           , .TaskStatus = TASK_STOP },\r
-};\r
+USB_ClassInfo_RNDIS_t Ethernet_RNDIS_Interface =\r
+       {\r
+               .ControlInterfaceNumber     = 0,\r
 \r
-/** Main program entry point. This routine configures the hardware required by the application, then\r
- *  starts the scheduler to run the USB management task.\r
- */\r
+               .DataINEndpointNumber       = CDC_TX_EPNUM,\r
+               .DataINEndpointSize         = CDC_TXRX_EPSIZE,\r
+\r
+               .DataOUTEndpointNumber      = CDC_RX_EPNUM,\r
+               .DataOUTEndpointSize        = CDC_TXRX_EPSIZE,\r
+\r
+               .NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,\r
+               .NotificationEndpointSize   = CDC_NOTIFICATION_EPSIZE,\r
+               \r
+               .AdapterVendorDescription   = "LUFA RNDIS Demo Adapter",\r
+               .AdapterMACAddress          = {ADAPTER_MAC_ADDRESS},\r
+       };\r
+       \r
 int main(void)\r
 {\r
+       SetupHardware();\r
+\r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
+       \r
+       printf_P(PSTR("\r\n\r\n****** RNDIS Demo running. ******\r\n"));\r
+\r
+       for (;;)\r
+       {\r
+               if (Ethernet_RNDIS_Interface.FrameIN.FrameInBuffer)\r
+               {\r
+                       LEDs_SetAllLEDs(LEDMASK_USB_BUSY);\r
+                       Ethernet_ProcessPacket(&Ethernet_RNDIS_Interface.FrameIN, &Ethernet_RNDIS_Interface.FrameOUT);\r
+                       LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
+               }\r
+\r
+               TCP_TCPTask(&Ethernet_RNDIS_Interface);\r
+\r
+               USB_RNDIS_USBTask(&Ethernet_RNDIS_Interface);\r
+               USB_USBTask();\r
+       }\r
+}\r
+\r
+void SetupHardware(void)\r
+{\r
        /* Disable watchdog if enabled by bootloader/fuses */\r
        MCUSR &= ~(1 << WDRF);\r
        wdt_disable();\r
@@ -60,279 +83,32 @@ int main(void)
        /* Hardware Initialization */\r
        LEDs_Init();\r
        SerialStream_Init(9600, false);\r
-       \r
-       /* Webserver Initialization */\r
-       TCP_Init();\r
-       Webserver_Init();\r
-\r
-       printf_P(PSTR("\r\n\r\n****** RNDIS Demo running. ******\r\n"));\r
-\r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
-       \r
-       /* Initialize Scheduler so that it can be used */\r
-       Scheduler_Init();\r
-\r
-       /* Initialize USB Subsystem */\r
        USB_Init();\r
 \r
-       /* Scheduling - routine never returns, so put this last in the main function */\r
-       Scheduler_Start();\r
+       /* Initialize TCP and Webserver modules */\r
+       TCP_Init();\r
+       Webserver_Init();\r
 }\r
 \r
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and\r
- *  starts the library USB task to begin the enumeration and USB management process.\r
- */\r
 void EVENT_USB_Connect(void)\r
 {\r
-       /* Start USB management task */\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);\r
-\r
-       /* Indicate USB enumerating */\r
-       UpdateStatus(Status_USBEnumerating);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);\r
 }\r
 \r
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via\r
- *  the status LEDs and stops all the relevant tasks.\r
- */\r
 void EVENT_USB_Disconnect(void)\r
 {\r
-       /* Stop running TCP/IP and USB management tasks */\r
-       Scheduler_SetTaskMode(RNDIS_Task, TASK_STOP);\r
-       Scheduler_SetTaskMode(Ethernet_Task, TASK_STOP);\r
-       Scheduler_SetTaskMode(TCP_Task, TASK_STOP);\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);\r
-\r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
 }\r
 \r
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host sets the current configuration\r
- *  of the USB device after enumeration, and configures the RNDIS device endpoints and starts the relevant tasks.\r
- */\r
 void EVENT_USB_ConfigurationChanged(void)\r
 {\r
-       /* Setup CDC Notification, Rx and Tx Endpoints */\r
-       Endpoint_ConfigureEndpoint(CDC_TX_EPNUM, EP_TYPE_BULK,\r
-                                      ENDPOINT_DIR_IN, CDC_TXRX_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
 \r
-       Endpoint_ConfigureEndpoint(CDC_RX_EPNUM, EP_TYPE_BULK,\r
-                                      ENDPOINT_DIR_OUT, CDC_TXRX_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
-\r
-       Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,\r
-                                      ENDPOINT_DIR_IN, CDC_NOTIFICATION_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
-\r
-       /* Indicate USB connected and ready */\r
-       UpdateStatus(Status_USBReady);\r
-\r
-       /* Start TCP/IP tasks */\r
-       Scheduler_SetTaskMode(RNDIS_Task, TASK_RUN);\r
-       Scheduler_SetTaskMode(Ethernet_Task, TASK_RUN);\r
-       Scheduler_SetTaskMode(TCP_Task, TASK_RUN);\r
+       if (!(USB_RNDIS_ConfigureEndpoints(&Ethernet_RNDIS_Interface)))\r
+         LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
 }\r
 \r
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific\r
- *  control requests that are not handled internally by the USB library (including the RNDIS control commands,\r
- *  which set up the USB RNDIS network adapter), so that they can be handled appropriately for the application.\r
- */\r
 void EVENT_USB_UnhandledControlPacket(void)\r
 {\r
-       /* Process RNDIS class commands */\r
-       switch (USB_ControlRequest.bRequest)\r
-       {\r
-               case REQ_SendEncapsulatedCommand:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               /* Clear the SETUP packet, ready for data transfer */\r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* Read in the RNDIS message into the message buffer */\r
-                               Endpoint_Read_Control_Stream_LE(RNDISMessageBuffer, USB_ControlRequest.wLength);\r
-\r
-                               /* Finalize the stream transfer to clear the last packet from the host */\r
-                               Endpoint_ClearIN();\r
-\r
-                               /* Process the RNDIS message */\r
-                               ProcessRNDISControlMessage();\r
-                       }\r
-                       \r
-                       break;\r
-               case REQ_GetEncapsulatedResponse:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               /* Clear the SETUP packet, ready for data transfer */\r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* Check if a response to the last message is ready */\r
-                               if (!(MessageHeader->MessageLength))\r
-                               {\r
-                                       /* Set the response to a single 0x00 byte to indicate that no response is ready */\r
-                                       RNDISMessageBuffer[0] = 0;\r
-                                       MessageHeader->MessageLength = 1;\r
-                               }\r
-\r
-                               /* Write the message response data to the endpoint */\r
-                               Endpoint_Write_Control_Stream_LE(RNDISMessageBuffer, MessageHeader->MessageLength);\r
-                               \r
-                               /* Finalize the stream transfer to send the last packet or clear the host abort */\r
-                               Endpoint_ClearOUT();\r
-\r
-                               /* Reset the message header once again after transmission */\r
-                               MessageHeader->MessageLength = 0;\r
-                       }\r
-       \r
-                       break;\r
-       }\r
-}\r
-\r
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to\r
- *  log to a serial port, or anything else that is suitable for status updates.\r
- *\r
- *  \param CurrentStatus  Current status of the system, from the RNDISEthernet_StatusCodes_t enum\r
- */\r
-void UpdateStatus(uint8_t CurrentStatus)\r
-{\r
-       uint8_t LEDMask = LEDS_NO_LEDS;\r
-       \r
-       /* Set the LED mask to the appropriate LED mask based on the given status code */\r
-       switch (CurrentStatus)\r
-       {\r
-               case Status_USBNotReady:\r
-                       LEDMask = (LEDS_LED1);\r
-                       break;\r
-               case Status_USBEnumerating:\r
-                       LEDMask = (LEDS_LED1 | LEDS_LED2);\r
-                       break;\r
-               case Status_USBReady:\r
-                       LEDMask = (LEDS_LED2 | LEDS_LED4);\r
-                       break;\r
-               case Status_ProcessingEthernetFrame:\r
-                       LEDMask = (LEDS_LED2 | LEDS_LED3);\r
-                       break;          \r
-       }\r
-       \r
-       /* Set the board LEDs to the new LED mask */\r
-       LEDs_SetAllLEDs(LEDMask);\r
-}\r
-\r
-/** Task to manage the sending and receiving of encapsulated RNDIS data and notifications. This removes the RNDIS\r
- *  wrapper from received Ethernet frames and places them in the FrameIN global buffer, or adds the RNDIS wrapper\r
- *  to a frame in the FrameOUT global before sending the buffer contents to the host.\r
- */\r
-TASK(RNDIS_Task)\r
-{\r
-       /* Select the notification endpoint */\r
-       Endpoint_SelectEndpoint(CDC_NOTIFICATION_EPNUM);\r
-\r
-       /* Check if a message response is ready for the host */\r
-       if (Endpoint_IsINReady() && ResponseReady)\r
-       {\r
-               USB_Notification_t Notification = (USB_Notification_t)\r
-                       {\r
-                               .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),\r
-                               .bNotification = NOTIF_RESPONSE_AVAILABLE,\r
-                               .wValue        = 0,\r
-                               .wIndex        = 0,\r
-                               .wLength       = 0,\r
-                       };\r
-               \r
-               /* Indicate that a message response is ready for the host */\r
-               Endpoint_Write_Stream_LE(&Notification, sizeof(Notification));\r
-\r
-               /* Finalize the stream transfer to send the last packet */\r
-               Endpoint_ClearIN();\r
-\r
-               /* Indicate a response is no longer ready */\r
-               ResponseReady = false;\r
-       }\r
-       \r
-       /* Don't process the data endpoints until the system is in the data initialized state, and the buffer is free */\r
-       if ((CurrRNDISState == RNDIS_Data_Initialized) && !(MessageHeader->MessageLength))\r
-       {\r
-               /* Create a new packet header for reading/writing */\r
-               RNDIS_PACKET_MSG_t RNDISPacketHeader;\r
-\r
-               /* Select the data OUT endpoint */\r
-               Endpoint_SelectEndpoint(CDC_RX_EPNUM);\r
-               \r
-               /* Check if the data OUT endpoint contains data, and that the IN buffer is empty */\r
-               if (Endpoint_IsOUTReceived() && !(FrameIN.FrameInBuffer))\r
-               {\r
-                       /* Read in the packet message header */\r
-                       Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_PACKET_MSG_t));\r
-\r
-                       /* Stall the request if the data is too large */\r
-                       if (RNDISPacketHeader.DataLength > ETHERNET_FRAME_SIZE_MAX)\r
-                       {\r
-                               Endpoint_StallTransaction();\r
-                               return;\r
-                       }\r
-                       \r
-                       /* Read in the Ethernet frame into the buffer */\r
-                       Endpoint_Read_Stream_LE(FrameIN.FrameData, RNDISPacketHeader.DataLength);\r
-\r
-                       /* Finalize the stream transfer to send the last packet */\r
-                       Endpoint_ClearOUT();\r
-                       \r
-                       /* Store the size of the Ethernet frame */\r
-                       FrameIN.FrameLength = RNDISPacketHeader.DataLength;\r
-\r
-                       /* Indicate Ethernet IN buffer full */\r
-                       FrameIN.FrameInBuffer = true;\r
-               }\r
-               \r
-               /* Select the data IN endpoint */\r
-               Endpoint_SelectEndpoint(CDC_TX_EPNUM);\r
-               \r
-               /* Check if the data IN endpoint is ready for more data, and that the IN buffer is full */\r
-               if (Endpoint_IsINReady() && FrameOUT.FrameInBuffer)\r
-               {\r
-                       /* Clear the packet header with all 0s so that the relevant fields can be filled */\r
-                       memset(&RNDISPacketHeader, 0, sizeof(RNDIS_PACKET_MSG_t));\r
-\r
-                       /* Construct the required packet header fields in the buffer */\r
-                       RNDISPacketHeader.MessageType   = REMOTE_NDIS_PACKET_MSG;\r
-                       RNDISPacketHeader.MessageLength = (sizeof(RNDIS_PACKET_MSG_t) + FrameOUT.FrameLength);\r
-                       RNDISPacketHeader.DataOffset    = (sizeof(RNDIS_PACKET_MSG_t) - sizeof(RNDIS_Message_Header_t));\r
-                       RNDISPacketHeader.DataLength    = FrameOUT.FrameLength;\r
-\r
-                       /* Send the packet header to the host */\r
-                       Endpoint_Write_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_PACKET_MSG_t));\r
-\r
-                       /* Send the Ethernet frame data to the host */\r
-                       Endpoint_Write_Stream_LE(FrameOUT.FrameData, RNDISPacketHeader.DataLength);\r
-                       \r
-                       /* Finalize the stream transfer to send the last packet */\r
-                       Endpoint_ClearIN();\r
-                       \r
-                       /* Indicate Ethernet OUT buffer no longer full */\r
-                       FrameOUT.FrameInBuffer = false;\r
-               }\r
-       }\r
-}\r
-\r
-/** Ethernet frame processing task. This task checks to see if a frame has been received, and if so hands off the processing\r
- *  of the frame to the Ethernet processing routines.\r
- */\r
-TASK(Ethernet_Task)\r
-{\r
-       /* Task for Ethernet processing. Incoming ethernet frames are loaded into the FrameIN structure, and\r
-          outgoing frames should be loaded into the FrameOUT structure. Both structures can only hold a single\r
-          Ethernet frame at a time, so the FrameInBuffer bool is used to indicate when the buffers contain data. */\r
-\r
-       /* Check if a frame has been written to the IN frame buffer */\r
-       if (FrameIN.FrameInBuffer)\r
-       {\r
-               /* Indicate packet processing started */\r
-               UpdateStatus(Status_ProcessingEthernetFrame);\r
-\r
-               /* Process the ethernet frame - replace this with your own Ethernet handler code as desired */\r
-               Ethernet_ProcessPacket();\r
-\r
-               /* Indicate packet processing complete */\r
-               UpdateStatus(Status_USBReady);\r
-       }\r
+       USB_RNDIS_ProcessControlPacket(&Ethernet_RNDIS_Interface);\r
 }\r
index 703af40..bc50042 100644 (file)
                #include <stdio.h>\r
 \r
                #include "Descriptors.h"\r
-\r
-               #include "Lib/RNDIS.h"\r
+
                #include "Lib/Ethernet.h"\r
                #include "Lib/TCP.h"\r
                #include "Lib/ARP.h"\r
                #include "Lib/Webserver.h"\r
 \r
-               #include <LUFA/Version.h>                         // Library Version Information\r
-               #include <LUFA/Drivers/USB/USB.h>                 // USB Functionality\r
-               #include <LUFA/Drivers/Board/LEDs.h>              // LEDs driver\r
-               #include <LUFA/Scheduler/Scheduler.h>             // Simple scheduler for task management\r
-               #include <LUFA/Drivers/Peripheral/SerialStream.h> // Serial stream driver\r
-       \r
-       /* Macros: */\r
-               /** Notification value to indicate that a frame is ready to be read by the host. */\r
-               #define NOTIF_RESPONSE_AVAILABLE                 0x01\r
+               #include <LUFA/Version.h>\r
+               #include <LUFA/Drivers/Board/LEDs.h>\r
+               #include <LUFA/Drivers/Board/Joystick.h>\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/RNDIS.h>\r
 \r
-       /* Type Defines: */\r
-               /** Type define for a RNDIS notification message, for transmission to the RNDIS host via the notification\r
-                *  Endpoint.\r
-                */\r
-               typedef struct\r
-               {\r
-                       uint8_t  bmRequestType; /**< Notification type, a mask of values from SrdRequestType.h */\r
-                       uint8_t  bNotification; /**< Notification index, indicating what the RNDIS notification relates to */\r
-                       uint16_t wValue; /**< Two byte notification value parameter */\r
-                       uint16_t wIndex; /**< Two byte notification index parameter */\r
-                       uint16_t wLength; /**< Size of data payload following the notification header */\r
-               } USB_Notification_t;\r
-\r
-       /* Enums: */\r
-               /** Enum for the possible status codes for passing to the UpdateStatus() function. */\r
-               enum RNDISEthernet_StatusCodes_t\r
-               {\r
-                       Status_USBNotReady             = 0, /**< USB is not ready (disconnected from a USB host) */\r
-                       Status_USBEnumerating          = 1, /**< USB interface is enumerating */\r
-                       Status_USBReady                = 2, /**< USB interface is connected and ready */\r
-                       Status_ProcessingEthernetFrame = 3, /**< Currently processing an ethernet frame from the host */\r
-               };\r
+       /* Macros: */\r
+               #define LEDMASK_USB_NOTREADY      LEDS_LED1\r
+               #define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)\r
+               #define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)\r
+               #define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)\r
+               #define LEDMASK_USB_BUSY          LEDS_LED2\r
                \r
-       /* Tasks: */\r
-               TASK(RNDIS_Task);\r
-               TASK(Ethernet_Task);\r
-\r
        /* Function Prototypes: */\r
+               void SetupHardware(void);\r
+\r
                void EVENT_USB_Connect(void);\r
                void EVENT_USB_Disconnect(void);\r
                void EVENT_USB_ConfigurationChanged(void);\r
                void EVENT_USB_UnhandledControlPacket(void);\r
-\r
-               void UpdateStatus(uint8_t CurrentStatus);\r
+               void EVENT_USB_StartOfFrame(void);\r
+               \r
+               void CALLBACK_USB_RNDIS_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);\r
        \r
 #endif\r
index f40c37b..3bcc37c 100644 (file)
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)\r
 SRC = $(TARGET).c                                                 \\r
       Descriptors.c                                               \\r
-      Lib/RNDIS.c                                                 \\r
          Lib/Ethernet.c                                              \\r
          Lib/ProtocolDecoders.c                                      \\r
          Lib/ICMP.c                                                  \\r
@@ -135,7 +134,6 @@ SRC = $(TARGET).c                                                 \
          Lib/ARP.c                                                   \\r
          Lib/IP.c                                                    \\r
          Lib/Webserver.c                                             \\r
-         $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \\r
          $(LUFA_PATH)/LUFA/Drivers/Peripheral/SerialStream.c         \\r
          $(LUFA_PATH)/LUFA/Drivers/Peripheral/Serial.c               \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \\r
@@ -148,7 +146,7 @@ SRC = $(TARGET).c                                                 \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \\r
-         $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \\r
+         $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/RNDIS.c          \\r
 \r
 \r
 # List C++ source files here. (C dependencies are automatically generated.)\r
@@ -195,7 +193,7 @@ CSTANDARD = -std=gnu99
 \r
 # Place -D or -U options here for C sources\r
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)\r
-CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY\r
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY\r
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION\r
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"\r
 CDEFS += -DNO_DECODE_ETHERNET -DNO_DECODE_ARP -DNO_DECODE_ICMP -DNO_DECODE_IP -DNO_DECODE_TCP -DNO_DECODE_UDP -DNO_DECODE_DHCP\r
index 41b4430..9e372e3 100644 (file)
 #define _DESCRIPTORS_H_\r
 \r
        /* Includes: */\r
-               #include <LUFA/Drivers/USB/USB.h>\r
-\r
                #include <avr/pgmspace.h>\r
 \r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/CDC.h>\r
+\r
        /* Macros: */\r
-               /** Macro to define a CDC class-specific functional descriptor. CDC functional descriptors have a\r
-                *  uniform structure but variable sized data payloads, thus cannot be represented accurately by\r
-                *  a single typedef struct. A macro is used instead so that functional descriptors can be created\r
-                *  easily by specifying the size of the payload. This allows sizeof() to work correctly.\r
-                *\r
-                *  \param DataSize  Size in bytes of the CDC functional descriptor's data payload\r
-                */\r
-               #define CDC_FUNCTIONAL_DESCRIPTOR(DataSize)        \\r
-                    struct                                        \\r
-                    {                                             \\r
-                         USB_Descriptor_Header_t Header;          \\r
-                             uint8_t                 SubType;         \\r
-                         uint8_t                 Data[DataSize];  \\r
-                    }\r
-                        \r
                /** Endpoint number of the CDC device-to-host notification IN endpoint. */\r
                #define CDC_NOTIFICATION_EPNUM         2\r
 \r
index 7cef565..7c89278 100644 (file)
 \r
 #include "USBtoSerial.h"\r
 \r
-/* Scheduler Task List */\r
-TASK_LIST\r
-{\r
-       { .Task = USB_USBTask          , .TaskStatus = TASK_STOP },\r
-       { .Task = CDC_Task             , .TaskStatus = TASK_STOP },\r
-};\r
+RingBuff_t Rx_Buffer;\r
+RingBuff_t Tx_Buffer;\r
 \r
-/* Globals: */\r
-/** Contains the current baud rate and other settings of the virtual serial port.\r
- *\r
- *  These values are set by the host via a class-specific request, and the physical USART should be reconfigured to match the\r
- *  new settings each time they are changed by the host.\r
- */\r
-CDC_Line_Coding_t LineCoding = { .BaudRateBPS = 9600,\r
-                                 .CharFormat  = OneStopBit,\r
-                                 .ParityType  = Parity_None,\r
-                                 .DataBits    = 8            };\r
+USB_ClassInfo_CDC_t VirtualSerial_CDC_Interface =\r
+       {\r
+               .ControlInterfaceNumber     = 0,\r
 \r
-/** Ring (circular) buffer to hold the RX data - data from the host to the attached device on the serial port. */\r
-RingBuff_t Rx_Buffer;\r
+               .DataINEndpointNumber       = CDC_TX_EPNUM,\r
+               .DataINEndpointSize         = CDC_TXRX_EPSIZE,\r
 \r
-/** Ring (circular) buffer to hold the TX data - data from the attached device on the serial port to the host. */\r
-RingBuff_t Tx_Buffer;\r
+               .DataOUTEndpointNumber      = CDC_RX_EPNUM,\r
+               .DataOUTEndpointSize        = CDC_TXRX_EPSIZE,\r
 \r
-/** Flag to indicate if the USART is currently transmitting data from the Rx_Buffer circular buffer. */\r
-volatile bool Transmitting = false;\r
+               .NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,\r
+               .NotificationEndpointSize   = CDC_NOTIFICATION_EPSIZE,\r
+       };\r
 \r
-/** Main program entry point. This routine configures the hardware required by the application, then\r
- *  starts the scheduler to run the application tasks.\r
- */\r
 int main(void)\r
 {\r
+       SetupHardware();\r
+       \r
+       Buffer_Initialize(&Rx_Buffer);\r
+       Buffer_Initialize(&Tx_Buffer);\r
+\r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
+\r
+       for (;;)\r
+       {\r
+               for (uint8_t DataBytesRem = USB_CDC_BytesReceived(&VirtualSerial_CDC_Interface); DataBytesRem != 0; DataBytesRem--)\r
+               {\r
+                       if (!(BUFF_STATICSIZE - Rx_Buffer.Elements))\r
+                         break;\r
+                         \r
+                       Buffer_StoreElement(&Rx_Buffer, USB_CDC_ReceiveByte(&VirtualSerial_CDC_Interface));\r
+               }\r
+               \r
+               if (Tx_Buffer.Elements)\r
+                 USB_CDC_SendByte(&VirtualSerial_CDC_Interface, Buffer_GetElement(&Rx_Buffer));\r
+                 \r
+               if (Rx_Buffer.Elements)\r
+                 Serial_TxByte(Buffer_GetElement(&Rx_Buffer));\r
+               \r
+               USB_CDC_USBTask(&VirtualSerial_CDC_Interface);\r
+               USB_USBTask();\r
+       }\r
+}\r
+\r
+void SetupHardware(void)\r
+{\r
        /* Disable watchdog if enabled by bootloader/fuses */\r
        MCUSR &= ~(1 << WDRF);\r
        wdt_disable();\r
@@ -70,304 +87,61 @@ int main(void)
        clock_prescale_set(clock_div_1);\r
 \r
        /* Hardware Initialization */\r
+       Joystick_Init();\r
        LEDs_Init();\r
-       ReconfigureUSART();\r
-       \r
-       /* Ring buffer Initialization */\r
-       Buffer_Initialize(&Rx_Buffer);\r
-       Buffer_Initialize(&Tx_Buffer);\r
-       \r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
-       \r
-       /* Initialize Scheduler so that it can be used */\r
-       Scheduler_Init();\r
-\r
-       /* Initialize USB Subsystem */\r
        USB_Init();\r
-\r
-       /* Scheduling - routine never returns, so put this last in the main function */\r
-       Scheduler_Start();\r
 }\r
 \r
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and\r
- *  starts the library USB task to begin the enumeration and USB management process.\r
- */\r
 void EVENT_USB_Connect(void)\r
 {\r
-       /* Start USB management task */\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);\r
-\r
-       /* Indicate USB enumerating */\r
-       UpdateStatus(Status_USBEnumerating);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);\r
 }\r
 \r
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via\r
- *  the status LEDs and stops the USB management and CDC management tasks.\r
- */\r
 void EVENT_USB_Disconnect(void)\r
 {\r
-       /* Stop running CDC and USB management tasks */\r
-       Scheduler_SetTaskMode(CDC_Task, TASK_STOP);\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);\r
-       \r
-       /* Reset Tx and Rx buffers, device disconnected */\r
-       Buffer_Initialize(&Rx_Buffer);\r
-       Buffer_Initialize(&Tx_Buffer);\r
-\r
-       /* Indicate USB not ready */\r
-       UpdateStatus(Status_USBNotReady);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
 }\r
 \r
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration\r
- *  of the USB device after enumeration - the device endpoints are configured and the CDC management task started.\r
- */\r
 void EVENT_USB_ConfigurationChanged(void)\r
 {\r
-       /* Setup CDC Notification, Rx and Tx Endpoints */\r
-       Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,\r
-                                      ENDPOINT_DIR_IN, CDC_NOTIFICATION_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
-\r
-       Endpoint_ConfigureEndpoint(CDC_TX_EPNUM, EP_TYPE_BULK,\r
-                                      ENDPOINT_DIR_IN, CDC_TXRX_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
+       LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
 \r
-       Endpoint_ConfigureEndpoint(CDC_RX_EPNUM, EP_TYPE_BULK,\r
-                                      ENDPOINT_DIR_OUT, CDC_TXRX_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
-\r
-       /* Indicate USB connected and ready */\r
-       UpdateStatus(Status_USBReady);\r
-\r
-       /* Start CDC task */\r
-       Scheduler_SetTaskMode(CDC_Task, TASK_RUN);\r
+       if (!(USB_CDC_ConfigureEndpoints(&VirtualSerial_CDC_Interface)))\r
+         LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
 }\r
 \r
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific\r
- *  control requests that are not handled internally by the USB library (including the CDC control commands,\r
- *  which are all issued via the control endpoint), so that they can be handled appropriately for the application.\r
- */\r
 void EVENT_USB_UnhandledControlPacket(void)\r
 {\r
-       uint8_t* LineCodingData = (uint8_t*)&LineCoding;\r
-\r
-       /* Process CDC specific control requests */\r
-       switch (USB_ControlRequest.bRequest)\r
-       {\r
-               case REQ_GetLineEncoding:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {       \r
-                               /* Acknowledge the SETUP packet, ready for data transfer */\r
-                               Endpoint_ClearSETUP();\r
-\r
-                               /* Write the line coding data to the control endpoint */\r
-                               Endpoint_Write_Control_Stream_LE(LineCodingData, sizeof(LineCoding));\r
-                               \r
-                               /* Finalize the stream transfer to send the last packet or clear the host abort */\r
-                               Endpoint_ClearOUT();\r
-                       }\r
-                       \r
-                       break;\r
-               case REQ_SetLineEncoding:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               /* Acknowledge the SETUP packet, ready for data transfer */\r
-                               Endpoint_ClearSETUP();\r
-\r
-                               /* Read the line coding data in from the host into the global struct */\r
-                               Endpoint_Read_Control_Stream_LE(LineCodingData, sizeof(LineCoding));\r
-\r
-                               /* Finalize the stream transfer to clear the last packet from the host */\r
-                               Endpoint_ClearIN();\r
-                               \r
-                               /* Reconfigure the USART with the new settings */\r
-                               ReconfigureUSART();\r
-                       }\r
-       \r
-                       break;\r
-               case REQ_SetControlLineState:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {                               \r
-                               /* Acknowledge the SETUP packet, ready for data transfer */\r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* NOTE: Here you can read in the line state mask from the host, to get the current state of the output handshake\r
-                                        lines. The mask is read in from the wValue parameter in USB_ControlRequest, and can be masked against the\r
-                                                CONTROL_LINE_OUT_* masks to determine the RTS and DTR line states using the following code:\r
-                               */\r
-\r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsINReady()));\r
-                               Endpoint_ClearIN();\r
-                       }\r
-       \r
-                       break;\r
-       }\r
-}\r
-\r
-/** Task to manage CDC data transmission and reception to and from the host, from and to the physical USART. */\r
-TASK(CDC_Task)\r
-{\r
-       if (USB_IsConnected)\r
-       {\r
-#if 0\r
-               /* NOTE: Here you can use the notification endpoint to send back line state changes to the host, for the special RS-232\r
-                                handshake signal lines (and some error states), via the CONTROL_LINE_IN_* masks and the following code:\r
-               */\r
-\r
-               USB_Notification_Header_t Notification = (USB_Notification_Header_t)\r
-                       {\r
-                               .NotificationType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),\r
-                               .Notification     = NOTIF_SerialState,\r
-                               .wValue           = 0,\r
-                               .wIndex           = 0,\r
-                               .wLength          = sizeof(uint16_t),\r
-                       };\r
-                       \r
-               uint16_t LineStateMask;\r
-               \r
-               // Set LineStateMask here to a mask of CONTROL_LINE_IN_* masks to set the input handshake line states to send to the host\r
-               \r
-               Endpoint_SelectEndpoint(CDC_NOTIFICATION_EPNUM);\r
-               Endpoint_Write_Stream_LE(&Notification, sizeof(Notification));\r
-               Endpoint_Write_Stream_LE(&LineStateMask, sizeof(LineStateMask));\r
-               Endpoint_ClearIN();\r
-#endif\r
-\r
-               /* Select the Serial Rx Endpoint */\r
-               Endpoint_SelectEndpoint(CDC_RX_EPNUM);\r
-               \r
-               /* Check to see if a packet has been received from the host */\r
-               if (Endpoint_IsOUTReceived())\r
-               {\r
-                       /* Read the bytes in from the endpoint into the buffer while space is available */\r
-                       while (Endpoint_BytesInEndpoint() && (BUFF_STATICSIZE - Rx_Buffer.Elements))\r
-                       {\r
-                               /* Store each character from the endpoint */\r
-                               Buffer_StoreElement(&Rx_Buffer, Endpoint_Read_Byte());\r
-                       }\r
-                       \r
-                       /* Check to see if all bytes in the current packet have been read */\r
-                       if (!(Endpoint_BytesInEndpoint()))\r
-                       {\r
-                               /* Clear the endpoint buffer */\r
-                               Endpoint_ClearOUT();\r
-                       }\r
-               }\r
-               \r
-               /* Check if Rx buffer contains data - if so, send it */\r
-               if (Rx_Buffer.Elements)\r
-                 Serial_TxByte(Buffer_GetElement(&Rx_Buffer));\r
-\r
-               /* Select the Serial Tx Endpoint */\r
-               Endpoint_SelectEndpoint(CDC_TX_EPNUM);\r
-\r
-               /* Check if the Tx buffer contains anything to be sent to the host */\r
-               if (Tx_Buffer.Elements)\r
-               {\r
-                       /* Wait until Serial Tx Endpoint Ready for Read/Write */\r
-                       while (!(Endpoint_IsReadWriteAllowed()));\r
-                       \r
-                       /* Write the bytes from the buffer to the endpoint while space is available */\r
-                       while (Tx_Buffer.Elements && (Endpoint_BytesInEndpoint() < CDC_TXRX_EPSIZE))\r
-                       {\r
-                               /* Write each byte retreived from the buffer to the endpoint */\r
-                               Endpoint_Write_Byte(Buffer_GetElement(&Tx_Buffer));\r
-                       }\r
-                       \r
-                       /* Remember if the packet to send completely fills the endpoint */\r
-                       bool IsFull = (Endpoint_BytesInEndpoint() == CDC_TXRX_EPSIZE);\r
-                       \r
-                       /* Send the data */\r
-                       Endpoint_ClearIN();\r
-\r
-                       /* If no more data to send and the last packet filled the endpoint, send an empty packet to release\r
-                        * the buffer on the receiver (otherwise all data will be cached until a non-full packet is received) */\r
-                       if (IsFull && !(Tx_Buffer.Elements))\r
-                       {\r
-                               /* Wait until Serial Tx Endpoint Ready for Read/Write */\r
-                               while (!(Endpoint_IsReadWriteAllowed()));\r
-\r
-                               /* Send an empty packet to terminate the transfer */\r
-                               Endpoint_ClearIN();\r
-                       }\r
-               }\r
-       }\r
+       USB_CDC_ProcessControlPacket(&VirtualSerial_CDC_Interface);\r
 }\r
 \r
-/** ISR to handle the USART receive complete interrupt, fired each time the USART has received a character. This stores the received\r
- *  character into the Tx_Buffer circular buffer for later transmission to the host.\r
- */\r
 ISR(USART1_RX_vect, ISR_BLOCK)\r
 {\r
-       /* Only store received characters if the USB interface is connected */\r
        if (USB_IsConnected)\r
-       {\r
-               /* Character received, store it into the buffer */\r
-               Buffer_StoreElement(&Tx_Buffer, UDR1);\r
-       }\r
+         Buffer_StoreElement(&Tx_Buffer, UDR1);\r
 }\r
 \r
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to\r
- *  log to a serial port, or anything else that is suitable for status updates.\r
- *\r
- *  \param CurrentStatus  Current status of the system, from the USBtoSerial_StatusCodes_t enum\r
- */\r
-void UpdateStatus(uint8_t CurrentStatus)\r
-{\r
-       uint8_t LEDMask = LEDS_NO_LEDS;\r
-       \r
-       /* Set the LED mask to the appropriate LED mask based on the given status code */\r
-       switch (CurrentStatus)\r
-       {\r
-               case Status_USBNotReady:\r
-                       LEDMask = (LEDS_LED1);\r
-                       break;\r
-               case Status_USBEnumerating:\r
-                       LEDMask = (LEDS_LED1 | LEDS_LED2);\r
-                       break;\r
-               case Status_USBReady:\r
-                       LEDMask = (LEDS_LED2 | LEDS_LED4);\r
-                       break;\r
-       }\r
-       \r
-       /* Set the board LEDs to the new LED mask */\r
-       LEDs_SetAllLEDs(LEDMask);\r
-}\r
-\r
-/** Reconfigures the USART to match the current serial port settings issued by the host as closely as possible. */\r
-void ReconfigureUSART(void)\r
+void EVENT_USB_CDC_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo)\r
 {\r
        uint8_t ConfigMask = 0;\r
 \r
-       /* Determine parity - non odd/even parity mode defaults to no parity */\r
-       if (LineCoding.ParityType == Parity_Odd)\r
+       if (CDCInterfaceInfo->LineEncoding.ParityType == Parity_Odd)\r
          ConfigMask = ((1 << UPM11) | (1 << UPM10));\r
-       else if (LineCoding.ParityType == Parity_Even)\r
+       else if (CDCInterfaceInfo->LineEncoding.ParityType == Parity_Even)\r
          ConfigMask = (1 << UPM11);\r
 \r
-       /* Determine stop bits - 1.5 stop bits is set as 1 stop bit due to hardware limitations */\r
-       if (LineCoding.CharFormat == TwoStopBits)\r
+       if (CDCInterfaceInfo->LineEncoding.CharFormat == TwoStopBits)\r
          ConfigMask |= (1 << USBS1);\r
 \r
-       /* Determine data size - 5, 6, 7, or 8 bits are supported */\r
-       if (LineCoding.DataBits == 6)\r
+       if (CDCInterfaceInfo->LineEncoding.DataBits == 6)\r
          ConfigMask |= (1 << UCSZ10);\r
-       else if (LineCoding.DataBits == 7)\r
+       else if (CDCInterfaceInfo->LineEncoding.DataBits == 7)\r
          ConfigMask |= (1 << UCSZ11);\r
-       else if (LineCoding.DataBits == 8)\r
+       else if (CDCInterfaceInfo->LineEncoding.DataBits == 8)\r
          ConfigMask |= ((1 << UCSZ11) | (1 << UCSZ10));\r
        \r
-       /* Enable double speed, gives better error percentages at 8MHz */\r
-       UCSR1A = (1 << U2X1);\r
-       \r
-       /* Enable transmit and receive modules and interrupts */\r
+       UCSR1A = (1 << U2X1);   \r
        UCSR1B = ((1 << RXCIE1) | (1 << TXEN1) | (1 << RXEN1));\r
-\r
-       /* Set the USART mode to the mask generated by the Line Coding options */\r
-       UCSR1C = ConfigMask;\r
-       \r
-       /* Set the USART baud rate register to the desired baud rate value */\r
-       UBRR1  = SERIAL_2X_UBBRVAL((uint16_t)LineCoding.BaudRateBPS);\r
+       UCSR1C = ConfigMask;    \r
+       UBRR1  = SERIAL_2X_UBBRVAL((uint16_t)CDCInterfaceInfo->LineEncoding.BaudRateBPS);\r
 }\r
index 8e7e8ae..7ff796e 100644 (file)
 \r
                #include "Lib/RingBuff.h"\r
 \r
-               #include <LUFA/Version.h>                         // Library Version Information\r
-               #include <LUFA/Drivers/USB/USB.h>                 // USB Functionality\r
-               #include <LUFA/Drivers/Peripheral/Serial.h>       // USART driver\r
-               #include <LUFA/Drivers/Board/LEDs.h>              // LEDs driver\r
-               #include <LUFA/Scheduler/Scheduler.h>             // Simple scheduler for task management\r
+               #include <LUFA/Version.h>\r
+               #include <LUFA/Drivers/Board/LEDs.h>\r
+               #include <LUFA/Drivers/Board/Joystick.h>\r
+               #include <LUFA/Drivers/Peripheral/Serial.h>\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/CDC.h>\r
 \r
        /* Macros: */\r
-               /** CDC Class specific request to get the current virtual serial port configuration settings. */\r
-               #define REQ_GetLineEncoding          0x21\r
-\r
-               /** CDC Class specific request to set the current virtual serial port configuration settings. */\r
-               #define REQ_SetLineEncoding          0x20\r
-\r
-               /** CDC Class specific request to set the current virtual serial port handshake line states. */\r
-               #define REQ_SetControlLineState      0x22\r
-               \r
-               /** Notification type constant for a change in the virtual serial port handshake line states, for\r
-                *  use with a USB_Notification_Header_t notification structure when sent to the host via the CDC \r
-                *  notification endpoint.\r
-                */\r
-               #define NOTIF_SerialState            0x20\r
-\r
-               /** Mask for the DTR handshake line for use with the REQ_SetControlLineState class specific request\r
-                *  from the host, to indicate that the DTR line state should be high.\r
-                */\r
-               #define CONTROL_LINE_OUT_DTR         (1 << 0)\r
-\r
-               /** Mask for the RTS handshake line for use with the REQ_SetControlLineState class specific request\r
-                *  from the host, to indicate that theRTS line state should be high.\r
-                */\r
-               #define CONTROL_LINE_OUT_RTS         (1 << 1)\r
+               #define LEDMASK_USB_NOTREADY      LEDS_LED1\r
+               #define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)\r
+               #define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)\r
+               #define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)\r
                \r
-               /** Mask for the DCD handshake line for use with the a NOTIF_SerialState class specific notification\r
-                *  from the device to the host, to indicate that the DCD line state is currently high.\r
-                */\r
-               #define CONTROL_LINE_IN_DCD          (1 << 0)\r
-\r
-               /** Mask for the DSR handshake line for use with the a NOTIF_SerialState class specific notification\r
-                *  from the device to the host, to indicate that the DSR line state is currently high.\r
-                */\r
-               #define CONTROL_LINE_IN_DSR          (1 << 1)\r
-\r
-               /** Mask for the BREAK handshake line for use with the a NOTIF_SerialState class specific notification\r
-                *  from the device to the host, to indicate that the BREAK line state is currently high.\r
-                */\r
-               #define CONTROL_LINE_IN_BREAK        (1 << 2)\r
-\r
-               /** Mask for the RING handshake line for use with the a NOTIF_SerialState class specific notification\r
-                *  from the device to the host, to indicate that the RING line state is currently high.\r
-                */\r
-               #define CONTROL_LINE_IN_RING         (1 << 3)\r
-\r
-               /** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,\r
-                *  to indicate that a framing error has occurred on the virtual serial port.\r
-                */\r
-               #define CONTROL_LINE_IN_FRAMEERROR   (1 << 4)\r
-\r
-               /** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,\r
-                *  to indicate that a parity error has occurred on the virtual serial port.\r
-                */\r
-               #define CONTROL_LINE_IN_PARITYERROR  (1 << 5)\r
-\r
-               /** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,\r
-                *  to indicate that a data overrun error has occurred on the virtual serial port.\r
-                */\r
-               #define CONTROL_LINE_IN_OVERRUNERROR (1 << 6)\r
-               \r
-       /* Type Defines: */\r
-               /** Type define for the virtual serial port line encoding settings, for storing the current USART configuration\r
-                *  as set by the host via a class specific request.\r
-                */\r
-               typedef struct\r
-               {\r
-                       uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */\r
-                       uint8_t  CharFormat; /**< Character format of the virtual serial port, a value from the\r
-                                             *   CDCDevice_CDC_LineCodingFormats_t enum\r
-                                             */\r
-                       uint8_t  ParityType; /**< Parity setting of the virtual serial port, a value from the\r
-                                             *   CDCDevice_LineCodingParity_t enum\r
-                                             */\r
-                       uint8_t  DataBits; /**< Bits of data per character of the virtual serial port */\r
-               } CDC_Line_Coding_t;\r
-               \r
-               /** Type define for a CDC notification, sent to the host via the CDC notification endpoint to indicate a\r
-                *  change in the device state asynchronously.\r
-                */\r
-               typedef struct\r
-               {\r
-                       uint8_t  NotificationType; /**< Notification type, a mask of REQDIR_*, REQTYPE_* and REQREC_* constants\r
-                                                   *   from the library StdRequestType.h header\r
-                                                   */\r
-                       uint8_t  Notification; /**< Notification value, a NOTIF_* constant */\r
-                       uint16_t wValue; /**< Notification wValue, notification-specific */\r
-                       uint16_t wIndex; /**< Notification wIndex, notification-specific */\r
-                       uint16_t wLength; /**< Notification wLength, notification-specific */\r
-               } USB_Notification_Header_t;\r
-               \r
-       /* Enums: */\r
-               /** Enum for the possible line encoding formats of a virtual serial port. */\r
-               enum CDCDevice_CDC_LineCodingFormats_t\r
-               {\r
-                       OneStopBit          = 0, /**< Each frame contains one stop bit */\r
-                       OneAndAHalfStopBits = 1, /**< Each frame contains one and a half stop bits */\r
-                       TwoStopBits         = 2, /**< Each frame contains two stop bits */\r
-               };\r
-               \r
-               /** Enum for the possible line encoding parity settings of a virtual serial port. */\r
-               enum CDCDevice_LineCodingParity_t\r
-               {\r
-                       Parity_None         = 0, /**< No parity bit mode on each frame */\r
-                       Parity_Odd          = 1, /**< Odd parity bit mode on each frame */\r
-                       Parity_Even         = 2, /**< Even parity bit mode on each frame */\r
-                       Parity_Mark         = 3, /**< Mark parity bit mode on each frame */\r
-                       Parity_Space        = 4, /**< Space parity bit mode on each frame */\r
-               };\r
-\r
-               /** Enum for the possible status codes for passing to the UpdateStatus() function. */\r
-               enum USBtoSerial_StatusCodes_t\r
-               {\r
-                       Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */\r
-                       Status_USBEnumerating = 1, /**< USB interface is enumerating */\r
-                       Status_USBReady       = 2, /**< USB interface is connected and ready */\r
-               };\r
-               \r
-       /* Tasks: */\r
-               TASK(CDC_Task);\r
-\r
        /* Function Prototypes: */\r
+               void SetupHardware(void);\r
+\r
                void EVENT_USB_Connect(void);\r
                void EVENT_USB_Disconnect(void);\r
                void EVENT_USB_ConfigurationChanged(void);\r
                void EVENT_USB_UnhandledControlPacket(void);\r
-\r
-               void ReconfigureUSART(void);\r
-               void UpdateStatus(uint8_t CurrentStatus);\r
+               void EVENT_USB_StartOfFrame(void);\r
+               \r
+               void EVENT_USB_CDC_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo);\r
 \r
 #endif\r
index 708e872..5cf9c61 100644 (file)
@@ -126,7 +126,6 @@ LUFA_PATH = ../../..
 SRC = $(TARGET).c                                                 \\r
          Descriptors.c                                               \\r
          Lib/RingBuff.c                                              \\r
-         $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \\r
@@ -137,7 +136,7 @@ SRC = $(TARGET).c                                                 \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \\r
-         $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \\r
+         $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/CDC.c            \\r
 \r
 \r
 # List C++ source files here. (C dependencies are automatically generated.)\r
@@ -184,7 +183,7 @@ CSTANDARD = -std=gnu99
 \r
 # Place -D or -U options here for C sources\r
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)\r
-CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY\r
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY\r
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION\r
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"\r
 \r
index b17ae16..b912b2f 100644 (file)
@@ -138,7 +138,7 @@ SRC = $(TARGET).c                                                 \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \\r
-         $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \\r
+         $(LUFA_PATH)/LUFA/Drivers/USB/Class/Host/HIDParser.c        \\r
 \r
 \r
 # List C++ source files here. (C dependencies are automatically generated.)\r
index 95aafca..f47e9f5 100644 (file)
@@ -119,10 +119,10 @@ static uint8_t MassStore_WaitForDataReceived(void)
        while (!(Pipe_IsINReceived()))\r
        {\r
                /* Check to see if a new frame has been issued (1ms elapsed) */\r
-               if (USB_INT_HasOccurred(USB_INT_HSOFI))\r
+               if (FrameElapsed)\r
                {\r
                        /* Clear the flag and decrement the timeout period counter */\r
-                       USB_INT_Clear(USB_INT_HSOFI);\r
+                       FrameElapsed = false;\r
                        TimeoutMSRem--;\r
 \r
                        /* Check to see if the timeout period for the command has elapsed */\r
index 8f05e48..f2f666b 100644 (file)
@@ -109,10 +109,10 @@ uint8_t SImage_RecieveBlockHeader(void)
        while (!(Pipe_IsReadWriteAllowed()))\r
        {\r
                /* Check to see if a new frame has been issued (1ms elapsed) */\r
-               if (USB_INT_HasOccurred(USB_INT_HSOFI))\r
+               if (FrameElapsed)\r
                {\r
                        /* Clear the flag and decrement the timeout period counter */\r
-                       USB_INT_Clear(USB_INT_HSOFI);\r
+                       FrameElapsed = false;\r
                        TimeoutMSRem--;\r
 \r
                        /* Check to see if the timeout period for the command has elapsed */\r
index de4d526..7ae5663 100644 (file)
@@ -45,7 +45,6 @@
                #include <LUFA/Version.h>                               // Library Version Information\r
                #include <LUFA/Drivers/USB/USB.h>                       // USB Functionality\r
                #include <LUFA/Scheduler/Scheduler.h>                   // Simple scheduler for task management\r
-               #include <LUFA/MemoryAllocator/DynAlloc.h>              // Auto-defragmenting Dynamic Memory allocation\r
                #include <LUFA/Drivers/Misc/TerminalCodes.h>            // ANSI Terminal Escape Codes\r
                #include <LUFA/Drivers/Peripheral/ADC.h>                // ADC driver\r
                #include <LUFA/Drivers/Peripheral/SerialStream.h>       // USART Stream driver\r
index dd6d8f4..a8bf4ac 100644 (file)
@@ -127,7 +127,6 @@ SRC = $(TARGET).c                                                 \
          TestEvents.c                                                \\r
          Descriptors.c                                               \\r
          $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \\r
-         $(LUFA_PATH)/LUFA/MemoryAllocator/DynAlloc.c                \\r
          $(LUFA_PATH)/LUFA/Drivers/Board/Temperature.c               \\r
          $(LUFA_PATH)/LUFA/Drivers/Peripheral/SerialStream.c         \\r
          $(LUFA_PATH)/LUFA/Drivers/Peripheral/Serial.c               \\r
@@ -141,7 +140,6 @@ SRC = $(TARGET).c                                                 \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \\r
-         $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \\r
 \r
 \r
 # List C++ source files here. (C dependencies are automatically generated.)\r
@@ -189,7 +187,6 @@ CSTANDARD = -std=gnu99
 # Place -D or -U options here for C sources\r
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)\r
 CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES\r
-CDEFS += -DNUM_BLOCKS=100 -DBLOCK_SIZE=8 -DNUM_HANDLES=20\r
 \r
 \r
 # Place -D or -U options here for ASM sources\r
index 235ccfa..ae38c0b 100644 (file)
@@ -1 +1 @@
-<Project name="LUFA"><Folder name="Demos"><Folder name="Device"><Folder name="AudioInput"><File path="Demos\Device\AudioInput\AudioInput.c"></File><File path="Demos\Device\AudioInput\AudioInput.h"></File><File path="Demos\Device\AudioInput\AudioInput.txt"></File><File path="Demos\Device\AudioInput\Descriptors.c"></File><File path="Demos\Device\AudioInput\Descriptors.h"></File><File path="Demos\Device\AudioInput\Doxygen.conf"></File><File path="Demos\Device\AudioInput\makefile"></File></Folder><Folder name="AudioOutput"><File path="Demos\Device\AudioOutput\AudioOutput.c"></File><File path="Demos\Device\AudioOutput\AudioOutput.h"></File><File path="Demos\Device\AudioOutput\AudioOutput.txt"></File><File path="Demos\Device\AudioOutput\Descriptors.c"></File><File path="Demos\Device\AudioOutput\Descriptors.h"></File><File path="Demos\Device\AudioOutput\Doxygen.conf"></File><File path="Demos\Device\AudioOutput\makefile"></File></Folder><Folder name="CDC"><File path="Demos\Device\CDC\CDC.c"></File><File path="Demos\Device\CDC\CDC.h"></File><File path="Demos\Device\CDC\CDC.txt"></File><File path="Demos\Device\CDC\Descriptors.c"></File><File path="Demos\Device\CDC\Descriptors.h"></File><File path="Demos\Device\CDC\Doxygen.conf"></File><File path="Demos\Device\CDC\LUFA CDC.inf"></File><File path="Demos\Device\CDC\makefile"></File></Folder><Folder name="DualCDC"><File path="Demos\Device\DualCDC\Descriptors.c"></File><File path="Demos\Device\DualCDC\Descriptors.h"></File><File path="Demos\Device\DualCDC\Doxygen.conf"></File><File path="Demos\Device\DualCDC\DualCDC.c"></File><File path="Demos\Device\DualCDC\DualCDC.h"></File><File path="Demos\Device\DualCDC\DualCDC.txt"></File><File path="Demos\Device\DualCDC\LUFA DualCDC.inf"></File><File path="Demos\Device\DualCDC\makefile"></File></Folder><Folder name="GenericHID"><File path="Demos\Device\GenericHID\Descriptors.c"></File><File path="Demos\Device\GenericHID\Descriptors.h"></File><File path="Demos\Device\GenericHID\GenericHID.c"></File><File path="Demos\Device\GenericHID\GenericHID.h"></File><File path="Demos\Device\GenericHID\makefile"></File><File path="Demos\Device\GenericHID\GenericHID.txt"></File><File path="Demos\Device\GenericHID\Doxygen.conf"></File></Folder><Folder name="Joystick"><File path="Demos\Device\Joystick\Descriptors.c"></File><File path="Demos\Device\Joystick\Descriptors.h"></File><File path="Demos\Device\Joystick\Doxygen.conf"></File><File path="Demos\Device\Joystick\Joystick.c"></File><File path="Demos\Device\Joystick\Joystick.h"></File><File path="Demos\Device\Joystick\Joystick.txt"></File><File path="Demos\Device\Joystick\makefile"></File></Folder><Folder name="Keyboard"><File path="Demos\Device\Keyboard\Descriptors.c"></File><File path="Demos\Device\Keyboard\Descriptors.h"></File><File path="Demos\Device\Keyboard\Doxygen.conf"></File><File path="Demos\Device\Keyboard\Keyboard.c"></File><File path="Demos\Device\Keyboard\Keyboard.h"></File><File path="Demos\Device\Keyboard\Keyboard.txt"></File><File path="Demos\Device\Keyboard\makefile"></File></Folder><Folder name="KeyboardMouse"><File path="Demos\Device\KeyboardMouse\Descriptors.c"></File><File path="Demos\Device\KeyboardMouse\Descriptors.h"></File><File path="Demos\Device\KeyboardMouse\Doxygen.conf"></File><File path="Demos\Device\KeyboardMouse\KeyboardMouse.c"></File><File path="Demos\Device\KeyboardMouse\KeyboardMouse.h"></File><File path="Demos\Device\KeyboardMouse\KeyboardMouse.txt"></File><File path="Demos\Device\KeyboardMouse\makefile"></File></Folder><Folder name="MassStorage"><Folder name="Lib"><File path="Demos\Device\MassStorage\Lib\DataflashManager.c"></File><File path="Demos\Device\MassStorage\Lib\DataflashManager.h"></File><File path="Demos\Device\MassStorage\Lib\SCSI.c"></File><File path="Demos\Device\MassStorage\Lib\SCSI.h"></File><File path="Demos\Device\MassStorage\Lib\SCSI_Codes.h"></File></Folder><File path="Demos\Device\MassStorage\Descriptors.c"></File><File path="Demos\Device\MassStorage\Descriptors.h"></File><File path="Demos\Device\MassStorage\Doxygen.conf"></File><File path="Demos\Device\MassStorage\makefile"></File><File path="Demos\Device\MassStorage\MassStorage.c"></File><File path="Demos\Device\MassStorage\MassStorage.h"></File><File path="Demos\Device\MassStorage\MassStorage.txt"></File></Folder><Folder name="MIDI"><File path="Demos\Device\MIDI\Descriptors.c"></File><File path="Demos\Device\MIDI\Descriptors.h"></File><File path="Demos\Device\MIDI\Doxygen.conf"></File><File path="Demos\Device\MIDI\makefile"></File><File path="Demos\Device\MIDI\MIDI.c"></File><File path="Demos\Device\MIDI\MIDI.h"></File><File path="Demos\Device\MIDI\MIDI.txt"></File></Folder><Folder name="Mouse"><File path="Demos\Device\Mouse\Descriptors.c"></File><File path="Demos\Device\Mouse\Descriptors.h"></File><File path="Demos\Device\Mouse\Doxygen.conf"></File><File path="Demos\Device\Mouse\makefile"></File><File path="Demos\Device\Mouse\Mouse.c"></File><File path="Demos\Device\Mouse\Mouse.h"></File><File path="Demos\Device\Mouse\Mouse.txt"></File></Folder><Folder name="RNDISEthernet"><Folder name="Lib"><File path="Demos\Device\RNDISEthernet\Lib\Webserver.h"></File><File path="Demos\Device\RNDISEthernet\Lib\ARP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\ARP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\DHCP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\DHCP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\Ethernet.c"></File><File path="Demos\Device\RNDISEthernet\Lib\Ethernet.h"></File><File path="Demos\Device\RNDISEthernet\Lib\EthernetProtocols.h"></File><File path="Demos\Device\RNDISEthernet\Lib\ICMP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\ICMP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\IP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\IP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\ProtocolDecoders.c"></File><File path="Demos\Device\RNDISEthernet\Lib\ProtocolDecoders.h"></File><File path="Demos\Device\RNDISEthernet\Lib\RNDIS.c"></File><File path="Demos\Device\RNDISEthernet\Lib\RNDIS.h"></File><File path="Demos\Device\RNDISEthernet\Lib\RNDISConstants.h"></File><File path="Demos\Device\RNDISEthernet\Lib\TCP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\TCP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\UDP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\UDP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\Webserver.c"></File></Folder><File path="Demos\Device\RNDISEthernet\Descriptors.c"></File><File path="Demos\Device\RNDISEthernet\Descriptors.h"></File><File path="Demos\Device\RNDISEthernet\Doxygen.conf"></File><File path="Demos\Device\RNDISEthernet\LUFA RNDIS.inf"></File><File path="Demos\Device\RNDISEthernet\makefile"></File><File path="Demos\Device\RNDISEthernet\RNDISEthernet.c"></File><File path="Demos\Device\RNDISEthernet\RNDISEthernet.h"></File><File path="Demos\Device\RNDISEthernet\RNDISEthernet.txt"></File></Folder><Folder name="USBtoSerial"><Folder name="Lib"><File path="Demos\Device\USBtoSerial\Lib\RingBuff.c"></File><File path="Demos\Device\USBtoSerial\Lib\RingBuff.h"></File></Folder><File path="Demos\Device\USBtoSerial\Descriptors.c"></File><File path="Demos\Device\USBtoSerial\Descriptors.h"></File><File path="Demos\Device\USBtoSerial\Doxygen.conf"></File><File path="Demos\Device\USBtoSerial\LUFA USBtoSerial.inf"></File><File path="Demos\Device\USBtoSerial\makefile"></File><File path="Demos\Device\USBtoSerial\USBtoSerial.c"></File><File path="Demos\Device\USBtoSerial\USBtoSerial.h"></File><File path="Demos\Device\USBtoSerial\USBtoSerial.txt"></File></Folder><File path="Demos\Device\makefile"></File></Folder><Folder name="Host"><Folder name="CDCHost"><File path="Demos\Host\CDCHost\CDCHost.c"></File><File path="Demos\Host\CDCHost\CDCHost.h"></File><File path="Demos\Host\CDCHost\CDCHost.txt"></File><File path="Demos\Host\CDCHost\ConfigDescriptor.c"></File><File path="Demos\Host\CDCHost\ConfigDescriptor.h"></File><File path="Demos\Host\CDCHost\Doxygen.conf"></File><File path="Demos\Host\CDCHost\makefile"></File></Folder><Folder name="GenericHIDHost"><File path="Demos\Host\GenericHIDHost\ConfigDescriptor.c"></File><File path="Demos\Host\GenericHIDHost\ConfigDescriptor.h"></File><File path="Demos\Host\GenericHIDHost\GenericHIDHost.c"></File><File path="Demos\Host\GenericHIDHost\GenericHIDHost.h"></File><File path="Demos\Host\GenericHIDHost\makefile"></File><File path="Demos\Host\GenericHIDHost\Doxygen.conf"></File><File path="Demos\Host\GenericHIDHost\GenericHIDHost.txt"></File></Folder><Folder name="KeyboardHost"><File path="Demos\Host\KeyboardHost\ConfigDescriptor.c"></File><File path="Demos\Host\KeyboardHost\ConfigDescriptor.h"></File><File path="Demos\Host\KeyboardHost\Doxygen.conf"></File><File path="Demos\Host\KeyboardHost\KeyboardHost.c"></File><File path="Demos\Host\KeyboardHost\KeyboardHost.h"></File><File path="Demos\Host\KeyboardHost\KeyboardHost.txt"></File><File path="Demos\Host\KeyboardHost\makefile"></File></Folder><Folder name="KeyboardHostWithParser"><File path="Demos\Host\KeyboardHostWithParser\ConfigDescriptor.c"></File><File path="Demos\Host\KeyboardHostWithParser\ConfigDescriptor.h"></File><File path="Demos\Host\KeyboardHostWithParser\Doxygen.conf"></File><File path="Demos\Host\KeyboardHostWithParser\HIDReport.c"></File><File path="Demos\Host\KeyboardHostWithParser\HIDReport.h"></File><File path="Demos\Host\KeyboardHostWithParser\KeyboardHostWithParser.c"></File><File path="Demos\Host\KeyboardHostWithParser\KeyboardHostWithParser.h"></File><File path="Demos\Host\KeyboardHostWithParser\KeyboardHostWithParser.txt"></File><File path="Demos\Host\KeyboardHostWithParser\makefile"></File></Folder><Folder name="MassStorageHost"><Folder name="Lib"><File path="Demos\Host\MassStorageHost\Lib\MassStoreCommands.c"></File><File path="Demos\Host\MassStorageHost\Lib\MassStoreCommands.h"></File><File path="Demos\Host\MassStorageHost\Lib\SCSI_Codes.h"></File></Folder><File path="Demos\Host\MassStorageHost\ConfigDescriptor.c"></File><File path="Demos\Host\MassStorageHost\ConfigDescriptor.h"></File><File path="Demos\Host\MassStorageHost\Doxygen.conf"></File><File path="Demos\Host\MassStorageHost\makefile"></File><File path="Demos\Host\MassStorageHost\MassStorageHost.c"></File><File path="Demos\Host\MassStorageHost\MassStorageHost.h"></File><File path="Demos\Host\MassStorageHost\MassStorageHost.txt"></File></Folder><Folder name="MouseHost"><File path="Demos\Host\MouseHost\ConfigDescriptor.c"></File><File path="Demos\Host\MouseHost\ConfigDescriptor.h"></File><File path="Demos\Host\MouseHost\Doxygen.conf"></File><File path="Demos\Host\MouseHost\makefile"></File><File path="Demos\Host\MouseHost\MouseHost.c"></File><File path="Demos\Host\MouseHost\MouseHost.h"></File><File path="Demos\Host\MouseHost\MouseHost.txt"></File></Folder><Folder name="MouseHostWithParser"><File path="Demos\Host\MouseHostWithParser\ConfigDescriptor.c"></File><File path="Demos\Host\MouseHostWithParser\ConfigDescriptor.h"></File><File path="Demos\Host\MouseHostWithParser\Doxygen.conf"></File><File path="Demos\Host\MouseHostWithParser\HIDReport.c"></File><File path="Demos\Host\MouseHostWithParser\HIDReport.h"></File><File path="Demos\Host\MouseHostWithParser\makefile"></File><File path="Demos\Host\MouseHostWithParser\MouseHostWithParser.c"></File><File path="Demos\Host\MouseHostWithParser\MouseHostWithParser.h"></File><File path="Demos\Host\MouseHostWithParser\MouseHostWithParser.txt"></File></Folder><Folder name="StillImageHost"><Folder name="Lib"><File path="Demos\Host\StillImageHost\Lib\PIMACodes.h"></File><File path="Demos\Host\StillImageHost\Lib\StillImageCommands.c"></File><File path="Demos\Host\StillImageHost\Lib\StillImageCommands.h"></File></Folder><File path="Demos\Host\StillImageHost\ConfigDescriptor.c"></File><File path="Demos\Host\StillImageHost\ConfigDescriptor.h"></File><File path="Demos\Host\StillImageHost\Doxygen.conf"></File><File path="Demos\Host\StillImageHost\makefile"></File><File path="Demos\Host\StillImageHost\StillImageHost.c"></File><File path="Demos\Host\StillImageHost\StillImageHost.h"></File><File path="Demos\Host\StillImageHost\StillImageHost.txt"></File></Folder><File path="Demos\Host\makefile"></File></Folder><Folder name="OTG"><Folder name="TestApp"><File path="Demos\OTG\TestApp\Descriptors.c"></File><File path="Demos\OTG\TestApp\Descriptors.h"></File><File path="Demos\OTG\TestApp\Doxygen.conf"></File><File path="Demos\OTG\TestApp\makefile"></File><File path="Demos\OTG\TestApp\TestApp.c"></File><File path="Demos\OTG\TestApp\TestApp.h"></File><File path="Demos\OTG\TestApp\TestApp.txt"></File><File path="Demos\OTG\TestApp\TestEvents.c"></File><File path="Demos\OTG\TestApp\TestEvents.h"></File></Folder><File path="Demos\OTG\makefile"></File></Folder><File path="Demos\makefile"></File></Folder><Folder name="LUFA"><Folder name="Common"><File path="LUFA\Common\Common.h"></File><File path="LUFA\Common\FunctionAttributes.h"></File><File path="LUFA\Common\BoardTypes.h"></File></Folder><Folder name="Drivers"><Folder name="USB"><Folder name="LowLevel"><File path="LUFA\Drivers\USB\LowLevel\HostChapter9.h"></File><File path="LUFA\Drivers\USB\LowLevel\LowLevel.c"></File><File path="LUFA\Drivers\USB\LowLevel\LowLevel.h"></File><File path="LUFA\Drivers\USB\LowLevel\Pipe.c"></File><File path="LUFA\Drivers\USB\LowLevel\Pipe.h"></File><File path="LUFA\Drivers\USB\LowLevel\DevChapter9.c"></File><File path="LUFA\Drivers\USB\LowLevel\DevChapter9.h"></File><File path="LUFA\Drivers\USB\LowLevel\Device.h"></File><File path="LUFA\Drivers\USB\LowLevel\Endpoint.c"></File><File path="LUFA\Drivers\USB\LowLevel\Endpoint.h"></File><File path="LUFA\Drivers\USB\LowLevel\Host.c"></File><File path="LUFA\Drivers\USB\LowLevel\Host.h"></File><File path="LUFA\Drivers\USB\LowLevel\HostChapter9.c"></File><File path="LUFA\Drivers\USB\LowLevel\OTG.h"></File></Folder><Folder name="HighLevel"><File path="LUFA\Drivers\USB\HighLevel\USBTask.h"></File><File path="LUFA\Drivers\USB\HighLevel\Events.c"></File><File path="LUFA\Drivers\USB\HighLevel\Events.h"></File><File path="LUFA\Drivers\USB\HighLevel\USBInterrupt.c"></File><File path="LUFA\Drivers\USB\HighLevel\USBInterrupt.h"></File><File path="LUFA\Drivers\USB\HighLevel\USBTask.c"></File><File path="LUFA\Drivers\USB\HighLevel\StdDescriptors.h"></File><File path="LUFA\Drivers\USB\HighLevel\StdRequestType.h"></File><File path="LUFA\Drivers\USB\HighLevel\StreamCallbacks.h"></File><File path="LUFA\Drivers\USB\HighLevel\USBMode.h"></File><File path="LUFA\Drivers\USB\HighLevel\ConfigDescriptor.c"></File><File path="LUFA\Drivers\USB\HighLevel\ConfigDescriptor.h"></File></Folder><Folder name="Class"><File path="LUFA\Drivers\USB\Class\HIDParser.c"></File><File path="LUFA\Drivers\USB\Class\HIDParser.h"></File><File path="LUFA\Drivers\USB\Class\HIDReportData.h"></File></Folder><File path="LUFA\Drivers\USB\USB.h"></File></Folder><Folder name="Misc"><File path="LUFA\Drivers\Misc\TerminalCodes.h"></File></Folder><Folder name="Board"><Folder name="USBKEY"><File path="LUFA\Drivers\Board\USBKEY\Dataflash.h"></File><File path="LUFA\Drivers\Board\USBKEY\Joystick.h"></File><File path="LUFA\Drivers\Board\USBKEY\AT45DB642D.h"></File><File path="LUFA\Drivers\Board\USBKEY\LEDs.h"></File><File path="LUFA\Drivers\Board\USBKEY\Buttons.h"></File></Folder><Folder name="STK526"><File path="LUFA\Drivers\Board\STK526\Dataflash.h"></File><File path="LUFA\Drivers\Board\STK526\Joystick.h"></File><File path="LUFA\Drivers\Board\STK526\AT45DB642D.h"></File><File path="LUFA\Drivers\Board\STK526\LEDs.h"></File><File path="LUFA\Drivers\Board\STK526\Buttons.h"></File></Folder><Folder name="STK525"><File path="LUFA\Drivers\Board\STK525\Dataflash.h"></File><File path="LUFA\Drivers\Board\STK525\Joystick.h"></File><File path="LUFA\Drivers\Board\STK525\AT45DB321C.h"></File><File path="LUFA\Drivers\Board\STK525\LEDs.h"></File><File path="LUFA\Drivers\Board\STK525\Buttons.h"></File></Folder><Folder name="RZUSBSTICK"><File path="LUFA\Drivers\Board\RZUSBSTICK\LEDs.h"></File></Folder><Folder name="ATAVRUSBRF01"><File path="LUFA\Drivers\Board\ATAVRUSBRF01\LEDs.h"></File><File path="LUFA\Drivers\Board\ATAVRUSBRF01\Buttons.h"></File></Folder><File path="LUFA\Drivers\Board\Temperature.h"></File><File path="LUFA\Drivers\Board\Dataflash.h"></File><File path="LUFA\Drivers\Board\Joystick.h"></File><File path="LUFA\Drivers\Board\Temperature.c"></File><File path="LUFA\Drivers\Board\LEDs.h"></File><File path="LUFA\Drivers\Board\Buttons.h"></File></Folder><Folder name="Peripheral"><Folder name="AT90USBXXX67"><File path="LUFA\Drivers\Peripheral\AT90USBXXX67\ADC.h"></File></Folder><File path="LUFA\Drivers\Peripheral\ADC.h"></File><File path="LUFA\Drivers\Peripheral\Serial.c"></File><File path="LUFA\Drivers\Peripheral\Serial.h"></File><File path="LUFA\Drivers\Peripheral\SPI.h"></File><File path="LUFA\Drivers\Peripheral\SerialStream.c"></File><File path="LUFA\Drivers\Peripheral\SerialStream.h"></File></Folder></Folder><Folder name="Scheduler"><File path="LUFA\Scheduler\Scheduler.h"></File><File path="LUFA\Scheduler\Scheduler.c"></File></Folder><Folder name="MemoryAllocator"><File path="LUFA\MemoryAllocator\DynAlloc.h"></File><File path="LUFA\MemoryAllocator\DynAlloc.c"></File></Folder><Folder name="DriverStubs"><File path="LUFA\DriverStubs\Dataflash.h"></File><File path="LUFA\DriverStubs\Joystick.h"></File><File path="LUFA\DriverStubs\LEDs.h"></File><File path="LUFA\DriverStubs\Buttons.h"></File></Folder><File path="LUFA\makefile"></File><File path="LUFA\Version.h"></File><File path="LUFA\BuildingLinkableLibraries.txt"></File><File path="LUFA\ChangeLog.txt"></File><File path="LUFA\CompileTimeTokens.txt"></File><File path="LUFA\DirectorySummaries.txt"></File><File path="LUFA\Doxygen.conf"></File><File path="LUFA\GettingStarted.txt"></File><File path="LUFA\Groups.txt"></File><File path="LUFA\LUFAPoweredProjects.txt"></File><File path="LUFA\MainPage.txt"></File><File path="LUFA\MigrationInformation.txt"></File><File path="LUFA\SchedulerOverview.txt"></File><File path="LUFA\VIDAndPIDValues.txt"></File><File path="LUFA\WritingBoardDrivers.txt"></File></Folder><Folder name="Projects"><Folder name="MagStripe"><Folder name="Lib"><File path="Projects\Magstripe\Lib\CircularBitBuffer.c"></File><File path="Projects\Magstripe\Lib\CircularBitBuffer.h"></File><File path="Projects\Magstripe\Lib\MagstripeHW.h"></File></Folder><File path="Projects\Magstripe\Descriptors.c"></File><File path="Projects\Magstripe\Descriptors.h"></File><File path="Projects\Magstripe\Magstripe.c"></File><File path="Projects\Magstripe\Magstripe.h"></File><File path="Projects\Magstripe\makefile"></File><File path="Projects\Magstripe\Magstripe.txt"></File><File path="Projects\Magstripe\Doxygen.conf"></File></Folder><File path="Projects\makefile"></File></Folder><Folder name="Bootloaders"><Folder name="DFU"><File path="Bootloaders\DFU\BootloaderDFU.c"></File><File path="Bootloaders\DFU\BootloaderDFU.h"></File><File path="Bootloaders\DFU\Descriptors.c"></File><File path="Bootloaders\DFU\Descriptors.h"></File><File path="Bootloaders\DFU\makefile"></File><File path="Bootloaders\DFU\BootloaderDFU.txt"></File><File path="Bootloaders\DFU\Doxygen.conf"></File></Folder><Folder name="CDC"><File path="Bootloaders\CDC\BootloaderCDC.c"></File><File path="Bootloaders\CDC\BootloaderCDC.h"></File><File path="Bootloaders\CDC\Descriptors.c"></File><File path="Bootloaders\CDC\Descriptors.h"></File><File path="Bootloaders\CDC\makefile"></File><File path="Bootloaders\CDC\LUFA CDC Bootloader.inf"></File><File path="Bootloaders\CDC\Doxygen.conf"></File><File path="Bootloaders\CDC\BootloaderCDC.txt"></File></Folder><Folder name="TeensyHID"><File path="Bootloaders\TeensyHID\Descriptors.c"></File><File path="Bootloaders\TeensyHID\Descriptors.h"></File><File path="Bootloaders\TeensyHID\makefile"></File><File path="Bootloaders\TeensyHID\TeensyHID.c"></File><File path="Bootloaders\TeensyHID\TeensyHID.h"></File><File path="Bootloaders\TeensyHID\TeensyHID.txt"></File></Folder><File path="Bootloaders\makefile"></File></Folder><File path="makefile"></File></Project>
\ No newline at end of file
+<Project name="LUFA"><Folder name="Demos"><Folder name="Device"><Folder name="AudioInput"><File path="Demos\Device\AudioInput\AudioInput.c"></File><File path="Demos\Device\AudioInput\AudioInput.h"></File><File path="Demos\Device\AudioInput\AudioInput.txt"></File><File path="Demos\Device\AudioInput\Descriptors.c"></File><File path="Demos\Device\AudioInput\Descriptors.h"></File><File path="Demos\Device\AudioInput\Doxygen.conf"></File><File path="Demos\Device\AudioInput\makefile"></File></Folder><Folder name="AudioOutput"><File path="Demos\Device\AudioOutput\AudioOutput.c"></File><File path="Demos\Device\AudioOutput\AudioOutput.h"></File><File path="Demos\Device\AudioOutput\AudioOutput.txt"></File><File path="Demos\Device\AudioOutput\Descriptors.c"></File><File path="Demos\Device\AudioOutput\Descriptors.h"></File><File path="Demos\Device\AudioOutput\Doxygen.conf"></File><File path="Demos\Device\AudioOutput\makefile"></File></Folder><Folder name="CDC"><File path="Demos\Device\CDC\CDC.c"></File><File path="Demos\Device\CDC\CDC.h"></File><File path="Demos\Device\CDC\CDC.txt"></File><File path="Demos\Device\CDC\Descriptors.c"></File><File path="Demos\Device\CDC\Descriptors.h"></File><File path="Demos\Device\CDC\Doxygen.conf"></File><File path="Demos\Device\CDC\LUFA CDC.inf"></File><File path="Demos\Device\CDC\makefile"></File></Folder><Folder name="DualCDC"><File path="Demos\Device\DualCDC\Descriptors.c"></File><File path="Demos\Device\DualCDC\Descriptors.h"></File><File path="Demos\Device\DualCDC\Doxygen.conf"></File><File path="Demos\Device\DualCDC\DualCDC.c"></File><File path="Demos\Device\DualCDC\DualCDC.h"></File><File path="Demos\Device\DualCDC\DualCDC.txt"></File><File path="Demos\Device\DualCDC\LUFA DualCDC.inf"></File><File path="Demos\Device\DualCDC\makefile"></File></Folder><Folder name="GenericHID"><File path="Demos\Device\GenericHID\Descriptors.c"></File><File path="Demos\Device\GenericHID\Descriptors.h"></File><File path="Demos\Device\GenericHID\GenericHID.c"></File><File path="Demos\Device\GenericHID\GenericHID.h"></File><File path="Demos\Device\GenericHID\makefile"></File><File path="Demos\Device\GenericHID\GenericHID.txt"></File><File path="Demos\Device\GenericHID\Doxygen.conf"></File></Folder><Folder name="Joystick"><File path="Demos\Device\Joystick\Descriptors.c"></File><File path="Demos\Device\Joystick\Descriptors.h"></File><File path="Demos\Device\Joystick\Doxygen.conf"></File><File path="Demos\Device\Joystick\Joystick.c"></File><File path="Demos\Device\Joystick\Joystick.h"></File><File path="Demos\Device\Joystick\Joystick.txt"></File><File path="Demos\Device\Joystick\makefile"></File></Folder><Folder name="Keyboard"><File path="Demos\Device\Keyboard\Descriptors.c"></File><File path="Demos\Device\Keyboard\Descriptors.h"></File><File path="Demos\Device\Keyboard\Doxygen.conf"></File><File path="Demos\Device\Keyboard\Keyboard.c"></File><File path="Demos\Device\Keyboard\Keyboard.h"></File><File path="Demos\Device\Keyboard\Keyboard.txt"></File><File path="Demos\Device\Keyboard\makefile"></File></Folder><Folder name="KeyboardMouse"><File path="Demos\Device\KeyboardMouse\Descriptors.c"></File><File path="Demos\Device\KeyboardMouse\Descriptors.h"></File><File path="Demos\Device\KeyboardMouse\Doxygen.conf"></File><File path="Demos\Device\KeyboardMouse\KeyboardMouse.c"></File><File path="Demos\Device\KeyboardMouse\KeyboardMouse.h"></File><File path="Demos\Device\KeyboardMouse\KeyboardMouse.txt"></File><File path="Demos\Device\KeyboardMouse\makefile"></File></Folder><Folder name="MassStorage"><Folder name="Lib"><File path="Demos\Device\MassStorage\Lib\DataflashManager.c"></File><File path="Demos\Device\MassStorage\Lib\DataflashManager.h"></File><File path="Demos\Device\MassStorage\Lib\SCSI.c"></File><File path="Demos\Device\MassStorage\Lib\SCSI.h"></File><File path="Demos\Device\MassStorage\Lib\SCSI_Codes.h"></File></Folder><File path="Demos\Device\MassStorage\Descriptors.c"></File><File path="Demos\Device\MassStorage\Descriptors.h"></File><File path="Demos\Device\MassStorage\Doxygen.conf"></File><File path="Demos\Device\MassStorage\makefile"></File><File path="Demos\Device\MassStorage\MassStorage.c"></File><File path="Demos\Device\MassStorage\MassStorage.h"></File><File path="Demos\Device\MassStorage\MassStorage.txt"></File></Folder><Folder name="MIDI"><File path="Demos\Device\MIDI\Descriptors.c"></File><File path="Demos\Device\MIDI\Descriptors.h"></File><File path="Demos\Device\MIDI\Doxygen.conf"></File><File path="Demos\Device\MIDI\makefile"></File><File path="Demos\Device\MIDI\MIDI.c"></File><File path="Demos\Device\MIDI\MIDI.h"></File><File path="Demos\Device\MIDI\MIDI.txt"></File></Folder><Folder name="Mouse"><File path="Demos\Device\Mouse\Descriptors.c"></File><File path="Demos\Device\Mouse\Descriptors.h"></File><File path="Demos\Device\Mouse\Doxygen.conf"></File><File path="Demos\Device\Mouse\makefile"></File><File path="Demos\Device\Mouse\Mouse.c"></File><File path="Demos\Device\Mouse\Mouse.h"></File><File path="Demos\Device\Mouse\Mouse.txt"></File></Folder><Folder name="RNDISEthernet"><Folder name="Lib"><File path="Demos\Device\RNDISEthernet\Lib\Webserver.h"></File><File path="Demos\Device\RNDISEthernet\Lib\ARP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\ARP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\DHCP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\DHCP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\Ethernet.c"></File><File path="Demos\Device\RNDISEthernet\Lib\Ethernet.h"></File><File path="Demos\Device\RNDISEthernet\Lib\EthernetProtocols.h"></File><File path="Demos\Device\RNDISEthernet\Lib\ICMP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\ICMP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\IP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\IP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\ProtocolDecoders.c"></File><File path="Demos\Device\RNDISEthernet\Lib\ProtocolDecoders.h"></File><File path="Demos\Device\RNDISEthernet\Lib\TCP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\TCP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\UDP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\UDP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\Webserver.c"></File></Folder><File path="Demos\Device\RNDISEthernet\Descriptors.c"></File><File path="Demos\Device\RNDISEthernet\Descriptors.h"></File><File path="Demos\Device\RNDISEthernet\Doxygen.conf"></File><File path="Demos\Device\RNDISEthernet\LUFA RNDIS.inf"></File><File path="Demos\Device\RNDISEthernet\makefile"></File><File path="Demos\Device\RNDISEthernet\RNDISEthernet.c"></File><File path="Demos\Device\RNDISEthernet\RNDISEthernet.h"></File><File path="Demos\Device\RNDISEthernet\RNDISEthernet.txt"></File></Folder><Folder name="USBtoSerial"><Folder name="Lib"><File path="Demos\Device\USBtoSerial\Lib\RingBuff.c"></File><File path="Demos\Device\USBtoSerial\Lib\RingBuff.h"></File></Folder><File path="Demos\Device\USBtoSerial\Descriptors.c"></File><File path="Demos\Device\USBtoSerial\Descriptors.h"></File><File path="Demos\Device\USBtoSerial\Doxygen.conf"></File><File path="Demos\Device\USBtoSerial\LUFA USBtoSerial.inf"></File><File path="Demos\Device\USBtoSerial\makefile"></File><File path="Demos\Device\USBtoSerial\USBtoSerial.c"></File><File path="Demos\Device\USBtoSerial\USBtoSerial.h"></File><File path="Demos\Device\USBtoSerial\USBtoSerial.txt"></File></Folder><File path="Demos\Device\makefile"></File></Folder><Folder name="Host"><Folder name="CDCHost"><File path="Demos\Host\CDCHost\CDCHost.c"></File><File path="Demos\Host\CDCHost\CDCHost.h"></File><File path="Demos\Host\CDCHost\CDCHost.txt"></File><File path="Demos\Host\CDCHost\ConfigDescriptor.c"></File><File path="Demos\Host\CDCHost\ConfigDescriptor.h"></File><File path="Demos\Host\CDCHost\Doxygen.conf"></File><File path="Demos\Host\CDCHost\makefile"></File></Folder><Folder name="GenericHIDHost"><File path="Demos\Host\GenericHIDHost\ConfigDescriptor.c"></File><File path="Demos\Host\GenericHIDHost\ConfigDescriptor.h"></File><File path="Demos\Host\GenericHIDHost\GenericHIDHost.c"></File><File path="Demos\Host\GenericHIDHost\GenericHIDHost.h"></File><File path="Demos\Host\GenericHIDHost\makefile"></File><File path="Demos\Host\GenericHIDHost\Doxygen.conf"></File><File path="Demos\Host\GenericHIDHost\GenericHIDHost.txt"></File></Folder><Folder name="KeyboardHost"><File path="Demos\Host\KeyboardHost\ConfigDescriptor.c"></File><File path="Demos\Host\KeyboardHost\ConfigDescriptor.h"></File><File path="Demos\Host\KeyboardHost\Doxygen.conf"></File><File path="Demos\Host\KeyboardHost\KeyboardHost.c"></File><File path="Demos\Host\KeyboardHost\KeyboardHost.h"></File><File path="Demos\Host\KeyboardHost\KeyboardHost.txt"></File><File path="Demos\Host\KeyboardHost\makefile"></File></Folder><Folder name="KeyboardHostWithParser"><File path="Demos\Host\KeyboardHostWithParser\ConfigDescriptor.c"></File><File path="Demos\Host\KeyboardHostWithParser\ConfigDescriptor.h"></File><File path="Demos\Host\KeyboardHostWithParser\Doxygen.conf"></File><File path="Demos\Host\KeyboardHostWithParser\HIDReport.c"></File><File path="Demos\Host\KeyboardHostWithParser\HIDReport.h"></File><File path="Demos\Host\KeyboardHostWithParser\KeyboardHostWithParser.c"></File><File path="Demos\Host\KeyboardHostWithParser\KeyboardHostWithParser.h"></File><File path="Demos\Host\KeyboardHostWithParser\KeyboardHostWithParser.txt"></File><File path="Demos\Host\KeyboardHostWithParser\makefile"></File></Folder><Folder name="MassStorageHost"><Folder name="Lib"><File path="Demos\Host\MassStorageHost\Lib\MassStoreCommands.c"></File><File path="Demos\Host\MassStorageHost\Lib\MassStoreCommands.h"></File><File path="Demos\Host\MassStorageHost\Lib\SCSI_Codes.h"></File></Folder><File path="Demos\Host\MassStorageHost\ConfigDescriptor.c"></File><File path="Demos\Host\MassStorageHost\ConfigDescriptor.h"></File><File path="Demos\Host\MassStorageHost\Doxygen.conf"></File><File path="Demos\Host\MassStorageHost\makefile"></File><File path="Demos\Host\MassStorageHost\MassStorageHost.c"></File><File path="Demos\Host\MassStorageHost\MassStorageHost.h"></File><File path="Demos\Host\MassStorageHost\MassStorageHost.txt"></File></Folder><Folder name="MouseHost"><File path="Demos\Host\MouseHost\ConfigDescriptor.c"></File><File path="Demos\Host\MouseHost\ConfigDescriptor.h"></File><File path="Demos\Host\MouseHost\Doxygen.conf"></File><File path="Demos\Host\MouseHost\makefile"></File><File path="Demos\Host\MouseHost\MouseHost.c"></File><File path="Demos\Host\MouseHost\MouseHost.h"></File><File path="Demos\Host\MouseHost\MouseHost.txt"></File></Folder><Folder name="MouseHostWithParser"><File path="Demos\Host\MouseHostWithParser\ConfigDescriptor.c"></File><File path="Demos\Host\MouseHostWithParser\ConfigDescriptor.h"></File><File path="Demos\Host\MouseHostWithParser\Doxygen.conf"></File><File path="Demos\Host\MouseHostWithParser\HIDReport.c"></File><File path="Demos\Host\MouseHostWithParser\HIDReport.h"></File><File path="Demos\Host\MouseHostWithParser\makefile"></File><File path="Demos\Host\MouseHostWithParser\MouseHostWithParser.c"></File><File path="Demos\Host\MouseHostWithParser\MouseHostWithParser.h"></File><File path="Demos\Host\MouseHostWithParser\MouseHostWithParser.txt"></File></Folder><Folder name="StillImageHost"><Folder name="Lib"><File path="Demos\Host\StillImageHost\Lib\PIMACodes.h"></File><File path="Demos\Host\StillImageHost\Lib\StillImageCommands.c"></File><File path="Demos\Host\StillImageHost\Lib\StillImageCommands.h"></File></Folder><File path="Demos\Host\StillImageHost\ConfigDescriptor.c"></File><File path="Demos\Host\StillImageHost\ConfigDescriptor.h"></File><File path="Demos\Host\StillImageHost\Doxygen.conf"></File><File path="Demos\Host\StillImageHost\makefile"></File><File path="Demos\Host\StillImageHost\StillImageHost.c"></File><File path="Demos\Host\StillImageHost\StillImageHost.h"></File><File path="Demos\Host\StillImageHost\StillImageHost.txt"></File></Folder><File path="Demos\Host\makefile"></File></Folder><Folder name="OTG"><Folder name="TestApp"><File path="Demos\OTG\TestApp\Descriptors.c"></File><File path="Demos\OTG\TestApp\Descriptors.h"></File><File path="Demos\OTG\TestApp\Doxygen.conf"></File><File path="Demos\OTG\TestApp\makefile"></File><File path="Demos\OTG\TestApp\TestApp.c"></File><File path="Demos\OTG\TestApp\TestApp.h"></File><File path="Demos\OTG\TestApp\TestApp.txt"></File><File path="Demos\OTG\TestApp\TestEvents.c"></File><File path="Demos\OTG\TestApp\TestEvents.h"></File></Folder><File path="Demos\OTG\makefile"></File></Folder><File path="Demos\makefile"></File></Folder><Folder name="LUFA"><Folder name="Common"><File path="LUFA\Common\Common.h"></File><File path="LUFA\Common\FunctionAttributes.h"></File><File path="LUFA\Common\BoardTypes.h"></File></Folder><Folder name="Drivers"><Folder name="USB"><Folder name="LowLevel"><File path="LUFA\Drivers\USB\LowLevel\HostChapter9.h"></File><File path="LUFA\Drivers\USB\LowLevel\LowLevel.c"></File><File path="LUFA\Drivers\USB\LowLevel\LowLevel.h"></File><File path="LUFA\Drivers\USB\LowLevel\Pipe.c"></File><File path="LUFA\Drivers\USB\LowLevel\Pipe.h"></File><File path="LUFA\Drivers\USB\LowLevel\DevChapter9.c"></File><File path="LUFA\Drivers\USB\LowLevel\DevChapter9.h"></File><File path="LUFA\Drivers\USB\LowLevel\Device.h"></File><File path="LUFA\Drivers\USB\LowLevel\Endpoint.c"></File><File path="LUFA\Drivers\USB\LowLevel\Endpoint.h"></File><File path="LUFA\Drivers\USB\LowLevel\Host.c"></File><File path="LUFA\Drivers\USB\LowLevel\Host.h"></File><File path="LUFA\Drivers\USB\LowLevel\HostChapter9.c"></File><File path="LUFA\Drivers\USB\LowLevel\OTG.h"></File></Folder><Folder name="HighLevel"><File path="LUFA\Drivers\USB\HighLevel\USBTask.h"></File><File path="LUFA\Drivers\USB\HighLevel\Events.c"></File><File path="LUFA\Drivers\USB\HighLevel\Events.h"></File><File path="LUFA\Drivers\USB\HighLevel\USBInterrupt.c"></File><File path="LUFA\Drivers\USB\HighLevel\USBInterrupt.h"></File><File path="LUFA\Drivers\USB\HighLevel\USBTask.c"></File><File path="LUFA\Drivers\USB\HighLevel\StdDescriptors.h"></File><File path="LUFA\Drivers\USB\HighLevel\StdRequestType.h"></File><File path="LUFA\Drivers\USB\HighLevel\StreamCallbacks.h"></File><File path="LUFA\Drivers\USB\HighLevel\USBMode.h"></File><File path="LUFA\Drivers\USB\HighLevel\ConfigDescriptor.c"></File><File path="LUFA\Drivers\USB\HighLevel\ConfigDescriptor.h"></File></Folder><Folder name="Class"><Folder name="Device"><File path="LUFA\Drivers\USB\Class\Device\HID.c"></File><File path="LUFA\Drivers\USB\Class\Device\HID.h"></File><File path="LUFA\Drivers\USB\Class\Device\CDC.c"></File><File path="LUFA\Drivers\USB\Class\Device\CDC.h"></File><File path="LUFA\Drivers\USB\Class\Device\RNDIS.c"></File><File path="LUFA\Drivers\USB\Class\Device\RNDIS.h"></File><File path="LUFA\Drivers\USB\Class\Device\RNDISConstants.h"></File><File path="LUFA\Drivers\USB\Class\Device\MassStorage.c"></File><File path="LUFA\Drivers\USB\Class\Device\MassStorage.h"></File><File path="LUFA\Drivers\USB\Class\Device\Audio.c"></File><File path="LUFA\Drivers\USB\Class\Device\Audio.h"></File></Folder><Folder name="Host"><File path="LUFA\Drivers\USB\Class\Host\HIDParser.c"></File><File path="LUFA\Drivers\USB\Class\Host\HIDParser.h"></File><File path="LUFA\Drivers\USB\Class\Host\HIDReportData.h"></File></Folder></Folder><File path="LUFA\Drivers\USB\USB.h"></File></Folder><Folder name="Misc"><File path="LUFA\Drivers\Misc\TerminalCodes.h"></File></Folder><Folder name="Board"><Folder name="USBKEY"><File path="LUFA\Drivers\Board\USBKEY\Dataflash.h"></File><File path="LUFA\Drivers\Board\USBKEY\Joystick.h"></File><File path="LUFA\Drivers\Board\USBKEY\AT45DB642D.h"></File><File path="LUFA\Drivers\Board\USBKEY\LEDs.h"></File><File path="LUFA\Drivers\Board\USBKEY\Buttons.h"></File></Folder><Folder name="STK526"><File path="LUFA\Drivers\Board\STK526\Dataflash.h"></File><File path="LUFA\Drivers\Board\STK526\Joystick.h"></File><File path="LUFA\Drivers\Board\STK526\AT45DB642D.h"></File><File path="LUFA\Drivers\Board\STK526\LEDs.h"></File><File path="LUFA\Drivers\Board\STK526\Buttons.h"></File></Folder><Folder name="STK525"><File path="LUFA\Drivers\Board\STK525\Dataflash.h"></File><File path="LUFA\Drivers\Board\STK525\Joystick.h"></File><File path="LUFA\Drivers\Board\STK525\AT45DB321C.h"></File><File path="LUFA\Drivers\Board\STK525\LEDs.h"></File><File path="LUFA\Drivers\Board\STK525\Buttons.h"></File></Folder><Folder name="RZUSBSTICK"><File path="LUFA\Drivers\Board\RZUSBSTICK\LEDs.h"></File></Folder><Folder name="ATAVRUSBRF01"><File path="LUFA\Drivers\Board\ATAVRUSBRF01\LEDs.h"></File><File path="LUFA\Drivers\Board\ATAVRUSBRF01\Buttons.h"></File></Folder><File path="LUFA\Drivers\Board\Temperature.h"></File><File path="LUFA\Drivers\Board\Dataflash.h"></File><File path="LUFA\Drivers\Board\Joystick.h"></File><File path="LUFA\Drivers\Board\Temperature.c"></File><File path="LUFA\Drivers\Board\LEDs.h"></File><File path="LUFA\Drivers\Board\Buttons.h"></File></Folder><Folder name="Peripheral"><Folder name="AT90USBXXX67"><File path="LUFA\Drivers\Peripheral\AT90USBXXX67\ADC.h"></File></Folder><File path="LUFA\Drivers\Peripheral\ADC.h"></File><File path="LUFA\Drivers\Peripheral\Serial.c"></File><File path="LUFA\Drivers\Peripheral\Serial.h"></File><File path="LUFA\Drivers\Peripheral\SPI.h"></File><File path="LUFA\Drivers\Peripheral\SerialStream.c"></File><File path="LUFA\Drivers\Peripheral\SerialStream.h"></File></Folder></Folder><Folder name="DriverStubs"><File path="LUFA\DriverStubs\Dataflash.h"></File><File path="LUFA\DriverStubs\Joystick.h"></File><File path="LUFA\DriverStubs\LEDs.h"></File><File path="LUFA\DriverStubs\Buttons.h"></File></Folder><File path="LUFA\makefile"></File><File path="LUFA\Version.h"></File><File path="LUFA\BuildingLinkableLibraries.txt"></File><File path="LUFA\ChangeLog.txt"></File><File path="LUFA\CompileTimeTokens.txt"></File><File path="LUFA\DirectorySummaries.txt"></File><File path="LUFA\Doxygen.conf"></File><File path="LUFA\GettingStarted.txt"></File><File path="LUFA\Groups.txt"></File><File path="LUFA\LUFAPoweredProjects.txt"></File><File path="LUFA\MainPage.txt"></File><File path="LUFA\MigrationInformation.txt"></File><File path="LUFA\VIDAndPIDValues.txt"></File><File path="LUFA\WritingBoardDrivers.txt"></File></Folder><Folder name="Projects"><Folder name="MagStripe"><Folder name="Lib"><File path="Projects\Magstripe\Lib\CircularBitBuffer.c"></File><File path="Projects\Magstripe\Lib\CircularBitBuffer.h"></File><File path="Projects\Magstripe\Lib\MagstripeHW.h"></File></Folder><File path="Projects\Magstripe\Descriptors.c"></File><File path="Projects\Magstripe\Descriptors.h"></File><File path="Projects\Magstripe\Magstripe.c"></File><File path="Projects\Magstripe\Magstripe.h"></File><File path="Projects\Magstripe\makefile"></File><File path="Projects\Magstripe\Magstripe.txt"></File><File path="Projects\Magstripe\Doxygen.conf"></File></Folder><File path="Projects\makefile"></File></Folder><Folder name="Bootloaders"><Folder name="DFU"><File path="Bootloaders\DFU\BootloaderDFU.c"></File><File path="Bootloaders\DFU\BootloaderDFU.h"></File><File path="Bootloaders\DFU\Descriptors.c"></File><File path="Bootloaders\DFU\Descriptors.h"></File><File path="Bootloaders\DFU\makefile"></File><File path="Bootloaders\DFU\BootloaderDFU.txt"></File><File path="Bootloaders\DFU\Doxygen.conf"></File></Folder><Folder name="CDC"><File path="Bootloaders\CDC\BootloaderCDC.c"></File><File path="Bootloaders\CDC\BootloaderCDC.h"></File><File path="Bootloaders\CDC\Descriptors.c"></File><File path="Bootloaders\CDC\Descriptors.h"></File><File path="Bootloaders\CDC\makefile"></File><File path="Bootloaders\CDC\LUFA CDC Bootloader.inf"></File><File path="Bootloaders\CDC\Doxygen.conf"></File><File path="Bootloaders\CDC\BootloaderCDC.txt"></File></Folder><Folder name="TeensyHID"><File path="Bootloaders\TeensyHID\Descriptors.c"></File><File path="Bootloaders\TeensyHID\Descriptors.h"></File><File path="Bootloaders\TeensyHID\makefile"></File><File path="Bootloaders\TeensyHID\TeensyHID.c"></File><File path="Bootloaders\TeensyHID\TeensyHID.h"></File><File path="Bootloaders\TeensyHID\TeensyHID.txt"></File></Folder><File path="Bootloaders\makefile"></File></Folder><File path="makefile"></File></Project>
\ No newline at end of file
index ac67534..fe3b633 100644 (file)
@@ -4,6 +4,14 @@
  *  documentation pages. It is not a project source file.\r
  */\r
    \r
+========== TODO: ===========\r
+       - Document new class drivers\r
+       - Re-document all demos now that they have changed\r
+       - Add standardized descriptor names to class driver structures, controlled by USE_NONSTANDARD_DESCRIPTOR_NAMES\r
+       - Add C++ compatibility to class drivers\r
+       - Disable JTAG in demos\r
+============================\r
+\r
  /** \page Page_ChangeLog Project Changelog\r
   *\r
   *  \section Sec_ChangeLogXXXXXX Version XXXXXX\r
@@ -30,6 +38,8 @@
   *    LUFA/Drivers/USB/Class/ directory to LUFA/Drivers/USB/HighLevel/ in preperation for the new USB class APIs\r
   *  - Moved out each demos' functionality library files (e.g. Ring Buffer library) to /Lib directories for a better directory structure\r
   *  - Removed Tx interrupt from the USBtoSerial demo; now sends characters via polling to ensure more time for the Rx interrupt\r
+  *  - Added new EVENT_USB_StartOfFrame event in the library to indicate the start of each USB frame (when generated)\r
+  *  - Removed psuedo-scheduler, dynamic memory block allocator from the library (no longer needed and not used respectively)\r
   *\r
   *\r
   *  \section Sec_ChangeLog090510 Version 090510\r
index f439847..3fae9c1 100644 (file)
  *  This folder contains header files which are common to all parts of the LUFA library. They may be used freely in\r
  *  user applications.\r
  *\r
- *  \dir MemoryAllocator\r
- *  \brief Auto-defragmenting dynamic memory allocation library.\r
- *  \r
- *  This folder contains a simple handle-based dynamic memory allocation library, capable of handing out memory in\r
- *  block chunks. As new memory is allocated, the library will defragment the already allocated memory to ensure\r
- *  optimal memory usage. It is not used within the LUFA library, and is provided as a convenience for user applications.\r
- *\r
- *  \dir Scheduler\r
- *  \brief Simple round-robbin scheduler.\r
- *  \r
- *  This folder contains the simple LUFA round-robbin scheduler, provided as a convenience for user applications. It\r
- *  is very simple in design, and is intended to make code easier to read, rather than providing a complete RTOS kernel.\r
- *\r
  *  \dir Drivers\r
  *  \brief Library hardware and software drivers.\r
  *  \r
diff --git a/LUFA/Drivers/USB/Class/Device/Audio.c b/LUFA/Drivers/USB/Class/Device/Audio.c
new file mode 100644 (file)
index 0000000..b0800ba
--- /dev/null
@@ -0,0 +1,154 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+#include "Audio.h"\r
+\r
+void USB_Audio_ProcessControlPacket(USB_ClassInfo_Audio_t* AudioInterfaceInfo)\r
+{\r
+       if (!(Endpoint_IsSETUPReceived()))\r
+         return;\r
+         \r
+//     if (USB_ControlRequest.wIndex != AudioInterfaceInfo->InterfaceNumber)\r
+//       return;\r
+\r
+       switch (USB_ControlRequest.bRequest)\r
+       {\r
+               case REQ_SetInterface:\r
+                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))\r
+                       {\r
+                               Endpoint_ClearSETUP();\r
+                               \r
+                               AudioInterfaceInfo->InterfaceEnabled = (USB_ControlRequest.wValue != 0);\r
+                                 \r
+                               while (!(Endpoint_IsINReady()));\r
+                               Endpoint_ClearIN();\r
+                       }\r
+\r
+                       break;\r
+       }\r
+}\r
+\r
+bool USB_Audio_ConfigureEndpoints(USB_ClassInfo_Audio_t* AudioInterfaceInfo)\r
+{\r
+       if (AudioInterfaceInfo->DataINEndpointNumber)\r
+       {\r
+               if (!(Endpoint_ConfigureEndpoint(AudioInterfaceInfo->DataINEndpointNumber, EP_TYPE_ISOCHRONOUS,\r
+                                                                                ENDPOINT_DIR_IN, AudioInterfaceInfo->DataINEndpointSize,\r
+                                                                                ENDPOINT_BANK_DOUBLE)))\r
+               {\r
+                       return false;\r
+               }\r
+       }\r
+\r
+       if (AudioInterfaceInfo->DataOUTEndpointNumber)\r
+       {\r
+               if (!(Endpoint_ConfigureEndpoint(AudioInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_ISOCHRONOUS,\r
+                                                                                ENDPOINT_DIR_OUT, AudioInterfaceInfo->DataOUTEndpointSize,\r
+                                                                                ENDPOINT_BANK_DOUBLE)))\r
+               {\r
+                       return false;\r
+               }\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
+int8_t USB_Audio_ReadSample8(void)\r
+{\r
+       int8_t Sample;\r
+\r
+       Sample = Endpoint_Read_Byte();\r
+\r
+       if (!(Endpoint_IsReadWriteAllowed()))\r
+         Endpoint_ClearOUT();\r
+       \r
+       return Sample;\r
+}\r
+\r
+int16_t USB_Audio_ReadSample16(void)\r
+{\r
+       int16_t Sample;\r
+\r
+       Sample = (int16_t)Endpoint_Read_Word_LE();\r
+                 \r
+       if (!(Endpoint_IsReadWriteAllowed()))\r
+         Endpoint_ClearOUT();\r
+\r
+       return Sample;\r
+}\r
+\r
+int32_t USB_Audio_ReadSample24(void)\r
+{\r
+       int32_t Sample;\r
+\r
+       Sample = (((uint32_t)Endpoint_Read_Byte() << 16) | Endpoint_Read_Word_LE());\r
+                 \r
+       if (!(Endpoint_IsReadWriteAllowed()))\r
+         Endpoint_ClearOUT();\r
+\r
+       return Sample;\r
+}\r
+\r
+void USB_Audio_WriteSample8(int8_t Sample)\r
+{\r
+       Endpoint_Write_Byte(Sample);\r
+\r
+       if (!(Endpoint_IsReadWriteAllowed()))\r
+         Endpoint_ClearIN();\r
+}\r
+\r
+void USB_Audio_WriteSample16(int16_t Sample)\r
+{\r
+       Endpoint_Write_Word_LE(Sample);\r
+\r
+       if (!(Endpoint_IsReadWriteAllowed()))\r
+         Endpoint_ClearIN();\r
+}\r
+\r
+void USB_Audio_WriteSample24(int32_t Sample)\r
+{\r
+       Endpoint_Write_Byte(Sample >> 16);\r
+       Endpoint_Write_Word_LE(Sample);\r
+\r
+       if (!(Endpoint_IsReadWriteAllowed()))\r
+         Endpoint_ClearIN();\r
+}\r
+\r
+bool USB_Audio_IsSampleReceived(USB_ClassInfo_Audio_t* AudioInterfaceInfo)\r
+{\r
+       Endpoint_SelectEndpoint(AudioInterfaceInfo->DataOUTEndpointNumber);\r
+       return Endpoint_IsOUTReceived();\r
+}\r
+\r
+bool USB_Audio_IsReadyForNextSample(USB_ClassInfo_Audio_t* AudioInterfaceInfo)\r
+{\r
+       Endpoint_SelectEndpoint(AudioInterfaceInfo->DataINEndpointNumber);\r
+       return Endpoint_IsINReady();\r
+}\r
diff --git a/LUFA/Drivers/USB/Class/Device/Audio.h b/LUFA/Drivers/USB/Class/Device/Audio.h
new file mode 100644 (file)
index 0000000..aa7b406
--- /dev/null
@@ -0,0 +1,70 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+#ifndef _AUDIO_CLASS_H_\r
+#define _AUDIO_CLASS_H_\r
+\r
+       /* Includes: */\r
+               #include "../../USB.h"\r
+\r
+               #include <string.h>\r
+\r
+       /* Macros: */\r
+\r
+       /* Enums: */\r
+\r
+       /* Type Defines: */\r
+               typedef struct\r
+               {\r
+                       uint8_t  InterfaceNumber;\r
+\r
+                       uint8_t  DataINEndpointNumber;\r
+                       uint16_t DataINEndpointSize;\r
+\r
+                       uint8_t  DataOUTEndpointNumber;\r
+                       uint16_t DataOUTEndpointSize;\r
+\r
+                       bool     InterfaceEnabled;\r
+               } USB_ClassInfo_Audio_t;\r
+               \r
+       /* Function Prototypes: */\r
+               bool     USB_Audio_ConfigureEndpoints(USB_ClassInfo_Audio_t* AudioInterfaceInfo);\r
+               void     USB_Audio_ProcessControlPacket(USB_ClassInfo_Audio_t* AudioInterfaceInfo);\r
+               void     USB_Audio_USBTask(USB_ClassInfo_Audio_t* AudioInterfaceInfo);\r
+               \r
+               int8_t   USB_Audio_ReadSample8(void);\r
+               int16_t  USB_Audio_ReadSample16(void);\r
+               int32_t  USB_Audio_ReadSample24(void);\r
+               void     USB_Audio_WriteSample8(int8_t Sample);\r
+               void     USB_Audio_WriteSample16(int16_t Sample);\r
+               void     USB_Audio_WriteSample24(int32_t Sample);\r
+               bool     USB_Audio_IsSampleReceived(USB_ClassInfo_Audio_t* AudioInterfaceInfo);\r
+               bool     USB_Audio_IsReadyForNextSample(USB_ClassInfo_Audio_t* AudioInterfaceInfo);\r
+#endif\r
diff --git a/LUFA/Drivers/USB/Class/Device/CDC.c b/LUFA/Drivers/USB/Class/Device/CDC.c
new file mode 100644 (file)
index 0000000..8acaac7
--- /dev/null
@@ -0,0 +1,185 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+#define  INCLUDE_FROM_CDC_CLASS_C\r
+#include "CDC.h"\r
+\r
+void USB_CDC_Event_Stub(void)\r
+{\r
+\r
+}\r
+\r
+void USB_CDC_ProcessControlPacket(USB_ClassInfo_CDC_t* CDCInterfaceInfo)\r
+{\r
+       if (!(Endpoint_IsSETUPReceived()))\r
+         return;\r
+         \r
+       if (USB_ControlRequest.wIndex != CDCInterfaceInfo->ControlInterfaceNumber)\r
+         return;\r
+\r
+       switch (USB_ControlRequest.bRequest)\r
+       {\r
+               case REQ_GetLineEncoding:\r
+                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
+                       {\r
+                               Endpoint_ClearSETUP();\r
+                               Endpoint_Write_Control_Stream_LE(&CDCInterfaceInfo->LineEncoding, sizeof(CDCInterfaceInfo->LineEncoding));\r
+                               Endpoint_ClearOUT();\r
+                       }\r
+                       \r
+                       break;\r
+               case REQ_SetLineEncoding:\r
+                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
+                       {\r
+                               Endpoint_ClearSETUP();\r
+                               Endpoint_Read_Control_Stream_LE(&CDCInterfaceInfo->LineEncoding, sizeof(CDCInterfaceInfo->LineEncoding));\r
+                               Endpoint_ClearIN();\r
+\r
+                               EVENT_USB_CDC_LineEncodingChanged(CDCInterfaceInfo);\r
+                       }\r
+       \r
+                       break;\r
+               case REQ_SetControlLineState:\r
+                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
+                       {                               \r
+                               Endpoint_ClearSETUP();\r
+                               \r
+                               CDCInterfaceInfo->ControlLineState = USB_ControlRequest.wValue;\r
+                               \r
+                               EVENT_USB_CDC_ControLineStateChanged();\r
+\r
+                               while (!(Endpoint_IsINReady()));\r
+                               Endpoint_ClearIN();\r
+                       }\r
+       \r
+                       break;\r
+       }\r
+}\r
+\r
+bool USB_CDC_ConfigureEndpoints(USB_ClassInfo_CDC_t* CDCInterfaceInfo)\r
+{\r
+       if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->DataINEndpointNumber, EP_TYPE_BULK,\r
+                                                                ENDPOINT_DIR_IN, CDCInterfaceInfo->DataINEndpointSize,\r
+                                                                ENDPOINT_BANK_SINGLE)))\r
+       {\r
+               return false;\r
+       }\r
+\r
+       if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_BULK,\r
+                                        ENDPOINT_DIR_OUT, CDCInterfaceInfo->DataOUTEndpointSize,\r
+                                        ENDPOINT_BANK_SINGLE)))\r
+       {\r
+               return false;\r
+       }\r
+\r
+       if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->NotificationEndpointNumber, EP_TYPE_INTERRUPT,\r
+                                        ENDPOINT_DIR_IN, CDCInterfaceInfo->NotificationEndpointSize,\r
+                                        ENDPOINT_BANK_SINGLE)))\r
+       {\r
+               return false;\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
+void USB_CDC_USBTask(USB_ClassInfo_CDC_t* CDCInterfaceInfo)\r
+{\r
+       if (!(USB_IsConnected))\r
+         return;\r
+\r
+       Endpoint_SelectEndpoint(CDCInterfaceInfo->DataINEndpointNumber);\r
+\r
+       if (!(Endpoint_BytesInEndpoint()))\r
+         return;\r
+         \r
+       if (!(Endpoint_IsReadWriteAllowed()))\r
+       {\r
+               Endpoint_ClearIN();\r
+               while (!(Endpoint_IsReadWriteAllowed()));\r
+       }       \r
+       \r
+       Endpoint_ClearIN();\r
+}\r
+\r
+void USB_CDC_SendString(USB_ClassInfo_CDC_t* CDCInterfaceInfo, char* Data, uint16_t Length)\r
+{\r
+       Endpoint_SelectEndpoint(CDCInterfaceInfo->DataINEndpointNumber);\r
+       Endpoint_Write_Stream_LE(Data, Length, NO_STREAM_CALLBACK);\r
+}\r
+\r
+void USB_CDC_SendByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint8_t Data)\r
+{\r
+       Endpoint_SelectEndpoint(CDCInterfaceInfo->DataINEndpointNumber);\r
+\r
+       if (!(Endpoint_IsReadWriteAllowed()))\r
+       {\r
+               Endpoint_ClearIN();\r
+               while (!(Endpoint_IsReadWriteAllowed()));\r
+       }\r
+\r
+       Endpoint_Write_Byte(Data);      \r
+}\r
+\r
+uint16_t USB_CDC_BytesReceived(USB_ClassInfo_CDC_t* CDCInterfaceInfo)\r
+{\r
+       Endpoint_SelectEndpoint(CDCInterfaceInfo->DataOUTEndpointNumber);\r
+\r
+       return Endpoint_BytesInEndpoint();\r
+}\r
+\r
+uint8_t USB_CDC_ReceiveByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo)\r
+{\r
+       Endpoint_SelectEndpoint(CDCInterfaceInfo->DataOUTEndpointNumber);\r
+       \r
+       uint8_t DataByte = Endpoint_Read_Byte();\r
+       \r
+       if (!(Endpoint_BytesInEndpoint()))\r
+         Endpoint_ClearOUT();\r
+         \r
+       return DataByte;\r
+}\r
+\r
+void USB_CDC_SendSerialLineStateChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint16_t LineStateMask)\r
+{\r
+       Endpoint_SelectEndpoint(CDCInterfaceInfo->NotificationEndpointNumber);\r
+       \r
+       USB_Request_Header_t Notification = (USB_Request_Header_t)\r
+               {\r
+                       .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),\r
+                       .bRequest      = NOTIF_SerialState,\r
+                       .wValue        = 0,\r
+                       .wIndex        = 0,\r
+                       .wLength       = sizeof(uint16_t),\r
+               };\r
+\r
+       Endpoint_Write_Stream_LE(&Notification, sizeof(Notification), NO_STREAM_CALLBACK);\r
+       Endpoint_Write_Stream_LE(&LineStateMask, sizeof(LineStateMask), NO_STREAM_CALLBACK);\r
+       Endpoint_ClearIN();\r
+}\r
diff --git a/LUFA/Drivers/USB/Class/Device/CDC.h b/LUFA/Drivers/USB/Class/Device/CDC.h
new file mode 100644 (file)
index 0000000..bbe1c98
--- /dev/null
@@ -0,0 +1,188 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+#ifndef _CDC_CLASS_H_\r
+#define _CDC_CLASS_H_\r
+\r
+       /* Includes: */\r
+               #include "../../USB.h"\r
+\r
+               #include <string.h>\r
+\r
+       /* Macros: */\r
+               /** CDC Class specific request to get the current virtual serial port configuration settings. */\r
+               #define REQ_GetLineEncoding          0x21\r
+\r
+               /** CDC Class specific request to set the current virtual serial port configuration settings. */\r
+               #define REQ_SetLineEncoding          0x20\r
+\r
+               /** CDC Class specific request to set the current virtual serial port handshake line states. */\r
+               #define REQ_SetControlLineState      0x22\r
+               \r
+               /** Notification type constant for a change in the virtual serial port handshake line states, for\r
+                *  use with a USB_Notification_Header_t notification structure when sent to the host via the CDC \r
+                *  notification endpoint.\r
+                */\r
+               #define NOTIF_SerialState            0x20\r
+\r
+               /** Mask for the DTR handshake line for use with the REQ_SetControlLineState class specific request\r
+                *  from the host, to indicate that the DTR line state should be high.\r
+                */\r
+               #define CONTROL_LINE_OUT_DTR         (1 << 0)\r
+\r
+               /** Mask for the RTS handshake line for use with the REQ_SetControlLineState class specific request\r
+                *  from the host, to indicate that theRTS line state should be high.\r
+                */\r
+               #define CONTROL_LINE_OUT_RTS         (1 << 1)\r
+               \r
+               /** Mask for the DCD handshake line for use with the a NOTIF_SerialState class specific notification\r
+                *  from the device to the host, to indicate that the DCD line state is currently high.\r
+                */\r
+               #define CONTROL_LINE_IN_DCD          (1 << 0)\r
+\r
+               /** Mask for the DSR handshake line for use with the a NOTIF_SerialState class specific notification\r
+                *  from the device to the host, to indicate that the DSR line state is currently high.\r
+                */\r
+               #define CONTROL_LINE_IN_DSR          (1 << 1)\r
+\r
+               /** Mask for the BREAK handshake line for use with the a NOTIF_SerialState class specific notification\r
+                *  from the device to the host, to indicate that the BREAK line state is currently high.\r
+                */\r
+               #define CONTROL_LINE_IN_BREAK        (1 << 2)\r
+\r
+               /** Mask for the RING handshake line for use with the a NOTIF_SerialState class specific notification\r
+                *  from the device to the host, to indicate that the RING line state is currently high.\r
+                */\r
+               #define CONTROL_LINE_IN_RING         (1 << 3)\r
+\r
+               /** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,\r
+                *  to indicate that a framing error has occurred on the virtual serial port.\r
+                */\r
+               #define CONTROL_LINE_IN_FRAMEERROR   (1 << 4)\r
+\r
+               /** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,\r
+                *  to indicate that a parity error has occurred on the virtual serial port.\r
+                */\r
+               #define CONTROL_LINE_IN_PARITYERROR  (1 << 5)\r
+\r
+               /** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,\r
+                *  to indicate that a data overrun error has occurred on the virtual serial port.\r
+                */\r
+               #define CONTROL_LINE_IN_OVERRUNERROR (1 << 6)\r
+               \r
+               /** Macro to define a CDC class-specific functional descriptor. CDC functional descriptors have a\r
+                *  uniform structure but variable sized data payloads, thus cannot be represented accurately by\r
+                *  a single typedef struct. A macro is used instead so that functional descriptors can be created\r
+                *  easily by specifying the size of the payload. This allows sizeof() to work correctly.\r
+                *\r
+                *  \param DataSize  Size in bytes of the CDC functional descriptor's data payload\r
+                */\r
+               #define CDC_FUNCTIONAL_DESCRIPTOR(DataSize)        \\r
+                    struct                                        \\r
+                    {                                             \\r
+                         USB_Descriptor_Header_t Header;          \\r
+                             uint8_t                 SubType;         \\r
+                         uint8_t                 Data[DataSize];  \\r
+                    }\r
+\r
+       /* Enums: */\r
+               /** Enum for the possible line encoding formats of a virtual serial port. */\r
+               enum CDCDevice_CDC_LineCodingFormats_t\r
+               {\r
+                       OneStopBit          = 0, /**< Each frame contains one stop bit */\r
+                       OneAndAHalfStopBits = 1, /**< Each frame contains one and a half stop bits */\r
+                       TwoStopBits         = 2, /**< Each frame contains two stop bits */\r
+               };\r
+               \r
+               /** Enum for the possible line encoding parity settings of a virtual serial port. */\r
+               enum CDCDevice_LineCodingParity_t\r
+               {\r
+                       Parity_None         = 0, /**< No parity bit mode on each frame */\r
+                       Parity_Odd          = 1, /**< Odd parity bit mode on each frame */\r
+                       Parity_Even         = 2, /**< Even parity bit mode on each frame */\r
+                       Parity_Mark         = 3, /**< Mark parity bit mode on each frame */\r
+                       Parity_Space        = 4, /**< Space parity bit mode on each frame */\r
+               };\r
+\r
+       /* Type Defines: */\r
+               /** Type define for the virtual serial port line encoding settings, for storing the current USART configuration\r
+                *  as set by the host via a class specific request.\r
+                */\r
+               typedef struct\r
+               {\r
+                       uint8_t  ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device */\r
+\r
+                       uint8_t  DataINEndpointNumber; /**< Endpoint number of the CDC interface's IN data endpoint */\r
+                       uint16_t DataINEndpointSize; /**< Size in bytes of the CDC interface's IN data endpoint */\r
+\r
+                       uint8_t  DataOUTEndpointNumber; /**< Endpoint number of the CDC interface's OUT data endpoint */\r
+                       uint16_t DataOUTEndpointSize;  /**< Size in bytes of the CDC interface's OUT data endpoint */\r
+\r
+                       uint8_t  NotificationEndpointNumber; /**< Endpoint number of the CDC interface's IN notification endpoint, if used */\r
+                       uint16_t NotificationEndpointSize;  /**< Size in bytes of the CDC interface's IN notification endpoint, if used */\r
+\r
+                       uint8_t  ControlLineState;\r
+\r
+                       struct\r
+                       {\r
+                               uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */\r
+                               uint8_t  CharFormat; /**< Character format of the virtual serial port, a value from the\r
+                                                                         *   CDCDevice_CDC_LineCodingFormats_t enum\r
+                                                                         */\r
+                               uint8_t  ParityType; /**< Parity setting of the virtual serial port, a value from the\r
+                                                                         *   CDCDevice_LineCodingParity_t enum\r
+                                                                         */\r
+                               uint8_t  DataBits; /**< Bits of data per character of the virtual serial port */\r
+                       } LineEncoding;\r
+               } USB_ClassInfo_CDC_t;\r
+               \r
+       /* Function Prototypes: */\r
+               #if defined(INCLUDE_FROM_CDC_CLASS_C)\r
+                       void USB_CDC_Event_Stub(void);\r
+                       void EVENT_USB_CDC_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo)\r
+                                                                                                  ATTR_WEAK ATTR_ALIAS(USB_CDC_Event_Stub);\r
+                       void EVENT_USB_CDC_ControLineStateChanged(void) ATTR_WEAK ATTR_ALIAS(USB_CDC_Event_Stub);; \r
+               #endif\r
+       \r
+               void     USB_CDC_USBTask(USB_ClassInfo_CDC_t* CDCInterfaceInfo);\r
+               bool     USB_CDC_ConfigureEndpoints(USB_ClassInfo_CDC_t* CDCInterfaceInfo);\r
+               void     USB_CDC_ProcessControlPacket(USB_ClassInfo_CDC_t* CDCInterfaceInfo);\r
+               void     USB_CDC_USBTask(USB_ClassInfo_CDC_t* CDCInterfaceInfo);\r
+\r
+               void     EVENT_USB_CDC_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo);\r
+               void     EVENT_USB_CDC_ControLineStateChanged(void);\r
+\r
+               void     USB_CDC_SendString(USB_ClassInfo_CDC_t* CDCInterfaceInfo, char* Data, uint16_t Length);\r
+               void     USB_CDC_SendByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint8_t Data);\r
+               uint16_t USB_CDC_BytesReceived(USB_ClassInfo_CDC_t* CDCInterfaceInfo);\r
+               uint8_t  USB_CDC_ReceiveByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo);\r
+               void USB_CDC_SendSerialLineStateChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint16_t LineStateMask);\r
+               \r
+#endif\r
diff --git a/LUFA/Drivers/USB/Class/Device/HID.c b/LUFA/Drivers/USB/Class/Device/HID.c
new file mode 100644 (file)
index 0000000..fbc5e3a
--- /dev/null
@@ -0,0 +1,211 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+#include "HID.h"\r
+\r
+void USB_HID_ProcessControlPacket(USB_ClassInfo_HID_t* HIDInterfaceInfo)\r
+{\r
+       if (!(Endpoint_IsSETUPReceived()))\r
+         return;\r
+         \r
+       if (USB_ControlRequest.wIndex != HIDInterfaceInfo->InterfaceNumber)\r
+         return;\r
+\r
+       switch (USB_ControlRequest.bRequest)\r
+       {\r
+               case REQ_GetReport:\r
+                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
+                       {\r
+                               Endpoint_ClearSETUP();  \r
+\r
+                               uint8_t  ReportINData[HIDInterfaceInfo->ReportBufferSize];\r
+                               uint16_t ReportINSize;\r
+\r
+                               memset(ReportINData, 0, sizeof(ReportINData));\r
+\r
+                               ReportINSize = CALLBACK_USB_HID_CreateNextHIDReport(HIDInterfaceInfo, ReportINData);\r
+\r
+                               Endpoint_Write_Control_Stream_LE(ReportINData, ReportINSize);\r
+                               Endpoint_ClearOUT();\r
+                       }\r
+               \r
+                       break;\r
+               case REQ_SetReport:\r
+                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
+                       {\r
+                               Endpoint_ClearSETUP();\r
+                               \r
+                               uint16_t ReportOUTSize = USB_ControlRequest.wLength;\r
+                               uint8_t  ReportOUTData[ReportOUTSize];\r
+\r
+                               Endpoint_Read_Control_Stream_LE(ReportOUTData, ReportOUTSize);\r
+                               Endpoint_ClearIN();\r
+                               \r
+                               CALLBACK_USB_HID_ProcessReceivedHIDReport(HIDInterfaceInfo, ReportOUTData, ReportOUTSize);\r
+                       }\r
+                       \r
+                       break;\r
+               case REQ_GetProtocol:\r
+                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
+                       {\r
+                               Endpoint_ClearSETUP();\r
+\r
+                               Endpoint_Write_Byte(HIDInterfaceInfo->UsingReportProtocol);\r
+                               Endpoint_ClearIN();\r
+\r
+                               while (!(Endpoint_IsOUTReceived()));\r
+                               Endpoint_ClearOUT();\r
+                       }\r
+                       \r
+                       break;\r
+               case REQ_SetProtocol:\r
+                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
+                       {\r
+                               Endpoint_ClearSETUP();\r
+\r
+                               HIDInterfaceInfo->UsingReportProtocol = (USB_ControlRequest.wValue != 0x0000);\r
+                               \r
+                               while (!(Endpoint_IsINReady()));\r
+                               Endpoint_ClearIN();\r
+                       }\r
+                       \r
+                       break;\r
+               case REQ_SetIdle:\r
+                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
+                       {\r
+                               Endpoint_ClearSETUP();\r
+                               \r
+                               HIDInterfaceInfo->IdleCount = ((USB_ControlRequest.wValue >> 8) << 2);\r
+                               \r
+                               while (!(Endpoint_IsINReady()));\r
+                               Endpoint_ClearIN();\r
+                       }\r
+                       \r
+                       break;\r
+               case REQ_GetIdle:\r
+                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
+                       {               \r
+                               Endpoint_ClearSETUP();\r
+                               \r
+                               Endpoint_Write_Byte(HIDInterfaceInfo->IdleCount >> 2);\r
+                               Endpoint_ClearIN();\r
+\r
+                               while (!(Endpoint_IsOUTReceived()));\r
+                               Endpoint_ClearOUT();\r
+                       }\r
+\r
+                       break;\r
+       }\r
+}\r
+\r
+bool USB_HID_ConfigureEndpoints(USB_ClassInfo_HID_t* HIDInterfaceInfo)\r
+{\r
+       HIDInterfaceInfo->UsingReportProtocol = true;\r
+\r
+       if (!(Endpoint_ConfigureEndpoint(HIDInterfaceInfo->ReportINEndpointNumber, EP_TYPE_INTERRUPT,\r
+                                                                        ENDPOINT_DIR_IN, HIDInterfaceInfo->ReportINEndpointSize, ENDPOINT_BANK_SINGLE)))\r
+       {\r
+               return false;\r
+       }\r
+       \r
+       if (HIDInterfaceInfo->ReportOUTEndpointNumber)\r
+       {\r
+               if (!(Endpoint_ConfigureEndpoint(HIDInterfaceInfo->ReportOUTEndpointNumber, EP_TYPE_INTERRUPT,\r
+                                                                                ENDPOINT_DIR_OUT, HIDInterfaceInfo->ReportOUTEndpointSize, ENDPOINT_BANK_SINGLE)))\r
+               {\r
+                       return false;\r
+               }\r
+       }\r
+       \r
+       return true;\r
+}\r
+\r
+void USB_HID_RegisterStartOfFrame(USB_ClassInfo_HID_t* HIDInterfaceInfo)\r
+{\r
+       if (HIDInterfaceInfo->IdleMSRemaining)\r
+         HIDInterfaceInfo->IdleMSRemaining--;\r
+}\r
+               \r
+void USB_HID_USBTask(USB_ClassInfo_HID_t* HIDInterfaceInfo)\r
+{\r
+       if (!(USB_IsConnected))\r
+         return;\r
+\r
+       Endpoint_SelectEndpoint(HIDInterfaceInfo->ReportINEndpointNumber);\r
+       \r
+       if (Endpoint_IsReadWriteAllowed() &&\r
+           !(HIDInterfaceInfo->IdleCount && HIDInterfaceInfo->IdleMSRemaining))\r
+       {\r
+               if (HIDInterfaceInfo->IdleCount && !(HIDInterfaceInfo->IdleMSRemaining))\r
+                 HIDInterfaceInfo->IdleMSRemaining = HIDInterfaceInfo->IdleCount;\r
+\r
+               uint8_t  ReportINData[HIDInterfaceInfo->ReportBufferSize];\r
+               uint16_t ReportINSize;\r
+\r
+               memset(ReportINData, 0, sizeof(ReportINData));\r
+\r
+               ReportINSize = CALLBACK_USB_HID_CreateNextHIDReport(HIDInterfaceInfo, ReportINData);\r
+\r
+               if (ReportINSize)\r
+               {\r
+                       Endpoint_Write_Stream_LE(ReportINData, ReportINSize\r
+                       #if !defined(NO_STREAM_CALLBACKS)\r
+                                                , NO_STREAM_CALLBACK\r
+                       #endif\r
+                                                );\r
+               }\r
+               \r
+               Endpoint_ClearIN();\r
+       }\r
+       \r
+       if (HIDInterfaceInfo->ReportOUTEndpointNumber)\r
+       {\r
+               Endpoint_SelectEndpoint(HIDInterfaceInfo->ReportOUTEndpointNumber);\r
+               \r
+               if (Endpoint_IsOUTReceived())\r
+               {\r
+                       uint16_t ReportOUTSize = Endpoint_BytesInEndpoint();\r
+                       uint8_t  ReportOUTData[ReportOUTSize];\r
+                       \r
+                       if (ReportOUTSize)\r
+                       {\r
+                               Endpoint_Read_Stream_LE(ReportOUTData, ReportOUTSize\r
+                               #if !defined(NO_STREAM_CALLBACKS)\r
+                                                   , NO_STREAM_CALLBACK\r
+                               #endif\r
+                                                   );\r
+                       }\r
+                         \r
+                       CALLBACK_USB_HID_ProcessReceivedHIDReport(HIDInterfaceInfo, ReportOUTData, ReportOUTSize);\r
+                       \r
+                       Endpoint_ClearOUT();\r
+               }\r
+       }\r
+}\r
diff --git a/LUFA/Drivers/USB/Class/Device/HID.h b/LUFA/Drivers/USB/Class/Device/HID.h
new file mode 100644 (file)
index 0000000..8fdeb06
--- /dev/null
@@ -0,0 +1,115 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+#ifndef _HID_CLASS_H_\r
+#define _HID_CLASS_H_\r
+\r
+       /* Includes: */\r
+               #include "../../USB.h"\r
+\r
+               #include <string.h>\r
+\r
+       /* Macros: */\r
+               /** HID Class Specific Request to get the current HID report from the device. */\r
+               #define REQ_GetReport      0x01\r
+\r
+               /** HID Class Specific Request to get the current device idle count. */\r
+               #define REQ_GetIdle        0x02\r
+\r
+               /** HID Class Specific Request to set the current HID report to the device. */\r
+               #define REQ_SetReport      0x09\r
+\r
+               /** HID Class Specific Request to set the device's idle count. */\r
+               #define REQ_SetIdle        0x0A\r
+\r
+               /** HID Class Specific Request to get the current HID report protocol mode. */\r
+               #define REQ_GetProtocol    0x03\r
+\r
+               /** HID Class Specific Request to set the current HID report protocol mode. */\r
+               #define REQ_SetProtocol    0x0B\r
+\r
+               /** Descriptor header type value, to indicate a HID class HID descriptor. */\r
+               #define DTYPE_HID          0x21\r
+               \r
+               /** Descriptor header type value, to indicate a HID class HID report descriptor. */\r
+               #define DTYPE_Report       0x22\r
+\r
+       /* Type Defines: */\r
+               /** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID\r
+                *  specification for details on the structure elements.\r
+                */\r
+               typedef struct\r
+               {\r
+                       USB_Descriptor_Header_t               Header;\r
+                               \r
+                       uint16_t                              HIDSpec;\r
+                       uint8_t                               CountryCode;\r
+               \r
+                       uint8_t                               TotalReportDescriptors;\r
+\r
+                       uint8_t                               HIDReportType;\r
+                       uint16_t                              HIDReportLength;\r
+               } USB_Descriptor_HID_t;\r
+\r
+               /** Type define for the data type used to store HID report descriptor elements. */\r
+               typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;\r
+\r
+               /** Class state structure. An instance of this structure should be made for each HID interface\r
+                *  within the user application, and passed to each of the HID class driver functions as the\r
+                *  HIDInterfaceInfo parameter. The contents of this structure should be set to their correct\r
+                *  values when used, or ommitted to force the library to use default values.\r
+                */\r
+               typedef struct\r
+               {\r
+                       uint8_t  InterfaceNumber; /**< Interface number of the HID interface within the device */\r
+\r
+                       uint8_t  ReportINEndpointNumber; /**< Endpoint number of the HID interface's IN report endpoint */\r
+                       uint16_t ReportINEndpointSize; /**< Size in bytes of the HID interface's IN report endpoint */\r
+\r
+                       uint8_t  ReportOUTEndpointNumber; /**< Endpoint number of the HID interface's OUT report endpoint, if used */\r
+                       uint16_t ReportOUTEndpointSize;  /**< Size in bytes of the HID interface's OUT report endpoint, if used */\r
+                       \r
+                       uint8_t  ReportBufferSize;\r
+\r
+                       bool     UsingReportProtocol; /**< Indicates if the HID interface is set to Boot or Report protocol mode */\r
+                       uint16_t IdleCount; /**< Report idle period, in ms, set by the host */\r
+                       uint16_t IdleMSRemaining; /**< Total number of ms remaining before the idle period elapses */\r
+               } USB_ClassInfo_HID_t;\r
+\r
+       /* Function Prototypes: */\r
+               bool USB_HID_ConfigureEndpoints(USB_ClassInfo_HID_t* HIDInterfaceInfo);\r
+               void USB_HID_ProcessControlPacket(USB_ClassInfo_HID_t* HIDInterfaceInfo);\r
+               void USB_HID_RegisterStartOfFrame(USB_ClassInfo_HID_t* HIDInterfaceInfo);\r
+               void USB_HID_USBTask(USB_ClassInfo_HID_t* HIDInterfaceInfo);\r
+               \r
+               uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);\r
+               void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize);\r
+\r
+#endif\r
diff --git a/LUFA/Drivers/USB/Class/Device/MassStorage.c b/LUFA/Drivers/USB/Class/Device/MassStorage.c
new file mode 100644 (file)
index 0000000..1c41f60
--- /dev/null
@@ -0,0 +1,208 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+#define  INCLUDE_FROM_MS_CLASS_C\r
+#include "MassStorage.h"\r
+\r
+static USB_ClassInfo_MS_t* CallbackMSInterfaceInfo;\r
+\r
+void USB_MS_ProcessControlPacket(USB_ClassInfo_MS_t* MSInterfaceInfo)\r
+{\r
+       if (!(Endpoint_IsSETUPReceived()))\r
+         return;\r
+         \r
+       if (USB_ControlRequest.wIndex != MSInterfaceInfo->InterfaceNumber)\r
+         return;\r
+\r
+       switch (USB_ControlRequest.bRequest)\r
+       {\r
+               case REQ_MassStorageReset:\r
+                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
+                       {\r
+                               Endpoint_ClearSETUP();\r
+\r
+                               MSInterfaceInfo->IsMassStoreReset = true;                       \r
+\r
+                               while (!(Endpoint_IsINReady()));\r
+                               Endpoint_ClearIN();\r
+                       }\r
+\r
+                       break;\r
+               case REQ_GetMaxLUN:\r
+                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
+                       {\r
+                               Endpoint_ClearSETUP();\r
+\r
+                               Endpoint_Write_Byte(MSInterfaceInfo->TotalLUNs - 1);\r
+                               \r
+                               Endpoint_ClearIN();\r
+                               \r
+                               while (!(Endpoint_IsOUTReceived()));\r
+                               Endpoint_ClearOUT();\r
+                       }\r
+                       \r
+                       break;\r
+       }\r
+}\r
+\r
+bool USB_MS_ConfigureEndpoints(USB_ClassInfo_MS_t* MSInterfaceInfo)\r
+{\r
+       if (!(Endpoint_ConfigureEndpoint(MSInterfaceInfo->DataINEndpointNumber, EP_TYPE_BULK,\r
+                                                                ENDPOINT_DIR_IN, MSInterfaceInfo->DataINEndpointSize,\r
+                                                                ENDPOINT_BANK_SINGLE)))\r
+       {\r
+               return false;\r
+       }\r
+\r
+       if (!(Endpoint_ConfigureEndpoint(MSInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_BULK,\r
+                                        ENDPOINT_DIR_OUT, MSInterfaceInfo->DataOUTEndpointSize,\r
+                                        ENDPOINT_BANK_SINGLE)))\r
+       {\r
+               return false;\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
+void USB_MS_USBTask(USB_ClassInfo_MS_t* MSInterfaceInfo)\r
+{\r
+       if (!(USB_IsConnected))\r
+         return;\r
+\r
+       Endpoint_SelectEndpoint(MSInterfaceInfo->DataOUTEndpointNumber);\r
+               \r
+       if (Endpoint_IsReadWriteAllowed())\r
+       {\r
+               if (USB_MS_ReadInCommandBlock(MSInterfaceInfo))\r
+               {\r
+                       if (MSInterfaceInfo->CommandBlock.Flags & COMMAND_DIRECTION_DATA_IN)\r
+                         Endpoint_SelectEndpoint(MSInterfaceInfo->DataINEndpointNumber);\r
+                         \r
+                       MSInterfaceInfo->CommandStatus.Status              = CALLBACK_USB_MS_SCSICommandReceived(MSInterfaceInfo) ?\r
+                                                                             Command_Pass : Command_Fail;\r
+                       MSInterfaceInfo->CommandStatus.Signature           = CSW_SIGNATURE;\r
+                       MSInterfaceInfo->CommandStatus.Tag                 = MSInterfaceInfo->CommandBlock.Tag;\r
+                       MSInterfaceInfo->CommandStatus.DataTransferResidue = MSInterfaceInfo->CommandBlock.DataTransferLength;\r
+\r
+                       if ((MSInterfaceInfo->CommandStatus.Status == Command_Fail) && (MSInterfaceInfo->CommandStatus.DataTransferResidue))\r
+                         Endpoint_StallTransaction();\r
+                       \r
+                       USB_MS_ReturnCommandStatus(MSInterfaceInfo);\r
+                       \r
+                       if (MSInterfaceInfo->IsMassStoreReset)\r
+                       {\r
+                               Endpoint_ResetFIFO(MSInterfaceInfo->DataOUTEndpointNumber);\r
+                               Endpoint_ResetFIFO(MSInterfaceInfo->DataINEndpointNumber);\r
+                               \r
+                               Endpoint_SelectEndpoint(MSInterfaceInfo->DataOUTEndpointNumber);\r
+                               Endpoint_ClearStall();\r
+                               Endpoint_SelectEndpoint(MSInterfaceInfo->DataINEndpointNumber);\r
+                               Endpoint_ClearStall();\r
+\r
+                               MSInterfaceInfo->IsMassStoreReset = false;\r
+                       }\r
+               }\r
+       }\r
+}\r
+\r
+static bool USB_MS_ReadInCommandBlock(USB_ClassInfo_MS_t* MSInterfaceInfo)\r
+{\r
+       Endpoint_SelectEndpoint(MSInterfaceInfo->DataOUTEndpointNumber);\r
+\r
+       CallbackMSInterfaceInfo = MSInterfaceInfo;\r
+       Endpoint_Read_Stream_LE(&MSInterfaceInfo->CommandBlock,\r
+                               (sizeof(CommandBlockWrapper_t) - MAX_SCSI_COMMAND_LENGTH),\r
+                               StreamCallback_AbortOnMassStoreReset);\r
+\r
+       if ((MSInterfaceInfo->CommandBlock.Signature         != CBW_SIGNATURE)              ||\r
+           (MSInterfaceInfo->CommandBlock.LUN               >= MSInterfaceInfo->TotalLUNs) ||\r
+               (MSInterfaceInfo->CommandBlock.SCSICommandLength >  MAX_SCSI_COMMAND_LENGTH))\r
+       {\r
+               Endpoint_StallTransaction();\r
+               Endpoint_SelectEndpoint(MSInterfaceInfo->DataINEndpointNumber);\r
+               Endpoint_StallTransaction();\r
+               \r
+               return false;\r
+       }\r
+\r
+       CallbackMSInterfaceInfo = MSInterfaceInfo;\r
+       Endpoint_Read_Stream_LE(&MSInterfaceInfo->CommandBlock.SCSICommandData,\r
+                               MSInterfaceInfo->CommandBlock.SCSICommandLength,\r
+                               StreamCallback_AbortOnMassStoreReset);\r
+                                                       \r
+       Endpoint_ClearOUT();\r
+         \r
+       if (MSInterfaceInfo->IsMassStoreReset)\r
+         return false;\r
+\r
+       return true;\r
+}\r
+\r
+static void USB_MS_ReturnCommandStatus(USB_ClassInfo_MS_t* MSInterfaceInfo)\r
+{\r
+       Endpoint_SelectEndpoint(MSInterfaceInfo->DataOUTEndpointNumber);\r
+\r
+       while (Endpoint_IsStalled())\r
+       {\r
+               USB_USBTask();\r
+\r
+               if (MSInterfaceInfo->IsMassStoreReset)\r
+                 return;\r
+       }\r
+\r
+       Endpoint_SelectEndpoint(MSInterfaceInfo->DataINEndpointNumber);\r
+\r
+       while (Endpoint_IsStalled())\r
+       {\r
+               USB_USBTask();\r
+\r
+               if (MSInterfaceInfo->IsMassStoreReset)\r
+                 return;\r
+       }\r
+       \r
+       CallbackMSInterfaceInfo = MSInterfaceInfo;\r
+       Endpoint_Write_Stream_LE(&MSInterfaceInfo->CommandStatus, sizeof(CommandStatusWrapper_t),\r
+                                StreamCallback_AbortOnMassStoreReset);\r
+       \r
+       Endpoint_ClearIN();\r
+\r
+       if (MSInterfaceInfo->IsMassStoreReset)\r
+         return;\r
+}\r
+\r
+static uint8_t StreamCallback_AbortOnMassStoreReset(void)\r
+{\r
+       USB_MS_USBTask(CallbackMSInterfaceInfo);\r
+\r
+       if (CallbackMSInterfaceInfo->IsMassStoreReset)\r
+         return STREAMCALLBACK_Abort;\r
+       else\r
+         return STREAMCALLBACK_Continue;\r
+}\r
diff --git a/LUFA/Drivers/USB/Class/Device/MassStorage.h b/LUFA/Drivers/USB/Class/Device/MassStorage.h
new file mode 100644 (file)
index 0000000..c1874b2
--- /dev/null
@@ -0,0 +1,127 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+#ifndef _MS_CLASS_H_\r
+#define _MS_CLASS_H_\r
+\r
+       /* Includes: */\r
+               #include "../../USB.h"\r
+\r
+               #include <string.h>\r
+\r
+       /* Macros: */\r
+               /** Mass Storage Class specific request to reset the Mass Storage interface, ready for the next command. */\r
+               #define REQ_MassStorageReset       0xFF\r
+\r
+               /** Mass Storage Class specific request to retrieve the total number of Logical Units (drives) in the SCSI device. */\r
+               #define REQ_GetMaxLUN              0xFE\r
+\r
+               /** Maximum length of a SCSI command which can be issued by the device or host in a Mass Storage bulk wrapper. */\r
+               #define MAX_SCSI_COMMAND_LENGTH    16\r
+               \r
+               /** Magic signature for a Command Block Wrapper used in the Mass Storage Bulk-Only transport protocol. */\r
+               #define CBW_SIGNATURE              0x43425355UL\r
+\r
+               /** Magic signature for a Command Status Wrapper used in the Mass Storage Bulk-Only transport protocol. */\r
+               #define CSW_SIGNATURE              0x53425355UL\r
+               \r
+               /** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from host-to-device. */\r
+               #define COMMAND_DIRECTION_DATA_OUT (0 << 7)\r
+\r
+               /** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from device-to-host. */\r
+               #define COMMAND_DIRECTION_DATA_IN  (1 << 7)\r
+\r
+       /* Type defines: */\r
+               /** Type define for a Command Block Wrapper, used in the Mass Storage Bulk-Only Transport protocol. */\r
+               typedef struct\r
+               {\r
+                       uint32_t Signature; /**< Command block signature, must be CBW_SIGNATURE to indicate a valid Command Block */\r
+                       uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper */\r
+                       uint32_t DataTransferLength; /** Length of the optional data portion of the issued command, in bytes */\r
+                       uint8_t  Flags; /**< Command block flags, indicating command data direction */\r
+                       uint8_t  LUN; /**< Logical Unit number this command is issued to */\r
+                       uint8_t  SCSICommandLength; /**< Length of the issued SCSI command within the SCSI command data array */\r
+                       uint8_t  SCSICommandData[MAX_SCSI_COMMAND_LENGTH]; /**< Issued SCSI command in the Command Block */\r
+               } CommandBlockWrapper_t;\r
+               \r
+               /** Type define for a Command Status Wrapper, used in the Mass Storage Bulk-Only Transport protocol. */\r
+               typedef struct\r
+               {\r
+                       uint32_t Signature; /**< Status block signature, must be CSW_SIGNATURE to indicate a valid Command Status */\r
+                       uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper */\r
+                       uint32_t DataTransferResidue; /**< Number of bytes of data not processed in the SCSI command */\r
+                       uint8_t  Status; /**< Status code of the issued command - a value from the MassStorage_CommandStatusCodes_t enum */\r
+               } CommandStatusWrapper_t;\r
+               \r
+       /* Enums: */\r
+               /** Enum for the possible command status wrapper return status codes. */\r
+               enum MassStorage_CommandStatusCodes_t\r
+               {\r
+                       Command_Pass = 0, /**< Command completed with no error */\r
+                       Command_Fail = 1, /**< Command failed to complete - host may check the exact error via a SCSI REQUEST SENSE command */\r
+                       Phase_Error  = 2  /**< Command failed due to being invalid in the current phase */\r
+               };\r
+               \r
+       /* Type Defines: */\r
+               /** Type define for the virtual serial port line encoding settings, for storing the current USART configuration\r
+                *  as set by the host via a class specific request.\r
+                */\r
+               typedef struct\r
+               {\r
+                       uint8_t  InterfaceNumber; /**< Interface number of the Mass Storage interface within the device */\r
+\r
+                       uint8_t  DataINEndpointNumber; /**< Endpoint number of the Mass Storage interface's IN data endpoint */\r
+                       uint16_t DataINEndpointSize; /**< Size in bytes of the Mass Storage interface's IN data endpoint */\r
+\r
+                       uint8_t  DataOUTEndpointNumber; /**< Endpoint number of the Mass Storage interface's OUT data endpoint */\r
+                       uint16_t DataOUTEndpointSize;  /**< Size in bytes of the Mass Storage interface's OUT data endpoint */\r
+\r
+                       uint8_t  TotalLUNs;\r
+\r
+                       CommandBlockWrapper_t  CommandBlock;\r
+                       CommandStatusWrapper_t CommandStatus;\r
+\r
+                       bool IsMassStoreReset;\r
+               } USB_ClassInfo_MS_t;\r
+               \r
+       /* Function Prototypes: */\r
+               #if defined(INCLUDE_FROM_MS_CLASS_C)\r
+                       static void    USB_MS_ReturnCommandStatus(USB_ClassInfo_MS_t* MSInterfaceInfo);\r
+                       static bool    USB_MS_ReadInCommandBlock(USB_ClassInfo_MS_t* MSInterfaceInfo);\r
+                       static uint8_t StreamCallback_AbortOnMassStoreReset(void);\r
+               #endif\r
+       \r
+               void USB_MS_USBTask(USB_ClassInfo_MS_t* MSInterfaceInfo);\r
+               bool USB_MS_ConfigureEndpoints(USB_ClassInfo_MS_t* MSInterfaceInfo);\r
+               void USB_MS_ProcessControlPacket(USB_ClassInfo_MS_t* MSInterfaceInfo);\r
+               \r
+               bool CALLBACK_USB_MS_SCSICommandReceived(USB_ClassInfo_MS_t* MSInterfaceInfo);\r
+               \r
+#endif\r
diff --git a/LUFA/Drivers/USB/Class/Device/RNDIS.c b/LUFA/Drivers/USB/Class/Device/RNDIS.c
new file mode 100644 (file)
index 0000000..49c7df0
--- /dev/null
@@ -0,0 +1,456 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+#define  INCLUDE_FROM_RNDIS_CLASS_C\r
+#include "RNDIS.h"\r
+\r
+static const uint32_t PROGMEM AdapterSupportedOIDList[]  =\r
+       {\r
+               OID_GEN_SUPPORTED_LIST,\r
+               OID_GEN_PHYSICAL_MEDIUM,\r
+               OID_GEN_HARDWARE_STATUS,\r
+               OID_GEN_MEDIA_SUPPORTED,\r
+               OID_GEN_MEDIA_IN_USE,\r
+               OID_GEN_MAXIMUM_FRAME_SIZE,\r
+               OID_GEN_MAXIMUM_TOTAL_SIZE,\r
+               OID_GEN_LINK_SPEED,\r
+               OID_GEN_TRANSMIT_BLOCK_SIZE,\r
+               OID_GEN_RECEIVE_BLOCK_SIZE,\r
+               OID_GEN_VENDOR_ID,\r
+               OID_GEN_VENDOR_DESCRIPTION,\r
+               OID_GEN_CURRENT_PACKET_FILTER,\r
+               OID_GEN_MAXIMUM_TOTAL_SIZE,\r
+               OID_GEN_MEDIA_CONNECT_STATUS,\r
+               OID_GEN_XMIT_OK,\r
+               OID_GEN_RCV_OK,\r
+               OID_GEN_XMIT_ERROR,\r
+               OID_GEN_RCV_ERROR,\r
+               OID_GEN_RCV_NO_BUFFER,\r
+               OID_802_3_PERMANENT_ADDRESS,\r
+               OID_802_3_CURRENT_ADDRESS,\r
+               OID_802_3_MULTICAST_LIST,\r
+               OID_802_3_MAXIMUM_LIST_SIZE,\r
+               OID_802_3_RCV_ERROR_ALIGNMENT,\r
+               OID_802_3_XMIT_ONE_COLLISION,\r
+               OID_802_3_XMIT_MORE_COLLISIONS,\r
+       };\r
+\r
+void USB_RNDIS_ProcessControlPacket(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)\r
+{\r
+       if (!(Endpoint_IsSETUPReceived()))\r
+         return;\r
+         \r
+       if (USB_ControlRequest.wIndex != RNDISInterfaceInfo->ControlInterfaceNumber)\r
+         return;\r
+\r
+       switch (USB_ControlRequest.bRequest)\r
+       {\r
+               case REQ_SendEncapsulatedCommand:\r
+                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
+                       {\r
+                               Endpoint_ClearSETUP();\r
+\r
+                               Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->RNDISMessageBuffer, USB_ControlRequest.wLength);\r
+                               Endpoint_ClearIN();\r
+\r
+                               USB_RNDIS_ProcessRNDISControlMessage(RNDISInterfaceInfo);\r
+                       }\r
+                       \r
+                       break;\r
+               case REQ_GetEncapsulatedResponse:\r
+                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
+                       {\r
+                               Endpoint_ClearSETUP();\r
+\r
+                               RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;\r
+\r
+                               if (!(MessageHeader->MessageLength))\r
+                               {\r
+                                       RNDISInterfaceInfo->RNDISMessageBuffer[0] = 0;\r
+                                       MessageHeader->MessageLength = 1;\r
+                               }\r
+\r
+                               Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->RNDISMessageBuffer, MessageHeader->MessageLength);                         \r
+                               Endpoint_ClearOUT();\r
+\r
+                               MessageHeader->MessageLength = 0;\r
+                       }\r
+       \r
+                       break;\r
+       }\r
+}\r
+\r
+bool USB_RNDIS_ConfigureEndpoints(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)\r
+{\r
+       if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->DataINEndpointNumber, EP_TYPE_BULK,\r
+                                                                ENDPOINT_DIR_IN, RNDISInterfaceInfo->DataINEndpointSize,\r
+                                                                ENDPOINT_BANK_SINGLE)))\r
+       {\r
+               return false;\r
+       }\r
+\r
+       if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_BULK,\r
+                                        ENDPOINT_DIR_OUT, RNDISInterfaceInfo->DataOUTEndpointSize,\r
+                                        ENDPOINT_BANK_SINGLE)))\r
+       {\r
+               return false;\r
+       }\r
+\r
+       if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->NotificationEndpointNumber, EP_TYPE_INTERRUPT,\r
+                                        ENDPOINT_DIR_IN, RNDISInterfaceInfo->NotificationEndpointSize,\r
+                                        ENDPOINT_BANK_SINGLE)))\r
+       {\r
+               return false;\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
+void USB_RNDIS_USBTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)\r
+{\r
+       if (!(USB_IsConnected))\r
+         return;\r
+\r
+       RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;\r
+\r
+       Endpoint_SelectEndpoint(RNDISInterfaceInfo->NotificationEndpointNumber);\r
+\r
+       if (Endpoint_IsINReady() && RNDISInterfaceInfo->ResponseReady)\r
+       {\r
+               USB_Request_Header_t Notification = (USB_Request_Header_t)\r
+                       {\r
+                               .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),\r
+                               .bRequest      = NOTIF_ResponseAvailable,\r
+                               .wValue        = 0,\r
+                               .wIndex        = 0,\r
+                               .wLength       = 0,\r
+                       };\r
+               \r
+               Endpoint_Write_Stream_LE(&Notification, sizeof(Notification), NO_STREAM_CALLBACK);\r
+\r
+               Endpoint_ClearIN();\r
+\r
+               RNDISInterfaceInfo->ResponseReady = false;\r
+       }\r
+       \r
+       if ((RNDISInterfaceInfo->CurrRNDISState == RNDIS_Data_Initialized) && !(MessageHeader->MessageLength))\r
+       {\r
+               RNDIS_PACKET_MSG_t RNDISPacketHeader;\r
+\r
+               Endpoint_SelectEndpoint(RNDISInterfaceInfo->DataOUTEndpointNumber);\r
+\r
+               if (Endpoint_IsOUTReceived() && !(RNDISInterfaceInfo->FrameIN.FrameInBuffer))\r
+               {\r
+                       Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_PACKET_MSG_t), NO_STREAM_CALLBACK);\r
+\r
+                       if (RNDISPacketHeader.DataLength > ETHERNET_FRAME_SIZE_MAX)\r
+                       {\r
+                               Endpoint_StallTransaction();\r
+                               return;\r
+                       }\r
+                       \r
+                       Endpoint_Read_Stream_LE(RNDISInterfaceInfo->FrameIN.FrameData, RNDISPacketHeader.DataLength, NO_STREAM_CALLBACK);\r
+\r
+                       Endpoint_ClearOUT();\r
+                       \r
+                       RNDISInterfaceInfo->FrameIN.FrameLength = RNDISPacketHeader.DataLength;\r
+\r
+                       RNDISInterfaceInfo->FrameIN.FrameInBuffer = true;\r
+               }\r
+               \r
+               Endpoint_SelectEndpoint(RNDISInterfaceInfo->DataINEndpointNumber);\r
+               \r
+               if (Endpoint_IsINReady() && RNDISInterfaceInfo->FrameOUT.FrameInBuffer)\r
+               {\r
+                       memset(&RNDISPacketHeader, 0, sizeof(RNDIS_PACKET_MSG_t));\r
+\r
+                       RNDISPacketHeader.MessageType   = REMOTE_NDIS_PACKET_MSG;\r
+                       RNDISPacketHeader.MessageLength = (sizeof(RNDIS_PACKET_MSG_t) + RNDISInterfaceInfo->FrameOUT.FrameLength);\r
+                       RNDISPacketHeader.DataOffset    = (sizeof(RNDIS_PACKET_MSG_t) - sizeof(RNDIS_Message_Header_t));\r
+                       RNDISPacketHeader.DataLength    = RNDISInterfaceInfo->FrameOUT.FrameLength;\r
+\r
+                       Endpoint_Write_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_PACKET_MSG_t), NO_STREAM_CALLBACK);\r
+                       Endpoint_Write_Stream_LE(RNDISInterfaceInfo->FrameOUT.FrameData, RNDISPacketHeader.DataLength, NO_STREAM_CALLBACK);\r
+                       Endpoint_ClearIN();\r
+                       \r
+                       RNDISInterfaceInfo->FrameOUT.FrameInBuffer = false;\r
+               }\r
+       }\r
+}                                                      \r
+\r
+void USB_RNDIS_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)\r
+{\r
+       /* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of\r
+                this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */\r
+\r
+       RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;\r
+\r
+       switch (MessageHeader->MessageType)\r
+       {\r
+               case REMOTE_NDIS_INITIALIZE_MSG:\r
+                       RNDISInterfaceInfo->ResponseReady = true;\r
+                       \r
+                       RNDIS_INITIALIZE_MSG_t*   INITIALIZE_Message  = (RNDIS_INITIALIZE_MSG_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;\r
+                       RNDIS_INITIALIZE_CMPLT_t* INITIALIZE_Response = (RNDIS_INITIALIZE_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;\r
+                       \r
+                       INITIALIZE_Response->MessageType           = REMOTE_NDIS_INITIALIZE_CMPLT;\r
+                       INITIALIZE_Response->MessageLength         = sizeof(RNDIS_INITIALIZE_CMPLT_t);\r
+                       INITIALIZE_Response->RequestId             = INITIALIZE_Message->RequestId;\r
+                       INITIALIZE_Response->Status                = REMOTE_NDIS_STATUS_SUCCESS;\r
+                       \r
+                       INITIALIZE_Response->MajorVersion          = REMOTE_NDIS_VERSION_MAJOR;\r
+                       INITIALIZE_Response->MinorVersion          = REMOTE_NDIS_VERSION_MINOR;                 \r
+                       INITIALIZE_Response->DeviceFlags           = REMOTE_NDIS_DF_CONNECTIONLESS;\r
+                       INITIALIZE_Response->Medium                = REMOTE_NDIS_MEDIUM_802_3;\r
+                       INITIALIZE_Response->MaxPacketsPerTransfer = 1;\r
+                       INITIALIZE_Response->MaxTransferSize       = (sizeof(RNDIS_PACKET_MSG_t) + ETHERNET_FRAME_SIZE_MAX);\r
+                       INITIALIZE_Response->PacketAlignmentFactor = 0;\r
+                       INITIALIZE_Response->AFListOffset          = 0;\r
+                       INITIALIZE_Response->AFListSize            = 0;\r
+                       \r
+                       RNDISInterfaceInfo->CurrRNDISState = RNDIS_Initialized;\r
+               \r
+                       break;\r
+               case REMOTE_NDIS_HALT_MSG:\r
+                       RNDISInterfaceInfo->ResponseReady = false;\r
+                       MessageHeader->MessageLength = 0;\r
+\r
+                       RNDISInterfaceInfo->CurrRNDISState = RNDIS_Uninitialized;\r
+\r
+                       break;\r
+               case REMOTE_NDIS_QUERY_MSG:\r
+                       RNDISInterfaceInfo->ResponseReady = true;\r
+                                               \r
+                       RNDIS_QUERY_MSG_t*   QUERY_Message  = (RNDIS_QUERY_MSG_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;\r
+                       RNDIS_QUERY_CMPLT_t* QUERY_Response = (RNDIS_QUERY_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;\r
+                       uint32_t             Query_Oid      = QUERY_Message->Oid;\r
+                                               \r
+                       void*     QueryData                 = &RNDISInterfaceInfo->RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +\r
+                                                                                                     QUERY_Message->InformationBufferOffset];\r
+                       void*     ResponseData              = &RNDISInterfaceInfo->RNDISMessageBuffer[sizeof(RNDIS_QUERY_CMPLT_t)];             \r
+                       uint16_t  ResponseSize;\r
+\r
+                       QUERY_Response->MessageType         = REMOTE_NDIS_QUERY_CMPLT;\r
+                       QUERY_Response->MessageLength       = sizeof(RNDIS_QUERY_CMPLT_t);\r
+                                               \r
+                       if (USB_RNDIS_ProcessNDISQuery(RNDISInterfaceInfo, Query_Oid, QueryData, QUERY_Message->InformationBufferLength,\r
+                                                      ResponseData, &ResponseSize))\r
+                       {\r
+                               QUERY_Response->Status                  = REMOTE_NDIS_STATUS_SUCCESS;\r
+                               QUERY_Response->MessageLength          += ResponseSize;\r
+                                                       \r
+                               QUERY_Response->InformationBufferLength = ResponseSize;\r
+                               QUERY_Response->InformationBufferOffset = (sizeof(RNDIS_QUERY_CMPLT_t) - sizeof(RNDIS_Message_Header_t));\r
+                       }\r
+                       else\r
+                       {                               \r
+                               QUERY_Response->Status                  = REMOTE_NDIS_STATUS_NOT_SUPPORTED;\r
+\r
+                               QUERY_Response->InformationBufferLength = 0;\r
+                               QUERY_Response->InformationBufferOffset = 0;\r
+                       }\r
+                       \r
+                       break;\r
+               case REMOTE_NDIS_SET_MSG:\r
+                       RNDISInterfaceInfo->ResponseReady = true;\r
+                       \r
+                       RNDIS_SET_MSG_t*   SET_Message  = (RNDIS_SET_MSG_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;\r
+                       RNDIS_SET_CMPLT_t* SET_Response = (RNDIS_SET_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;\r
+                       uint32_t           SET_Oid      = SET_Message->Oid;\r
+\r
+                       SET_Response->MessageType       = REMOTE_NDIS_SET_CMPLT;\r
+                       SET_Response->MessageLength     = sizeof(RNDIS_SET_CMPLT_t);\r
+                       SET_Response->RequestId         = SET_Message->RequestId;\r
+\r
+                       void* SetData                   = &RNDISInterfaceInfo->RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +\r
+                                                                                                 SET_Message->InformationBufferOffset];\r
+                                               \r
+                       if (USB_RNDIS_ProcessNDISSet(RNDISInterfaceInfo, SET_Oid, SetData, SET_Message->InformationBufferLength))\r
+                         SET_Response->Status        = REMOTE_NDIS_STATUS_SUCCESS;\r
+                       else\r
+                         SET_Response->Status        = REMOTE_NDIS_STATUS_NOT_SUPPORTED;\r
+\r
+                       break;\r
+               case REMOTE_NDIS_RESET_MSG:\r
+                       RNDISInterfaceInfo->ResponseReady = true;\r
+                       \r
+                       RNDIS_RESET_CMPLT_t* RESET_Response = (RNDIS_RESET_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;\r
+\r
+                       RESET_Response->MessageType         = REMOTE_NDIS_RESET_CMPLT;\r
+                       RESET_Response->MessageLength       = sizeof(RNDIS_RESET_CMPLT_t);\r
+                       RESET_Response->Status              = REMOTE_NDIS_STATUS_SUCCESS;\r
+                       RESET_Response->AddressingReset     = 0;\r
+\r
+                       break;\r
+               case REMOTE_NDIS_KEEPALIVE_MSG:\r
+                       RNDISInterfaceInfo->ResponseReady = true;\r
+                       \r
+                       RNDIS_KEEPALIVE_MSG_t*   KEEPALIVE_Message  = (RNDIS_KEEPALIVE_MSG_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;\r
+                       RNDIS_KEEPALIVE_CMPLT_t* KEEPALIVE_Response = (RNDIS_KEEPALIVE_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;\r
+\r
+                       KEEPALIVE_Response->MessageType     = REMOTE_NDIS_KEEPALIVE_CMPLT;\r
+                       KEEPALIVE_Response->MessageLength   = sizeof(RNDIS_KEEPALIVE_CMPLT_t);\r
+                       KEEPALIVE_Response->RequestId       = KEEPALIVE_Message->RequestId;\r
+                       KEEPALIVE_Response->Status          = REMOTE_NDIS_STATUS_SUCCESS;\r
+                       \r
+                       break;\r
+       }\r
+}\r
+\r
+static bool USB_RNDIS_ProcessNDISQuery(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo,\r
+                                       uint32_t OId, void* QueryData, uint16_t QuerySize,\r
+                                       void* ResponseData, uint16_t* ResponseSize)\r
+{\r
+       switch (OId)\r
+       {\r
+               case OID_GEN_SUPPORTED_LIST:\r
+                       *ResponseSize = sizeof(AdapterSupportedOIDList);\r
+                       \r
+                       memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList));\r
+                       \r
+                       return true;\r
+               case OID_GEN_PHYSICAL_MEDIUM:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       /* Indicate that the device is a true ethernet link */\r
+                       *((uint32_t*)ResponseData) = 0;\r
+                       \r
+                       return true;\r
+               case OID_GEN_HARDWARE_STATUS:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       *((uint32_t*)ResponseData) = NdisHardwareStatusReady;\r
+                       \r
+                       return true;\r
+               case OID_GEN_MEDIA_SUPPORTED:\r
+               case OID_GEN_MEDIA_IN_USE:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       *((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIUM_802_3;\r
+                       \r
+                       return true;\r
+               case OID_GEN_VENDOR_ID:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       /* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */\r
+                       *((uint32_t*)ResponseData) = 0x00FFFFFF;\r
+                       \r
+                       return true;\r
+               case OID_GEN_MAXIMUM_FRAME_SIZE:\r
+               case OID_GEN_TRANSMIT_BLOCK_SIZE:\r
+               case OID_GEN_RECEIVE_BLOCK_SIZE:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       *((uint32_t*)ResponseData) = ETHERNET_FRAME_SIZE_MAX;\r
+                       \r
+                       return true;\r
+               case OID_GEN_VENDOR_DESCRIPTION:\r
+                       *ResponseSize = (strlen(RNDISInterfaceInfo->AdapterVendorDescription) + 1);\r
+                       \r
+                       memcpy(ResponseData, RNDISInterfaceInfo->AdapterVendorDescription, *ResponseSize);\r
+                       \r
+                       return true;\r
+               case OID_GEN_MEDIA_CONNECT_STATUS:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       *((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIA_STATE_CONNECTED;\r
+                       \r
+                       return true;\r
+               case OID_GEN_LINK_SPEED:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       /* Indicate 10Mb/s link speed */\r
+                       *((uint32_t*)ResponseData) = 100000;\r
+\r
+                       return true;\r
+               case OID_802_3_PERMANENT_ADDRESS:\r
+               case OID_802_3_CURRENT_ADDRESS:\r
+                       *ResponseSize = sizeof(MAC_Address_t);\r
+                       \r
+                       memcpy(ResponseData, &RNDISInterfaceInfo->AdapterMACAddress, sizeof(MAC_Address_t));\r
+\r
+                       return true;\r
+               case OID_802_3_MAXIMUM_LIST_SIZE:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       /* Indicate only one multicast address supported */\r
+                       *((uint32_t*)ResponseData) = 1;\r
+               \r
+                       return true;\r
+               case OID_GEN_CURRENT_PACKET_FILTER:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       *((uint32_t*)ResponseData) = RNDISInterfaceInfo->CurrPacketFilter;\r
+               \r
+                       return true;                    \r
+               case OID_GEN_XMIT_OK:\r
+               case OID_GEN_RCV_OK:\r
+               case OID_GEN_XMIT_ERROR:\r
+               case OID_GEN_RCV_ERROR:\r
+               case OID_GEN_RCV_NO_BUFFER:\r
+               case OID_802_3_RCV_ERROR_ALIGNMENT:\r
+               case OID_802_3_XMIT_ONE_COLLISION:\r
+               case OID_802_3_XMIT_MORE_COLLISIONS:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       /* Unused statistic OIDs - always return 0 for each */\r
+                       *((uint32_t*)ResponseData) = 0;\r
+               \r
+                       return true;\r
+               case OID_GEN_MAXIMUM_TOTAL_SIZE:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       /* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */\r
+                       *((uint32_t*)ResponseData) = (RNDIS_MESSAGE_BUFFER_SIZE + ETHERNET_FRAME_SIZE_MAX);\r
+               \r
+                       return true;\r
+               default:\r
+                       return false;\r
+       }\r
+}\r
+\r
+static bool USB_RNDIS_ProcessNDISSet(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo, uint32_t OId, void* SetData, uint16_t SetSize)\r
+{\r
+       switch (OId)\r
+       {\r
+               case OID_GEN_CURRENT_PACKET_FILTER:\r
+                       RNDISInterfaceInfo->CurrPacketFilter = *((uint32_t*)SetData);\r
+                       RNDISInterfaceInfo->CurrRNDISState = ((RNDISInterfaceInfo->CurrPacketFilter) ?\r
+                                                             RNDIS_Data_Initialized : RNDIS_Data_Initialized);\r
+                       \r
+                       return true;\r
+               case OID_802_3_MULTICAST_LIST:\r
+                       /* Do nothing - throw away the value from the host as it is unused */\r
+               \r
+                       return true;\r
+               default:\r
+                       return false;\r
+       }\r
+}\r
diff --git a/LUFA/Drivers/USB/Class/Device/RNDIS.h b/LUFA/Drivers/USB/Class/Device/RNDIS.h
new file mode 100644 (file)
index 0000000..73622a4
--- /dev/null
@@ -0,0 +1,260 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+#ifndef _RNDIS_CLASS_H_\r
+#define _RNDIS_CLASS_H_\r
+\r
+       /* Includes: */\r
+               #include <string.h>\r
+       \r
+               #include "../../USB.h"\r
+               #include "RNDISConstants.h"\r
+               \r
+       /* Macros: */\r
+               /** Implemented RNDIS Version Major */\r
+               #define REMOTE_NDIS_VERSION_MAJOR             0x01\r
+\r
+               /** Implemented RNDIS Version Minor */\r
+               #define REMOTE_NDIS_VERSION_MINOR             0x00\r
+       \r
+               /** RNDIS request to issue a host-to-device NDIS command */\r
+               #define REQ_SendEncapsulatedCommand           0x00\r
+\r
+               /** RNDIS request to issue a device-to-host NDIS response */\r
+               #define REQ_GetEncapsulatedResponse           0x01\r
+               \r
+               #define RNDIS_MESSAGE_BUFFER_SIZE             128\r
+\r
+               #define ETHERNET_FRAME_SIZE_MAX               1500\r
+               \r
+               #define NOTIF_ResponseAvailable               1\r
+               \r
+       /* Enums: */\r
+               /** Enum for the possible NDIS adapter states. */\r
+               enum RNDIS_States_t\r
+               {\r
+                       RNDIS_Uninitialized    = 0, /**< Adapter currently uninitialized */\r
+                       RNDIS_Initialized      = 1, /**< Adapter currently initialized but not ready for data transfers */\r
+                       RNDIS_Data_Initialized = 2, /**< Adapter currently initialized and ready for data transfers */\r
+               };\r
+\r
+               /** Enum for the NDIS hardware states */\r
+               enum NDIS_Hardware_Status_t\r
+               {\r
+                       NdisHardwareStatusReady, /**< Hardware Ready to accept commands from the host */\r
+                       NdisHardwareStatusInitializing, /**< Hardware busy initializing */\r
+                       NdisHardwareStatusReset, /**< Hardware reset */\r
+                       NdisHardwareStatusClosing, /**< Hardware currently closing */\r
+                       NdisHardwareStatusNotReady /**< Hardware not ready to accept commands from the host */\r
+               };\r
+               \r
+       /* Type Defines: */\r
+               /** Type define for a physical MAC address of a device on a network */\r
+               typedef struct\r
+               {\r
+                       uint8_t       Octets[6]; /**< Individual bytes of a MAC address */\r
+               } MAC_Address_t;\r
+\r
+               /** Type define for a RNDIS message header, sent before RNDIS messages */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType; /**< RNDIS message type, a REMOTE_NDIS_*_MSG constant */\r
+                       uint32_t MessageLength; /**< Total length of the RNDIS message, in bytes */\r
+               } RNDIS_Message_Header_t;\r
+\r
+               /** Type define for an Ethernet frame buffer. */\r
+               typedef struct\r
+               {\r
+                       uint8_t       FrameData[ETHERNET_FRAME_SIZE_MAX]; /**< Ethernet frame contents */\r
+                       uint16_t      FrameLength; /**< Length in bytes of the Ethernet frame stored in the buffer */\r
+                       bool          FrameInBuffer; /**< Indicates if a frame is currently stored in the buffer */\r
+               } Ethernet_Frame_Info_t;\r
+\r
+               /** Type define for a RNDIS packet message, used to encapsulate Ethernet packets sent to and from the adapter */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType;\r
+                       uint32_t MessageLength;\r
+                       uint32_t DataOffset;\r
+                       uint32_t DataLength;\r
+                       uint32_t OOBDataOffset;\r
+                       uint32_t OOBDataLength;\r
+                       uint32_t NumOOBDataElements;\r
+                       uint32_t PerPacketInfoOffset;\r
+                       uint32_t PerPacketInfoLength;\r
+                       uint32_t VcHandle;\r
+                       uint32_t Reserved;\r
+               } RNDIS_PACKET_MSG_t;\r
+\r
+               typedef struct\r
+               {\r
+                       uint8_t  ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device */\r
+\r
+                       uint8_t  DataINEndpointNumber; /**< Endpoint number of the CDC interface's IN data endpoint */\r
+                       uint16_t DataINEndpointSize; /**< Size in bytes of the CDC interface's IN data endpoint */\r
+\r
+                       uint8_t  DataOUTEndpointNumber; /**< Endpoint number of the CDC interface's OUT data endpoint */\r
+                       uint16_t DataOUTEndpointSize;  /**< Size in bytes of the CDC interface's OUT data endpoint */\r
+\r
+                       uint8_t  NotificationEndpointNumber; /**< Endpoint number of the CDC interface's IN notification endpoint, if used */\r
+                       uint16_t NotificationEndpointSize;  /**< Size in bytes of the CDC interface's IN notification endpoint, if used */\r
+                       \r
+                       char*         AdapterVendorDescription;\r
+                       MAC_Address_t AdapterMACAddress;\r
+\r
+                       uint8_t  RNDISMessageBuffer[RNDIS_MESSAGE_BUFFER_SIZE];\r
+                       bool     ResponseReady;\r
+                       uint8_t  CurrRNDISState;\r
+                       uint32_t CurrPacketFilter;\r
+                       Ethernet_Frame_Info_t FrameIN;\r
+                       Ethernet_Frame_Info_t FrameOUT;\r
+               } USB_ClassInfo_RNDIS_t;\r
+               \r
+               /** Type define for a RNDIS Initialize command message */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType;\r
+                       uint32_t MessageLength;\r
+                       uint32_t RequestId;\r
+                       \r
+                       uint32_t MajorVersion;\r
+                       uint32_t MinorVersion;\r
+                       uint32_t MaxTransferSize;\r
+               } RNDIS_INITIALIZE_MSG_t;\r
+               \r
+               /** Type define for a RNDIS Initialize complete response message */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType;\r
+                       uint32_t MessageLength;\r
+                       uint32_t RequestId;\r
+                       uint32_t Status;\r
+                       \r
+                       uint32_t MajorVersion;\r
+                       uint32_t MinorVersion;\r
+                       uint32_t DeviceFlags;\r
+                       uint32_t Medium;\r
+                       uint32_t MaxPacketsPerTransfer;\r
+                       uint32_t MaxTransferSize;\r
+                       uint32_t PacketAlignmentFactor;\r
+                       uint32_t AFListOffset;\r
+                       uint32_t AFListSize;\r
+               } RNDIS_INITIALIZE_CMPLT_t;\r
+               \r
+               /** Type define for a RNDIS Keepalive command message */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType;\r
+                       uint32_t MessageLength;\r
+                       uint32_t RequestId;\r
+               } RNDIS_KEEPALIVE_MSG_t;\r
+\r
+               /** Type define for a RNDIS Keepalive complete message */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType;\r
+                       uint32_t MessageLength;\r
+                       uint32_t RequestId;\r
+                       uint32_t Status;\r
+               } RNDIS_KEEPALIVE_CMPLT_t;\r
+\r
+               /** Type define for a RNDIS Reset complete message */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType;\r
+                       uint32_t MessageLength;\r
+                       uint32_t Status;\r
+\r
+                       uint32_t AddressingReset;\r
+               } RNDIS_RESET_CMPLT_t;\r
+               \r
+               /** Type define for a RNDIS Set command message */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType;\r
+                       uint32_t MessageLength;\r
+                       uint32_t RequestId;\r
+                       \r
+                       uint32_t Oid;\r
+                       uint32_t InformationBufferLength;\r
+                       uint32_t InformationBufferOffset;\r
+                       uint32_t DeviceVcHandle;\r
+               } RNDIS_SET_MSG_t;\r
+\r
+               /** Type define for a RNDIS Set complete response message */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType;\r
+                       uint32_t MessageLength;\r
+                       uint32_t RequestId;\r
+                       uint32_t Status;\r
+               } RNDIS_SET_CMPLT_t;\r
+               \r
+               /** Type define for a RNDIS Query command message */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType;\r
+                       uint32_t MessageLength;\r
+                       uint32_t RequestId;\r
+                       \r
+                       uint32_t Oid;\r
+                       uint32_t InformationBufferLength;\r
+                       uint32_t InformationBufferOffset;\r
+                       uint32_t DeviceVcHandle;\r
+               } RNDIS_QUERY_MSG_t;\r
+               \r
+               /** Type define for a RNDIS Query complete response message */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType;\r
+                       uint32_t MessageLength;\r
+                       uint32_t RequestId;\r
+                       uint32_t Status;\r
+                       \r
+                       uint32_t InformationBufferLength;\r
+                       uint32_t InformationBufferOffset;\r
+               } RNDIS_QUERY_CMPLT_t;\r
+               \r
+       /* Function Prototypes: */\r
+               #if defined(INCLUDE_FROM_RNDIS_CLASS_C)\r
+                       static void USB_RNDIS_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);\r
+                       static bool USB_RNDIS_ProcessNDISQuery(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo, \r
+                                                              uint32_t OId, void* QueryData, uint16_t QuerySize,\r
+                                                                                          void* ResponseData, uint16_t* ResponseSize);\r
+                       static bool USB_RNDIS_ProcessNDISSet(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo, uint32_t OId,\r
+                                                            void* SetData, uint16_t SetSize);  \r
+               #endif\r
+\r
+               void     USB_RNDIS_USBTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);\r
+               bool     USB_RNDIS_ConfigureEndpoints(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);\r
+               void     USB_RNDIS_ProcessControlPacket(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);\r
+               void     USB_RNDIS_USBTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);\r
+               \r
+#endif\r
diff --git a/LUFA/Drivers/USB/Class/Device/RNDISConstants.h b/LUFA/Drivers/USB/Class/Device/RNDISConstants.h
new file mode 100644 (file)
index 0000000..ad66f62
--- /dev/null
@@ -0,0 +1,99 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  RNDIS specification related constants. For more information on these\r
+ *  constants, please refer to the Microsoft RNDIS specification.\r
+ */\r
\r
+#ifndef _RNDIS_CONSTANTS_H_\r
+#define _RNDIS_CONSTANTS_H_\r
+\r
+       /* Macros: */\r
+               #define REMOTE_NDIS_PACKET_MSG                0x00000001UL\r
+               #define REMOTE_NDIS_INITIALIZE_MSG            0x00000002UL\r
+               #define REMOTE_NDIS_HALT_MSG                  0x00000003UL\r
+               #define REMOTE_NDIS_QUERY_MSG                 0x00000004UL\r
+               #define REMOTE_NDIS_SET_MSG                   0x00000005UL\r
+               #define REMOTE_NDIS_RESET_MSG                 0x00000006UL\r
+               #define REMOTE_NDIS_INDICATE_STATUS_MSG       0x00000007UL\r
+               #define REMOTE_NDIS_KEEPALIVE_MSG             0x00000008UL\r
+\r
+               #define REMOTE_NDIS_INITIALIZE_CMPLT          0x80000002UL\r
+               #define REMOTE_NDIS_QUERY_CMPLT               0x80000004UL\r
+               #define REMOTE_NDIS_SET_CMPLT                 0x80000005UL\r
+               #define REMOTE_NDIS_RESET_CMPLT               0x80000006UL\r
+               #define REMOTE_NDIS_KEEPALIVE_CMPLT           0x80000008UL\r
+               \r
+               #define REMOTE_NDIS_STATUS_SUCCESS            0x00000000UL\r
+               #define REMOTE_NDIS_STATUS_FAILURE            0xC0000001UL\r
+               #define REMOTE_NDIS_STATUS_INVALID_DATA       0xC0010015UL\r
+               #define REMOTE_NDIS_STATUS_NOT_SUPPORTED      0xC00000BBUL\r
+               #define REMOTE_NDIS_STATUS_MEDIA_CONNECT      0x4001000BUL\r
+               #define REMOTE_NDIS_STATUS_MEDIA_DISCONNECT   0x4001000CUL\r
+               \r
+               #define REMOTE_NDIS_MEDIA_STATE_CONNECTED     0x00000000UL\r
+               #define REMOTE_NDIS_MEDIA_STATE_DISCONNECTED  0x00000001UL\r
+               \r
+               #define REMOTE_NDIS_MEDIUM_802_3              0x00000000UL\r
+               \r
+               #define REMOTE_NDIS_DF_CONNECTIONLESS         0x00000001UL\r
+               #define REMOTE_NDIS_DF_CONNECTION_ORIENTED    0x00000002UL\r
+               \r
+               #define OID_GEN_SUPPORTED_LIST                0x00010101UL\r
+               #define OID_GEN_HARDWARE_STATUS               0x00010102UL\r
+               #define OID_GEN_MEDIA_SUPPORTED               0x00010103UL\r
+               #define OID_GEN_MEDIA_IN_USE                  0x00010104UL\r
+               #define OID_GEN_MAXIMUM_FRAME_SIZE            0x00010106UL\r
+               #define OID_GEN_MAXIMUM_TOTAL_SIZE            0x00010111UL\r
+               #define OID_GEN_LINK_SPEED                    0x00010107UL\r
+               #define OID_GEN_TRANSMIT_BLOCK_SIZE           0x0001010AUL\r
+               #define OID_GEN_RECEIVE_BLOCK_SIZE            0x0001010BUL\r
+               #define OID_GEN_VENDOR_ID                     0x0001010CUL\r
+               #define OID_GEN_VENDOR_DESCRIPTION            0x0001010DUL\r
+               #define OID_GEN_CURRENT_PACKET_FILTER         0x0001010EUL\r
+               #define OID_GEN_MAXIMUM_TOTAL_SIZE            0x00010111UL\r
+               #define OID_GEN_MEDIA_CONNECT_STATUS          0x00010114UL\r
+               #define OID_GEN_PHYSICAL_MEDIUM               0x00010202UL\r
+               #define OID_GEN_XMIT_OK                       0x00020101UL\r
+               #define OID_GEN_RCV_OK                        0x00020102UL\r
+               #define OID_GEN_XMIT_ERROR                    0x00020103UL\r
+               #define OID_GEN_RCV_ERROR                     0x00020104UL\r
+               #define OID_GEN_RCV_NO_BUFFER                 0x00020105UL\r
+               #define OID_802_3_PERMANENT_ADDRESS           0x01010101UL\r
+               #define OID_802_3_CURRENT_ADDRESS             0x01010102UL\r
+               #define OID_802_3_MULTICAST_LIST              0x01010103UL\r
+               #define OID_802_3_MAXIMUM_LIST_SIZE           0x01010104UL\r
+               #define OID_802_3_RCV_ERROR_ALIGNMENT         0x01020101UL\r
+               #define OID_802_3_XMIT_ONE_COLLISION          0x01020102UL\r
+               #define OID_802_3_XMIT_MORE_COLLISIONS        0x01020103UL\r
+\r
+#endif\r
diff --git a/LUFA/Drivers/USB/Class/HIDParser.c b/LUFA/Drivers/USB/Class/HIDParser.c
deleted file mode 100644 (file)
index 5fb29aa..0000000
+++ /dev/null
@@ -1,326 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-#include "HIDParser.h"\r
-\r
-uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID_ReportInfo_t* const ParserData)\r
-{\r
-       HID_StateTable_t  StateTable[HID_STATETABLE_STACK_DEPTH];\r
-       HID_StateTable_t* CurrStateTable               = &StateTable[0];\r
-       uint16_t          UsageStack[HID_USAGE_STACK_DEPTH];\r
-       uint8_t           UsageStackSize               = 0;\r
-       uint16_t          BitOffsetIn                  = 0;\r
-       uint16_t          BitOffsetOut                 = 0;\r
-#if defined(HID_ENABLE_FEATURE_PROCESSING)\r
-       uint16_t          BitOffsetFeature             = 0;\r
-#endif\r
-       HID_CollectionPath_t* CurrCollectionPath       = NULL;\r
-\r
-       memset((void*)ParserData, 0x00, sizeof(HID_ReportInfo_t));\r
-       memset((void*)StateTable, 0x00, sizeof(StateTable));\r
-\r
-       while (ReportSize)\r
-       {\r
-               uint32_t ReportItemData = 0;\r
-               \r
-               switch (*ReportData & DATA_SIZE_MASK)\r
-               {\r
-                       case DATA_SIZE_4:\r
-                               ReportItemData = *((uint32_t*)(ReportData + 1));\r
-                               break;\r
-                       case DATA_SIZE_2:\r
-                               ReportItemData = *((uint16_t*)(ReportData + 1));\r
-                               break;\r
-                       case DATA_SIZE_1:\r
-                               ReportItemData = *((uint8_t*)(ReportData + 1));\r
-                               break;\r
-               }\r
-\r
-               switch (*ReportData & (TYPE_MASK | TAG_MASK))\r
-               {\r
-                       case (TYPE_GLOBAL | TAG_GLOBAL_PUSH):\r
-                               if (CurrStateTable == &StateTable[HID_STATETABLE_STACK_DEPTH])\r
-                                 return HID_PARSE_HIDStackOverflow;\r
-       \r
-                               memcpy((CurrStateTable - 1),\r
-                                      CurrStateTable,\r
-                                      sizeof(HID_ReportItem_t));\r
-\r
-                               CurrStateTable++;\r
-                               break;\r
-                       case (TYPE_GLOBAL | TAG_GLOBAL_POP):\r
-                               if (CurrStateTable == &StateTable[0])\r
-                                 return HID_PARSE_HIDStackUnderflow;\r
-                                 \r
-                               CurrStateTable--;\r
-                               break;\r
-                       case (TYPE_GLOBAL | TAG_GLOBAL_USAGEPAGE):\r
-                               CurrStateTable->Attributes.Usage.Page       = ReportItemData;\r
-                               break;\r
-                       case (TYPE_GLOBAL | TAG_GLOBAL_LOGICALMIN):\r
-                               CurrStateTable->Attributes.Logical.Minimum  = ReportItemData;\r
-                               break;\r
-                       case (TYPE_GLOBAL | TAG_GLOBAL_LOGICALMAX):\r
-                               CurrStateTable->Attributes.Logical.Maximum  = ReportItemData;\r
-                               break;\r
-                       case (TYPE_GLOBAL | TAG_GLOBAL_PHYSMIN):\r
-                               CurrStateTable->Attributes.Physical.Minimum = ReportItemData;\r
-                               break;\r
-                       case (TYPE_GLOBAL | TAG_GLOBAL_PHYSMAX):\r
-                               CurrStateTable->Attributes.Physical.Maximum = ReportItemData;\r
-                               break;\r
-                       case (TYPE_GLOBAL | TAG_GLOBAL_UNITEXP):\r
-                               CurrStateTable->Attributes.Unit.Exponent    = ReportItemData;\r
-                               break;\r
-                       case (TYPE_GLOBAL | TAG_GLOBAL_UNIT):\r
-                               CurrStateTable->Attributes.Unit.Type        = ReportItemData;\r
-                               break;\r
-                       case (TYPE_GLOBAL | TAG_GLOBAL_REPORTSIZE):\r
-                               CurrStateTable->Attributes.BitSize          = ReportItemData;\r
-                               break;\r
-                       case (TYPE_GLOBAL | TAG_GLOBAL_REPORTCOUNT):\r
-                               CurrStateTable->ReportCount                 = ReportItemData;\r
-                               break;\r
-                       case (TYPE_GLOBAL | TAG_GLOBAL_REPORTID):\r
-                               CurrStateTable->ReportID                    = ReportItemData;\r
-                               break;\r
-                       case (TYPE_LOCAL | TAG_LOCAL_USAGE):\r
-                               if (UsageStackSize == HID_USAGE_STACK_DEPTH)\r
-                                 return HID_PARSE_UsageStackOverflow;\r
-                       \r
-                               UsageStack[UsageStackSize++] = ReportItemData;\r
-                               break;\r
-                       case (TYPE_LOCAL | TAG_LOCAL_USAGEMIN):\r
-                               CurrStateTable->Attributes.Usage.MinMax.Minimum = ReportItemData;\r
-                               break;\r
-                       case (TYPE_LOCAL | TAG_LOCAL_USAGEMAX):\r
-                               CurrStateTable->Attributes.Usage.MinMax.Maximum = ReportItemData;\r
-                               break;\r
-                       case (TYPE_MAIN | TAG_MAIN_COLLECTION):\r
-                               if (CurrCollectionPath == NULL)\r
-                               {\r
-                                       CurrCollectionPath = &ParserData->CollectionPaths[0];\r
-                               }\r
-                               else\r
-                               {\r
-                                       HID_CollectionPath_t* ParentCollectionPath = CurrCollectionPath;\r
-                       \r
-                                       CurrCollectionPath = &ParserData->CollectionPaths[1];\r
-\r
-                                       while (CurrCollectionPath->Parent != NULL);\r
-                                       {\r
-                                               if (CurrCollectionPath == &ParserData->CollectionPaths[HID_MAX_COLLECTIONS])\r
-                                                 return HID_PARSE_InsufficientCollectionPaths;\r
-                                       \r
-                                               CurrCollectionPath++;\r
-                                       }\r
-\r
-                                       CurrCollectionPath->Parent = ParentCollectionPath;\r
-                               }\r
-                               \r
-                               CurrCollectionPath->Type = ReportItemData;\r
-                               CurrCollectionPath->Usage.Page = CurrStateTable->Attributes.Usage.Page;\r
-                               \r
-                               if (UsageStackSize)\r
-                               {\r
-                                       CurrCollectionPath->Usage.Usage = UsageStack[0];\r
-\r
-                                       for (uint8_t i = 0; i < UsageStackSize; i++)\r
-                                         UsageStack[i] = UsageStack[i + 1];\r
-                                         \r
-                                       UsageStackSize--;\r
-                               }\r
-                               else\r
-                               {\r
-                                       CurrCollectionPath->Usage.Usage = 0;\r
-                               }\r
-                               \r
-                               break;\r
-                       case (TYPE_MAIN | TAG_MAIN_ENDCOLLECTION):\r
-                               if (CurrCollectionPath == NULL)\r
-                                 return HID_PARSE_UnexpectedEndCollection;\r
-               \r
-                               CurrCollectionPath = CurrCollectionPath->Parent;\r
-\r
-                               break;\r
-                       case (TYPE_MAIN | TAG_MAIN_INPUT):\r
-                       case (TYPE_MAIN | TAG_MAIN_OUTPUT):\r
-#if defined(HID_ENABLE_FEATURE_PROCESSING)\r
-                       case (TYPE_MAIN | TAG_MAIN_FEATURE):\r
-#endif\r
-                               for (uint8_t ReportItemNum = 0; ReportItemNum < CurrStateTable->ReportCount; ReportItemNum++)\r
-                               {\r
-                                       HID_ReportItem_t* CurrReportItem = &ParserData->ReportItems[ParserData->TotalReportItems];\r
-                               \r
-                                       if (ParserData->TotalReportItems == HID_MAX_REPORTITEMS)\r
-                                         return HID_PARSE_InsufficientReportItems;\r
-                                 \r
-                                       memcpy(&CurrReportItem->Attributes,\r
-                                              &CurrStateTable->Attributes,\r
-                                              sizeof(HID_ReportItem_Attributes_t));\r
-\r
-                                       CurrReportItem->ItemFlags      = ReportItemData;\r
-                                       CurrReportItem->CollectionPath = CurrCollectionPath;\r
-                                       CurrReportItem->ReportID       = CurrStateTable->ReportID;\r
-\r
-                                       if (UsageStackSize)\r
-                                       {\r
-                                               CurrReportItem->Attributes.Usage.Usage = UsageStack[0];\r
-\r
-                                               for (uint8_t i = 0; i < UsageStackSize; i++)\r
-                                                 UsageStack[i] = UsageStack[i + 1];\r
-                                                 \r
-                                               UsageStackSize--;\r
-                                       }\r
-                                       else\r
-                                       {\r
-                                               CurrReportItem->Attributes.Usage.Usage = 0;\r
-                                       }\r
-                                                                                       \r
-                                       switch (*ReportData & TAG_MASK)\r
-                                       {\r
-                                               case TAG_MAIN_INPUT:\r
-                                                       CurrReportItem->ItemType  = REPORT_ITEM_TYPE_In;\r
-                                                       CurrReportItem->BitOffset = BitOffsetIn;\r
-                                                               \r
-                                                       BitOffsetIn += CurrStateTable->Attributes.BitSize;\r
-                                                       \r
-                                                       break;\r
-                                               case TAG_MAIN_OUTPUT:\r
-                                                       CurrReportItem->ItemType  = REPORT_ITEM_TYPE_Out;\r
-                                                       CurrReportItem->BitOffset = BitOffsetOut;\r
-                                                               \r
-                                                       BitOffsetOut += CurrStateTable->Attributes.BitSize;\r
-                                                       \r
-                                                       break;\r
-#if defined(HID_ENABLE_FEATURE_PROCESSING)\r
-                                               case TAG_MAIN_FEATURE:\r
-                                                       CurrReportItem->ItemType  = REPORT_ITEM_TYPE_Feature;                                           \r
-                                                       CurrReportItem->BitOffset = BitOffsetFeature;\r
-                                                               \r
-                                                       BitOffsetFeature += CurrStateTable->Attributes.BitSize;         \r
-\r
-                                                       break;\r
-#endif\r
-                                       }\r
-                                       \r
-#if !defined(HID_INCLUDE_CONSTANT_DATA_ITEMS)\r
-                                       if (!(ReportItemData & IOF_CONSTANT))\r
-                                         ParserData->TotalReportItems++;\r
-#else\r
-                                       ParserData->TotalReportItems++;\r
-#endif\r
-                               }\r
-                               \r
-                               UsageStackSize = 0;\r
-                               \r
-                               break;\r
-               }\r
-         \r
-               if ((*ReportData & TYPE_MASK) == TYPE_MAIN)\r
-               {\r
-                       CurrStateTable->Attributes.Usage.MinMax.Minimum = 0;\r
-                       CurrStateTable->Attributes.Usage.MinMax.Maximum = 0;\r
-                       UsageStackSize = 0;\r
-               }\r
-               \r
-               switch (*ReportData & DATA_SIZE_MASK)\r
-               {\r
-                       case DATA_SIZE_4:\r
-                               ReportSize -= 5;\r
-                               ReportData += 5;\r
-                               break;\r
-                       case DATA_SIZE_2:\r
-                               ReportSize -= 3;\r
-                               ReportData += 3;\r
-                               break;\r
-                       case DATA_SIZE_1:\r
-                               ReportSize -= 2;\r
-                               ReportData += 2;\r
-                               break;\r
-                       case DATA_SIZE_0:\r
-                               ReportSize -= 1;\r
-                               ReportData += 1;\r
-                               break;\r
-               }\r
-       }\r
-       \r
-       return HID_PARSE_Successful;\r
-}\r
-\r
-bool USB_GetHIDReportItemInfo(const uint8_t* ReportData, HID_ReportItem_t* const ReportItem)\r
-{\r
-       uint16_t DataBitsRem  = ReportItem->Attributes.BitSize;\r
-       uint16_t CurrentBit   = ReportItem->BitOffset;\r
-       uint32_t BitMask      = (1 << 0);\r
-\r
-       ReportItem->Value = 0;\r
-       \r
-       if (ReportItem->ReportID)\r
-       {\r
-               if (ReportItem->ReportID != ReportData[0])\r
-                 return false;\r
-\r
-               ReportData++;\r
-       }\r
-\r
-       while (DataBitsRem--)\r
-       {\r
-               if (ReportData[CurrentBit / 8] & (1 << (CurrentBit % 8)))\r
-                 ReportItem->Value |= BitMask;\r
-               \r
-               CurrentBit++;\r
-               BitMask <<= 1;\r
-       }\r
-       \r
-       return true;\r
-}\r
-\r
-void USB_SetHIDReportItemInfo(uint8_t* ReportData, const HID_ReportItem_t* ReportItem)\r
-{\r
-       uint16_t DataBitsRem  = ReportItem->Attributes.BitSize;\r
-       uint16_t CurrentBit   = ReportItem->BitOffset;\r
-       uint32_t BitMask      = (1 << 0);\r
-\r
-       if (ReportItem->ReportID)\r
-       {\r
-               ReportData[0] = ReportItem->ReportID;\r
-               ReportData++;\r
-       }\r
-\r
-       while (DataBitsRem--)\r
-       {\r
-               if (ReportItem->Value & (1 << (CurrentBit % 8)))\r
-                 ReportData[CurrentBit / 8] |= BitMask;\r
-\r
-               CurrentBit++;\r
-               BitMask <<= 1;\r
-       }\r
-}\r
diff --git a/LUFA/Drivers/USB/Class/HIDParser.h b/LUFA/Drivers/USB/Class/HIDParser.h
deleted file mode 100644 (file)
index 49e57c2..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  USB Human Interface Device (HID) Class report descriptor processing routines. This file allows for the easy\r
- *  parsing of the complex HID report descriptor, which describes the data that the device transmits to the host.\r
- *\r
- */\r
\r
-/** \ingroup Group_USB\r
- *  @defgroup Group_HIDParser HID Report Parser\r
- *\r
- *  Functions, macros, variables, enums and types related to the parsing of HID class device report descriptors.\r
- *\r
- *  The processed HID report is presented back to the user application as a flat structure containing each report\r
- *  item's IN, OUT and FEATURE (if desired) items along with each item's attributes.\r
- *\r
- *  This library portion also allows for easy setting and retrieval of data from a HID report, including devices\r
- *  with multiple reports on the one HID interface.\r
- *\r
- *  By default, FEATURE reports and IN/OUT reports with constant data are ignored in the HID report when processed\r
- *  to save on memory. This can be overridden by defining the HID_ENABLE_FEATURE_PROCESSING or\r
- *  HID_INCLUDE_CONSTANT_DATA_ITEMS tokens in the user project makefile, passing them to the compiler via the -D\r
- *  switch.\r
- *\r
- *  @{\r
- */\r
-\r
-#ifndef __HIDPARSER_H__\r
-#define __HIDPARSER_H__\r
-\r
-       /* Includes: */\r
-               #include <string.h>\r
-               #include <stdbool.h>\r
-\r
-               #include "HIDReportData.h"\r
-\r
-               #include "../../../Common/Common.h"\r
-\r
-       /* Enable C linkage for C++ Compilers: */\r
-               #if defined(__cplusplus)\r
-                       extern "C" {\r
-               #endif\r
-\r
-       /* Preprocessor checks and defines: */\r
-               #if !defined(HID_STATETABLE_STACK_DEPTH) || defined(__DOXYGEN__)\r
-                       /** Constant indicating the maximum stack depth of the state table. A larger state table\r
-                        *  allows for more PUSH/POP report items to be nested, but consumes more memory. By default\r
-                        *  this is set to 3 levels (allowing for two PUSHes to be nested) but this can be overridden by\r
-                        *  defining HID_STATETABLE_STACK_DEPTH to another value in the user project makefile, passing the\r
-                        *  define to the compiler using the -D compiler switch.\r
-                        */\r
-                       #define HID_STATETABLE_STACK_DEPTH    3\r
-               #endif\r
-               \r
-               #if !defined(HID_USAGE_STACK_DEPTH) || defined(__DOXYGEN__)\r
-                       /** Constant indicating the maximum stack depth of the usage table. A larger usage table\r
-                        *  allows for more USAGE items to be indicated sequentially for REPORT COUNT entries of more than\r
-                        *  one, but requires more stack space. By default this is set to 8 levels (allowing for a report\r
-                        *  item with a count of 8) but this can be overridden by defining HID_USAGE_STACK_DEPTH to another\r
-                        *  value in the user project makefile, passing the define to the compiler using the -D compiler\r
-                        *  switch.\r
-                        */\r
-                       #define HID_USAGE_STACK_DEPTH         8\r
-               #endif\r
-\r
-               #if !defined(HID_MAX_COLLECTIONS) || defined(__DOXYGEN__)\r
-                       /** Constant indicating the maximum number of COLLECTION items (nested or unnested) that can be\r
-                        *  processed in the report item descriptor. A large value allows for more COLLECTION items to be\r
-                        *  processed, but consumes more memory. By default this is set to 5 collections, but this can be\r
-                        *  overridden by defining HID_MAX_COLLECTIONS to another value in the user project makefile, passing\r
-                        *  the define to the compiler using the -D compiler switch.\r
-                        */\r
-                       #define HID_MAX_COLLECTIONS           5\r
-               #endif\r
-               \r
-               #if !defined(HID_MAX_REPORTITEMS) || defined(__DOXYGEN__)\r
-                       /** Constant indicating the maximum number of report items (IN, OUT or FEATURE if enabled) that can be\r
-                        *  processed in the report item descriptor. A large value allows for more report items to be\r
-                        *  processed, but consumes more memory. By default this is set to 30 items, but this can be\r
-                        *  overridden by defining HID_MAX_REPORTITEMS to another value in the user project makefile, passing\r
-                        *  the define to the compiler using the -D compiler switch.\r
-                        */\r
-                       #define HID_MAX_REPORTITEMS           30\r
-               #endif\r
-\r
-       /* Public Interface - May be used in end-application: */\r
-               /* Enums: */\r
-                       /** Enum for indicating what type of report item an entry in a \ref HID_ReportInfo_t ReportItem array is */\r
-                       enum HID_ReportItemTypes_t\r
-                       {\r
-                               REPORT_ITEM_TYPE_In                   = 0, /**< Indicates that the item is an IN report type. */\r
-                               REPORT_ITEM_TYPE_Out                  = 1, /**< Indicates that the item is an OUT report type. */\r
-                               REPORT_ITEM_TYPE_Feature              = 2, /**< Indicates that the item is a FEATURE report type. */\r
-                       };\r
-                       \r
-                       /** Enum for the possible error codes in the return value of the \ref USB_ProcessHIDReport() function */\r
-                       enum HID_Parse_ErrorCodes_t\r
-                       {\r
-                               HID_PARSE_Successful                  = 0, /**< Successful parse of the HID report descriptor, no error. */\r
-                               HID_PARSE_HIDStackOverflow            = 1, /**< More than \ref HID_STATETABLE_STACK_DEPTH nested PUSHes in the report. */ \r
-                               HID_PARSE_HIDStackUnderflow           = 2, /**< A POP was found when the state table stack was empty. */\r
-                               HID_PARSE_InsufficientReportItems     = 3, /**< More than \ref HID_MAX_REPORTITEMS report items in the report. */\r
-                               HID_PARSE_UnexpectedEndCollection     = 4, /**< END COLLECTION found without matching COLLECTION item. */\r
-                               HID_PARSE_InsufficientCollectionPaths = 5, /**< More than \ref HID_MAX_COLLECTIONS collections in the report. */\r
-                               HID_PARSE_UsageStackOverflow          = 6, /**< More than \ref HID_USAGE_STACK_DEPTH usages listed in a row. */\r
-                       };\r
-               \r
-               /* Type Defines: */             \r
-                       /** Type define for an attribute with both minimum and maximum values (e.g. Logical Min/Max). */\r
-                       typedef struct\r
-                       {\r
-                               uint32_t                     Minimum; /**< Minimum value for the attribute. */\r
-                               uint32_t                     Maximum; /**< Maximum value for the attribute. */\r
-                       } HID_MinMax_t;\r
-\r
-                       /** Type define for the Unit attributes of a report item. */\r
-                       typedef struct\r
-                       {\r
-                               uint32_t                     Type;     /**< Unit type (refer to HID specifications for details). */\r
-                               uint8_t                      Exponent; /**< Unit exponent (refer to HID specifications for details). */\r
-                       } HID_Unit_t;\r
-                       \r
-                       /** Type define for the Usage attributes of a report item. */\r
-                       typedef struct\r
-                       {\r
-                               uint16_t                     Page;   /**< Usage page of the report item. */\r
-                               uint16_t                     Usage;  /**< Usage of the report item. */\r
-                               HID_MinMax_t                 MinMax; /**< Usage minimum and maximum of the report item. */\r
-                       } HID_Usage_t;\r
-\r
-                       /** Type define for a COLLECTION object. Contains the collection attributes and a reference to the\r
-                        *  parent collection if any.\r
-                        */\r
-                       typedef struct CollectionPath\r
-                       {\r
-                               uint8_t                      Type;   /**< Collection type (e.g. "Generic Desktop"). */\r
-                               HID_Usage_t                  Usage;  /**< Collection usage. */\r
-                               struct CollectionPath*       Parent; /**< Reference to parent collection, or NULL if root collection. */\r
-                       } HID_CollectionPath_t;\r
-\r
-                       /** Type define for all the data attributes of a report item, except flags. */\r
-                       typedef struct\r
-                       {\r
-                               uint8_t                      BitSize;  /**< Size in bits of the report item's data. */\r
-                               \r
-                               HID_Usage_t                  Usage;    /**< Usage of the report item. */\r
-                               HID_Unit_t                   Unit;     /**< Unit type and exponent of the report item. */\r
-                               HID_MinMax_t                 Logical;  /**< Logical minimum and maximum of the report item. */\r
-                               HID_MinMax_t                 Physical; /**< Physical minimum and maximum of the report item. */\r
-                       } HID_ReportItem_Attributes_t;\r
-                       \r
-                       /** Type define for a report item (IN, OUT or FEATURE) attributes and other details. */\r
-                       typedef struct\r
-                       {\r
-                               uint16_t                     BitOffset;      /**< Bit offset in the IN, OUT or FEATURE report of the item. */\r
-                               uint8_t                      ItemType;       /**< Report item type, a value in HID_Types_t. */\r
-                               uint16_t                     ItemFlags;      /**< Item data flags, such as constant/variable, etc. */\r
-                               uint8_t                      ReportID;       /**< Report ID this item belongs to, or 0x00 if device has only one report */\r
-                               HID_CollectionPath_t*        CollectionPath; /**< Collection path of the item. */\r
-\r
-                               HID_ReportItem_Attributes_t  Attributes;     /**< Report item attributes. */\r
-                                                       \r
-                               uint32_t                     Value;          /**< Current value of the report item. */\r
-                       } HID_ReportItem_t;\r
-\r
-                       /** Type define for a complete processed HID report, including all report item data and collections. */\r
-                       typedef struct\r
-                       {\r
-                               uint8_t                      TotalReportItems; /**< Total number of report items stored in the\r
-                                                                               *   ReportItems array. */\r
-\r
-                               HID_ReportItem_t             ReportItems[HID_MAX_REPORTITEMS]; /**< Report items array, including\r
-                                                                                           *   all IN, OUT and FEATURE items. */\r
-\r
-                               HID_CollectionPath_t         CollectionPaths[HID_MAX_COLLECTIONS]; /**< All collection items, referenced\r
-                                                                                                   *   by the report items. */\r
-                       } HID_ReportInfo_t;\r
-                       \r
-               /* Function Prototypes: */\r
-                       /** Function to process a given HID report returned from an attached device, and store it into a given\r
-                        *  \ref HID_ReportInfo_t structure.\r
-                        *\r
-                        *  \param ReportData  Buffer containing the device's HID report table\r
-                        *  \param ReportSize  Size in bytes of the HID report table\r
-                        *  \param ParserData  Pointer to a \ref HID_ReportInfo_t instance for the parser output\r
-                        *\r
-                        *  \return A value in the \ref HID_Parse_ErrorCodes_t enum\r
-                        */\r
-                       uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID_ReportInfo_t* const ParserData)\r
-                                                    ATTR_NON_NULL_PTR_ARG(1, 3);\r
-\r
-                       /** Extracts the given report item's value out of the given HID report and places it into the Value\r
-                        *  member of the report item's \ref HID_ReportItem_t structure.\r
-                        *\r
-                        *  \param ReportData  Buffer containing an IN or FEATURE report from an attached device\r
-                        *  \param ReportItem  Pointer to the report item of interest in a \ref HID_ReportInfo_t ReportItem array\r
-                        *\r
-                        *  \returns Boolean true if the item to retrieve was located in the given report, false otherwise\r
-                        */\r
-                       bool USB_GetHIDReportItemInfo(const uint8_t* ReportData, HID_ReportItem_t* const ReportItem)\r
-                                                     ATTR_NON_NULL_PTR_ARG(1, 2);\r
-\r
-                       /** Retrieves the given report item's value out of the Value member of the report item's\r
-                        *  \ref HID_ReportItem_t structure and places it into the correct position in the HID report\r
-                        *  buffer. The report buffer is assumed to have the appropriate bits cleared before calling\r
-                        *  this function (i.e., the buffer should be explicitly cleared before report values are added).\r
-                        *\r
-                        *  If the device has multiple HID reports, the report ID is set to the report ID of the given item.\r
-                        *\r
-                        *  \param ReportData  Buffer holding the current OUT report data\r
-                        *  \param ReportItem  Pointer to the report item of interest in a \ref HID_ReportInfo_t ReportItem array\r
-                        */\r
-                       void USB_SetHIDReportItemInfo(uint8_t* ReportData, const HID_ReportItem_t* ReportItem)\r
-                                                     ATTR_NON_NULL_PTR_ARG(1, 2);\r
-\r
-       /* Private Interface - For use in library only: */\r
-       #if !defined(__DOXYGEN__)\r
-               /* Type Defines: */\r
-                       typedef struct\r
-                       {\r
-                                HID_ReportItem_Attributes_t Attributes;\r
-                                uint8_t                     ReportCount;\r
-                                uint8_t                     ReportID;\r
-                       } HID_StateTable_t;\r
-       #endif\r
-                       \r
-       /* Disable C linkage for C++ Compilers: */\r
-               #if defined(__cplusplus)\r
-                       }\r
-               #endif\r
-\r
-#endif\r
-\r
-/** @} */\r
diff --git a/LUFA/Drivers/USB/Class/HIDReportData.h b/LUFA/Drivers/USB/Class/HIDReportData.h
deleted file mode 100644 (file)
index eee38be..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Constants for HID report item attributes. Refer to the HID specification for details on each\r
- *  flag's meaning when applied to an IN, OUT or FEATURE item.\r
- */\r
-\r
-/** \ingroup Group_HIDParser\r
- *  @defgroup Group_HIDIOFConst Input/Output/Feature Masks\r
- *\r
- *  Masks indicating the type of Input, Output of Feature HID report item.\r
- *\r
- *  @{\r
- */\r
\r
-#ifndef __HIDREPORTDATA_H__\r
-#define __HIDREPORTDATA_H__\r
-\r
-       /* Public Interface - May be used in end-application: */\r
-               /* Macros: */\r
-                       /** HID_ReportItem_t.ItemFlags flag for constant data. */\r
-                       #define IOF_CONSTANT             (1 << 0)\r
-\r
-                       /** HID_ReportItem_t.ItemFlags flag for data. */\r
-                       #define IOF_DATA                 (0 << 0)\r
-\r
-                       /** HID_ReportItem_t.ItemFlags flag for variable data. */\r
-                       #define IOF_VARIABLE             (1 << 1)\r
-\r
-                       /** HID_ReportItem_t.ItemFlags flag for array data. */\r
-                       #define IOF_ARRAY                (0 << 1)\r
-\r
-                       /** HID_ReportItem_t.ItemFlags flag for relative data. */\r
-                       #define IOF_RELATIVE             (1 << 2)\r
-\r
-                       /** HID_ReportItem_t.ItemFlags flag for absolute data. */\r
-                       #define IOF_ABSOLUTE             (0 << 2)\r
-\r
-                       /** HID_ReportItem_t.ItemFlags flag for wrapped value data. */\r
-                       #define IOF_WRAP                 (1 << 3)\r
-\r
-                       /** HID_ReportItem_t.ItemFlags flag for non-wrapped value data. */\r
-                       #define IOF_NOWRAP               (0 << 3)\r
-\r
-                       /** HID_ReportItem_t.ItemFlags flag for non linear data. */\r
-                       #define IOF_NONLINEAR            (1 << 4)\r
-\r
-                       /** HID_ReportItem_t.ItemFlags flag for linear data. */\r
-                       #define IOF_LINEAR               (0 << 4)\r
-\r
-                       /** HID_ReportItem_t.ItemFlags flag for no preferred state. */\r
-                       #define IOF_NOPREFERRED          (1 << 5)\r
-\r
-                       /** HID_ReportItem_t.ItemFlags flag for preferred state items. */\r
-                       #define IOF_PREFERREDSTATE       (0 << 5)\r
-\r
-                       /** HID_ReportItem_t.ItemFlags flag for null state items. */\r
-                       #define IOF_NULLSTATE            (1 << 6)\r
-\r
-                       /** HID_ReportItem_t.ItemFlags flag for no null position data. */\r
-                       #define IOF_NONULLPOSITION       (0 << 6)\r
-\r
-                       /** HID_ReportItem_t.ItemFlags flag for buffered bytes. */\r
-                       #define IOF_BUFFEREDBYTES        (1 << 8)\r
-\r
-                       /** HID_ReportItem_t.ItemFlags flag for bit field data. */\r
-                       #define IOF_BITFIELD             (0 << 8)\r
-\r
-       /* Private Interface - For use in library only: */\r
-       #if !defined(__DOXYGEN__)\r
-               /* Macros: */\r
-                       #define DATA_SIZE_MASK           0x03\r
-                       #define TYPE_MASK                0x0C\r
-                       #define TAG_MASK                 0xF0\r
-\r
-                       #define DATA_SIZE_0              0x00\r
-                       #define DATA_SIZE_1              0x01\r
-                       #define DATA_SIZE_2              0x02\r
-                       #define DATA_SIZE_4              0x03\r
-                       \r
-                       #define TYPE_MAIN                0x00\r
-                       #define TYPE_GLOBAL              0x04\r
-                       #define TYPE_LOCAL               0x08\r
-                       \r
-                       #define TAG_MAIN_INPUT           0x80\r
-                       #define TAG_MAIN_OUTPUT          0x90\r
-                       #define TAG_MAIN_COLLECTION      0xA0\r
-                       #define TAG_MAIN_FEATURE         0xB0\r
-                       #define TAG_MAIN_ENDCOLLECTION   0xC0\r
-\r
-                       #define TAG_GLOBAL_USAGEPAGE     0x00\r
-                       #define TAG_GLOBAL_LOGICALMIN    0x10\r
-                       #define TAG_GLOBAL_LOGICALMAX    0x20\r
-                       #define TAG_GLOBAL_PHYSMIN       0x30\r
-                       #define TAG_GLOBAL_PHYSMAX       0x40\r
-                       #define TAG_GLOBAL_UNITEXP       0x50\r
-                       #define TAG_GLOBAL_UNIT          0x60\r
-                       #define TAG_GLOBAL_REPORTSIZE    0x70\r
-                       #define TAG_GLOBAL_REPORTID      0x80\r
-                       #define TAG_GLOBAL_REPORTCOUNT   0x90\r
-                       #define TAG_GLOBAL_PUSH          0xA0\r
-                       #define TAG_GLOBAL_POP           0xB0\r
-                       \r
-                       #define TAG_LOCAL_USAGE          0x00\r
-                       #define TAG_LOCAL_USAGEMIN       0x10\r
-                       #define TAG_LOCAL_USAGEMAX       0x20\r
-       #endif\r
-\r
-/** @} */\r
-               \r
-#endif\r
diff --git a/LUFA/Drivers/USB/Class/Host/HIDParser.c b/LUFA/Drivers/USB/Class/Host/HIDParser.c
new file mode 100644 (file)
index 0000000..5fb29aa
--- /dev/null
@@ -0,0 +1,326 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+#include "HIDParser.h"\r
+\r
+uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID_ReportInfo_t* const ParserData)\r
+{\r
+       HID_StateTable_t  StateTable[HID_STATETABLE_STACK_DEPTH];\r
+       HID_StateTable_t* CurrStateTable               = &StateTable[0];\r
+       uint16_t          UsageStack[HID_USAGE_STACK_DEPTH];\r
+       uint8_t           UsageStackSize               = 0;\r
+       uint16_t          BitOffsetIn                  = 0;\r
+       uint16_t          BitOffsetOut                 = 0;\r
+#if defined(HID_ENABLE_FEATURE_PROCESSING)\r
+       uint16_t          BitOffsetFeature             = 0;\r
+#endif\r
+       HID_CollectionPath_t* CurrCollectionPath       = NULL;\r
+\r
+       memset((void*)ParserData, 0x00, sizeof(HID_ReportInfo_t));\r
+       memset((void*)StateTable, 0x00, sizeof(StateTable));\r
+\r
+       while (ReportSize)\r
+       {\r
+               uint32_t ReportItemData = 0;\r
+               \r
+               switch (*ReportData & DATA_SIZE_MASK)\r
+               {\r
+                       case DATA_SIZE_4:\r
+                               ReportItemData = *((uint32_t*)(ReportData + 1));\r
+                               break;\r
+                       case DATA_SIZE_2:\r
+                               ReportItemData = *((uint16_t*)(ReportData + 1));\r
+                               break;\r
+                       case DATA_SIZE_1:\r
+                               ReportItemData = *((uint8_t*)(ReportData + 1));\r
+                               break;\r
+               }\r
+\r
+               switch (*ReportData & (TYPE_MASK | TAG_MASK))\r
+               {\r
+                       case (TYPE_GLOBAL | TAG_GLOBAL_PUSH):\r
+                               if (CurrStateTable == &StateTable[HID_STATETABLE_STACK_DEPTH])\r
+                                 return HID_PARSE_HIDStackOverflow;\r
+       \r
+                               memcpy((CurrStateTable - 1),\r
+                                      CurrStateTable,\r
+                                      sizeof(HID_ReportItem_t));\r
+\r
+                               CurrStateTable++;\r
+                               break;\r
+                       case (TYPE_GLOBAL | TAG_GLOBAL_POP):\r
+                               if (CurrStateTable == &StateTable[0])\r
+                                 return HID_PARSE_HIDStackUnderflow;\r
+                                 \r
+                               CurrStateTable--;\r
+                               break;\r
+                       case (TYPE_GLOBAL | TAG_GLOBAL_USAGEPAGE):\r
+                               CurrStateTable->Attributes.Usage.Page       = ReportItemData;\r
+                               break;\r
+                       case (TYPE_GLOBAL | TAG_GLOBAL_LOGICALMIN):\r
+                               CurrStateTable->Attributes.Logical.Minimum  = ReportItemData;\r
+                               break;\r
+                       case (TYPE_GLOBAL | TAG_GLOBAL_LOGICALMAX):\r
+                               CurrStateTable->Attributes.Logical.Maximum  = ReportItemData;\r
+                               break;\r
+                       case (TYPE_GLOBAL | TAG_GLOBAL_PHYSMIN):\r
+                               CurrStateTable->Attributes.Physical.Minimum = ReportItemData;\r
+                               break;\r
+                       case (TYPE_GLOBAL | TAG_GLOBAL_PHYSMAX):\r
+                               CurrStateTable->Attributes.Physical.Maximum = ReportItemData;\r
+                               break;\r
+                       case (TYPE_GLOBAL | TAG_GLOBAL_UNITEXP):\r
+                               CurrStateTable->Attributes.Unit.Exponent    = ReportItemData;\r
+                               break;\r
+                       case (TYPE_GLOBAL | TAG_GLOBAL_UNIT):\r
+                               CurrStateTable->Attributes.Unit.Type        = ReportItemData;\r
+                               break;\r
+                       case (TYPE_GLOBAL | TAG_GLOBAL_REPORTSIZE):\r
+                               CurrStateTable->Attributes.BitSize          = ReportItemData;\r
+                               break;\r
+                       case (TYPE_GLOBAL | TAG_GLOBAL_REPORTCOUNT):\r
+                               CurrStateTable->ReportCount                 = ReportItemData;\r
+                               break;\r
+                       case (TYPE_GLOBAL | TAG_GLOBAL_REPORTID):\r
+                               CurrStateTable->ReportID                    = ReportItemData;\r
+                               break;\r
+                       case (TYPE_LOCAL | TAG_LOCAL_USAGE):\r
+                               if (UsageStackSize == HID_USAGE_STACK_DEPTH)\r
+                                 return HID_PARSE_UsageStackOverflow;\r
+                       \r
+                               UsageStack[UsageStackSize++] = ReportItemData;\r
+                               break;\r
+                       case (TYPE_LOCAL | TAG_LOCAL_USAGEMIN):\r
+                               CurrStateTable->Attributes.Usage.MinMax.Minimum = ReportItemData;\r
+                               break;\r
+                       case (TYPE_LOCAL | TAG_LOCAL_USAGEMAX):\r
+                               CurrStateTable->Attributes.Usage.MinMax.Maximum = ReportItemData;\r
+                               break;\r
+                       case (TYPE_MAIN | TAG_MAIN_COLLECTION):\r
+                               if (CurrCollectionPath == NULL)\r
+                               {\r
+                                       CurrCollectionPath = &ParserData->CollectionPaths[0];\r
+                               }\r
+                               else\r
+                               {\r
+                                       HID_CollectionPath_t* ParentCollectionPath = CurrCollectionPath;\r
+                       \r
+                                       CurrCollectionPath = &ParserData->CollectionPaths[1];\r
+\r
+                                       while (CurrCollectionPath->Parent != NULL);\r
+                                       {\r
+                                               if (CurrCollectionPath == &ParserData->CollectionPaths[HID_MAX_COLLECTIONS])\r
+                                                 return HID_PARSE_InsufficientCollectionPaths;\r
+                                       \r
+                                               CurrCollectionPath++;\r
+                                       }\r
+\r
+                                       CurrCollectionPath->Parent = ParentCollectionPath;\r
+                               }\r
+                               \r
+                               CurrCollectionPath->Type = ReportItemData;\r
+                               CurrCollectionPath->Usage.Page = CurrStateTable->Attributes.Usage.Page;\r
+                               \r
+                               if (UsageStackSize)\r
+                               {\r
+                                       CurrCollectionPath->Usage.Usage = UsageStack[0];\r
+\r
+                                       for (uint8_t i = 0; i < UsageStackSize; i++)\r
+                                         UsageStack[i] = UsageStack[i + 1];\r
+                                         \r
+                                       UsageStackSize--;\r
+                               }\r
+                               else\r
+                               {\r
+                                       CurrCollectionPath->Usage.Usage = 0;\r
+                               }\r
+                               \r
+                               break;\r
+                       case (TYPE_MAIN | TAG_MAIN_ENDCOLLECTION):\r
+                               if (CurrCollectionPath == NULL)\r
+                                 return HID_PARSE_UnexpectedEndCollection;\r
+               \r
+                               CurrCollectionPath = CurrCollectionPath->Parent;\r
+\r
+                               break;\r
+                       case (TYPE_MAIN | TAG_MAIN_INPUT):\r
+                       case (TYPE_MAIN | TAG_MAIN_OUTPUT):\r
+#if defined(HID_ENABLE_FEATURE_PROCESSING)\r
+                       case (TYPE_MAIN | TAG_MAIN_FEATURE):\r
+#endif\r
+                               for (uint8_t ReportItemNum = 0; ReportItemNum < CurrStateTable->ReportCount; ReportItemNum++)\r
+                               {\r
+                                       HID_ReportItem_t* CurrReportItem = &ParserData->ReportItems[ParserData->TotalReportItems];\r
+                               \r
+                                       if (ParserData->TotalReportItems == HID_MAX_REPORTITEMS)\r
+                                         return HID_PARSE_InsufficientReportItems;\r
+                                 \r
+                                       memcpy(&CurrReportItem->Attributes,\r
+                                              &CurrStateTable->Attributes,\r
+                                              sizeof(HID_ReportItem_Attributes_t));\r
+\r
+                                       CurrReportItem->ItemFlags      = ReportItemData;\r
+                                       CurrReportItem->CollectionPath = CurrCollectionPath;\r
+                                       CurrReportItem->ReportID       = CurrStateTable->ReportID;\r
+\r
+                                       if (UsageStackSize)\r
+                                       {\r
+                                               CurrReportItem->Attributes.Usage.Usage = UsageStack[0];\r
+\r
+                                               for (uint8_t i = 0; i < UsageStackSize; i++)\r
+                                                 UsageStack[i] = UsageStack[i + 1];\r
+                                                 \r
+                                               UsageStackSize--;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               CurrReportItem->Attributes.Usage.Usage = 0;\r
+                                       }\r
+                                                                                       \r
+                                       switch (*ReportData & TAG_MASK)\r
+                                       {\r
+                                               case TAG_MAIN_INPUT:\r
+                                                       CurrReportItem->ItemType  = REPORT_ITEM_TYPE_In;\r
+                                                       CurrReportItem->BitOffset = BitOffsetIn;\r
+                                                               \r
+                                                       BitOffsetIn += CurrStateTable->Attributes.BitSize;\r
+                                                       \r
+                                                       break;\r
+                                               case TAG_MAIN_OUTPUT:\r
+                                                       CurrReportItem->ItemType  = REPORT_ITEM_TYPE_Out;\r
+                                                       CurrReportItem->BitOffset = BitOffsetOut;\r
+                                                               \r
+                                                       BitOffsetOut += CurrStateTable->Attributes.BitSize;\r
+                                                       \r
+                                                       break;\r
+#if defined(HID_ENABLE_FEATURE_PROCESSING)\r
+                                               case TAG_MAIN_FEATURE:\r
+                                                       CurrReportItem->ItemType  = REPORT_ITEM_TYPE_Feature;                                           \r
+                                                       CurrReportItem->BitOffset = BitOffsetFeature;\r
+                                                               \r
+                                                       BitOffsetFeature += CurrStateTable->Attributes.BitSize;         \r
+\r
+                                                       break;\r
+#endif\r
+                                       }\r
+                                       \r
+#if !defined(HID_INCLUDE_CONSTANT_DATA_ITEMS)\r
+                                       if (!(ReportItemData & IOF_CONSTANT))\r
+                                         ParserData->TotalReportItems++;\r
+#else\r
+                                       ParserData->TotalReportItems++;\r
+#endif\r
+                               }\r
+                               \r
+                               UsageStackSize = 0;\r
+                               \r
+                               break;\r
+               }\r
+         \r
+               if ((*ReportData & TYPE_MASK) == TYPE_MAIN)\r
+               {\r
+                       CurrStateTable->Attributes.Usage.MinMax.Minimum = 0;\r
+                       CurrStateTable->Attributes.Usage.MinMax.Maximum = 0;\r
+                       UsageStackSize = 0;\r
+               }\r
+               \r
+               switch (*ReportData & DATA_SIZE_MASK)\r
+               {\r
+                       case DATA_SIZE_4:\r
+                               ReportSize -= 5;\r
+                               ReportData += 5;\r
+                               break;\r
+                       case DATA_SIZE_2:\r
+                               ReportSize -= 3;\r
+                               ReportData += 3;\r
+                               break;\r
+                       case DATA_SIZE_1:\r
+                               ReportSize -= 2;\r
+                               ReportData += 2;\r
+                               break;\r
+                       case DATA_SIZE_0:\r
+                               ReportSize -= 1;\r
+                               ReportData += 1;\r
+                               break;\r
+               }\r
+       }\r
+       \r
+       return HID_PARSE_Successful;\r
+}\r
+\r
+bool USB_GetHIDReportItemInfo(const uint8_t* ReportData, HID_ReportItem_t* const ReportItem)\r
+{\r
+       uint16_t DataBitsRem  = ReportItem->Attributes.BitSize;\r
+       uint16_t CurrentBit   = ReportItem->BitOffset;\r
+       uint32_t BitMask      = (1 << 0);\r
+\r
+       ReportItem->Value = 0;\r
+       \r
+       if (ReportItem->ReportID)\r
+       {\r
+               if (ReportItem->ReportID != ReportData[0])\r
+                 return false;\r
+\r
+               ReportData++;\r
+       }\r
+\r
+       while (DataBitsRem--)\r
+       {\r
+               if (ReportData[CurrentBit / 8] & (1 << (CurrentBit % 8)))\r
+                 ReportItem->Value |= BitMask;\r
+               \r
+               CurrentBit++;\r
+               BitMask <<= 1;\r
+       }\r
+       \r
+       return true;\r
+}\r
+\r
+void USB_SetHIDReportItemInfo(uint8_t* ReportData, const HID_ReportItem_t* ReportItem)\r
+{\r
+       uint16_t DataBitsRem  = ReportItem->Attributes.BitSize;\r
+       uint16_t CurrentBit   = ReportItem->BitOffset;\r
+       uint32_t BitMask      = (1 << 0);\r
+\r
+       if (ReportItem->ReportID)\r
+       {\r
+               ReportData[0] = ReportItem->ReportID;\r
+               ReportData++;\r
+       }\r
+\r
+       while (DataBitsRem--)\r
+       {\r
+               if (ReportItem->Value & (1 << (CurrentBit % 8)))\r
+                 ReportData[CurrentBit / 8] |= BitMask;\r
+\r
+               CurrentBit++;\r
+               BitMask <<= 1;\r
+       }\r
+}\r
diff --git a/LUFA/Drivers/USB/Class/Host/HIDParser.h b/LUFA/Drivers/USB/Class/Host/HIDParser.h
new file mode 100644 (file)
index 0000000..4acce24
--- /dev/null
@@ -0,0 +1,263 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  USB Human Interface Device (HID) Class report descriptor processing routines. This file allows for the easy\r
+ *  parsing of the complex HID report descriptor, which describes the data that the device transmits to the host.\r
+ *\r
+ */\r
\r
+/** \ingroup Group_USB\r
+ *  @defgroup Group_HIDParser HID Report Parser\r
+ *\r
+ *  Functions, macros, variables, enums and types related to the parsing of HID class device report descriptors.\r
+ *\r
+ *  The processed HID report is presented back to the user application as a flat structure containing each report\r
+ *  item's IN, OUT and FEATURE (if desired) items along with each item's attributes.\r
+ *\r
+ *  This library portion also allows for easy setting and retrieval of data from a HID report, including devices\r
+ *  with multiple reports on the one HID interface.\r
+ *\r
+ *  By default, FEATURE reports and IN/OUT reports with constant data are ignored in the HID report when processed\r
+ *  to save on memory. This can be overridden by defining the HID_ENABLE_FEATURE_PROCESSING or\r
+ *  HID_INCLUDE_CONSTANT_DATA_ITEMS tokens in the user project makefile, passing them to the compiler via the -D\r
+ *  switch.\r
+ *\r
+ *  @{\r
+ */\r
+\r
+#ifndef __HIDPARSER_H__\r
+#define __HIDPARSER_H__\r
+\r
+       /* Includes: */\r
+               #include <string.h>\r
+               #include <stdbool.h>\r
+\r
+               #include "HIDReportData.h"\r
+\r
+               #include "../../../../Common/Common.h"\r
+\r
+       /* Enable C linkage for C++ Compilers: */\r
+               #if defined(__cplusplus)\r
+                       extern "C" {\r
+               #endif\r
+\r
+       /* Preprocessor checks and defines: */\r
+               #if !defined(HID_STATETABLE_STACK_DEPTH) || defined(__DOXYGEN__)\r
+                       /** Constant indicating the maximum stack depth of the state table. A larger state table\r
+                        *  allows for more PUSH/POP report items to be nested, but consumes more memory. By default\r
+                        *  this is set to 3 levels (allowing for two PUSHes to be nested) but this can be overridden by\r
+                        *  defining HID_STATETABLE_STACK_DEPTH to another value in the user project makefile, passing the\r
+                        *  define to the compiler using the -D compiler switch.\r
+                        */\r
+                       #define HID_STATETABLE_STACK_DEPTH    3\r
+               #endif\r
+               \r
+               #if !defined(HID_USAGE_STACK_DEPTH) || defined(__DOXYGEN__)\r
+                       /** Constant indicating the maximum stack depth of the usage table. A larger usage table\r
+                        *  allows for more USAGE items to be indicated sequentially for REPORT COUNT entries of more than\r
+                        *  one, but requires more stack space. By default this is set to 8 levels (allowing for a report\r
+                        *  item with a count of 8) but this can be overridden by defining HID_USAGE_STACK_DEPTH to another\r
+                        *  value in the user project makefile, passing the define to the compiler using the -D compiler\r
+                        *  switch.\r
+                        */\r
+                       #define HID_USAGE_STACK_DEPTH         8\r
+               #endif\r
+\r
+               #if !defined(HID_MAX_COLLECTIONS) || defined(__DOXYGEN__)\r
+                       /** Constant indicating the maximum number of COLLECTION items (nested or unnested) that can be\r
+                        *  processed in the report item descriptor. A large value allows for more COLLECTION items to be\r
+                        *  processed, but consumes more memory. By default this is set to 5 collections, but this can be\r
+                        *  overridden by defining HID_MAX_COLLECTIONS to another value in the user project makefile, passing\r
+                        *  the define to the compiler using the -D compiler switch.\r
+                        */\r
+                       #define HID_MAX_COLLECTIONS           5\r
+               #endif\r
+               \r
+               #if !defined(HID_MAX_REPORTITEMS) || defined(__DOXYGEN__)\r
+                       /** Constant indicating the maximum number of report items (IN, OUT or FEATURE if enabled) that can be\r
+                        *  processed in the report item descriptor. A large value allows for more report items to be\r
+                        *  processed, but consumes more memory. By default this is set to 30 items, but this can be\r
+                        *  overridden by defining HID_MAX_REPORTITEMS to another value in the user project makefile, passing\r
+                        *  the define to the compiler using the -D compiler switch.\r
+                        */\r
+                       #define HID_MAX_REPORTITEMS           30\r
+               #endif\r
+\r
+       /* Public Interface - May be used in end-application: */\r
+               /* Enums: */\r
+                       /** Enum for indicating what type of report item an entry in a \ref HID_ReportInfo_t ReportItem array is */\r
+                       enum HID_ReportItemTypes_t\r
+                       {\r
+                               REPORT_ITEM_TYPE_In                   = 0, /**< Indicates that the item is an IN report type. */\r
+                               REPORT_ITEM_TYPE_Out                  = 1, /**< Indicates that the item is an OUT report type. */\r
+                               REPORT_ITEM_TYPE_Feature              = 2, /**< Indicates that the item is a FEATURE report type. */\r
+                       };\r
+                       \r
+                       /** Enum for the possible error codes in the return value of the \ref USB_ProcessHIDReport() function */\r
+                       enum HID_Parse_ErrorCodes_t\r
+                       {\r
+                               HID_PARSE_Successful                  = 0, /**< Successful parse of the HID report descriptor, no error. */\r
+                               HID_PARSE_HIDStackOverflow            = 1, /**< More than \ref HID_STATETABLE_STACK_DEPTH nested PUSHes in the report. */ \r
+                               HID_PARSE_HIDStackUnderflow           = 2, /**< A POP was found when the state table stack was empty. */\r
+                               HID_PARSE_InsufficientReportItems     = 3, /**< More than \ref HID_MAX_REPORTITEMS report items in the report. */\r
+                               HID_PARSE_UnexpectedEndCollection     = 4, /**< END COLLECTION found without matching COLLECTION item. */\r
+                               HID_PARSE_InsufficientCollectionPaths = 5, /**< More than \ref HID_MAX_COLLECTIONS collections in the report. */\r
+                               HID_PARSE_UsageStackOverflow          = 6, /**< More than \ref HID_USAGE_STACK_DEPTH usages listed in a row. */\r
+                       };\r
+               \r
+               /* Type Defines: */             \r
+                       /** Type define for an attribute with both minimum and maximum values (e.g. Logical Min/Max). */\r
+                       typedef struct\r
+                       {\r
+                               uint32_t                     Minimum; /**< Minimum value for the attribute. */\r
+                               uint32_t                     Maximum; /**< Maximum value for the attribute. */\r
+                       } HID_MinMax_t;\r
+\r
+                       /** Type define for the Unit attributes of a report item. */\r
+                       typedef struct\r
+                       {\r
+                               uint32_t                     Type;     /**< Unit type (refer to HID specifications for details). */\r
+                               uint8_t                      Exponent; /**< Unit exponent (refer to HID specifications for details). */\r
+                       } HID_Unit_t;\r
+                       \r
+                       /** Type define for the Usage attributes of a report item. */\r
+                       typedef struct\r
+                       {\r
+                               uint16_t                     Page;   /**< Usage page of the report item. */\r
+                               uint16_t                     Usage;  /**< Usage of the report item. */\r
+                               HID_MinMax_t                 MinMax; /**< Usage minimum and maximum of the report item. */\r
+                       } HID_Usage_t;\r
+\r
+                       /** Type define for a COLLECTION object. Contains the collection attributes and a reference to the\r
+                        *  parent collection if any.\r
+                        */\r
+                       typedef struct CollectionPath\r
+                       {\r
+                               uint8_t                      Type;   /**< Collection type (e.g. "Generic Desktop"). */\r
+                               HID_Usage_t                  Usage;  /**< Collection usage. */\r
+                               struct CollectionPath*       Parent; /**< Reference to parent collection, or NULL if root collection. */\r
+                       } HID_CollectionPath_t;\r
+\r
+                       /** Type define for all the data attributes of a report item, except flags. */\r
+                       typedef struct\r
+                       {\r
+                               uint8_t                      BitSize;  /**< Size in bits of the report item's data. */\r
+                               \r
+                               HID_Usage_t                  Usage;    /**< Usage of the report item. */\r
+                               HID_Unit_t                   Unit;     /**< Unit type and exponent of the report item. */\r
+                               HID_MinMax_t                 Logical;  /**< Logical minimum and maximum of the report item. */\r
+                               HID_MinMax_t                 Physical; /**< Physical minimum and maximum of the report item. */\r
+                       } HID_ReportItem_Attributes_t;\r
+                       \r
+                       /** Type define for a report item (IN, OUT or FEATURE) attributes and other details. */\r
+                       typedef struct\r
+                       {\r
+                               uint16_t                     BitOffset;      /**< Bit offset in the IN, OUT or FEATURE report of the item. */\r
+                               uint8_t                      ItemType;       /**< Report item type, a value in HID_Types_t. */\r
+                               uint16_t                     ItemFlags;      /**< Item data flags, such as constant/variable, etc. */\r
+                               uint8_t                      ReportID;       /**< Report ID this item belongs to, or 0x00 if device has only one report */\r
+                               HID_CollectionPath_t*        CollectionPath; /**< Collection path of the item. */\r
+\r
+                               HID_ReportItem_Attributes_t  Attributes;     /**< Report item attributes. */\r
+                                                       \r
+                               uint32_t                     Value;          /**< Current value of the report item. */\r
+                       } HID_ReportItem_t;\r
+\r
+                       /** Type define for a complete processed HID report, including all report item data and collections. */\r
+                       typedef struct\r
+                       {\r
+                               uint8_t                      TotalReportItems; /**< Total number of report items stored in the\r
+                                                                               *   ReportItems array. */\r
+\r
+                               HID_ReportItem_t             ReportItems[HID_MAX_REPORTITEMS]; /**< Report items array, including\r
+                                                                                           *   all IN, OUT and FEATURE items. */\r
+\r
+                               HID_CollectionPath_t         CollectionPaths[HID_MAX_COLLECTIONS]; /**< All collection items, referenced\r
+                                                                                                   *   by the report items. */\r
+                       } HID_ReportInfo_t;\r
+                       \r
+               /* Function Prototypes: */\r
+                       /** Function to process a given HID report returned from an attached device, and store it into a given\r
+                        *  \ref HID_ReportInfo_t structure.\r
+                        *\r
+                        *  \param ReportData  Buffer containing the device's HID report table\r
+                        *  \param ReportSize  Size in bytes of the HID report table\r
+                        *  \param ParserData  Pointer to a \ref HID_ReportInfo_t instance for the parser output\r
+                        *\r
+                        *  \return A value in the \ref HID_Parse_ErrorCodes_t enum\r
+                        */\r
+                       uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID_ReportInfo_t* const ParserData)\r
+                                                    ATTR_NON_NULL_PTR_ARG(1, 3);\r
+\r
+                       /** Extracts the given report item's value out of the given HID report and places it into the Value\r
+                        *  member of the report item's \ref HID_ReportItem_t structure.\r
+                        *\r
+                        *  \param ReportData  Buffer containing an IN or FEATURE report from an attached device\r
+                        *  \param ReportItem  Pointer to the report item of interest in a \ref HID_ReportInfo_t ReportItem array\r
+                        *\r
+                        *  \returns Boolean true if the item to retrieve was located in the given report, false otherwise\r
+                        */\r
+                       bool USB_GetHIDReportItemInfo(const uint8_t* ReportData, HID_ReportItem_t* const ReportItem)\r
+                                                     ATTR_NON_NULL_PTR_ARG(1, 2);\r
+\r
+                       /** Retrieves the given report item's value out of the Value member of the report item's\r
+                        *  \ref HID_ReportItem_t structure and places it into the correct position in the HID report\r
+                        *  buffer. The report buffer is assumed to have the appropriate bits cleared before calling\r
+                        *  this function (i.e., the buffer should be explicitly cleared before report values are added).\r
+                        *\r
+                        *  If the device has multiple HID reports, the report ID is set to the report ID of the given item.\r
+                        *\r
+                        *  \param ReportData  Buffer holding the current OUT report data\r
+                        *  \param ReportItem  Pointer to the report item of interest in a \ref HID_ReportInfo_t ReportItem array\r
+                        */\r
+                       void USB_SetHIDReportItemInfo(uint8_t* ReportData, const HID_ReportItem_t* ReportItem)\r
+                                                     ATTR_NON_NULL_PTR_ARG(1, 2);\r
+\r
+       /* Private Interface - For use in library only: */\r
+       #if !defined(__DOXYGEN__)\r
+               /* Type Defines: */\r
+                       typedef struct\r
+                       {\r
+                                HID_ReportItem_Attributes_t Attributes;\r
+                                uint8_t                     ReportCount;\r
+                                uint8_t                     ReportID;\r
+                       } HID_StateTable_t;\r
+       #endif\r
+                       \r
+       /* Disable C linkage for C++ Compilers: */\r
+               #if defined(__cplusplus)\r
+                       }\r
+               #endif\r
+\r
+#endif\r
+\r
+/** @} */\r
diff --git a/LUFA/Drivers/USB/Class/Host/HIDReportData.h b/LUFA/Drivers/USB/Class/Host/HIDReportData.h
new file mode 100644 (file)
index 0000000..eee38be
--- /dev/null
@@ -0,0 +1,140 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Constants for HID report item attributes. Refer to the HID specification for details on each\r
+ *  flag's meaning when applied to an IN, OUT or FEATURE item.\r
+ */\r
+\r
+/** \ingroup Group_HIDParser\r
+ *  @defgroup Group_HIDIOFConst Input/Output/Feature Masks\r
+ *\r
+ *  Masks indicating the type of Input, Output of Feature HID report item.\r
+ *\r
+ *  @{\r
+ */\r
\r
+#ifndef __HIDREPORTDATA_H__\r
+#define __HIDREPORTDATA_H__\r
+\r
+       /* Public Interface - May be used in end-application: */\r
+               /* Macros: */\r
+                       /** HID_ReportItem_t.ItemFlags flag for constant data. */\r
+                       #define IOF_CONSTANT             (1 << 0)\r
+\r
+                       /** HID_ReportItem_t.ItemFlags flag for data. */\r
+                       #define IOF_DATA                 (0 << 0)\r
+\r
+                       /** HID_ReportItem_t.ItemFlags flag for variable data. */\r
+                       #define IOF_VARIABLE             (1 << 1)\r
+\r
+                       /** HID_ReportItem_t.ItemFlags flag for array data. */\r
+                       #define IOF_ARRAY                (0 << 1)\r
+\r
+                       /** HID_ReportItem_t.ItemFlags flag for relative data. */\r
+                       #define IOF_RELATIVE             (1 << 2)\r
+\r
+                       /** HID_ReportItem_t.ItemFlags flag for absolute data. */\r
+                       #define IOF_ABSOLUTE             (0 << 2)\r
+\r
+                       /** HID_ReportItem_t.ItemFlags flag for wrapped value data. */\r
+                       #define IOF_WRAP                 (1 << 3)\r
+\r
+                       /** HID_ReportItem_t.ItemFlags flag for non-wrapped value data. */\r
+                       #define IOF_NOWRAP               (0 << 3)\r
+\r
+                       /** HID_ReportItem_t.ItemFlags flag for non linear data. */\r
+                       #define IOF_NONLINEAR            (1 << 4)\r
+\r
+                       /** HID_ReportItem_t.ItemFlags flag for linear data. */\r
+                       #define IOF_LINEAR               (0 << 4)\r
+\r
+                       /** HID_ReportItem_t.ItemFlags flag for no preferred state. */\r
+                       #define IOF_NOPREFERRED          (1 << 5)\r
+\r
+                       /** HID_ReportItem_t.ItemFlags flag for preferred state items. */\r
+                       #define IOF_PREFERREDSTATE       (0 << 5)\r
+\r
+                       /** HID_ReportItem_t.ItemFlags flag for null state items. */\r
+                       #define IOF_NULLSTATE            (1 << 6)\r
+\r
+                       /** HID_ReportItem_t.ItemFlags flag for no null position data. */\r
+                       #define IOF_NONULLPOSITION       (0 << 6)\r
+\r
+                       /** HID_ReportItem_t.ItemFlags flag for buffered bytes. */\r
+                       #define IOF_BUFFEREDBYTES        (1 << 8)\r
+\r
+                       /** HID_ReportItem_t.ItemFlags flag for bit field data. */\r
+                       #define IOF_BITFIELD             (0 << 8)\r
+\r
+       /* Private Interface - For use in library only: */\r
+       #if !defined(__DOXYGEN__)\r
+               /* Macros: */\r
+                       #define DATA_SIZE_MASK           0x03\r
+                       #define TYPE_MASK                0x0C\r
+                       #define TAG_MASK                 0xF0\r
+\r
+                       #define DATA_SIZE_0              0x00\r
+                       #define DATA_SIZE_1              0x01\r
+                       #define DATA_SIZE_2              0x02\r
+                       #define DATA_SIZE_4              0x03\r
+                       \r
+                       #define TYPE_MAIN                0x00\r
+                       #define TYPE_GLOBAL              0x04\r
+                       #define TYPE_LOCAL               0x08\r
+                       \r
+                       #define TAG_MAIN_INPUT           0x80\r
+                       #define TAG_MAIN_OUTPUT          0x90\r
+                       #define TAG_MAIN_COLLECTION      0xA0\r
+                       #define TAG_MAIN_FEATURE         0xB0\r
+                       #define TAG_MAIN_ENDCOLLECTION   0xC0\r
+\r
+                       #define TAG_GLOBAL_USAGEPAGE     0x00\r
+                       #define TAG_GLOBAL_LOGICALMIN    0x10\r
+                       #define TAG_GLOBAL_LOGICALMAX    0x20\r
+                       #define TAG_GLOBAL_PHYSMIN       0x30\r
+                       #define TAG_GLOBAL_PHYSMAX       0x40\r
+                       #define TAG_GLOBAL_UNITEXP       0x50\r
+                       #define TAG_GLOBAL_UNIT          0x60\r
+                       #define TAG_GLOBAL_REPORTSIZE    0x70\r
+                       #define TAG_GLOBAL_REPORTID      0x80\r
+                       #define TAG_GLOBAL_REPORTCOUNT   0x90\r
+                       #define TAG_GLOBAL_PUSH          0xA0\r
+                       #define TAG_GLOBAL_POP           0xB0\r
+                       \r
+                       #define TAG_LOCAL_USAGE          0x00\r
+                       #define TAG_LOCAL_USAGEMIN       0x10\r
+                       #define TAG_LOCAL_USAGEMAX       0x20\r
+       #endif\r
+\r
+/** @} */\r
+               \r
+#endif\r
index e6d2bea..ded027b 100644 (file)
                         *        \ref Group_USBManagement documentation).\r
                         */\r
                        void EVENT_USB_Reset(void);\r
+                       \r
+                       /** Event for the USB start of frame interrupt, firing once each millisecond in either device or host\r
+                        *  mode, while USB frames are being generated or recieved.\r
+                        */\r
+                       void EVENT_USB_StartOfFrame(void);\r
                #endif\r
                \r
        /* Private Interface - For use in library only: */\r
                                void EVENT_USB_Suspend(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);\r
                                void EVENT_USB_WakeUp(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);\r
                                void EVENT_USB_Reset(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);\r
+                               void EVENT_USB_StartOfFrame(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);\r
                        #endif\r
        #endif\r
 \r
index 0b9d082..0ccbe61 100644 (file)
@@ -180,6 +180,15 @@ ISR(USB_GEN_vect, ISR_BLOCK)
 \r
                EVENT_USB_Reset();\r
        }\r
+       \r
+       if (USB_INT_HasOccurred(USB_INT_SOFI) && USB_INT_IsEnabled(USB_INT_SOFI))\r
+       {\r
+               USB_INT_Clear(USB_INT_SOFI);\r
+\r
+               FrameElapsed = true;\r
+               \r
+               EVENT_USB_StartOfFrame();\r
+       }\r
        #endif\r
        \r
        #if defined(USB_CAN_BE_HOST)\r
@@ -232,6 +241,15 @@ ISR(USB_GEN_vect, ISR_BLOCK)
 \r
                USB_ResetInterface();\r
        }\r
+\r
+       if (USB_INT_HasOccurred(USB_INT_HSOFI) && USB_INT_IsEnabled(USB_INT_HSOFI))\r
+       {\r
+               USB_INT_Clear(USB_INT_HSOFI);\r
+\r
+               FrameElapsed = true;\r
+               \r
+               EVENT_USB_StartOfFrame();\r
+       }\r
        #endif\r
 \r
        #if defined(USB_CAN_BE_BOTH)\r
index e2b7e91..46fcd57 100644 (file)
@@ -42,7 +42,7 @@ USB_Request_Header_t USB_ControlRequest;
 volatile uint8_t   USB_HostState;\r
 #endif\r
 \r
-TASK(USB_USBTask)\r
+void USB_USBTask(void)\r
 {\r
        #if defined(USB_HOST_ONLY)\r
                USB_HostTask();\r
index 1e1209a..e4c8a02 100644 (file)
@@ -38,7 +38,6 @@
                #include <stdbool.h>\r
                #include <stddef.h>\r
                \r
-               #include "../../../Scheduler/Scheduler.h"\r
                #include "../LowLevel/LowLevel.h"\r
                #include "StdRequestType.h"\r
                #include "USBMode.h"\r
                        extern volatile uint8_t USB_HostState;\r
                        #endif\r
 \r
-               /* Tasks: */\r
+               /* Function Prototypes: */\r
                        /** This is the main USB management task. The USB driver requires that this task be executed\r
                         *  continuously when the USB system is active (device attached in host mode, or attached to a host\r
                         *  in device mode) in order to manage USB communications. This task may be executed inside an RTOS,\r
-                        *  scheduler (e.g. the simple LUFA Scheduler), fast timer ISR or the main user application loop.\r
+                        *  fast timer ISR or the main user application loop.\r
                         *\r
                         *  The USB task must be serviced within 30ms while in device mode, or within 1ms while in host mode.\r
                         *  The task may be serviced at all times, or (for minimum CPU consumption):\r
                         *\r
                         *  \ingroup Group_USBManagement\r
                         */\r
-                       TASK(USB_USBTask);\r
+                       void USB_USBTask(void);\r
 \r
        /* Private Interface - For use in library only: */\r
        #if !defined(__DOXYGEN__)\r
index 099022c..d02071b 100644 (file)
@@ -80,8 +80,6 @@ uint8_t Endpoint_WaitUntilReady(void)
        uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;\r
        #endif\r
 \r
-       USB_INT_Clear(USB_INT_SOFI);\r
-\r
        for (;;)\r
        {\r
                if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN)\r
@@ -100,9 +98,9 @@ uint8_t Endpoint_WaitUntilReady(void)
                else if (Endpoint_IsStalled())\r
                  return ENDPOINT_READYWAIT_EndpointStalled;\r
                          \r
-               if (USB_INT_HasOccurred(USB_INT_SOFI))\r
+               if (FrameElapsed)\r
                {\r
-                       USB_INT_Clear(USB_INT_SOFI);\r
+                       FrameElapsed = false;\r
 \r
                        if (!(TimeoutMSRem--))\r
                          return ENDPOINT_READYWAIT_Timeout;\r
index b606515..02a1c21 100644 (file)
@@ -210,14 +210,13 @@ uint8_t USB_Host_WaitMS(uint8_t MS)
        bool    BusSuspended = USB_Host_IsBusSuspended();\r
        uint8_t ErrorCode    = HOST_WAITERROR_Successful;\r
        \r
-       USB_INT_Clear(USB_INT_HSOFI);\r
        USB_Host_ResumeBus();\r
 \r
        while (MS)\r
        {\r
-               if (USB_INT_HasOccurred(USB_INT_HSOFI))\r
+               if (FrameElapsed)\r
                {\r
-                       USB_INT_Clear(USB_INT_HSOFI);\r
+                       FrameElapsed = false;\r
                        MS--;\r
                }\r
                                        \r
@@ -260,9 +259,10 @@ static void USB_Host_ResetDevice(void)
        USB_Host_ResetBus();\r
        while (!(USB_Host_IsBusResetComplete()));\r
 \r
-       USB_INT_Clear(USB_INT_HSOFI);\r
        USB_Host_ResumeBus();   \r
        \r
+       FrameElapsed = false;\r
+\r
        for (uint8_t MSRem = 10; MSRem != 0; MSRem--)\r
        {\r
                /* Workaround for powerless-pull-up devices. After a USB bus reset,\r
@@ -270,8 +270,10 @@ static void USB_Host_ResetDevice(void)
                   looked for - if it is found within 10ms, the device is still\r
                   present.                                                        */\r
 \r
-               if (USB_INT_HasOccurred(USB_INT_HSOFI))\r
+               if (FrameElapsed)\r
                {\r
+                       FrameElapsed = false;\r
+                       \r
                        USB_INT_Clear(USB_INT_DDISCI);\r
                        break;\r
                }\r
index 8b395be..255a6ef 100644 (file)
@@ -38,6 +38,8 @@ volatile uint8_t USB_CurrentMode = USB_MODE_NONE;
 volatile uint8_t USB_Options;\r
 #endif\r
 \r
+volatile bool FrameElapsed;\r
+\r
 void USB_Init(\r
                #if defined(USB_CAN_BE_BOTH)\r
                const uint8_t Mode\r
@@ -150,6 +152,8 @@ void USB_ResetInterface(void)
        USB_INT_DisableAllInterrupts();\r
        USB_INT_ClearAllInterrupts();\r
 \r
+       FrameElapsed = false;\r
+\r
        USB_IsConnected = false;\r
 \r
        #if defined(USB_CAN_BE_HOST)\r
@@ -224,6 +228,7 @@ void USB_ResetInterface(void)
        #if defined(USB_DEVICE_ONLY)    \r
        USB_INT_Enable(USB_INT_SUSPEND);\r
        USB_INT_Enable(USB_INT_EORSTI);\r
+       USB_INT_Enable(USB_INT_SOFI);\r
 \r
        #if defined(CONTROL_ONLY_DEVICE)\r
        UENUM = ENDPOINT_CONTROLEP;\r
@@ -240,11 +245,13 @@ void USB_ResetInterface(void)
        \r
        USB_INT_Enable(USB_INT_SRPI);\r
        USB_INT_Enable(USB_INT_BCERRI);\r
+       USB_INT_Enable(USB_INT_HSOFI);\r
        #else\r
        if (USB_CurrentMode == USB_MODE_DEVICE)\r
        {\r
                USB_INT_Enable(USB_INT_SUSPEND);\r
                USB_INT_Enable(USB_INT_EORSTI);\r
+               USB_INT_Enable(USB_INT_SOFI);\r
 \r
                #if defined(CONTROL_ONLY_DEVICE)\r
                UENUM = ENDPOINT_CONTROLEP;\r
@@ -262,6 +269,7 @@ void USB_ResetInterface(void)
                \r
                USB_INT_Enable(USB_INT_SRPI);\r
                USB_INT_Enable(USB_INT_BCERRI);\r
+               USB_INT_Enable(USB_INT_HSOFI);\r
        }\r
        #endif\r
 }\r
index 41b0ff5..4279ca3 100644 (file)
                                  return USB_MODE_HOST;\r
                        }\r
                        #endif\r
+               \r
+               /* External Variables: */\r
+                       extern volatile bool FrameElapsed;\r
                        \r
        #endif\r
        \r
index 71a33d6..720da17 100644 (file)
@@ -76,8 +76,6 @@ uint8_t Pipe_WaitUntilReady(void)
        uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;\r
        #endif\r
 \r
-       USB_INT_Clear(USB_INT_HSOFI);\r
-\r
        for (;;)\r
        {\r
                if (Pipe_GetPipeToken() == PIPE_TOKEN_IN)\r
@@ -96,9 +94,9 @@ uint8_t Pipe_WaitUntilReady(void)
                else if (!(USB_IsConnected))\r
                  return PIPE_READYWAIT_DeviceDisconnected;\r
                          \r
-               if (USB_INT_HasOccurred(USB_INT_HSOFI))\r
+               if (FrameElapsed)\r
                {\r
-                       USB_INT_Clear(USB_INT_HSOFI);\r
+                       FrameElapsed = false;\r
 \r
                        if (!(TimeoutMSRem--))\r
                          return PIPE_READYWAIT_Timeout;\r
index 6d66c4d..3c8f062 100644 (file)
@@ -49,7 +49,6 @@
  *    - LUFA/Drivers/USB/HighLevel/USBInterrupt.c\r
  *    - LUFA/Drivers/USB/HighLevel/USBTask.c\r
  *    - LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c\r
- *    - LUFA/Drivers/USB/Class/HIDParser.c\r
  *\r
  *  \section Module Description\r
  *  Functions, macros, variables, enums and types related to the management of USB communications.\r
@@ -97,7 +96,6 @@
                #endif\r
                \r
                #include "HighLevel/ConfigDescriptor.h"\r
-               #include "Class/HIDParser.h"\r
                \r
 #endif\r
 \r
diff --git a/LUFA/MemoryAllocator/DynAlloc.c b/LUFA/MemoryAllocator/DynAlloc.c
deleted file mode 100644 (file)
index 4f1c822..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-#define  INCLUDE_FROM_DYNALLOC_C\r
-#include "DynAlloc.h"\r
-\r
-struct\r
-{\r
-       char    Mem_Heap[NUM_BLOCKS * BLOCK_SIZE];\r
-       void*   Mem_Handles[NUM_HANDLES];\r
-       uint8_t Mem_Block_Flags[(NUM_BLOCKS / 4) + ((NUM_BLOCKS % 4) ? 1 : 0)];\r
-       uint8_t FlagMaskLookupMask[4];\r
-       uint8_t FlagMaskLookupNum[4];\r
-} Mem_MemData = {.FlagMaskLookupMask = {(3 << 0), (3 << 2), (3 << 4), (3 << 6)},\r
-                 .FlagMaskLookupNum  = {      0,        2,        4,        6}};\r
-\r
-static uint8_t Mem_GetBlockFlags(const Block_Number_t BlockNum)\r
-{\r
-       const Block_Number_t BlockIndex    = (BlockNum >> 2);\r
-       const uint8_t        FlagMask      = Mem_MemData.FlagMaskLookupMask[BlockNum & 0x03];\r
-       const uint8_t        FlagMaskShift = Mem_MemData.FlagMaskLookupNum[BlockNum & 0x03];\r
-\r
-       return ((Mem_MemData.Mem_Block_Flags[BlockIndex] & FlagMask) >> FlagMaskShift);\r
-}\r
-\r
-static void Mem_SetBlockFlags(const Block_Number_t BlockNum, const uint8_t Flags)\r
-{\r
-       const Block_Number_t BlockIndex    = (BlockNum >> 2);\r
-       const uint8_t        FlagMask      = Mem_MemData.FlagMaskLookupMask[BlockNum & 0x03];\r
-       const uint8_t        FlagMaskShift = Mem_MemData.FlagMaskLookupNum[BlockNum & 0x03];\r
-\r
-       Mem_MemData.Mem_Block_Flags[BlockIndex] &= ~FlagMask;\r
-       Mem_MemData.Mem_Block_Flags[BlockIndex] |= (Flags << FlagMaskShift);\r
-}\r
-\r
-static inline void Mem_Defrag(void)\r
-{\r
-       Block_Number_t FreeStartBlock = 0;\r
-       char*          FreeStartPtr   = NULL;\r
-       char*          UsedStartPtr   = NULL;\r
-       Block_Number_t CurrBlock;\r
-       \r
-       for (CurrBlock = 0; CurrBlock < NUM_BLOCKS; CurrBlock++)\r
-       {\r
-               if (!(Mem_GetBlockFlags(CurrBlock) & BLOCK_USED_MASK))\r
-               {\r
-                       FreeStartPtr   = &Mem_MemData.Mem_Heap[CurrBlock * BLOCK_SIZE];\r
-                       FreeStartBlock = CurrBlock;\r
-                       break;\r
-               }\r
-       }\r
-       \r
-       if (FreeStartPtr == NULL)\r
-         return;\r
-\r
-       while (++CurrBlock < NUM_BLOCKS)\r
-       {\r
-               uint8_t CurrBlockFlags = Mem_GetBlockFlags(CurrBlock);\r
-       \r
-               if (CurrBlockFlags & BLOCK_USED_MASK)\r
-               {\r
-                       UsedStartPtr = &Mem_MemData.Mem_Heap[CurrBlock * BLOCK_SIZE];\r
-               \r
-                       for (Handle_Number_t HandleNum = 0; HandleNum < NUM_HANDLES; HandleNum++)\r
-                       {\r
-                               if (Mem_MemData.Mem_Handles[HandleNum] == UsedStartPtr)\r
-                               {\r
-                                       Mem_MemData.Mem_Handles[HandleNum] = FreeStartPtr;\r
-                                       break;\r
-                               }\r
-                       }\r
-\r
-                       memcpy(FreeStartPtr, UsedStartPtr, BLOCK_SIZE);\r
-                       FreeStartPtr += BLOCK_SIZE;\r
-                         \r
-                       Mem_SetBlockFlags(FreeStartBlock++, CurrBlockFlags);\r
-                       Mem_SetBlockFlags(CurrBlock, 0);\r
-               }\r
-       }\r
-}\r
-\r
-static inline bool Mem_FindFreeBlocks(Block_Number_t* const RetStartPtr, const Block_Number_t Blocks)\r
-{\r
-       Block_Number_t FreeInCurrSec = 0;\r
-\r
-       for (Block_Number_t CurrBlock = 0; CurrBlock < NUM_BLOCKS; CurrBlock++)\r
-       {\r
-               if (Mem_GetBlockFlags(CurrBlock) & BLOCK_USED_MASK)\r
-                 FreeInCurrSec = 0;\r
-               else\r
-                 FreeInCurrSec++;\r
-\r
-               if (FreeInCurrSec >= Blocks)\r
-               {\r
-                       *RetStartPtr = CurrBlock;\r
-                       return true;\r
-               }\r
-       }\r
-\r
-       return false;\r
-}\r
-\r
-Mem_Handle_t Mem_Alloc(const Alloc_Size_t Bytes)\r
-{\r
-       Block_Number_t ReqBlocks = (Bytes / BLOCK_SIZE);\r
-       Block_Number_t StartBlock;\r
-       \r
-       if (Bytes % BLOCK_SIZE)\r
-         ReqBlocks++;\r
-       \r
-       if (!(Mem_FindFreeBlocks(&StartBlock, ReqBlocks)))\r
-       {\r
-               Mem_Defrag();\r
-               \r
-               if (!(Mem_FindFreeBlocks(&StartBlock, ReqBlocks)))\r
-                 return NULL;  \r
-       }\r
-\r
-       for (Block_Number_t UsedBlock = 0; UsedBlock < (ReqBlocks - 1); UsedBlock++)\r
-         Mem_SetBlockFlags((StartBlock + UsedBlock), (BLOCK_USED_MASK | BLOCK_LINKED_MASK));\r
-\r
-       Mem_SetBlockFlags((StartBlock + (ReqBlocks - 1)), BLOCK_USED_MASK);\r
-       \r
-       for (Handle_Number_t AllocEntry = 0; AllocEntry < NUM_HANDLES; AllocEntry++)\r
-       {\r
-               Mem_Handle_t CurrHdl = (Mem_Handle_t)&Mem_MemData.Mem_Handles[AllocEntry];\r
-       \r
-               if (DEREF(CurrHdl, void*) == NULL)\r
-               {\r
-                       DEREF(CurrHdl, void*) = &Mem_MemData.Mem_Heap[StartBlock * BLOCK_SIZE];\r
-                       return CurrHdl;\r
-               }\r
-       }\r
-\r
-       return NULL;\r
-}\r
-\r
-Mem_Handle_t Mem_Realloc(Mem_Handle_t CurrAllocHdl, const Alloc_Size_t Bytes)\r
-{\r
-       Mem_Free(CurrAllocHdl);\r
-       return Mem_Alloc(Bytes);\r
-}\r
-\r
-Mem_Handle_t Mem_Calloc(const Alloc_Size_t Bytes)\r
-{\r
-       Mem_Handle_t AllocHdl = Mem_Alloc(Bytes);\r
-       \r
-       if (AllocHdl != NULL)\r
-         memset(DEREF(AllocHdl, void*), 0x00, Bytes);\r
-\r
-       return AllocHdl;\r
-}\r
-\r
-void Mem_Free(Mem_Handle_t CurrAllocHdl)\r
-{\r
-       char*          MemBlockPtr = DEREF(CurrAllocHdl, char*);\r
-       Block_Number_t CurrBlock   = ((uint16_t)(MemBlockPtr - Mem_MemData.Mem_Heap) / BLOCK_SIZE);\r
-       uint8_t        CurrBlockFlags;\r
-\r
-       if ((CurrAllocHdl == NULL) || (MemBlockPtr == NULL))\r
-         return;\r
-\r
-       do\r
-       {\r
-               CurrBlockFlags = Mem_GetBlockFlags(CurrBlock);\r
-               Mem_SetBlockFlags(CurrBlock, 0);\r
-\r
-               CurrBlock++;\r
-       }\r
-       while (CurrBlockFlags & BLOCK_LINKED_MASK);\r
-       \r
-       DEREF(CurrAllocHdl, void*) = NULL;\r
-}\r
-\r
-Block_Number_t Mem_TotalFreeBlocks(void)\r
-{\r
-       Block_Number_t FreeBlocks = 0;\r
-       \r
-       for (Block_Number_t CurrBlock = 0; CurrBlock < NUM_BLOCKS; CurrBlock++)\r
-       {\r
-               if (!(Mem_GetBlockFlags(CurrBlock) & BLOCK_USED_MASK))\r
-                 FreeBlocks++;\r
-       }\r
-       \r
-       return FreeBlocks;\r
-}\r
-\r
-Handle_Number_t Mem_TotalFreeHandles(void)\r
-{\r
-       Handle_Number_t FreeHandles = 0;\r
-       \r
-       for (Handle_Number_t CurrHandle = 0; CurrHandle < NUM_HANDLES; CurrHandle++)\r
-       {\r
-               if (Mem_MemData.Mem_Handles[CurrHandle] == NULL)\r
-                 FreeHandles++;\r
-       }\r
-       \r
-       return FreeHandles;\r
-}\r
diff --git a/LUFA/MemoryAllocator/DynAlloc.h b/LUFA/MemoryAllocator/DynAlloc.h
deleted file mode 100644 (file)
index acbfbd1..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Dynamic, auto-defragmenting block memory allocator library. This library provides a convenient replacement for\r
- *  the standard avr-libc dynamic memory allocation routines. Memory is handed out in block chunks, to reduce the\r
- *  management memory overhead.\r
- */\r
-\r
-/** @defgroup Group_MemoryAllocator Dynamic Block Memory Allocator - LUFA/MemoryAllocator/DynAlloc.h\r
- *\r
- *  \section Sec_Dependencies Module Source Dependencies\r
- *  The following files must be built with any user project that uses this module:\r
- *    - LUFA/MemoryAllocator/DynAlloc.c\r
- *\r
- *  \section Module Description\r
- *  Dynamic, auto-defragmenting block memory allocator library. This library provides a convenient replacement for\r
- *  the standard avr-libc dynamic memory allocation routines. Memory is handed out in block chunks, to reduce the\r
- *  management memory overhead.\r
- *\r
- *  Unlike the normal memory allocation routines, this library gives out handles to memory which must be dereferenced\r
- *  at the exact time of use, rather than handing back direct memory pointers. By using library managed handles\r
- *  instead of pointers, allocated memory blocks can be shifted around as needed transparently to defragment the\r
- *  memory as more blocks are requested.\r
- *\r
- *  The memory heap is static, thus the total memory usage of the compiled application (as reported by the avr-size\r
- *  tool of the AVR-GCC toolchain) includes the dynamic memory heap.\r
- *\r
- *  The constants NUM_BLOCKS, BLOCK_SIZE and NUM_HANDLES must be defined in the project makefile (and passed to the\r
- *  preprocessor via the -D GCC switch) for this library to compile.\r
- *\r
- *  NUM_BLOCKS indicates the number of memory blocks in the memory psudoheap which can be chained together and handed\r
- *  to the application via a memory handle. NUM_HANDLES is the maximum number of memory handles (pointing to one or\r
- *  more chained memory blocks) which can be handed out simultaneously before requiring a handle (and its associated\r
- *  memory) to be freed. BLOCK_SIZE gives the number of bytes in each memory block. \r
- *\r
- *  @{\r
- */\r
-\r
-#ifndef __DYN_ALLOC__\r
-#define __DYN_ALLOC__\r
-\r
-       /* Includes : */\r
-               #include <avr/io.h>\r
-               #include <stdbool.h>\r
-               #include <string.h>\r
-       \r
-       /* Preprocessor Checks: */\r
-               #if (!defined(NUM_BLOCKS) || !defined(BLOCK_SIZE) || !defined(NUM_HANDLES))\r
-                       #error NUM_BLOCKS, BLOCK_SIZE and NUM_HANDLES must be defined before use via makefile.\r
-               #endif\r
-\r
-       /* Public Interface - May be used in end-application: */\r
-               /* Macros: */\r
-                       /** Macro to dereference a given memory handle into the given type. The given type should be a pointer\r
-                        *  if the memory is to contain an array of items, or should be a standard type (such as a primitive or\r
-                        *  structure) if the memory is to hold a single item of a single type. */\r
-                       #define DEREF(handle, type)       (*(type*)handle)\r
-                       \r
-                       /** Constant, giving the total heap size in bytes. */\r
-                       #define ALLOCABLE_BYTES           (1UL * NUM_BLOCKS * BLOCK_SIZE)\r
-               \r
-               /* Type Defines: */\r
-                       /** Memory handle type, used to store handles given by the library functions. */\r
-                       typedef const void** Mem_Handle_t;\r
-                       \r
-                       #if (ALLOCABLE_BYTES > 0xFFFF) || defined(__DOXYGEN__)\r
-                               /** Type define for the size (in bytes) for an allocation for passing to the library functions.\r
-                                *  The exact type width varies depending on the value of ALLOCABLE_BYTES to ensure that a single\r
-                                *  allocation can request the entire heap if needed.\r
-                                */\r
-                               typedef uint32_t Alloc_Size_t;\r
-                       #elif (ALLOCABLE_BYTES > 0xFF)\r
-                               typedef uint16_t Alloc_Size_t;\r
-                       #else                   \r
-                               typedef uint8_t  Alloc_Size_t;\r
-                       #endif\r
-\r
-                       #if (NUM_BLOCKS > 0xFFFF) || defined(__DOXYGEN__)\r
-                               /** Type define for a block number in the heap. The exact type width varies depending on the\r
-                                *   value of NUM_BLOCKS to ensure that the type can store an index to any block in the block pool.\r
-                                */\r
-                               typedef uint32_t Block_Number_t;\r
-                       #elif (NUM_BLOCKS > 0xFF)\r
-                               typedef uint16_t Block_Number_t;\r
-                       #else\r
-                               typedef uint8_t  Block_Number_t;\r
-                       #endif\r
-\r
-                       #if (NUM_HANDLES > 0xFFFF) || defined(__DOXYGEN__)\r
-                               /** Type define for a handle number. The exact type width varies depending on the value of NUM_HANDLES\r
-                                *  to ensure that the type can store the index of any handle in the handle pool.\r
-                                */\r
-                               typedef uint32_t Handle_Number_t;\r
-                       #elif (NUM_HANDLES > 0xFF)\r
-                               typedef uint16_t Handle_Number_t;\r
-                       #else                   \r
-                               typedef uint8_t  Handle_Number_t;\r
-                       #endif\r
-                       \r
-               /* Function Prototypes: */\r
-                       /** Allocates a given number of blocks from the heap (calculated from the requested number of bytes) and\r
-                        *  returns a handle to the newly allocated memory.\r
-                        *\r
-                        *  \param Bytes  The number of bytes requested to be allocated from the heap\r
-                        *\r
-                        *  \return NULL handle if the allocation fails, or handle to the allocated memory if the allocation succeeds\r
-                        */\r
-                       Mem_Handle_t    Mem_Alloc(const Alloc_Size_t Bytes);\r
-                       \r
-                       /** Allocates a given number of blocks from the heap (calculated from the requested number of bytes) and\r
-                        *  returns a handle to the newly allocated memory. Calloced memory is automatically cleared to all 0x00\r
-                        *  values at the time of allocation.\r
-                        *\r
-                        *  \param Bytes  The number of pre-cleared bytes requested to be allocated from the heap\r
-                        *\r
-                        *  \return NULL handle if the allocation fails, or handle to the allocated memory if the allocation succeeds\r
-                        */\r
-                       Mem_Handle_t    Mem_Calloc(const Alloc_Size_t Bytes);\r
-\r
-                       /** Deallocates a given memory handle, and attempts to allocates the given number of blocks from the heap\r
-                        *  (calculated from the requested number of bytes) immediately following the deallocation. The new memory\r
-                        *  may be located in the same area as the previous memory, but this is not guaranteed.\r
-                        *\r
-                        *  \param CurrAllocHdl  Handle to an already allocated section of memory in the heap to deallocate\r
-                        *  \param Bytes         The number of bytes requested to be allocated from the heap following the\r
-                        *                       deallocation\r
-                        *\r
-                        *  \return NULL handle if the allocation fails, or handle to the allocated memory if the allocation succeeds\r
-                        *\r
-                        *  \warning Even if the allocation fails, the deallocation will still occur. Care should be taken to ensure\r
-                        *           that the previously allocated memory is not used following an unsuccessful realloc().\r
-                        */\r
-                       Mem_Handle_t    Mem_Realloc(Mem_Handle_t CurrAllocHdl, const Alloc_Size_t Bytes);\r
-                       \r
-                       /** Deallocates a given previously allocated section of memory from the heap.\r
-                        *\r
-                        *  \param CurrAllocHdl  Handle to a previously allocated section of memory in the heap\r
-                        */\r
-                       void            Mem_Free(Mem_Handle_t CurrAllocHdl);\r
-                       \r
-                       /** Returns the total number of unallocated blocks in the heap.\r
-                        *\r
-                        *  \return Number of free blocks in the heap, as a Block_Number_t integer\r
-                        */\r
-                       Block_Number_t  Mem_TotalFreeBlocks(void);\r
-\r
-                       /** Returns the total number of unallocated handles in the handle pool.\r
-                        *\r
-                        *  \return Number of free handles in the handle pool, as a Handle_Number_t integer\r
-                        */\r
-                       Handle_Number_t Mem_TotalFreeHandles(void);\r
-               \r
-       /* Private Interface - For use in library only: */\r
-       #if !defined(__DOXYGEN__)\r
-               /* Macros: */\r
-                       #define BLOCK_USED_MASK           (1 << 0)\r
-                       #define BLOCK_LINKED_MASK         (1 << 1)\r
-                       \r
-               /* Function Prototypes: */\r
-                       #if defined(INCLUDE_FROM_DYNALLOC_C)\r
-                               static uint8_t Mem_GetBlockFlags(const Block_Number_t BlockNum);\r
-                               static void    Mem_SetBlockFlags(const Block_Number_t BlockNum, const uint8_t Flags);\r
-                               static void    Mem_Defrag(void);\r
-                       #endif\r
-       #endif\r
-       \r
-#endif\r
-\r
-/** @} */\r
diff --git a/LUFA/Scheduler/Scheduler.c b/LUFA/Scheduler/Scheduler.c
deleted file mode 100644 (file)
index ff8946a..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-#include "Scheduler.h"\r
-\r
-volatile SchedulerDelayCounter_t Scheduler_TickCounter;\r
-volatile uint8_t                 Scheduler_TotalTasks;\r
-\r
-bool Scheduler_HasDelayElapsed(const uint16_t Delay, SchedulerDelayCounter_t* const DelayCounter)\r
-{\r
-       SchedulerDelayCounter_t CurrentTickValue_LCL;\r
-       SchedulerDelayCounter_t DelayCounter_LCL;\r
-       \r
-       ATOMIC_BLOCK(ATOMIC_RESTORESTATE)\r
-       {\r
-               CurrentTickValue_LCL = Scheduler_TickCounter;\r
-       }\r
-       \r
-       DelayCounter_LCL = *DelayCounter;\r
-       \r
-       if (CurrentTickValue_LCL >= DelayCounter_LCL)\r
-       {\r
-               if ((CurrentTickValue_LCL - DelayCounter_LCL) >= Delay)\r
-               {\r
-                       *DelayCounter = CurrentTickValue_LCL;\r
-                       return true;\r
-               }\r
-       }\r
-       else\r
-       {\r
-               if (((MAX_DELAYCTR_COUNT - DelayCounter_LCL) + CurrentTickValue_LCL) >= Delay)\r
-               {\r
-                       *DelayCounter = CurrentTickValue_LCL;\r
-                       return true;\r
-               }       \r
-       }\r
-       \r
-       return false;\r
-}\r
-\r
-void Scheduler_SetTaskMode(const TaskPtr_t Task, const bool TaskStatus)\r
-{\r
-       TaskEntry_t* CurrTask = &Scheduler_TaskList[0];\r
-                                       \r
-       while (CurrTask != &Scheduler_TaskList[Scheduler_TotalTasks])\r
-       {\r
-               if (CurrTask->Task == Task)\r
-               {\r
-                       CurrTask->TaskStatus = TaskStatus;\r
-                       break;\r
-               }\r
-               \r
-               CurrTask++;\r
-       }\r
-}\r
-\r
-void Scheduler_SetGroupTaskMode(const uint8_t GroupID, const bool TaskStatus)\r
-{\r
-       TaskEntry_t* CurrTask = &Scheduler_TaskList[0];\r
-                                       \r
-       while (CurrTask != &Scheduler_TaskList[Scheduler_TotalTasks])\r
-       {\r
-               if (CurrTask->GroupID == GroupID)\r
-                 CurrTask->TaskStatus = TaskStatus;\r
-               \r
-               CurrTask++;\r
-       }\r
-}\r
diff --git a/LUFA/Scheduler/Scheduler.h b/LUFA/Scheduler/Scheduler.h
deleted file mode 100644 (file)
index 0da80bb..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Simple round-robbin cooperative scheduler for use in basic projects where non real-time tasks need\r
- *  to be executed. Each task is executed in sequence, and can be enabled or disabled individually or as a group.\r
- */\r
\r
-/** @defgroup Group_Scheduler Simple Task Scheduler - LUFA/Scheduler/Scheduler.h\r
- *\r
- *  \section Sec_Dependencies Module Source Dependencies\r
- *  The following files must be built with any user project that uses this module:\r
- *    - LUFA/Scheduler/Scheduler.c\r
- *\r
- *  \section Module Description\r
- *  Simple round-robbin cooperative scheduler for use in basic projects where non real-time tasks need\r
- *  to be executed. Each task is executed in sequence, and can be enabled or disabled individually or as a group.\r
- *\r
- *  For a task to yield it must return, thus each task should have persistent data marked with the static attribute.\r
- *\r
- *  Usage Example:\r
- *  \code\r
- *      #include <LUFA/Scheduler/Scheduler.h>\r
- *      \r
- *      TASK(MyTask1);\r
- *      TASK(MyTask2);\r
- *      \r
- *      TASK_LIST\r
- *      {\r
- *             { .Task = MyTask1, .TaskStatus = TASK_RUN, .GroupID = 1  },\r
- *             { .Task = MyTask2, .TaskStatus = TASK_RUN, .GroupID = 1  },\r
- *      }\r
- *\r
- *      int main(void)\r
- *      {\r
- *             Scheduler_Start();\r
- *      }\r
- *\r
- *      TASK(MyTask1)\r
- *      {\r
- *             // Implementation Here\r
- *      }\r
- *\r
- *      TASK(MyTask2)\r
- *      {\r
- *             // Implementation Here\r
- *      }\r
- *  \endcode\r
- *\r
- *  @{\r
- */\r
\r
-#ifndef __SCHEDULER_H__\r
-#define __SCHEDULER_H__\r
-\r
-       /* Includes: */\r
-               #include <avr/io.h>\r
-               #include <stdbool.h>\r
-               \r
-               #include <util/atomic.h>\r
-\r
-               #include "../Common/Common.h"\r
-\r
-       /* Enable C linkage for C++ Compilers: */\r
-               #if defined(__cplusplus)\r
-                       extern "C" {\r
-               #endif\r
-\r
-       /* Public Interface - May be used in end-application: */\r
-               /* Macros: */\r
-                       /** Creates a new scheduler task body or prototype. Should be used in the form:\r
-                        *  \code\r
-                        *      TASK(TaskName); // Prototype\r
-                        *\r
-                        *      TASK(TaskName)\r
-                        *      {\r
-                        *           // Task body\r
-                        *      }\r
-                        *  \endcode\r
-                        */\r
-                       #define TASK(name)                        void name (void)\r
-                       \r
-                       /** Defines a task list array, containing one or more task entries of the type TaskEntry_t. Each task list\r
-                        *  should be encased in curly braces and ended with a comma.\r
-                        *\r
-                        *  Usage Example:\r
-                        *  \code\r
-                        *      TASK_LIST\r
-                        *      {\r
-                        *           { .Task = MyTask1, .TaskStatus = TASK_RUN, .GroupID = 1 },\r
-                        *           // More task entries here\r
-                        *      }\r
-                        *  \endcode\r
-                        */\r
-                       #define TASK_LIST                         TaskEntry_t Scheduler_TaskList[] = \r
-                       \r
-                       /** Constant, giving the maximum delay in scheduler ticks which can be stored in a variable of type\r
-                        *  SchedulerDelayCounter_t.\r
-                        */\r
-                       #define TASK_MAX_DELAY                    (MAX_DELAYCTR_COUNT - 1)\r
-\r
-                       /** Task status mode constant, for passing to Scheduler_SetTaskMode() or Scheduler_SetGroupTaskMode(). */\r
-                       #define TASK_RUN                          true\r
-\r
-                       /** Task status mode constant, for passing to Scheduler_SetTaskMode() or Scheduler_SetGroupTaskMode(). */\r
-                       #define TASK_STOP                         false\r
-                       \r
-               /* Pseudo-Function Macros: */\r
-                       #if defined(__DOXYGEN__)\r
-                               /** Starts the scheduler in its infinite loop, executing running tasks. This should be placed at the end\r
-                                *  of the user application's main() function, as it can never return to the calling function.\r
-                                */\r
-                               void Scheduler_Start(void);\r
-                               \r
-                               /** Initializes the scheduler so that the scheduler functions can be called before the scheduler itself\r
-                                *  is started. This must be executed before any scheduler function calls other than Scheduler_Start(),\r
-                                *  and can be omitted if no such functions could be called before the scheduler is started.\r
-                                */\r
-                               void Scheduler_Init(void);\r
-                       #else\r
-                               #define Scheduler_Start()                 Scheduler_GoSchedule(TOTAL_TASKS);\r
-                               \r
-                               #define Scheduler_Init()                  Scheduler_InitScheduler(TOTAL_TASKS);\r
-                       #endif\r
-\r
-               /* Type Defines: */\r
-                       /** Type define for a pointer to a scheduler task. */\r
-                       typedef void (*TaskPtr_t)(void);\r
-                       \r
-                       /** Type define for a variable which can hold a tick delay value for the scheduler up to the maximum delay\r
-                        *  possible.\r
-                        */\r
-                       typedef uint16_t SchedulerDelayCounter_t;\r
-                       \r
-                       /** Structure for holding a single task's information in the scheduler task list. */\r
-                       typedef struct\r
-                       {\r
-                               TaskPtr_t Task;       /**< Pointer to the task to execute. */\r
-                               bool      TaskStatus; /**< Status of the task (either TASK_RUN or TASK_STOP). */\r
-                               uint8_t   GroupID;    /**< Group ID of the task so that its status can be changed as a group. */\r
-                       } TaskEntry_t;                  \r
-\r
-               /* Global Variables: */\r
-                       /** Task entry list, containing the scheduler tasks, task statuses and group IDs. Each entry is of type\r
-                        *  TaskEntry_t and can be manipulated as desired, although it is preferential that the proper Scheduler\r
-                        *  functions should be used instead of direct manipulation.\r
-                        */\r
-                       extern          TaskEntry_t               Scheduler_TaskList[];\r
-                       \r
-                       /** Contains the total number of tasks in the task list, irrespective of if the task's status is set to\r
-                        *  TASK_RUN or TASK_STOP.\r
-                        *\r
-                        *  \note This value should be treated as read-only, and never altered in user-code.\r
-                        */\r
-                       extern volatile uint8_t                   Scheduler_TotalTasks;\r
-\r
-                       /**  Contains the current scheduler tick count, for use with the delay functions. If the delay functions\r
-                        *   are used in the user code, this should be incremented each tick period so that the delays can be\r
-                        *   calculated.\r
-                        */\r
-                       extern volatile SchedulerDelayCounter_t   Scheduler_TickCounter;\r
-\r
-               /* Inline Functions: */\r
-                       /** Resets the delay counter value to the current tick count. This should be called to reset the period\r
-                        *  for a delay in a task which is dependant on the current tick value.\r
-                        *\r
-                        *  \param DelayCounter  Counter which is storing the starting tick count for a given delay.\r
-                        */\r
-                       static inline void Scheduler_ResetDelay(SchedulerDelayCounter_t* const DelayCounter)\r
-                                                               ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;\r
-                       static inline void Scheduler_ResetDelay(SchedulerDelayCounter_t* const DelayCounter)\r
-                       {\r
-                               ATOMIC_BLOCK(ATOMIC_RESTORESTATE)\r
-                               {\r
-                                       *DelayCounter = Scheduler_TickCounter;\r
-                               }\r
-                       }\r
-               \r
-               /* Function Prototypes: */\r
-                       /** Determines if the given tick delay has elapsed, based on the given .\r
-                        *\r
-                        *  \param Delay         The delay to test for, measured in ticks\r
-                        *  \param DelayCounter  The counter which is storing the starting tick value for the delay\r
-                        *\r
-                        *  \return Boolean true if the delay has elapsed, false otherwise\r
-                        *\r
-                        *  Usage Example:\r
-                        *  \code\r
-                        *      static SchedulerDelayCounter_t DelayCounter = 10000; // Force immediate run on start-up\r
-                        *                               \r
-                        *      // Task runs every 10000 ticks, 10 seconds for this demo\r
-                        *      if (Scheduler_HasDelayElapsed(10000, &DelayCounter))\r
-                        *      {\r
-                        *           // Code to execute after delay interval elapsed here\r
-                        *      }\r
-                        *  \endcode\r
-                        */\r
-                       bool Scheduler_HasDelayElapsed(const uint16_t Delay,\r
-                                                      SchedulerDelayCounter_t* const DelayCounter)\r
-                                                                                  ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(2);\r
-                       \r
-                       /** Sets the task mode for a given task.\r
-                        *\r
-                        *  \param Task        Name of the task whose status is to be changed\r
-                        *  \param TaskStatus  New task status for the task (TASK_RUN or TASK_STOP)\r
-                        */\r
-                       void Scheduler_SetTaskMode(const TaskPtr_t Task, const bool TaskStatus);\r
-                       \r
-                       /** Sets the task mode for a given task group ID, allowing for an entire group of tasks to have their\r
-                        *  statuses changed at once.\r
-                        *\r
-                        *  \param GroupID     Value of the task group ID whose status is to be changed\r
-                        *  \param TaskStatus  New task status for tasks in the specified group (TASK_RUN or TASK_STOP)\r
-                        */\r
-                       void Scheduler_SetGroupTaskMode(const uint8_t GroupID, const bool TaskStatus);\r
-\r
-       /* Private Interface - For use in library only: */              \r
-       #if !defined(__DOXYGEN__)\r
-               /* Macros: */\r
-                       #define TOTAL_TASKS                       (sizeof(Scheduler_TaskList) / sizeof(TaskEntry_t))\r
-                       #define MAX_DELAYCTR_COUNT                0xFFFF\r
-\r
-               /* Inline Functions: */\r
-                       static inline void Scheduler_InitScheduler(const uint8_t TotalTasks) ATTR_ALWAYS_INLINE;\r
-                       static inline void Scheduler_InitScheduler(const uint8_t TotalTasks)\r
-                       {\r
-                               Scheduler_TotalTasks = TotalTasks;\r
-                       }\r
-               \r
-                       static inline void Scheduler_GoSchedule(const uint8_t TotalTasks) ATTR_NO_RETURN ATTR_ALWAYS_INLINE;\r
-                       static inline void Scheduler_GoSchedule(const uint8_t TotalTasks)\r
-                       {\r
-                               Scheduler_InitScheduler(TotalTasks);\r
-\r
-                               for (;;)\r
-                               {\r
-                                       TaskEntry_t* CurrTask = &Scheduler_TaskList[0];\r
-                                       \r
-                                       while (CurrTask != &Scheduler_TaskList[TotalTasks])\r
-                                       {\r
-                                               if (CurrTask->TaskStatus == TASK_RUN)\r
-                                                 CurrTask->Task();\r
-\r
-                                               CurrTask++;\r
-                                       }\r
-                               }\r
-                       }\r
-       #endif\r
-               \r
-       /* Disable C linkage for C++ Compilers: */\r
-               #if defined(__cplusplus)\r
-                       }\r
-               #endif\r
-               \r
-#endif\r
-\r
-/** @} */\r
diff --git a/LUFA/SchedulerOverview.txt b/LUFA/SchedulerOverview.txt
deleted file mode 100644 (file)
index 5c031fe..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/** \file\r
- *\r
- *  This file contains special DoxyGen information for the generation of the main page and other special\r
- *  documentation pages. It is not a project source file.\r
- */\r
-\r
-/** \page Page_SchedulerOverview LUFA Scheduler Overview\r
- *\r
- *  The LUFA library comes with a small, basic round-robbin scheduler which allows for small "tasks" to be executed\r
- *  continuously in sequence, and enabled/disabled at runtime. Unlike a conventional, complex RTOS scheduler, the\r
- *  LUFA scheduler is very simple in design and operation and is essentially a loop conditionally executing a series\r
- *  of functions.\r
- *\r
- *  Each LUFA scheduler task should be written similar to an ISR; it should execute quickly (so that no one task\r
- *  hogs the processor, preventing another from running before some sort of timeout is exceeded). Unlike normal RTOS\r
- *  tasks, each LUFA scheduler task is a regular function, and thus must be designed to be called, and designed to\r
- *  return to the calling scheduler function repeatedly. Data which must be preserved between task calls should be\r
- *  declared as global or (preferably) as a static local variable inside the task.\r
- *\r
- *  The scheduler consists of a task list, listing all the tasks which can be executed by the scheduler. Once started,\r
- *  each task is then called one after another, unless the task is stopped by another running task or interrupt.\r
- *\r
- *\r
- *  If desired, the LUFA scheduler <b>does not need to be used</b> in a LUFA powered application. A more conventional\r
- *  approach to application design can be used, or a proper scheduling RTOS inserted in the place of the LUFA scheduler.\r
- *  In the case of the former the USB task must be run manually repeatedly to maintain USB communications, and in the\r
- *  case of the latter a proper RTOS task must be set up to do the same.\r
- *\r
- *\r
- *  For more information on the LUFA scheduler, see the Scheduler.h file documentation.\r
- */\r
index fc00097..20f943a 100644 (file)
@@ -15,13 +15,9 @@ LUFA_SRC_FILES =     ./Drivers/USB/LowLevel/DevChapter9.c        \
                      ./Drivers/USB/LowLevel/LowLevel.c           \\r
                      ./Drivers/USB/LowLevel/Pipe.c               \\r
                      ./Drivers/USB/HighLevel/Events.c            \\r
-                     ./Drivers/USB/HighLevel/StdDescriptors.c    \\r
                      ./Drivers/USB/HighLevel/USBInterrupt.c      \\r
                      ./Drivers/USB/HighLevel/USBTask.c           \\r
-                     ./Drivers/USB/Class/ConfigDescriptor.c      \\r
-                     ./Drivers/USB/Class/HIDParser.c             \\r
-                     ./Scheduler/Scheduler.c                     \\r
-                     ./MemoryAllocator/DynAlloc.c                \\r
+                     ./Drivers/USB/HighLevel/ConfigDescriptor.c  \\r
                      ./Drivers/Board/Temperature.c               \\r
                      ./Drivers/Peripheral/Serial.c               \\r
                      ./Drivers/Peripheral/SerialStream.c         \\r
index 1dee586..52b2c09 100644 (file)
@@ -142,7 +142,7 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
                        \r
                        .HIDSpec                = VERSION_BCD(01.11),\r
                        .CountryCode            = 0x00,\r
-                       .TotalHIDDescriptors    = 1,\r
+                       .TotalReportDescriptors = 1,\r
                        .HIDReportType          = DTYPE_Report,\r
                        .HIDReportLength        = sizeof(KeyboardReport)\r
                },\r
index 9948085..0fff2c2 100644 (file)
 #define _DESCRIPTORS_H_\r
 \r
        /* Includes: */\r
-               #include <LUFA/Drivers/USB/USB.h>\r
-\r
                #include <avr/pgmspace.h>\r
 \r
-       /* Type Defines: */\r
-               /** Type define for the HID class specific HID descriptor. A HID descriptor is used in HID class devices\r
-                *  to give information about the HID device, including the HID specification used, and the report descriptors\r
-                *  the device contains to describe how the HID device should be controlled.\r
-                */\r
-               typedef struct\r
-               {\r
-                       USB_Descriptor_Header_t Header; /**< Standard USB descriptor header */\r
-                               \r
-                       uint16_t                HIDSpec; /**< HID specification implemented by the device, in BCD form */\r
-                       uint8_t                 CountryCode; /**< Country code for the country the HID device is localised for */\r
-               \r
-                       uint8_t                 TotalHIDDescriptors; /**< Total number of HID reports linked to this HID interface */\r
-\r
-                       uint8_t                 HIDReportType; /**< Type of the first HID report descriptor */\r
-                       uint16_t                HIDReportLength; /**< Length of the first HID report descriptor */\r
-               } USB_Descriptor_HID_t;\r
-\r
-               /** Type define for the data type used for the HID Report descriptor data elements. A HID report\r
-                *  descriptor contains an array of this data type, indicating how the reports from and to the\r
-                *  device are formatted and how the report data is to be used by the host.\r
-                */\r
-               typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/HID.h>\r
 \r
+       /* Type Defines: */\r
                /** Type define for the device configuration descriptor structure. This must be defined in the\r
                 *  application code, as the configuration descriptor contains several sub-descriptors which\r
                 *  vary between devices, and which describe the device's usage to the host.\r
                /** Size of the keyboard report endpoints, in bytes. */\r
                #define KEYBOARD_EPSIZE              8\r
 \r
-               /** Descriptor type value for a HID descriptor. */\r
-               #define DTYPE_HID                    0x21\r
-\r
-               /** Descriptor type value for a HID report. */\r
-               #define DTYPE_Report                 0x22\r
-\r
        /* Function Prototypes: */\r
                uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)\r
-                                                                                       ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);\r
+                                                   ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);\r
 \r
 #endif\r
index e860d5a..5cd107e 100644 (file)
   arising out of or in connection with the use or performance of\r
   this software.\r
 */\r
-\r
-/** \file\r
- *\r
- *  Main source file for the MagStripe application. This file contains the code which drives\r
- *  the USB keyboard interface from the magnetic card stripe reader device.\r
- */\r
  \r
 #include "Magstripe.h"\r
 \r
-/* Scheduler Task List */\r
-TASK_LIST\r
-{\r
-       { .Task = USB_USBTask          , .TaskStatus = TASK_STOP },\r
-       { .Task = USB_Keyboard_Report  , .TaskStatus = TASK_STOP },\r
-       { .Task = Magstripe_Read       , .TaskStatus = TASK_STOP },\r
-};\r
-\r
-/* Global Variables */\r
-/** Indicates if the device is using Report Protocol mode, instead of Boot Protocol mode. Boot Protocol mode\r
- *  is a special reporting mode used by compatible PC BIOS to support USB keyboards before a full OS and USB\r
- *  driver has been loaded, by using predefined report structures indicated in the USB HID standard.\r
- */\r
-bool UsingReportProtocol = true;\r
+BitBuffer_t TrackDataBuffers[3];\r
 \r
-/** Total idle period in milliseconds set by the host via a SetIdle request, used to silence the report endpoint\r
- *  until the report data changes or the idle period elapsed. Generally used to implement hardware key repeats, or\r
- *  by some BIOS to reduce the number of reports when in Boot Protocol mode.\r
- */\r
-uint8_t IdleCount = 0;\r
-\r
-/** Milliseconds remaining counter for the HID class SetIdle and GetIdle requests, used to silence the report\r
- *  endpoint for an amount of time indicated by the host or until the report changes.\r
- */\r
-uint16_t IdleMSRemaining = 0;\r
-\r
-/** Circular buffer to hold the read bits from track 1 of the inserted magnetic card. */\r
-BitBuffer_t Track1Data;\r
+USB_ClassInfo_HID_t Keyboard_HID_Interface =\r
+       {\r
+               .InterfaceNumber         = 0,\r
 \r
-/** Circular buffer to hold the read bits from track 2 of the inserted magnetic card. */\r
-BitBuffer_t Track2Data;\r
+               .ReportINEndpointNumber  = KEYBOARD_EPNUM,\r
+               .ReportINEndpointSize    = KEYBOARD_EPSIZE,\r
+       };\r
 \r
-/** Circular buffer to hold the read bits from track 3 of the inserted magnetic card. */\r
-BitBuffer_t Track3Data;\r
+int main(void)\r
+{\r
+       SetupHardware();\r
+       \r
+       for (uint8_t Buffer = 0; Buffer < 3; Buffer++)\r
+         BitBuffer_Init(&TrackDataBuffers[Buffer]);\r
 \r
-/** Delay counter between successive key strokes. This is to prevent the OS from ignoring multiple keys in a short\r
- *  period of time due to key repeats. Two milliseconds works for most OSes.\r
- */\r
-uint8_t KeyDelayRemaining;\r
+       for (;;)\r
+       {\r
+               if (Magstripe_GetStatus() & MAG_CARDPRESENT)\r
+                 ReadMagstripeData();\r
 \r
+               USB_HID_USBTask(&Keyboard_HID_Interface);\r
+               USB_USBTask();\r
+       }\r
+}\r
 \r
-/** Main program entry point. This routine configures the hardware required by the application, then\r
- *  starts the scheduler to run the application tasks.\r
- */\r
-int main(void)\r
+void SetupHardware(void)\r
 {\r
        /* Disable watchdog if enabled by bootloader/fuses */\r
        MCUSR &= ~(1 << WDRF);\r
@@ -92,330 +69,97 @@ int main(void)
 \r
        /* Hardware Initialization */\r
        Magstripe_Init();\r
-       \r
-       /* Buffer Initialization */\r
-       BitBuffer_Init(&Track1Data);\r
-       BitBuffer_Init(&Track2Data);\r
-       BitBuffer_Init(&Track3Data);\r
-       \r
-       /* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */\r
-       OCR0A  = 0xFA;\r
-       TCCR0A = (1 << WGM01);\r
-       TCCR0B = ((1 << CS01) | (1 << CS00));\r
-       TIMSK0 = (1 << OCIE0A);\r
-       \r
-       /* Initialize Scheduler so that it can be used */\r
-       Scheduler_Init();\r
-\r
-       /* Initialize USB Subsystem */\r
        USB_Init();\r
-       \r
-       /* Scheduling - routine never returns, so put this last in the main function */\r
-       Scheduler_Start();\r
 }\r
 \r
-/** Event handler for the USB_Connect event. This starts the USB task. */\r
-void EVENT_USB_Connect(void)\r
+void ReadMagstripeData(void)\r
 {\r
-       /* Start USB management task */\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);\r
-}\r
+       /* Arrays to hold the buffer pointers, clock and data bit masks for the separate card tracks */\r
+       const struct\r
+       {\r
+               uint8_t ClockMask;\r
+               uint8_t DataMask;       \r
+       } TrackInfo[] = {{MAG_T1_CLOCK, MAG_T1_DATA},\r
+                        {MAG_T2_CLOCK, MAG_T2_DATA},\r
+                        {MAG_T3_CLOCK, MAG_T3_DATA}};\r
 \r
-/** Event handler for the USB_Disconnect event. This stops the USB and keyboard report tasks. */\r
-void EVENT_USB_Disconnect(void)\r
-{\r
-       /* Stop running keyboard reporting, card reading and USB management tasks */\r
-       Scheduler_SetTaskMode(USB_Keyboard_Report, TASK_STOP);\r
-       Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);\r
-       Scheduler_SetTaskMode(Magstripe_Read, TASK_STOP);\r
+       uint8_t Magstripe_Prev = 0;\r
+       uint8_t Magstripe_LCL  = Magstripe_GetStatus();\r
+\r
+       while (Magstripe_LCL & MAG_CARDPRESENT)\r
+       {\r
+               for (uint8_t Track = 0; Track < 3; Track++)\r
+               {\r
+                       bool DataPinLevel      = ((Magstripe_LCL & TrackInfo[Track].DataMask) != 0);\r
+                       bool ClockPinLevel     = ((Magstripe_LCL & TrackInfo[Track].ClockMask) != 0);\r
+                       bool ClockLevelChanged = (((Magstripe_LCL ^ Magstripe_Prev) & TrackInfo[Track].ClockMask) != 0);\r
+               \r
+                       if (ClockPinLevel && ClockLevelChanged)\r
+                         BitBuffer_StoreNextBit(&TrackDataBuffers[Track], DataPinLevel);\r
+               }\r
+\r
+               Magstripe_Prev = Magstripe_LCL;\r
+               Magstripe_LCL  = Magstripe_GetStatus();\r
+       }\r
 }\r
 \r
-/** Event handler for the USB_ConfigurationChanged event. This configures the device's endpoints ready\r
- *  to relay reports to the host, and starts the keyboard report task.\r
- */\r
 void EVENT_USB_ConfigurationChanged(void)\r
 {\r
-       /* Setup Keyboard Keycode Report Endpoint */\r
-       Endpoint_ConfigureEndpoint(KEYBOARD_EPNUM, EP_TYPE_INTERRUPT,\r
-                                      ENDPOINT_DIR_IN, KEYBOARD_EPSIZE,\r
-                                  ENDPOINT_BANK_SINGLE);\r
-       \r
-       /* Default to report protocol on connect */\r
-       UsingReportProtocol = true;\r
-\r
-       /* Start Keyboard reporting and card reading tasks */\r
-       Scheduler_SetTaskMode(USB_Keyboard_Report, TASK_RUN);\r
-       Scheduler_SetTaskMode(Magstripe_Read, TASK_RUN);\r
+       USB_HID_ConfigureEndpoints(&Keyboard_HID_Interface);\r
 }\r
 \r
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific\r
- *  control requests that are not handled internally by the USB library, so that they can be handled appropriately\r
- *  for the application.\r
- */\r
 void EVENT_USB_UnhandledControlPacket(void)\r
 {\r
-       /* Handle HID Class specific requests */\r
-       switch (USB_ControlRequest.bRequest)\r
-       {\r
-               case REQ_GetReport:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               USB_KeyboardReport_Data_t KeyboardReportData;\r
-\r
-                               /* Create the next keyboard report for transmission to the host */\r
-                               GetNextReport(&KeyboardReportData);\r
-\r
-                               Endpoint_ClearSETUP();\r
-       \r
-                               /* Write the report data to the control endpoint */\r
-                               Endpoint_Write_Control_Stream_LE(&KeyboardReportData, sizeof(KeyboardReportData));\r
-                               \r
-                               /* Finalize the stream transfer to send the last packet or clear the host abort */\r
-                               Endpoint_ClearOUT();\r
-                       }\r
-               \r
-                       break;\r
-               case REQ_GetProtocol:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* Write the current protocol flag to the host */\r
-                               Endpoint_Write_Byte(UsingReportProtocol);\r
-                               \r
-                               /* Send the flag to the host */\r
-                               Endpoint_ClearIN();\r
-\r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsOUTReceived()));\r
-                               Endpoint_ClearOUT();\r
-                       }\r
-                       \r
-                       break;\r
-               case REQ_SetProtocol:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               Endpoint_ClearSETUP();\r
-\r
-                               /* Set or clear the flag depending on what the host indicates that the current Protocol should be */\r
-                               UsingReportProtocol = (USB_ControlRequest.wValue != 0x0000);\r
-                               \r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsINReady()));\r
-                               Endpoint_ClearIN();\r
-                       }\r
-                       \r
-                       break;\r
-               case REQ_SetIdle:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {\r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* Get idle period in MSB */\r
-                               IdleCount = (USB_ControlRequest.wValue >> 8);\r
-                               \r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsINReady()));\r
-                               Endpoint_ClearIN();\r
-                       }\r
-                       \r
-                       break;\r
-               case REQ_GetIdle:\r
-                       if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
-                       {               \r
-                               Endpoint_ClearSETUP();\r
-                               \r
-                               /* Write the current idle duration to the host */\r
-                               Endpoint_Write_Byte(IdleCount);\r
-                               \r
-                               /* Send the flag to the host */\r
-                               Endpoint_ClearIN();\r
-\r
-                               /* Acknowledge status stage */\r
-                               while (!(Endpoint_IsOUTReceived()));\r
-                               Endpoint_ClearOUT();\r
-                       }\r
-\r
-                       break;\r
-       }\r
+       USB_HID_ProcessControlPacket(&Keyboard_HID_Interface);\r
 }\r
 \r
-/** ISR for the timer 0 compare vector. This ISR fires once each millisecond, and decrements the counter indicating\r
- *  the number of milliseconds left to idle (not send the host reports) if the device has been instructed to idle\r
- *  by the host via a SetIdle class specific request.\r
- */\r
-ISR(TIMER0_COMPA_vect, ISR_BLOCK)\r
+void EVENT_USB_StartOfFrame(void)\r
 {\r
-       /* One millisecond has elapsed, decrement the idle time remaining counter if it has not already elapsed */\r
-       if (IdleMSRemaining)\r
-         IdleMSRemaining--;\r
-         \r
-       if (KeyDelayRemaining)\r
-         KeyDelayRemaining--;\r
+       USB_HID_RegisterStartOfFrame(&Keyboard_HID_Interface);\r
 }\r
 \r
-/** Constructs a keyboard report indicating the currently pressed keyboard keys to the host.\r
- *\r
- *  \param ReportData  Pointer to a USB_KeyboardReport_Data_t report structure where the resulting report should\r
- *                     be stored\r
- *\r
- *  \return Boolean true if the current report is different to the previous report, false otherwise\r
- */\r
-bool GetNextReport(USB_KeyboardReport_Data_t* ReportData)\r
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)\r
 {\r
-       static bool OddReport   = false;\r
-       static bool MustRelease = false;\r
-       \r
-       BitBuffer_t* Buffer     = NULL;\r
-\r
-       /* Clear the report contents */\r
-       memset(ReportData, 0, sizeof(USB_KeyboardReport_Data_t));\r
+       static bool IsKeyReleaseReport;\r
+       static bool IsNewlineReport;\r
 \r
-       /* Get the next non-empty track data buffer */\r
-       if (Track1Data.Elements)\r
-         Buffer = &Track1Data;\r
-       else if (Track2Data.Elements)\r
-         Buffer = &Track2Data;                 \r
-       else if (Track3Data.Elements)\r
-         Buffer = &Track3Data;\r
-\r
-       if (Buffer != NULL)\r
-       {\r
-               /* Toggle the odd report number indicator */\r
-               OddReport   = !OddReport;\r
+       BitBuffer_t*               Buffer         = NULL;\r
+       USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;\r
                \r
-               /* Set the flag indicating that a null report must eventually be sent to release all pressed keys */\r
-               MustRelease = true;\r
-\r
-               /* Only send the next key on odd reports, so that they are interspersed with null reports to release keys */\r
-               if (OddReport)\r
-               {\r
-                       /* Set the report key code to the key code for the next data bit */\r
-                       ReportData->KeyCode = BitBuffer_GetNextBit(Buffer) ? KEY_1 : KEY_0;\r
-                       \r
-                       /* If buffer is now empty, a new line must be sent instead of the terminating bit */\r
-                       if (!(Buffer->Elements))\r
-                       {\r
-                               /* Set the keycode to the code for an enter key press */\r
-                               ReportData->KeyCode = KEY_ENTER;                                \r
-                       }\r
-               }\r
+       /* Key reports must be interleaved with 0 Key Code reports to release the keys, or repeated keys will be ignored */\r
+       IsKeyReleaseReport = !IsKeyReleaseReport;       \r
 \r
-               return true;\r
-       }\r
-       else if (MustRelease)\r
+       if (IsKeyReleaseReport)\r
        {\r
-               /* Leave key code to null (0), to release all pressed keys */\r
-               return true;\r
+               KeyboardReport->KeyCode = 0;\r
        }\r
-       \r
-       return false;\r
-}\r
-\r
-/** Task to read out data from inserted magnetic cards and place the separate track data into their respective\r
- *  data buffers for later sending to the host as keyboard key presses.\r
- */\r
-TASK(Magstripe_Read)\r
-{\r
-       /* Arrays to hold the buffer pointers, clock and data bit masks for the separate card tracks */\r
-       const struct\r
+       else if (IsNewlineReport)\r
        {\r
-               BitBuffer_t* Buffer;\r
-               uint8_t      ClockMask;\r
-               uint8_t      DataMask;  \r
-       } TrackInfo[] = {{&Track1Data, MAG_T1_CLOCK, MAG_T1_DATA},\r
-                        {&Track2Data, MAG_T2_CLOCK, MAG_T2_DATA},\r
-                        {&Track3Data, MAG_T3_CLOCK, MAG_T3_DATA}};\r
-\r
-       /* Previous magnetic card control line' status, for later comparison */\r
-       uint8_t Magstripe_Prev = 0;\r
-       \r
-       /* Buffered current card reader control line' status */\r
-       uint8_t Magstripe_LCL  = Magstripe_GetStatus();\r
-\r
-       /* Exit the task early if no card is present in the reader */\r
-       if (!(Magstripe_LCL & MAG_CARDPRESENT))\r
-         return;\r
-\r
-       /* Read out card data while a card is present */\r
-       while (Magstripe_LCL & MAG_CARDPRESENT)\r
+               IsNewlineReport = false;\r
+               KeyboardReport->KeyCode = KEY_ENTER;\r
+       }\r
+       else\r
        {\r
-               /* Read out the next bit for each track of the card */\r
-               for (uint8_t Track = 0; Track < 3; Track++)\r
-               {\r
-                       /* Current data line status for the current card track */\r
-                       bool DataLevel    = ((Magstripe_LCL & TrackInfo[Track].DataMask) != 0);\r
-\r
-                       /* Current clock line status for the current card track */\r
-                       bool ClockLevel   = ((Magstripe_LCL & TrackInfo[Track].ClockMask) != 0);\r
-\r
-                       /* Current track clock transition check */\r
-                       bool ClockChanged = (((Magstripe_LCL ^ Magstripe_Prev) & TrackInfo[Track].ClockMask) != 0);\r
-               \r
-                       /* Sample the next bit on the falling edge of the track's clock line, store key code into the track's buffer */\r
-                       if (ClockLevel && ClockChanged)\r
-                         BitBuffer_StoreNextBit(TrackInfo[Track].Buffer, DataLevel);\r
-               }\r
-\r
-               /* Retain the current card reader control line states for later edge detection */\r
-               Magstripe_Prev = Magstripe_LCL;\r
+               if (TrackDataBuffers[0].Elements)\r
+                 Buffer = &TrackDataBuffers[0];\r
+               else if (TrackDataBuffers[1].Elements)\r
+                 Buffer = &TrackDataBuffers[1];                        \r
+               else if (TrackDataBuffers[2].Elements)\r
+                 Buffer = &TrackDataBuffers[2];\r
+               else\r
+                 return 0;\r
+\r
+               KeyboardReport->KeyCode = BitBuffer_GetNextBit(Buffer) ? KEY_1 : KEY_0;\r
                \r
-               /* Retrieve the new card reader control line states */\r
-               Magstripe_LCL  = Magstripe_GetStatus();\r
+               /* If buffer now empty, next report must be a newline to seperate track data */\r
+               if (!(Buffer->Elements))\r
+                 IsNewlineReport = true;\r
        }\r
        \r
-       /* Add terminators to the end of each track buffer */\r
-       BitBuffer_StoreNextBit(&Track1Data, 0);\r
-       BitBuffer_StoreNextBit(&Track2Data, 0);\r
-       BitBuffer_StoreNextBit(&Track3Data, 0);\r
+       return sizeof(USB_KeyboardReport_Data_t);\r
 }\r
 \r
-/** Task for the magnetic card reading and keyboard report generation. This task waits until a card is inserted,\r
- *  then reads off the card data and sends it to the host as a series of keyboard key presses via keyboard reports.\r
- */\r
-TASK(USB_Keyboard_Report)\r
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)\r
 {\r
-       USB_KeyboardReport_Data_t KeyboardReportData;\r
-       bool                      SendReport = false;\r
-       \r
-       /* Check if the USB system is connected to a host */\r
-       if (USB_IsConnected)\r
-       {\r
-               /* Select the Keyboard Report Endpoint */\r
-               Endpoint_SelectEndpoint(KEYBOARD_EPNUM);\r
-\r
-               /* Check if Keyboard Endpoint Ready for Read/Write */\r
-               if (Endpoint_IsReadWriteAllowed())\r
-               {\r
-                       /* Only fetch the next key to send once the period between key presses has elapsed */\r
-                       if (!(KeyDelayRemaining))\r
-                       {\r
-                               /* Create the next keyboard report for transmission to the host */\r
-                               SendReport = GetNextReport(&KeyboardReportData);\r
-                       }\r
-                       \r
-                       /* Check if the idle period is set and has elapsed */\r
-                       if (IdleCount && !(IdleMSRemaining))\r
-                       {\r
-                               /* Idle period elapsed, indicate that a report must be sent */\r
-                               SendReport = true;\r
-                               \r
-                               /* Reset the idle time remaining counter, must multiply by 4 to get the duration in milliseconds */\r
-                               IdleMSRemaining = (IdleCount << 2);\r
-                       }\r
-\r
-                       /* Write the keyboard report if a report is to be sent to the host */\r
-                       if (SendReport)\r
-                       {\r
-                               /* Write Keyboard Report Data */\r
-                               Endpoint_Write_Stream_LE(&KeyboardReportData, sizeof(USB_KeyboardReport_Data_t));\r
-\r
-                               /* Finalize the stream transfer to send the last packet */\r
-                               Endpoint_ClearIN();\r
-\r
-                               /* Reset the key delay period counter */\r
-                               KeyDelayRemaining = 2;\r
-                       }\r
-               }\r
-       }\r
+       // Unused (but mandatory for the HID class driver) in this demo, since there are no Host->Device reports\r
 }\r
index c700bca..b0e47d5 100644 (file)
        /* Includes: */\r
                #include <avr/io.h>\r
                #include <avr/wdt.h>\r
-               #include <avr/interrupt.h>\r
                #include <avr/power.h>\r
-               #include <stdbool.h>\r
-               #include <string.h>\r
 \r
                #include "Descriptors.h"\r
-\r
                #include "Lib/MagstripeHW.h"\r
                #include "Lib/CircularBitBuffer.h"\r
 \r
-               #include <LUFA/Version.h>                    // Library Version Information\r
-               #include <LUFA/Drivers/USB/USB.h>            // USB Functionality\r
-               #include <LUFA/Scheduler/Scheduler.h>        // Simple scheduler for task management\r
-\r
-               \r
-       /* Task Definitions: */\r
-               /** Task definition for the keyboard and magnetic card reading task. */\r
-               TASK(USB_Keyboard_Report);\r
-               \r
-               TASK(Magstripe_Read);\r
+               #include <LUFA/Version.h>\r
+               #include <LUFA/Drivers/USB/USB.h>\r
+               #include <LUFA/Drivers/USB/Class/Device/HID.h>\r
 \r
        /* Macros: */\r
-               /** HID Class Specific Request to get the current HID report from the device. */\r
-               #define REQ_GetReport      0x01\r
-\r
-               /** HID Class Specific Request to get the current device idle count. */\r
-               #define REQ_GetIdle        0x02\r
-\r
-               /** HID Class Specific Request to set the current HID report to the device. */\r
-               #define REQ_SetReport      0x09\r
-\r
-               /** HID Class Specific Request to set the device's idle count. */\r
-               #define REQ_SetIdle        0x0A\r
-\r
-               /** HID Class Specific Request to get the current HID report protocol mode. */\r
-               #define REQ_GetProtocol    0x03\r
-\r
-               /** HID Class Specific Request to set the current HID report protocol mode. */\r
-               #define REQ_SetProtocol    0x0B\r
-               \r
                /** HID keyboard keycode to indicate that the "1" key is currently pressed. */\r
                #define KEY_1              30\r
 \r
                } USB_KeyboardReport_Data_t;\r
        \r
        /* Function Prototypes: */\r
-               void EVENT_USB_Connect(void);\r
-               void EVENT_USB_Disconnect(void);\r
+               void SetupHardware(void);\r
+               void ReadMagstripeData(void);\r
+               \r
                void EVENT_USB_ConfigurationChanged(void);\r
                void EVENT_USB_UnhandledControlPacket(void);\r
-       \r
-               bool GetNextReport(USB_KeyboardReport_Data_t* ReportData);\r
+               void EVENT_USB_StartOfFrame(void);\r
+\r
+               uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);\r
+               void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,\r
+                                                                  void* ReportData, uint16_t ReportSize);\r
                \r
 #endif\r
index 962c999..138456f 100644 (file)
@@ -126,7 +126,6 @@ LUFA_PATH = ../..
 SRC = $(TARGET).c                                                 \
          Descriptors.c                                               \
          Lib/CircularBitBuffer.c                                     \
-         $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \
@@ -137,7 +136,7 @@ SRC = $(TARGET).c                                                 \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \
          $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \
-         $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \
+         $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/HID.c            \
 
 
 # List C++ source files here. (C dependencies are automatically generated.)