aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2009-06-01 11:03:39 +0000
committerDean Camera <dean@fourwalledcubicle.com>2009-06-01 11:03:39 +0000
commitd1e52660368d34d693131f6aff3c8fd8584162e5 (patch)
tree333916f85f9fd38a80b0785478aa596f11f166b6
parent2440ca268ac444c1aed2441cefe9e25a767d961a (diff)
downloadlufa-d1e52660368d34d693131f6aff3c8fd8584162e5.tar.gz
lufa-d1e52660368d34d693131f6aff3c8fd8584162e5.tar.bz2
lufa-d1e52660368d34d693131f6aff3c8fd8584162e5.zip
Commit of new class abstraction APIs for all device demos other than the MIDI demo - not documented yet.
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.
-rw-r--r--Bootloaders/CDC/makefile1
-rw-r--r--Bootloaders/DFU/makefile1
-rw-r--r--Bootloaders/TeensyHID/makefile1
-rw-r--r--Demos/Device/AudioInput/AudioInput.c188
-rw-r--r--Demos/Device/AudioInput/AudioInput.h36
-rw-r--r--Demos/Device/AudioInput/makefile3
-rw-r--r--Demos/Device/AudioOutput/AudioOutput.c277
-rw-r--r--Demos/Device/AudioOutput/AudioOutput.h33
-rw-r--r--Demos/Device/AudioOutput/makefile5
-rw-r--r--Demos/Device/CDC/CDC.c317
-rw-r--r--Demos/Device/CDC/CDC.h139
-rw-r--r--Demos/Device/CDC/Descriptors.h22
-rw-r--r--Demos/Device/CDC/makefile5
-rw-r--r--Demos/Device/DualCDC/Descriptors.h20
-rw-r--r--Demos/Device/DualCDC/DualCDC.c370
-rw-r--r--Demos/Device/DualCDC/DualCDC.h75
-rw-r--r--Demos/Device/DualCDC/makefile5
-rw-r--r--Demos/Device/GenericHID/Descriptors.h32
-rw-r--r--Demos/Device/GenericHID/GenericHID.c243
-rw-r--r--Demos/Device/GenericHID/GenericHID.h40
-rw-r--r--Demos/Device/GenericHID/makefile5
-rw-r--r--Demos/Device/Joystick/Descriptors.h30
-rw-r--r--Demos/Device/Joystick/Joystick.c211
-rw-r--r--Demos/Device/Joystick/Joystick.h40
-rw-r--r--Demos/Device/Joystick/makefile5
-rw-r--r--Demos/Device/Keyboard/Descriptors.h30
-rw-r--r--Demos/Device/Keyboard/Keyboard.c437
-rw-r--r--Demos/Device/Keyboard/Keyboard.h60
-rw-r--r--Demos/Device/Keyboard/makefile5
-rw-r--r--Demos/Device/KeyboardMouse/Descriptors.h30
-rw-r--r--Demos/Device/KeyboardMouse/KeyboardMouse.c353
-rw-r--r--Demos/Device/KeyboardMouse/KeyboardMouse.h47
-rw-r--r--Demos/Device/KeyboardMouse/makefile5
-rw-r--r--Demos/Device/MIDI/makefile2
-rw-r--r--Demos/Device/MassStorage/Lib/DataflashManager.c18
-rw-r--r--Demos/Device/MassStorage/Lib/DataflashManager.h4
-rw-r--r--Demos/Device/MassStorage/Lib/SCSI.c116
-rw-r--r--Demos/Device/MassStorage/Lib/SCSI.h25
-rw-r--r--Demos/Device/MassStorage/MassStorage.c331
-rw-r--r--Demos/Device/MassStorage/MassStorage.h103
-rw-r--r--Demos/Device/MassStorage/makefile4
-rw-r--r--Demos/Device/Mouse/Descriptors.h30
-rw-r--r--Demos/Device/Mouse/Mouse.c309
-rw-r--r--Demos/Device/Mouse/Mouse.h58
-rw-r--r--Demos/Device/Mouse/makefile5
-rw-r--r--Demos/Device/RNDISEthernet/Lib/ARP.h4
-rw-r--r--Demos/Device/RNDISEthernet/Lib/Ethernet.c32
-rw-r--r--Demos/Device/RNDISEthernet/Lib/Ethernet.h24
-rw-r--r--Demos/Device/RNDISEthernet/Lib/EthernetProtocols.h8
-rw-r--r--Demos/Device/RNDISEthernet/Lib/ICMP.c4
-rw-r--r--Demos/Device/RNDISEthernet/Lib/ICMP.h2
-rw-r--r--Demos/Device/RNDISEthernet/Lib/IP.c5
-rw-r--r--Demos/Device/RNDISEthernet/Lib/IP.h2
-rw-r--r--Demos/Device/RNDISEthernet/Lib/RNDIS.c394
-rw-r--r--Demos/Device/RNDISEthernet/Lib/TCP.c22
-rw-r--r--Demos/Device/RNDISEthernet/Lib/TCP.h8
-rw-r--r--Demos/Device/RNDISEthernet/RNDISEthernet.c322
-rw-r--r--Demos/Device/RNDISEthernet/RNDISEthernet.h56
-rw-r--r--Demos/Device/RNDISEthernet/makefile6
-rw-r--r--Demos/Device/USBtoSerial/Descriptors.h20
-rw-r--r--Demos/Device/USBtoSerial/USBtoSerial.c346
-rw-r--r--Demos/Device/USBtoSerial/USBtoSerial.h142
-rw-r--r--Demos/Device/USBtoSerial/makefile5
-rw-r--r--Demos/Host/GenericHIDHost/makefile2
-rw-r--r--Demos/Host/MassStorageHost/Lib/MassStoreCommands.c4
-rw-r--r--Demos/Host/StillImageHost/Lib/StillImageCommands.c4
-rw-r--r--Demos/OTG/TestApp/TestApp.h1
-rw-r--r--Demos/OTG/TestApp/makefile3
-rw-r--r--LUFA.pnproj2
-rw-r--r--LUFA/ChangeLog.txt10
-rw-r--r--LUFA/DirectorySummaries.txt13
-rw-r--r--LUFA/Drivers/USB/Class/Device/Audio.c154
-rw-r--r--LUFA/Drivers/USB/Class/Device/Audio.h70
-rw-r--r--LUFA/Drivers/USB/Class/Device/CDC.c185
-rw-r--r--LUFA/Drivers/USB/Class/Device/CDC.h188
-rw-r--r--LUFA/Drivers/USB/Class/Device/HID.c211
-rw-r--r--LUFA/Drivers/USB/Class/Device/HID.h115
-rw-r--r--LUFA/Drivers/USB/Class/Device/MassStorage.c208
-rw-r--r--LUFA/Drivers/USB/Class/Device/MassStorage.h127
-rw-r--r--LUFA/Drivers/USB/Class/Device/RNDIS.c456
-rw-r--r--LUFA/Drivers/USB/Class/Device/RNDIS.h (renamed from Demos/Device/RNDISEthernet/Lib/RNDIS.h)94
-rw-r--r--LUFA/Drivers/USB/Class/Device/RNDISConstants.h (renamed from Demos/Device/RNDISEthernet/Lib/RNDISConstants.h)0
-rw-r--r--LUFA/Drivers/USB/Class/Host/HIDParser.c (renamed from LUFA/Drivers/USB/Class/HIDParser.c)0
-rw-r--r--LUFA/Drivers/USB/Class/Host/HIDParser.h (renamed from LUFA/Drivers/USB/Class/HIDParser.h)2
-rw-r--r--LUFA/Drivers/USB/Class/Host/HIDReportData.h (renamed from LUFA/Drivers/USB/Class/HIDReportData.h)0
-rw-r--r--LUFA/Drivers/USB/HighLevel/Events.h6
-rw-r--r--LUFA/Drivers/USB/HighLevel/USBInterrupt.c18
-rw-r--r--LUFA/Drivers/USB/HighLevel/USBTask.c2
-rw-r--r--LUFA/Drivers/USB/HighLevel/USBTask.h7
-rw-r--r--LUFA/Drivers/USB/LowLevel/Endpoint.c6
-rw-r--r--LUFA/Drivers/USB/LowLevel/Host.c12
-rw-r--r--LUFA/Drivers/USB/LowLevel/LowLevel.c8
-rw-r--r--LUFA/Drivers/USB/LowLevel/LowLevel.h3
-rw-r--r--LUFA/Drivers/USB/LowLevel/Pipe.c6
-rw-r--r--LUFA/Drivers/USB/USB.h2
-rw-r--r--LUFA/MemoryAllocator/DynAlloc.c226
-rw-r--r--LUFA/MemoryAllocator/DynAlloc.h198
-rw-r--r--LUFA/Scheduler/Scheduler.c95
-rw-r--r--LUFA/Scheduler/Scheduler.h285
-rw-r--r--LUFA/SchedulerOverview.txt31
-rw-r--r--LUFA/makefile6
-rw-r--r--Projects/Magstripe/Descriptors.c2
-rw-r--r--Projects/Magstripe/Descriptors.h36
-rw-r--r--Projects/Magstripe/Magstripe.c422
-rw-r--r--Projects/Magstripe/Magstripe.h47
-rw-r--r--Projects/Magstripe/makefile3
106 files changed, 3030 insertions, 5718 deletions
diff --git a/Bootloaders/CDC/makefile b/Bootloaders/CDC/makefile
index bc8e2ca1a..e3d8e5c51 100644
--- a/Bootloaders/CDC/makefile
+++ b/Bootloaders/CDC/makefile
@@ -124,7 +124,6 @@ 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 \
# List C++ source files here. (C dependencies are automatically generated.)
diff --git a/Bootloaders/DFU/makefile b/Bootloaders/DFU/makefile
index 4e51e299c..b3eb1b0a1 100644
--- a/Bootloaders/DFU/makefile
+++ b/Bootloaders/DFU/makefile
@@ -124,7 +124,6 @@ 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 \
# List C++ source files here. (C dependencies are automatically generated.)
diff --git a/Bootloaders/TeensyHID/makefile b/Bootloaders/TeensyHID/makefile
index de929edfb..68b016022 100644
--- a/Bootloaders/TeensyHID/makefile
+++ b/Bootloaders/TeensyHID/makefile
@@ -124,7 +124,6 @@ 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 \
# List C++ source files here. (C dependencies are automatically generated.)
diff --git a/Demos/Device/AudioInput/AudioInput.c b/Demos/Device/AudioInput/AudioInput.c
index ecd8cdda8..bcfb04be1 100644
--- a/Demos/Device/AudioInput/AudioInput.c
+++ b/Demos/Device/AudioInput/AudioInput.c
@@ -28,26 +28,32 @@
this software.
*/
-/** \file
- *
- * Main source file for the Audio Input demo. This file contains the main tasks of the demo and
- * is responsible for the initial application hardware configuration.
- */
-
#include "AudioInput.h"
-/* Scheduler Task List */
-TASK_LIST
+USB_ClassInfo_Audio_t Microphone_Audio_Interface =
+ {
+ .InterfaceNumber = 0,
+
+ .DataINEndpointNumber = AUDIO_STREAM_EPNUM,
+ .DataINEndpointSize = AUDIO_STREAM_EPSIZE,
+ };
+
+int main(void)
{
- { .Task = USB_USBTask , .TaskStatus = TASK_STOP },
- { .Task = USB_Audio_Task , .TaskStatus = TASK_STOP },
-};
+ SetupHardware();
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+
+ for (;;)
+ {
+ if (Microphone_Audio_Interface.InterfaceEnabled)
+ ProcessNextSample();
-/** Main program entry point. This routine configures the hardware required by the application, then
- * starts the scheduler to run the application tasks.
- */
-int main(void)
+ USB_USBTask();
+ }
+}
+
+void SetupHardware(void)
{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
@@ -58,35 +64,35 @@ int main(void)
/* Hardware Initialization */
LEDs_Init();
+ USB_Init();
ADC_Init(ADC_FREE_RUNNING | ADC_PRESCALE_32);
ADC_SetupChannel(MIC_IN_ADC_CHANNEL);
/* Start the ADC conversion in free running mode */
ADC_StartReading(ADC_REFERENCE_AVCC | ADC_RIGHT_ADJUSTED | MIC_IN_ADC_CHANNEL);
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
-
- /* Initialize Scheduler so that it can be used */
- Scheduler_Init();
+}
- /* Initialize USB Subsystem */
- USB_Init();
+void ProcessNextSample(void)
+{
+ if ((TIFR0 & (1 << OCF0A)) && USB_Audio_IsReadyForNextSample(&Microphone_Audio_Interface))
+ {
+ TIFR0 |= (1 << OCF0A);
+
+ /* Audio sample is ADC value scaled to fit the entire range */
+ int16_t AudioSample = ((SAMPLE_MAX_RANGE / ADC_MAX_RANGE) * ADC_GetResult());
+
+#if defined(MICROPHONE_BIASED_TO_HALF_RAIL)
+ /* Microphone is biased to half rail voltage, subtract the bias from the sample value */
+ AudioSample -= (SAMPLE_MAX_RANGE / 2));
+#endif
- /* Scheduling - routine never returns, so put this last in the main function */
- Scheduler_Start();
+ USB_Audio_WriteSample16(AudioSample);
+ }
}
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs, and
- * configures the sample update and PWM timers.
- */
void EVENT_USB_Connect(void)
{
- /* Start USB management task */
- Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
- /* Indicate USB enumerating */
- UpdateStatus(Status_USBEnumerating);
+ LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
/* Sample reload timer initialization */
OCR0A = (F_CPU / AUDIO_SAMPLE_FREQUENCY) - 1;
@@ -94,127 +100,23 @@ void EVENT_USB_Connect(void)
TCCR0B = (1 << CS00); // Fcpu speed
}
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- * the status LEDs, disables the sample update and PWM output timers and stops the USB and Audio management tasks.
- */
void EVENT_USB_Disconnect(void)
{
/* Stop the sample reload timer */
TCCR0B = 0;
- /* Stop running audio and USB management tasks */
- Scheduler_SetTaskMode(USB_Audio_Task, TASK_STOP);
- Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration
- * of the USB device after enumeration - the device endpoints are configured.
- */
void EVENT_USB_ConfigurationChanged(void)
{
- /* Setup audio stream endpoint */
- Endpoint_ConfigureEndpoint(AUDIO_STREAM_EPNUM, EP_TYPE_ISOCHRONOUS,
- ENDPOINT_DIR_IN, AUDIO_STREAM_EPSIZE,
- ENDPOINT_BANK_DOUBLE);
-
- /* Indicate USB connected and ready */
- UpdateStatus(Status_USBReady);
-}
-
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- * control requests that are not handled internally by the USB library (including the Audio class-specific
- * requests) so that they can be handled appropriately for the application.
- */
-void EVENT_USB_UnhandledControlPacket(void)
-{
- /* Process General and Audio specific control requests */
- switch (USB_ControlRequest.bRequest)
- {
- case REQ_SetInterface:
- /* Set Interface is not handled by the library, as its function is application-specific */
- if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
- {
- Endpoint_ClearSETUP();
-
- /* Check if the host is enabling the audio interface (setting AlternateSetting to 1) */
- if (USB_ControlRequest.wValue)
- {
- /* Start audio task */
- Scheduler_SetTaskMode(USB_Audio_Task, TASK_RUN);
- }
- else
- {
- /* Stop audio task */
- Scheduler_SetTaskMode(USB_Audio_Task, TASK_STOP);
- }
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsINReady()));
- Endpoint_ClearIN();
- }
-
- break;
- }
-}
-
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- * log to a serial port, or anything else that is suitable for status updates.
- *
- * \param CurrentStatus Current status of the system, from the AudioInput_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
-{
- uint8_t LEDMask = LEDS_NO_LEDS;
+ LEDs_SetAllLEDs(LEDMASK_USB_READY);
- /* Set the LED mask to the appropriate LED mask based on the given status code */
- switch (CurrentStatus)
- {
- case Status_USBNotReady:
- LEDMask = (LEDS_LED1);
- break;
- case Status_USBEnumerating:
- LEDMask = (LEDS_LED1 | LEDS_LED2);
- break;
- case Status_USBReady:
- LEDMask = (LEDS_LED2 | LEDS_LED4);
- break;
- }
-
- /* Set the board LEDs to the new LED mask */
- LEDs_SetAllLEDs(LEDMask);
+ if (!(USB_Audio_ConfigureEndpoints(&Microphone_Audio_Interface)))
+ LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
-/** Task to manage the Audio interface, reading in ADC samples from the microphone, and them to the host. */
-TASK(USB_Audio_Task)
+void EVENT_USB_UnhandledControlPacket(void)
{
- /* Select the audio stream endpoint */
- Endpoint_SelectEndpoint(AUDIO_STREAM_EPNUM);
-
- /* Check if the current endpoint can be written to and that the next sample should be stored */
- if (Endpoint_IsINReady() && (TIFR0 & (1 << OCF0A)))
- {
- /* Clear the sample reload timer */
- TIFR0 |= (1 << OCF0A);
-
- /* Audio sample is ADC value scaled to fit the entire range */
- int16_t AudioSample = ((SAMPLE_MAX_RANGE / ADC_MAX_RANGE) * ADC_GetResult());
-
-#if defined(MICROPHONE_BIASED_TO_HALF_RAIL)
- /* Microphone is biased to half rail voltage, subtract the bias from the sample value */
- AudioSample -= (SAMPLE_MAX_RANGE / 2));
-#endif
-
- /* Write the sample to the buffer */
- Endpoint_Write_Word_LE(AudioSample);
-
- /* Check to see if the bank is now full */
- if (!(Endpoint_IsReadWriteAllowed()))
- {
- /* Send the full packet to the host */
- Endpoint_ClearIN();
- }
- }
+ USB_Audio_ProcessControlPacket(&Microphone_Audio_Interface);
}
diff --git a/Demos/Device/AudioInput/AudioInput.h b/Demos/Device/AudioInput/AudioInput.h
index a394492f0..e9f56b30a 100644
--- a/Demos/Device/AudioInput/AudioInput.h
+++ b/Demos/Device/AudioInput/AudioInput.h
@@ -43,12 +43,13 @@
#include "Descriptors.h"
- #include <LUFA/Version.h> // Library Version Information
- #include <LUFA/Drivers/USB/USB.h> // USB Functionality
- #include <LUFA/Drivers/Board/LEDs.h> // LEDs driver
- #include <LUFA/Drivers/Peripheral/ADC.h> // ADC driver
- #include <LUFA/Scheduler/Scheduler.h> // Simple scheduler for task management
-
+ #include <LUFA/Version.h>
+ #include <LUFA/Drivers/Board/LEDs.h>
+ #include <LUFA/Drivers/Board/Joystick.h>
+ #include <LUFA/Drivers/Peripheral/ADC.h>
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/Audio.h>
+
/* Macros: */
/** ADC channel number for the microphone input. */
#define MIC_IN_ADC_CHANNEL 2
@@ -59,24 +60,19 @@
/** Maximum ADC range for the microphone input. */
#define ADC_MAX_RANGE 0x3FF
- /* Enums: */
- /** Enum for the possible status codes for passing to the UpdateStatus() function. */
- enum AudioInput_StatusCodes_t
- {
- Status_USBNotReady = 0, /**< USB is not ready (disconnected from a USB host) */
- Status_USBEnumerating = 1, /**< USB interface is enumerating */
- Status_USBReady = 2, /**< USB interface is connected and ready */
- };
-
- /* Task Definitions: */
- TASK(USB_Audio_Task);
-
+ /* Macros: */
+ #define LEDMASK_USB_NOTREADY LEDS_LED1
+ #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
+ #define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
+ #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
+
/* Function Prototypes: */
+ void SetupHardware(void);
+ void ProcessNextSample(void);
+
void EVENT_USB_Connect(void);
void EVENT_USB_Disconnect(void);
void EVENT_USB_ConfigurationChanged(void);
void EVENT_USB_UnhandledControlPacket(void);
- void UpdateStatus(uint8_t CurrentStatus);
-
#endif
diff --git a/Demos/Device/AudioInput/makefile b/Demos/Device/AudioInput/makefile
index c70e98e04..9d3adff69 100644
--- a/Demos/Device/AudioInput/makefile
+++ b/Demos/Device/AudioInput/makefile
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
Descriptors.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 \
@@ -136,7 +135,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/Audio.c \
# List C++ source files here. (C dependencies are automatically generated.)
diff --git a/Demos/Device/AudioOutput/AudioOutput.c b/Demos/Device/AudioOutput/AudioOutput.c
index 40e376b52..0f193567a 100644
--- a/Demos/Device/AudioOutput/AudioOutput.c
+++ b/Demos/Device/AudioOutput/AudioOutput.c
@@ -28,27 +28,33 @@
this software.
*/
-/** \file
- *
- * Main source file for the Audio Output demo. This file contains the main tasks of the demo and
- * is responsible for the initial application hardware configuration.
- */
-
#include "AudioOutput.h"
-/* Scheduler Task List */
-TASK_LIST
-{
- { .Task = USB_USBTask , .TaskStatus = TASK_STOP },
- { .Task = USB_Audio_Task , .TaskStatus = TASK_STOP },
-};
+USB_ClassInfo_Audio_t Speaker_Audio_Interface =
+ {
+ .InterfaceNumber = 0,
+ .DataOUTEndpointNumber = AUDIO_STREAM_EPNUM,
+ .DataOUTEndpointSize = AUDIO_STREAM_EPSIZE,
+ };
-/** Main program entry point. This routine configures the hardware required by the application, then
- * starts the scheduler to run the application tasks.
- */
int main(void)
{
+ SetupHardware();
+
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+
+ for (;;)
+ {
+ if (Speaker_Audio_Interface.InterfaceEnabled)
+ ProcessNextSample();
+
+ USB_USBTask();
+ }
+}
+
+void SetupHardware(void)
+{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
wdt_disable();
@@ -58,186 +64,19 @@ int main(void)
/* Hardware Initialization */
LEDs_Init();
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
-
- /* Initialize Scheduler so that it can be used */
- Scheduler_Init();
-
- /* Initialize USB Subsystem */
USB_Init();
-
- /* Scheduling - routine never returns, so put this last in the main function */
- Scheduler_Start();
-}
-
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs, and
- * configures the sample update and PWM timers.
- */
-void EVENT_USB_Connect(void)
-{
- /* Start USB management task */
- Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
- /* Indicate USB enumerating */
- UpdateStatus(Status_USBEnumerating);
-
- /* Sample reload timer initialization */
- OCR0A = (F_CPU / AUDIO_SAMPLE_FREQUENCY) - 1;
- TCCR0A = (1 << WGM01); // CTC mode
- TCCR0B = (1 << CS00); // Fcpu speed
-
-#if defined(AUDIO_OUT_MONO)
- /* Set speaker as output */
- DDRC |= (1 << 6);
-#elif defined(AUDIO_OUT_STEREO)
- /* Set speakers as outputs */
- DDRC |= ((1 << 6) | (1 << 5));
-#elif defined(AUDIO_OUT_PORTC)
- /* Set PORTC as outputs */
- DDRC |= 0xFF;
-#endif
-
-#if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))
- /* PWM speaker timer initialization */
- TCCRxA = ((1 << WGMx0) | (1 << COMxA1) | (1 << COMxA0)
- | (1 << COMxB1) | (1 << COMxB0)); // Set on match, clear on TOP
- TCCRxB = ((1 << WGMx2) | (1 << CSx0)); // Fast 8-Bit PWM, Fcpu speed
-#endif
}
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- * the status LEDs, disables the sample update and PWM output timers and stops the USB and Audio management tasks.
- */
-void EVENT_USB_Disconnect(void)
-{
- /* Stop the timers */
- TCCR0B = 0;
-#if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))
- TCCRxB = 0;
-#endif
-
-#if defined(AUDIO_OUT_MONO)
- /* Set speaker as input to reduce current draw */
- DDRC &= ~(1 << 6);
-#elif defined(AUDIO_OUT_STEREO)
- /* Set speakers as inputs to reduce current draw */
- DDRC &= ~((1 << 6) | (1 << 5));
-#elif defined(AUDIO_OUT_PORTC)
- /* Set PORTC low */
- PORTC = 0x00;
-#endif
-
- /* Stop running audio and USB management tasks */
- Scheduler_SetTaskMode(USB_Audio_Task, TASK_STOP);
- Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
-}
-
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration
- * of the USB device after enumeration - the device endpoints are configured.
- */
-void EVENT_USB_ConfigurationChanged(void)
-{
- /* Setup audio stream endpoint */
- Endpoint_ConfigureEndpoint(AUDIO_STREAM_EPNUM, EP_TYPE_ISOCHRONOUS,
- ENDPOINT_DIR_OUT, AUDIO_STREAM_EPSIZE,
- ENDPOINT_BANK_DOUBLE);
-
- /* Indicate USB connected and ready */
- UpdateStatus(Status_USBReady);
-}
-
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- * control requests that are not handled internally by the USB library (including the Audio class-specific
- * requests) so that they can be handled appropriately for the application.
- */
-void EVENT_USB_UnhandledControlPacket(void)
+void ProcessNextSample(void)
{
- /* Process General and Audio specific control requests */
- switch (USB_ControlRequest.bRequest)
- {
- case REQ_SetInterface:
- /* Set Interface is not handled by the library, as its function is application-specific */
- if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
- {
- Endpoint_ClearSETUP();
-
- /* Check if the host is enabling the audio interface (setting AlternateSetting to 1) */
- if (USB_ControlRequest.wValue)
- {
- /* Start audio task */
- Scheduler_SetTaskMode(USB_Audio_Task, TASK_RUN);
- }
- else
- {
- /* Stop audio task */
- Scheduler_SetTaskMode(USB_Audio_Task, TASK_STOP);
- }
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsINReady()));
- Endpoint_ClearIN();
- }
-
- break;
- }
-}
-
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- * log to a serial port, or anything else that is suitable for status updates.
- *
- * \param CurrentStatus Current status of the system, from the AudioOutput_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
-{
- uint8_t LEDMask = LEDS_NO_LEDS;
-
- /* Set the LED mask to the appropriate LED mask based on the given status code */
- switch (CurrentStatus)
- {
- case Status_USBNotReady:
- LEDMask = (LEDS_LED1);
- break;
- case Status_USBEnumerating:
- LEDMask = (LEDS_LED1 | LEDS_LED2);
- break;
- case Status_USBReady:
- LEDMask = (LEDS_LED2 | LEDS_LED4);
- break;
- }
-
- /* Set the board LEDs to the new LED mask */
- LEDs_SetAllLEDs(LEDMask);
-}
-
-/** Task to manage the Audio interface, reading in audio samples from the host, and outputting them to the speakers/LEDs as
- * desired.
- */
-TASK(USB_Audio_Task)
-{
- /* Select the audio stream endpoint */
- Endpoint_SelectEndpoint(AUDIO_STREAM_EPNUM);
-
- /* Check if the current endpoint can be read from (contains a packet) and that the next sample should be read */
- if (Endpoint_IsOUTReceived() && (TIFR0 & (1 << OCF0A)))
+ if ((TIFR0 & (1 << OCF0A)) && USB_Audio_IsSampleReceived(&Speaker_Audio_Interface))
{
/* Clear the sample reload timer */
TIFR0 |= (1 << OCF0A);
/* Retrieve the signed 16-bit left and right audio samples */
- int16_t LeftSample_16Bit = (int16_t)Endpoint_Read_Word_LE();
- int16_t RightSample_16Bit = (int16_t)Endpoint_Read_Word_LE();
-
- /* Check to see if the bank is now empty */
- if (!(Endpoint_IsReadWriteAllowed()))
- {
- /* Acknowledge the packet, clear the bank ready for the next packet */
- Endpoint_ClearOUT();
- }
+ int16_t LeftSample_16Bit = (int16_t)USB_Audio_ReadSample16();
+ int16_t RightSample_16Bit = (int16_t)USB_Audio_ReadSample16();
/* Massage signed 16-bit left and right audio samples into signed 8-bit */
int8_t LeftSample_8Bit = (LeftSample_16Bit >> 8);
@@ -289,3 +128,69 @@ TASK(USB_Audio_Task)
#endif
}
}
+
+void EVENT_USB_Connect(void)
+{
+ LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+
+ /* Sample reload timer initialization */
+ OCR0A = (F_CPU / AUDIO_SAMPLE_FREQUENCY) - 1;
+ TCCR0A = (1 << WGM01); // CTC mode
+ TCCR0B = (1 << CS00); // Fcpu speed
+
+#if defined(AUDIO_OUT_MONO)
+ /* Set speaker as output */
+ DDRC |= (1 << 6);
+#elif defined(AUDIO_OUT_STEREO)
+ /* Set speakers as outputs */
+ DDRC |= ((1 << 6) | (1 << 5));
+#elif defined(AUDIO_OUT_PORTC)
+ /* Set PORTC as outputs */
+ DDRC |= 0xFF;
+#endif
+
+#if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))
+ /* PWM speaker timer initialization */
+ TCCRxA = ((1 << WGMx0) | (1 << COMxA1) | (1 << COMxA0)
+ | (1 << COMxB1) | (1 << COMxB0)); // Set on match, clear on TOP
+ TCCRxB = ((1 << WGMx2) | (1 << CSx0)); // Fast 8-Bit PWM, Fcpu speed
+#endif
+}
+
+/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
+ * the status LEDs, disables the sample update and PWM output timers and stops the USB and Audio management tasks.
+ */
+void EVENT_USB_Disconnect(void)
+{
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+
+ /* Stop the timers */
+ TCCR0B = 0;
+#if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))
+ TCCRxB = 0;
+#endif
+
+#if defined(AUDIO_OUT_MONO)
+ /* Set speaker as input to reduce current draw */
+ DDRC &= ~(1 << 6);
+#elif defined(AUDIO_OUT_STEREO)
+ /* Set speakers as inputs to reduce current draw */
+ DDRC &= ~((1 << 6) | (1 << 5));
+#elif defined(AUDIO_OUT_PORTC)
+ /* Set PORTC low */
+ PORTC = 0x00;
+#endif
+}
+
+void EVENT_USB_ConfigurationChanged(void)
+{
+ LEDs_SetAllLEDs(LEDMASK_USB_READY);
+
+ if (!(USB_Audio_ConfigureEndpoints(&Speaker_Audio_Interface)))
+ LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+}
+
+void EVENT_USB_UnhandledControlPacket(void)
+{
+ USB_Audio_ProcessControlPacket(&Speaker_Audio_Interface);
+}
diff --git a/Demos/Device/AudioOutput/AudioOutput.h b/Demos/Device/AudioOutput/AudioOutput.h
index d8725a07b..7d112db88 100644
--- a/Demos/Device/AudioOutput/AudioOutput.h
+++ b/Demos/Device/AudioOutput/AudioOutput.h
@@ -43,10 +43,12 @@
#include "Descriptors.h"
- #include <LUFA/Version.h> // Library Version Information
- #include <LUFA/Drivers/USB/USB.h> // USB Functionality
- #include <LUFA/Drivers/Board/LEDs.h> // LEDs driver
- #include <LUFA/Scheduler/Scheduler.h> // Simple scheduler for task management
+ #include <LUFA/Version.h>
+ #include <LUFA/Drivers/Board/LEDs.h>
+ #include <LUFA/Drivers/Board/Joystick.h>
+ #include <LUFA/Drivers/Peripheral/ADC.h>
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/Audio.h>
/* Macros: */
#if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER)
@@ -96,24 +98,19 @@
#define CSx0 CS10
#endif
- /* Enums: */
- /** Enum for the possible status codes for passing to the UpdateStatus() function. */
- enum AudioOutput_StatusCodes_t
- {
- Status_USBNotReady = 0, /**< USB is not ready (disconnected from a USB host) */
- Status_USBEnumerating = 1, /**< USB interface is enumerating */
- Status_USBReady = 2, /**< USB interface is connected and ready */
- };
-
- /* Task Definitions: */
- TASK(USB_Audio_Task);
-
+ /* Macros: */
+ #define LEDMASK_USB_NOTREADY LEDS_LED1
+ #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
+ #define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
+ #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
+
/* Function Prototypes: */
+ void SetupHardware(void);
+ void ProcessNextSample(void);
+
void EVENT_USB_Connect(void);
void EVENT_USB_Disconnect(void);
void EVENT_USB_ConfigurationChanged(void);
void EVENT_USB_UnhandledControlPacket(void);
-
- void UpdateStatus(uint8_t CurrentStatus);
#endif
diff --git a/Demos/Device/AudioOutput/makefile b/Demos/Device/AudioOutput/makefile
index 28f038f49..8ad1def4d 100644
--- a/Demos/Device/AudioOutput/makefile
+++ b/Demos/Device/AudioOutput/makefile
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
Descriptors.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 \
@@ -136,7 +135,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/Audio.c \
# List C++ source files here. (C dependencies are automatically generated.)
@@ -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
CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
-CDEFS += -DAUDIO_OUT_STEREO
+CDEFS += -DAUDIO_OUT_MONO
# Place -D or -U options here for ASM sources
ADEFS = -DF_CPU=$(F_CPU)
diff --git a/Demos/Device/CDC/CDC.c b/Demos/Device/CDC/CDC.c
index d7ebb9e6b..e6bc1a455 100644
--- a/Demos/Device/CDC/CDC.c
+++ b/Demos/Device/CDC/CDC.c
@@ -28,54 +28,42 @@
this software.
*/
-/** \file
- *
- * Main source file for the CDC demo. This file contains the main tasks of the demo and
- * is responsible for the initial application hardware configuration.
- */
-
#include "CDC.h"
-/* Scheduler Task List */
-TASK_LIST
-{
- { .Task = USB_USBTask , .TaskStatus = TASK_STOP },
- { .Task = CDC_Task , .TaskStatus = TASK_STOP },
-};
+USB_ClassInfo_CDC_t VirtualSerial_CDC_Interface =
+ {
+ .ControlInterfaceNumber = 0,
-/* Globals: */
-/** Contains the current baud rate and other settings of the virtual serial port. While this demo does not use
- * the physical USART and thus does not use these settings, they must still be retained and returned to the host
- * upon request or the host will assume the device is non-functional.
- *
- * These values are set by the host via a class-specific request, however they are not required to be used accurately.
- * It is possible to completely ignore these value or use other settings as the host is completely unaware of the physical
- * serial link characteristics and instead sends and receives data in endpoint streams.
- */
-CDC_Line_Coding_t LineCoding = { .BaudRateBPS = 9600,
- .CharFormat = OneStopBit,
- .ParityType = Parity_None,
- .DataBits = 8 };
+ .DataINEndpointNumber = CDC_TX_EPNUM,
+ .DataINEndpointSize = CDC_TXRX_EPSIZE,
-/** String to print through the virtual serial port when the joystick is pressed upwards. */
-char JoystickUpString[] = "Joystick Up\r\n";
+ .DataOUTEndpointNumber = CDC_RX_EPNUM,
+ .DataOUTEndpointSize = CDC_TXRX_EPSIZE,
-/** String to print through the virtual serial port when the joystick is pressed downward. */
-char JoystickDownString[] = "Joystick Down\r\n";
+ .NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
+ .NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
+ };
-/** String to print through the virtual serial port when the joystick is pressed left. */
-char JoystickLeftString[] = "Joystick Left\r\n";
+int main(void)
+{
+ SetupHardware();
+
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
-/** String to print through the virtual serial port when the joystick is pressed right. */
-char JoystickRightString[] = "Joystick Right\r\n";
+ for (;;)
+ {
+ CheckJoystickMovement();
+
+ uint16_t BytesToDiscard = USB_CDC_BytesReceived(&VirtualSerial_CDC_Interface);
+ while (BytesToDiscard--)
+ USB_CDC_ReceiveByte(&VirtualSerial_CDC_Interface);
-/** String to print through the virtual serial port when the joystick is pressed inwards. */
-char JoystickPressedString[] = "Joystick Pressed\r\n";
+ USB_CDC_USBTask(&VirtualSerial_CDC_Interface);
+ USB_USBTask();
+ }
+}
-/** Main program entry point. This routine configures the hardware required by the application, then
- * starts the scheduler to run the application tasks.
- */
-int main(void)
+void SetupHardware(void)
{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
@@ -87,235 +75,64 @@ int main(void)
/* Hardware Initialization */
Joystick_Init();
LEDs_Init();
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
-
- /* Initialize Scheduler so that it can be used */
- Scheduler_Init();
-
- /* Initialize USB Subsystem */
USB_Init();
-
- /* Scheduling - routine never returns, so put this last in the main function */
- Scheduler_Start();
-}
-
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
- * starts the library USB task to begin the enumeration and USB management process.
- */
-void EVENT_USB_Connect(void)
-{
- /* Start USB management task */
- Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
- /* Indicate USB enumerating */
- UpdateStatus(Status_USBEnumerating);
-}
-
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- * the status LEDs and stops the USB management and CDC management tasks.
- */
-void EVENT_USB_Disconnect(void)
-{
- /* Stop running CDC and USB management tasks */
- Scheduler_SetTaskMode(CDC_Task, TASK_STOP);
- Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
-}
-
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration
- * of the USB device after enumeration - the device endpoints are configured and the CDC management task started.
- */
-void EVENT_USB_ConfigurationChanged(void)
-{
- /* Setup CDC Notification, Rx and Tx Endpoints */
- Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,
- ENDPOINT_DIR_IN, CDC_NOTIFICATION_EPSIZE,
- ENDPOINT_BANK_SINGLE);
-
- Endpoint_ConfigureEndpoint(CDC_TX_EPNUM, EP_TYPE_BULK,
- ENDPOINT_DIR_IN, CDC_TXRX_EPSIZE,
- ENDPOINT_BANK_SINGLE);
-
- Endpoint_ConfigureEndpoint(CDC_RX_EPNUM, EP_TYPE_BULK,
- ENDPOINT_DIR_OUT, CDC_TXRX_EPSIZE,
- ENDPOINT_BANK_SINGLE);
-
- /* Indicate USB connected and ready */
- UpdateStatus(Status_USBReady);
-
- /* Start CDC task */
- Scheduler_SetTaskMode(CDC_Task, TASK_RUN);
-}
-
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- * control requests that are not handled internally by the USB library (including the CDC control commands,
- * which are all issued via the control endpoint), so that they can be handled appropriately for the application.
- */
-void EVENT_USB_UnhandledControlPacket(void)
-{
- uint8_t* LineCodingData = (uint8_t*)&LineCoding;
-
- /* Process CDC specific control requests */
- switch (USB_ControlRequest.bRequest)
- {
- case REQ_GetLineEncoding:
- if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- /* Acknowledge the SETUP packet, ready for data transfer */
- Endpoint_ClearSETUP();
-
- /* Write the line coding data to the control endpoint */
- Endpoint_Write_Control_Stream_LE(LineCodingData, sizeof(CDC_Line_Coding_t));
-
- /* Finalize the stream transfer to send the last packet or clear the host abort */
- Endpoint_ClearOUT();
- }
-
- break;
- case REQ_SetLineEncoding:
- if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- /* Acknowledge the SETUP packet, ready for data transfer */
- Endpoint_ClearSETUP();
-
- /* Read the line coding data in from the host into the global struct */
- Endpoint_Read_Control_Stream_LE(LineCodingData, sizeof(CDC_Line_Coding_t));
-
- /* Finalize the stream transfer to clear the last packet from the host */
- Endpoint_ClearIN();
- }
-
- break;
- case REQ_SetControlLineState:
- if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- /* Acknowledge the SETUP packet, ready for data transfer */
- Endpoint_ClearSETUP();
-
- /* NOTE: Here you can read in the line state mask from the host, to get the current state of the output handshake
- lines. The mask is read in from the wValue parameter in USB_ControlRequest, and can be masked against the
- CONTROL_LINE_OUT_* masks to determine the RTS and DTR line states using the following code:
- */
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsINReady()));
- Endpoint_ClearIN();
- }
-
- break;
- }
}
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- * log to a serial port, or anything else that is suitable for status updates.
- *
- * \param CurrentStatus Current status of the system, from the CDC_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
+void CheckJoystickMovement(void)
{
- uint8_t LEDMask = LEDS_NO_LEDS;
-
- /* Set the LED mask to the appropriate LED mask based on the given status code */
- switch (CurrentStatus)
- {
- case Status_USBNotReady:
- LEDMask = (LEDS_LED1);
- break;
- case Status_USBEnumerating:
- LEDMask = (LEDS_LED1 | LEDS_LED2);
- break;
- case Status_USBReady:
- LEDMask = (LEDS_LED2 | LEDS_LED4);
- break;
- }
+ uint8_t JoyStatus_LCL = Joystick_GetStatus();
+ char* ReportString = NULL;
+ static bool ActionSent = false;
- /* Set the board LEDs to the new LED mask */
- LEDs_SetAllLEDs(LEDMask);
-}
-
-/** Function to manage CDC data transmission and reception to and from the host. */
-TASK(CDC_Task)
-{
- char* ReportString = NULL;
- uint8_t JoyStatus_LCL = Joystick_GetStatus();
- static bool ActionSent = false;
-
-#if 0
- /* NOTE: Here you can use the notification endpoint to send back line state changes to the host, for the special RS-232
- handshake signal lines (and some error states), via the CONTROL_LINE_IN_* masks and the following code:
- */
- USB_Notification_Header_t Notification = (USB_Notification_Header_t)
+ char* JoystickStrings[] =
{
- .NotificationType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
- .Notification = NOTIF_SerialState,
- .wValue = 0,
- .wIndex = 0,
- .wLength = sizeof(uint16_t),
+ "Joystick Up\r\n",
+ "Joystick Down\r\n",
+ "Joystick Left\r\n",
+ "Joystick Right\r\n",
+ "Joystick Pressed\r\n",
};
-
- uint16_t LineStateMask;
-
- // Set LineStateMask here to a mask of CONTROL_LINE_IN_* masks to set the input handshake line states to send to the host
-
- Endpoint_SelectEndpoint(CDC_NOTIFICATION_EPNUM);
- Endpoint_Write_Stream_LE(&Notification, sizeof(Notification));
- Endpoint_Write_Stream_LE(&LineStateMask, sizeof(LineStateMask));
- Endpoint_ClearIN();
-#endif
- /* Determine if a joystick action has occurred */
if (JoyStatus_LCL & JOY_UP)
- ReportString = JoystickUpString;
+ ReportString = JoystickStrings[0];
else if (JoyStatus_LCL & JOY_DOWN)
- ReportString = JoystickDownString;
+ ReportString = JoystickStrings[1];
else if (JoyStatus_LCL & JOY_LEFT)
- ReportString = JoystickLeftString;
+ ReportString = JoystickStrings[2];
else if (JoyStatus_LCL & JOY_RIGHT)
- ReportString = JoystickRightString;
+ ReportString = JoystickStrings[3];
else if (JoyStatus_LCL & JOY_PRESS)
- ReportString = JoystickPressedString;
-
- /* Flag management - Only allow one string to be sent per action */
- if (ReportString == NULL)
- {
- ActionSent = false;
- }
- else if (ActionSent == false)
+ ReportString = JoystickStrings[4];
+ else
+ ActionSent = false;
+
+ if ((ReportString != NULL) && (ActionSent == false))
{
ActionSent = true;
+
+ USB_CDC_SendString(&VirtualSerial_CDC_Interface, ReportString, strlen(ReportString));
+ }
+}
- /* Select the Serial Tx Endpoint */
- Endpoint_SelectEndpoint(CDC_TX_EPNUM);
+void EVENT_USB_Connect(void)
+{
+ LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+}
- /* Write the String to the Endpoint */
- Endpoint_Write_Stream_LE(ReportString, strlen(ReportString));
-
- /* Remember if the packet to send completely fills the endpoint */
- bool IsFull = (Endpoint_BytesInEndpoint() == CDC_TXRX_EPSIZE);
+void EVENT_USB_Disconnect(void)
+{
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+}
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearIN();
+void EVENT_USB_ConfigurationChanged(void)
+{
+ LEDs_SetAllLEDs(LEDMASK_USB_READY);
- /* If the last packet filled the endpoint, send an empty packet to release the buffer on
- * the receiver (otherwise all data will be cached until a non-full packet is received) */
- if (IsFull)
- {
- /* Wait until the endpoint is ready for another packet */
- while (!(Endpoint_IsINReady()));
-
- /* Send an empty packet to ensure that the host does not buffer data sent to it */
- Endpoint_ClearIN();
- }
- }
+ if (!(USB_CDC_ConfigureEndpoints(&VirtualSerial_CDC_Interface)))
+ LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+}
- /* Select the Serial Rx Endpoint */
- Endpoint_SelectEndpoint(CDC_RX_EPNUM);
-
- /* Throw away any received data from the host */
- if (Endpoint_IsOUTReceived())
- Endpoint_ClearOUT();
+void EVENT_USB_UnhandledControlPacket(void)
+{
+ USB_CDC_ProcessControlPacket(&VirtualSerial_CDC_Interface);
}
diff --git a/Demos/Device/CDC/CDC.h b/Demos/Device/CDC/CDC.h
index 4c4ca74d5..b487813b0 100644
--- a/Demos/Device/CDC/CDC.h
+++ b/Demos/Device/CDC/CDC.h
@@ -44,139 +44,26 @@
#include "Descriptors.h"
- #include <LUFA/Version.h> // Library Version Information
- #include <LUFA/Drivers/USB/USB.h> // USB Functionality
- #include <LUFA/Drivers/Board/Joystick.h> // Joystick driver
- #include <LUFA/Drivers/Board/LEDs.h> // LEDs driver
- #include <LUFA/Scheduler/Scheduler.h> // Simple scheduler for task management
+ #include <LUFA/Version.h>
+ #include <LUFA/Drivers/Board/LEDs.h>
+ #include <LUFA/Drivers/Board/Joystick.h>
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/CDC.h>
/* Macros: */
- /** CDC Class specific request to get the current virtual serial port configuration settings. */
- #define REQ_GetLineEncoding 0x21
-
- /** CDC Class specific request to set the current virtual serial port configuration settings. */
- #define REQ_SetLineEncoding 0x20
-
- /** CDC Class specific request to set the current virtual serial port handshake line states. */
- #define REQ_SetControlLineState 0x22
-
- /** Notification type constant for a change in the virtual serial port handshake line states, for
- * use with a USB_Notification_Header_t notification structure when sent to the host via the CDC
- * notification endpoint.
- */
- #define NOTIF_SerialState 0x20
-
- /** Mask for the DTR handshake line for use with the REQ_SetControlLineState class specific request
- * from the host, to indicate that the DTR line state should be high.
- */
- #define CONTROL_LINE_OUT_DTR (1 << 0)
-
- /** Mask for the RTS handshake line for use with the REQ_SetControlLineState class specific request
- * from the host, to indicate that theRTS line state should be high.
- */
- #define CONTROL_LINE_OUT_RTS (1 << 1)
-
- /** Mask for the DCD handshake line for use with the a NOTIF_SerialState class specific notification
- * from the device to the host, to indicate that the DCD line state is currently high.
- */
- #define CONTROL_LINE_IN_DCD (1 << 0)
-
- /** Mask for the DSR handshake line for use with the a NOTIF_SerialState class specific notification
- * from the device to the host, to indicate that the DSR line state is currently high.
- */
- #define CONTROL_LINE_IN_DSR (1 << 1)
-
- /** Mask for the BREAK handshake line for use with the a NOTIF_SerialState class specific notification
- * from the device to the host, to indicate that the BREAK line state is currently high.
- */
- #define CONTROL_LINE_IN_BREAK (1 << 2)
-
- /** Mask for the RING handshake line for use with the a NOTIF_SerialState class specific notification
- * from the device to the host, to indicate that the RING line state is currently high.
- */
- #define CONTROL_LINE_IN_RING (1 << 3)
-
- /** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
- * to indicate that a framing error has occurred on the virtual serial port.
- */
- #define CONTROL_LINE_IN_FRAMEERROR (1 << 4)
-
- /** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
- * to indicate that a parity error has occurred on the virtual serial port.
- */
- #define CONTROL_LINE_IN_PARITYERROR (1 << 5)
-
- /** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
- * to indicate that a data overrun error has occurred on the virtual serial port.
- */
- #define CONTROL_LINE_IN_OVERRUNERROR (1 << 6)
-
- /* Type Defines: */
- /** Type define for the virtual serial port line encoding settings, for storing the current USART configuration
- * as set by the host via a class specific request.
- */
- typedef struct
- {
- uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */
- uint8_t CharFormat; /**< Character format of the virtual serial port, a value from the
- * CDCDevice_CDC_LineCodingFormats_t enum
- */
- uint8_t ParityType; /**< Parity setting of the virtual serial port, a value from the
- * CDCDevice_LineCodingParity_t enum
- */
- uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
- } CDC_Line_Coding_t;
-
- /** Type define for a CDC notification, sent to the host via the CDC notification endpoint to indicate a
- * change in the device state asynchronously.
- */
- typedef struct
- {
- uint8_t NotificationType; /**< Notification type, a mask of REQDIR_*, REQTYPE_* and REQREC_* constants
- * from the library StdRequestType.h header
- */
- uint8_t Notification; /**< Notification value, a NOTIF_* constant */
- uint16_t wValue; /**< Notification wValue, notification-specific */
- uint16_t wIndex; /**< Notification wIndex, notification-specific */
- uint16_t wLength; /**< Notification wLength, notification-specific */
- } USB_Notification_Header_t;
-
- /* Enums: */
- /** Enum for the possible line encoding formats of a virtual serial port. */
- enum CDCDevice_CDC_LineCodingFormats_t
- {
- OneStopBit = 0, /**< Each frame contains one stop bit */
- OneAndAHalfStopBits = 1, /**< Each frame contains one and a half stop bits */
- TwoStopBits = 2, /**< Each frame contains two stop bits */
- };
+ #define LEDMASK_USB_NOTREADY LEDS_LED1
+ #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
+ #define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
+ #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
- /** Enum for the possible line encoding parity settings of a virtual serial port. */
- enum CDCDevice_LineCodingParity_t
- {
- Parity_None = 0, /**< No parity bit mode on each frame */
- Parity_Odd = 1, /**< Odd parity bit mode on each frame */
- Parity_Even = 2, /**< Even parity bit mode on each frame */
- Parity_Mark = 3, /**< Mark parity bit mode on each frame */
- Parity_Space = 4, /**< Space parity bit mode on each frame */
- };
-
- /** Enum for the possible status codes for passing to the UpdateStatus() function. */
- enum CDC_StatusCodes_t
- {
- Status_USBNotReady = 0, /**< USB is not ready (disconnected from a USB host) */
- Status_USBEnumerating = 1, /**< USB interface is enumerating */
- Status_USBReady = 2, /**< USB interface is connected and ready */
- };
-
- /* Tasks: */
- TASK(CDC_Task);
-
/* Function Prototypes: */
+ void SetupHardware(void);
+ void CheckJoystickMovement(void);
+
void EVENT_USB_Connect(void);
void EVENT_USB_Disconnect(void);
void EVENT_USB_ConfigurationChanged(void);
void EVENT_USB_UnhandledControlPacket(void);
-
- void UpdateStatus(uint8_t CurrentStatus);
+ void EVENT_USB_StartOfFrame(void);
#endif
diff --git a/Demos/Device/CDC/Descriptors.h b/Demos/Device/CDC/Descriptors.h
index 41b44300a..1a9dbb5bf 100644
--- a/Demos/Device/CDC/Descriptors.h
+++ b/Demos/Device/CDC/Descriptors.h
@@ -37,26 +37,12 @@
#define _DESCRIPTORS_H_
/* Includes: */
- #include <LUFA/Drivers/USB/USB.h>
-
#include <avr/pgmspace.h>
- /* Macros: */
- /** Macro to define a CDC class-specific functional descriptor. CDC functional descriptors have a
- * uniform structure but variable sized data payloads, thus cannot be represented accurately by
- * a single typedef struct. A macro is used instead so that functional descriptors can be created
- * easily by specifying the size of the payload. This allows sizeof() to work correctly.
- *
- * \param DataSize Size in bytes of the CDC functional descriptor's data payload
- */
- #define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \
- struct \
- { \
- USB_Descriptor_Header_t Header; \
- uint8_t SubType; \
- uint8_t Data[DataSize]; \
- }
-
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/CDC.h>
+
+ /* Macros: */
/** Endpoint number of the CDC device-to-host notification IN endpoint. */
#define CDC_NOTIFICATION_EPNUM 2
diff --git a/Demos/Device/CDC/makefile b/Demos/Device/CDC/makefile
index bc22be5c0..bd4ff36b9 100644
--- a/Demos/Device/CDC/makefile
+++ b/Demos/Device/CDC/makefile
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
Descriptors.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 \
@@ -136,7 +135,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/CDC.c \
# List C++ source files here. (C dependencies are automatically generated.)
@@ -183,7 +182,7 @@ CSTANDARD = -std=gnu99
# Place -D or -U options here for C sources
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
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
diff --git a/Demos/Device/DualCDC/Descriptors.h b/Demos/Device/DualCDC/Descriptors.h
index 2c2311b9c..97165e5de 100644
--- a/Demos/Device/DualCDC/Descriptors.h
+++ b/Demos/Device/DualCDC/Descriptors.h
@@ -37,26 +37,12 @@
#define _DESCRIPTORS_H_
/* Includes: */
- #include <LUFA/Drivers/USB/USB.h>
-
#include <avr/pgmspace.h>
- /* Macros: */
- /** Macro to define a CDC class-specific functional descriptor. CDC functional descriptors have a
- * uniform structure but variable sized data payloads, thus cannot be represented accurately by
- * a single typedef struct. A macro is used instead so that functional descriptors can be created
- * easily by specifying the size of the payload. This allows sizeof() to work correctly.
- *
- * \param DataSize Size in bytes of the CDC functional descriptor's data payload
- */
- #define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \
- struct \
- { \
- USB_Descriptor_Header_t Header; \
- uint8_t SubType; \
- uint8_t Data[DataSize]; \
- }
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/CDC.h>
+ /* Macros: */
/** Endpoint number of the first CDC interface's device-to-host notification IN endpoint. */
#define CDC1_NOTIFICATION_EPNUM 3
diff --git a/Demos/Device/DualCDC/DualCDC.c b/Demos/Device/DualCDC/DualCDC.c
index 34d772ff0..26947f433 100644
--- a/Demos/Device/DualCDC/DualCDC.c
+++ b/Demos/Device/DualCDC/DualCDC.c
@@ -27,70 +27,63 @@
arising out of or in connection with the use or performance of
this software.
*/
-
-/** \file
- *
- * Main source file for the DualCDC demo. This file contains the main tasks of the demo and
- * is responsible for the initial application hardware configuration.
- */
#include "DualCDC.h"
-/* Scheduler Task List */
-TASK_LIST
-{
- { .Task = USB_USBTask , .TaskStatus = TASK_STOP },
- { .Task = CDC1_Task , .TaskStatus = TASK_STOP },
- { .Task = CDC2_Task , .TaskStatus = TASK_STOP },
-};
+USB_ClassInfo_CDC_t VirtualSerial1_CDC_Interface =
+ {
+ .ControlInterfaceNumber = 0,
-/* Globals: */
-/** Contains the current baud rate and other settings of the first virtual serial port. While this demo does not use
- * the physical USART and thus does not use these settings, they must still be retained and returned to the host
- * upon request or the host will assume the device is non-functional.
- *
- * These values are set by the host via a class-specific request, however they are not required to be used accurately.
- * It is possible to completely ignore these value or use other settings as the host is completely unaware of the physical
- * serial link characteristics and instead sends and receives data in endpoint streams.
- */
-CDC_Line_Coding_t LineCoding1 = { .BaudRateBPS = 9600,
- .CharFormat = OneStopBit,
- .ParityType = Parity_None,
- .DataBits = 8 };
+ .DataINEndpointNumber = CDC1_TX_EPNUM,
+ .DataINEndpointSize = CDC_TXRX_EPSIZE,
-/** Contains the current baud rate and other settings of the second virtual serial port. While this demo does not use
- * the physical USART and thus does not use these settings, they must still be retained and returned to the host
- * upon request or the host will assume the device is non-functional.
- *
- * These values are set by the host via a class-specific request, however they are not required to be used accurately.
- * It is possible to completely ignore these value or use other settings as the host is completely unaware of the physical
- * serial link characteristics and instead sends and receives data in endpoint streams.
- */
-CDC_Line_Coding_t LineCoding2 = { .BaudRateBPS = 9600,
- .CharFormat = OneStopBit,
- .ParityType = Parity_None,
- .DataBits = 8 };
-
-/** String to print through the first virtual serial port when the joystick is pressed upwards. */
-char JoystickUpString[] = "Joystick Up\r\n";
+ .DataOUTEndpointNumber = CDC1_RX_EPNUM,
+ .DataOUTEndpointSize = CDC_TXRX_EPSIZE,
-/** String to print through the first virtual serial port when the joystick is pressed downward. */
-char JoystickDownString[] = "Joystick Down\r\n";
+ .NotificationEndpointNumber = CDC1_NOTIFICATION_EPNUM,
+ .NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
+ };
+
+USB_ClassInfo_CDC_t VirtualSerial2_CDC_Interface =
+ {
+ .ControlInterfaceNumber = 0,
-/** String to print through the first virtual serial port when the joystick is pressed left. */
-char JoystickLeftString[] = "Joystick Left\r\n";
+ .DataINEndpointNumber = CDC2_TX_EPNUM,
+ .DataINEndpointSize = CDC_TXRX_EPSIZE,
-/** String to print through the first virtual serial port when the joystick is pressed right. */
-char JoystickRightString[] = "Joystick Right\r\n";
+ .DataOUTEndpointNumber = CDC2_RX_EPNUM,
+ .DataOUTEndpointSize = CDC_TXRX_EPSIZE,
-/** String to print through the first virtual serial port when the joystick is pressed inwards. */
-char JoystickPressedString[] = "Joystick Pressed\r\n";
+ .NotificationEndpointNumber = CDC2_NOTIFICATION_EPNUM,
+ .NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
+ };
-/** Main program entry point. This routine configures the hardware required by the application, then
- * starts the scheduler to run the application tasks.
- */
int main(void)
{
+ SetupHardware();
+
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+
+ for (;;)
+ {
+ CheckJoystickMovement();
+
+ uint16_t BytesToDiscard = USB_CDC_BytesReceived(&VirtualSerial1_CDC_Interface);
+ while (BytesToDiscard--)
+ USB_CDC_ReceiveByte(&VirtualSerial1_CDC_Interface);
+
+ uint16_t BytesToEcho = USB_CDC_BytesReceived(&VirtualSerial2_CDC_Interface);
+ while (BytesToEcho--)
+ USB_CDC_SendByte(&VirtualSerial2_CDC_Interface, USB_CDC_ReceiveByte(&VirtualSerial2_CDC_Interface));
+
+ USB_CDC_USBTask(&VirtualSerial1_CDC_Interface);
+ USB_CDC_USBTask(&VirtualSerial2_CDC_Interface);
+ USB_USBTask();
+ }
+}
+
+void SetupHardware(void)
+{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
wdt_disable();
@@ -101,257 +94,68 @@ int main(void)
/* Hardware Initialization */
Joystick_Init();
LEDs_Init();
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
-
- /* Initialize Scheduler so that it can be used */
- Scheduler_Init();
-
- /* Initialize USB Subsystem */
USB_Init();
-
- /* Scheduling - routine never returns, so put this last in the main function */
- Scheduler_Start();
-}
-
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
- * starts the library USB task to begin the enumeration and USB management process.
- */
-void EVENT_USB_Connect(void)
-{
- /* Start USB management task */
- Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
- /* Indicate USB enumerating */
- UpdateStatus(Status_USBEnumerating);
-}
-
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- * the status LEDs and stops the USB management and CDC management tasks.
- */
-void EVENT_USB_Disconnect(void)
-{
- /* Stop running CDC and USB management tasks */
- Scheduler_SetTaskMode(CDC1_Task, TASK_STOP);
- Scheduler_SetTaskMode(CDC2_Task, TASK_STOP);
- Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
-}
-
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration
- * of the USB device after enumeration - the device endpoints are configured and the CDC management tasks are started.
- */
-void EVENT_USB_ConfigurationChanged(void)
-{
- /* Setup CDC Notification, Rx and Tx Endpoints for the first CDC */
- Endpoint_ConfigureEndpoint(CDC1_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,
- ENDPOINT_DIR_IN, CDC_NOTIFICATION_EPSIZE,
- ENDPOINT_BANK_SINGLE);
-
- Endpoint_ConfigureEndpoint(CDC1_TX_EPNUM, EP_TYPE_BULK,
- ENDPOINT_DIR_IN, CDC_TXRX_EPSIZE,
- ENDPOINT_BANK_SINGLE);
-
- Endpoint_ConfigureEndpoint(CDC1_RX_EPNUM, EP_TYPE_BULK,
- ENDPOINT_DIR_OUT, CDC_TXRX_EPSIZE,
- ENDPOINT_BANK_SINGLE);
-
- /* Setup CDC Notification, Rx and Tx Endpoints for the second CDC */
- Endpoint_ConfigureEndpoint(CDC2_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,
- ENDPOINT_DIR_IN, CDC_NOTIFICATION_EPSIZE,
- ENDPOINT_BANK_SINGLE);
-
- Endpoint_ConfigureEndpoint(CDC2_TX_EPNUM, EP_TYPE_BULK,
- ENDPOINT_DIR_IN, CDC_TXRX_EPSIZE,
- ENDPOINT_BANK_SINGLE);
-
- Endpoint_ConfigureEndpoint(CDC2_RX_EPNUM, EP_TYPE_BULK,
- ENDPOINT_DIR_OUT, CDC_TXRX_EPSIZE,
- ENDPOINT_BANK_SINGLE);
-
- /* Indicate USB connected and ready */
- UpdateStatus(Status_USBReady);
-
- /* Start CDC tasks */
- Scheduler_SetTaskMode(CDC1_Task, TASK_RUN);
- Scheduler_SetTaskMode(CDC2_Task, TASK_RUN);
-}
-
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- * control requests that are not handled internally by the USB library (including the CDC control commands,
- * which are all issued via the control endpoint), so that they can be handled appropriately for the application.
- */
-void EVENT_USB_UnhandledControlPacket(void)
-{
- /* Determine which interface's Line Coding data is being set from the wIndex parameter */
- uint8_t* LineCodingData = (USB_ControlRequest.wIndex == 0) ? (uint8_t*)&LineCoding1 : (uint8_t*)&LineCoding2;
-
- /* Process CDC specific control requests */
- switch (USB_ControlRequest.bRequest)
- {
- case REQ_GetLineEncoding:
- if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- /* Acknowledge the SETUP packet, ready for data transfer */
- Endpoint_ClearSETUP();
-
- /* Write the line coding data to the control endpoint */
- Endpoint_Write_Control_Stream_LE(LineCodingData, sizeof(CDC_Line_Coding_t));
-
- /* Finalize the stream transfer to send the last packet or clear the host abort */
- Endpoint_ClearOUT();
- }
-
- break;
- case REQ_SetLineEncoding:
- if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- /* Acknowledge the SETUP packet, ready for data transfer */
- Endpoint_ClearSETUP();
-
- /* Read the line coding data in from the host into the global struct */
- Endpoint_Read_Control_Stream_LE(LineCodingData, sizeof(CDC_Line_Coding_t));
-
- /* Finalize the stream transfer to clear the last packet from the host */
- Endpoint_ClearIN();
- }
-
- break;
- case REQ_SetControlLineState:
- if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- /* Acknowledge the SETUP packet, ready for data transfer */
- Endpoint_ClearSETUP();
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsINReady()));
- Endpoint_ClearIN();
- }
-
- break;
- }
-}
-
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- * log to a serial port, or anything else that is suitable for status updates.
- *
- * \param CurrentStatus Current status of the system, from the DualCDC_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
-{
- uint8_t LEDMask = LEDS_NO_LEDS;
-
- /* Set the LED mask to the appropriate LED mask based on the given status code */
- switch (CurrentStatus)
- {
- case Status_USBNotReady:
- LEDMask = (LEDS_LED1);
- break;
- case Status_USBEnumerating:
- LEDMask = (LEDS_LED1 | LEDS_LED2);
- break;
- case Status_USBReady:
- LEDMask = (LEDS_LED2 | LEDS_LED4);
- break;
- }
-
- /* Set the board LEDs to the new LED mask */
- LEDs_SetAllLEDs(LEDMask);
}
-/** Function to manage CDC data transmission and reception to and from the host for the first CDC interface, which sends joystick
- * movements to the host as ASCII strings.
- */
-TASK(CDC1_Task)
+void CheckJoystickMovement(void)
{
- char* ReportString = NULL;
- uint8_t JoyStatus_LCL = Joystick_GetStatus();
- static bool ActionSent = false;
+ uint8_t JoyStatus_LCL = Joystick_GetStatus();
+ char* ReportString = NULL;
+ static bool ActionSent = false;
+
+ char* JoystickStrings[] =
+ {
+ "Joystick Up\r\n",
+ "Joystick Down\r\n",
+ "Joystick Left\r\n",
+ "Joystick Right\r\n",
+ "Joystick Pressed\r\n",
+ };
- /* Determine if a joystick action has occurred */
if (JoyStatus_LCL & JOY_UP)
- ReportString = JoystickUpString;
+ ReportString = JoystickStrings[0];
else if (JoyStatus_LCL & JOY_DOWN)
- ReportString = JoystickDownString;
+ ReportString = JoystickStrings[1];
else if (JoyStatus_LCL & JOY_LEFT)
- ReportString = JoystickLeftString;
+ ReportString = JoystickStrings[2];
else if (JoyStatus_LCL & JOY_RIGHT)
- ReportString = JoystickRightString;
+ ReportString = JoystickStrings[3];
else if (JoyStatus_LCL & JOY_PRESS)
- ReportString = JoystickPressedString;
-
- /* Flag management - Only allow one string to be sent per action */
- if (ReportString == NULL)
- {
- ActionSent = false;
- }
- else if (ActionSent == false)
+ ReportString = JoystickStrings[4];
+ else
+ ActionSent = false;
+
+ if ((ReportString != NULL) && (ActionSent == false))
{
ActionSent = true;
- /* Select the Serial Tx Endpoint */
- Endpoint_SelectEndpoint(CDC1_TX_EPNUM);
-
- /* Write the String to the Endpoint */
- Endpoint_Write_Stream_LE(ReportString, strlen(ReportString));
-
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearIN();
-
- /* Wait until the endpoint is ready for another packet */
- while (!(Endpoint_IsINReady()));
-
- /* Send an empty packet to ensure that the host does not buffer data sent to it */
- Endpoint_ClearIN();
+ USB_CDC_SendString(&VirtualSerial1_CDC_Interface, ReportString, strlen(ReportString));
}
-
- /* Select the Serial Rx Endpoint */
- Endpoint_SelectEndpoint(CDC1_RX_EPNUM);
-
- /* Throw away any received data from the host */
- if (Endpoint_IsOUTReceived())
- Endpoint_ClearOUT();
}
-/** Function to manage CDC data transmission and reception to and from the host for the second CDC interface, which echoes back
- * all data sent to it from the host.
- */
-TASK(CDC2_Task)
+void EVENT_USB_Connect(void)
{
- /* Select the Serial Rx Endpoint */
- Endpoint_SelectEndpoint(CDC2_RX_EPNUM);
-
- /* Check to see if any data has been received */
- if (Endpoint_IsOUTReceived())
- {
- /* Create a temp buffer big enough to hold the incoming endpoint packet */
- uint8_t Buffer[Endpoint_BytesInEndpoint()];
-
- /* Remember how large the incoming packet is */
- uint16_t DataLength = Endpoint_BytesInEndpoint();
-
- /* Read in the incoming packet into the buffer */
- Endpoint_Read_Stream_LE(&Buffer, DataLength);
+ LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+}
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearOUT();
+void EVENT_USB_Disconnect(void)
+{
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+}
- /* Select the Serial Tx Endpoint */
- Endpoint_SelectEndpoint(CDC2_TX_EPNUM);
-
- /* Write the received data to the endpoint */
- Endpoint_Write_Stream_LE(&Buffer, DataLength);
+void EVENT_USB_ConfigurationChanged(void)
+{
+ LEDs_SetAllLEDs(LEDMASK_USB_READY);
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearIN();
+ if (!(USB_CDC_ConfigureEndpoints(&VirtualSerial1_CDC_Interface)))
+ LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
- /* Wait until the endpoint is ready for the next packet */
- while (!(Endpoint_IsINReady()));
+ if (!(USB_CDC_ConfigureEndpoints(&VirtualSerial2_CDC_Interface)))
+ LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+}
- /* Send an empty packet to prevent host buffering */
- Endpoint_ClearIN();
- }
+void EVENT_USB_UnhandledControlPacket(void)
+{
+ USB_CDC_ProcessControlPacket(&VirtualSerial1_CDC_Interface);
+ USB_CDC_ProcessControlPacket(&VirtualSerial2_CDC_Interface);
}
diff --git a/Demos/Device/DualCDC/DualCDC.h b/Demos/Device/DualCDC/DualCDC.h
index 117af601e..3c1e29612 100644
--- a/Demos/Device/DualCDC/DualCDC.h
+++ b/Demos/Device/DualCDC/DualCDC.h
@@ -44,75 +44,26 @@
#include "Descriptors.h"
- #include <LUFA/Version.h> // Library Version Information
- #include <LUFA/Drivers/USB/USB.h> // USB Functionality
- #include <LUFA/Drivers/Board/Joystick.h> // Joystick driver
- #include <LUFA/Drivers/Board/LEDs.h> // LEDs driver
- #include <LUFA/Scheduler/Scheduler.h> // Simple scheduler for task management
+ #include <LUFA/Version.h>
+ #include <LUFA/Drivers/Board/LEDs.h>
+ #include <LUFA/Drivers/Board/Joystick.h>
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/CDC.h>
/* Macros: */
- /** CDC Class specific request to get the current virtual serial port configuration settings. */
- #define REQ_GetLineEncoding 0x21
-
- /** CDC Class specific request to set the current virtual serial port configuration settings. */
- #define REQ_SetLineEncoding 0x20
-
- /** CDC Class specific request to set the current virtual serial port handshake line states. */
- #define REQ_SetControlLineState 0x22
-
- /* Type Defines: */
- /** Type define for the virtual serial port line encoding settings, for storing the current USART configuration
- * as set by the host via a class specific request.
- */
- typedef struct
- {
- uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */
- uint8_t CharFormat; /**< Character format of the virtual serial port, a value from the
- * CDCDevice_CDC_LineCodingFormats_t enum
- */
- uint8_t ParityType; /**< Parity setting of the virtual serial port, a value from the
- * CDCDevice_LineCodingParity_t enum
- */
- uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
- } CDC_Line_Coding_t;
+ #define LEDMASK_USB_NOTREADY LEDS_LED1
+ #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
+ #define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
+ #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
- /* Enums: */
- /** Enum for the possible line encoding formats of a virtual serial port. */
- enum CDCDevice_CDC_LineCodingFormats_t
- {
- OneStopBit = 0, /**< Each frame contains one stop bit */
- OneAndAHalfStopBits = 1, /**< Each frame contains one and a half stop bits */
- TwoStopBits = 2, /**< Each frame contains two stop bits */
- };
-
- /** Enum for the possible line encoding parity settings of a virtual serial port. */
- enum CDCDevice_LineCodingParity_t
- {
- Parity_None = 0, /**< No parity bit mode on each frame */
- Parity_Odd = 1, /**< Odd parity bit mode on each frame */
- Parity_Even = 2, /**< Even parity bit mode on each frame */
- Parity_Mark = 3, /**< Mark parity bit mode on each frame */
- Parity_Space = 4, /**< Space parity bit mode on each frame */
- };
-
- /** Enum for the possible status codes for passing to the UpdateStatus() function. */
- enum DualCDC_StatusCodes_t
- {
- Status_USBNotReady = 0, /**< USB is not ready (disconnected from a USB host) */
- Status_USBEnumerating = 1, /**< USB interface is enumerating */
- Status_USBReady = 2, /**< USB interface is connected and ready */
- };
-
- /* Tasks: */
- TASK(CDC1_Task);
- TASK(CDC2_Task);
-
/* Function Prototypes: */
+ void SetupHardware(void);
+ void CheckJoystickMovement(void);
+
void EVENT_USB_Connect(void);
void EVENT_USB_Disconnect(void);
void EVENT_USB_ConfigurationChanged(void);
void EVENT_USB_UnhandledControlPacket(void);
-
- void UpdateStatus(uint8_t CurrentStatus);
+ void EVENT_USB_StartOfFrame(void);
#endif
diff --git a/Demos/Device/DualCDC/makefile b/Demos/Device/DualCDC/makefile
index 06d0e184b..5fbda61dd 100644
--- a/Demos/Device/DualCDC/makefile
+++ b/Demos/Device/DualCDC/makefile
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
Descriptors.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 \
@@ -136,7 +135,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/CDC.c \
# List C++ source files here. (C dependencies are automatically generated.)
@@ -183,7 +182,7 @@ CSTANDARD = -std=gnu99
# Place -D or -U options here for C sources
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
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
diff --git a/Demos/Device/GenericHID/Descriptors.h b/Demos/Device/GenericHID/Descriptors.h
index 023687032..bc4c68ae6 100644
--- a/Demos/Device/GenericHID/Descriptors.h
+++ b/Demos/Device/GenericHID/Descriptors.h
@@ -37,30 +37,12 @@
#define _DESCRIPTORS_H_
/* Includes: */
- #include <LUFA/Drivers/USB/USB.h>
-
#include <avr/pgmspace.h>
- /* Type Defines: */
- /** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID
- * specification for details on the structure elements.
- */
- typedef struct
- {
- USB_Descriptor_Header_t Header;
-
- uint16_t HIDSpec;
- uint8_t CountryCode;
-
- uint8_t TotalReportDescriptors;
-
- uint8_t HIDReportType;
- uint16_t HIDReportLength;
- } USB_Descriptor_HID_t;
-
- /** Type define for the data type used to store HID report descriptor elements. */
- typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/HID.h>
+ /** Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host.
@@ -73,7 +55,7 @@
USB_Descriptor_Endpoint_t GenericINEndpoint;
USB_Descriptor_Endpoint_t GenericOUTEndpoint;
} USB_Descriptor_Configuration_t;
-
+
/* Macros: */
/** Endpoint number of the Generic HID reporting IN endpoint. */
#define GENERIC_IN_EPNUM 1
@@ -86,13 +68,7 @@
/** Size in bytes of the Generic HID reports (including report ID byte). */
#define GENERIC_REPORT_SIZE 8
-
- /** Descriptor header type value, to indicate a HID class HID descriptor. */
- #define DTYPE_HID 0x21
- /** Descriptor header type value, to indicate a HID class HID report descriptor. */
- #define DTYPE_Report 0x22
-
/* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
diff --git a/Demos/Device/GenericHID/GenericHID.c b/Demos/Device/GenericHID/GenericHID.c
index 058d269fe..4dfb8e455 100644
--- a/Demos/Device/GenericHID/GenericHID.c
+++ b/Demos/Device/GenericHID/GenericHID.c
@@ -28,30 +28,38 @@
this software.
*/
-/** \file
- *
- * Main source file for the GenericHID demo. This file contains the main tasks of the demo and
- * is responsible for the initial application hardware configuration.
- */
-
#include "GenericHID.h"
-/* Scheduler Task List */
-TASK_LIST
-{
- { .Task = USB_USBTask , .TaskStatus = TASK_STOP },
- { .Task = USB_HID_Report , .TaskStatus = TASK_STOP },
-};
+USB_ClassInfo_HID_t Generic_HID_Interface =
+ {
+ .InterfaceNumber = 0,
-/** Static buffer to hold the last received report from the host, so that it can be echoed back in the next sent report */
-static uint8_t LastReceived[GENERIC_REPORT_SIZE];
+ .ReportINEndpointNumber = GENERIC_IN_EPNUM,
+ .ReportINEndpointSize = GENERIC_EPSIZE,
+
+ .ReportOUTEndpointNumber = GENERIC_OUT_EPNUM,
+ .ReportOUTEndpointSize = GENERIC_EPSIZE,
+
+ .ReportBufferSize = GENERIC_REPORT_SIZE,
+ .UsingReportProtocol = true,
+ };
-/** Main program entry point. This routine configures the hardware required by the application, then
- * starts the scheduler to run the USB management task.
- */
int main(void)
{
+ SetupHardware();
+
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+
+ for (;;)
+ {
+ USB_HID_USBTask(&Generic_HID_Interface);
+ USB_USBTask();
+ }
+}
+
+void SetupHardware(void)
+{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
wdt_disable();
@@ -61,220 +69,45 @@ int main(void)
/* Hardware Initialization */
LEDs_Init();
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
-
- /* Initialize Scheduler so that it can be used */
- Scheduler_Init();
-
- /* Initialize USB Subsystem */
USB_Init();
-
- /* Scheduling - routine never returns, so put this last in the main function */
- Scheduler_Start();
}
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
- * starts the library USB task to begin the enumeration and USB management process.
- */
void EVENT_USB_Connect(void)
{
- /* Start USB management task */
- Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
- /* Indicate USB enumerating */
- UpdateStatus(Status_USBEnumerating);
+ LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- * the status LEDs and stops the USB management task.
- */
void EVENT_USB_Disconnect(void)
{
- /* Stop running HID reporting and USB management tasks */
- Scheduler_SetTaskMode(USB_HID_Report, TASK_STOP);
- Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host sets the current configuration
- * of the USB device after enumeration, and configures the generic HID device endpoints.
- */
void EVENT_USB_ConfigurationChanged(void)
{
- /* Setup Generic IN Report Endpoint */
- Endpoint_ConfigureEndpoint(GENERIC_IN_EPNUM, EP_TYPE_INTERRUPT,
- ENDPOINT_DIR_IN, GENERIC_EPSIZE,
- ENDPOINT_BANK_SINGLE);
+ LEDs_SetAllLEDs(LEDMASK_USB_READY);
- /* Setup Generic OUT Report Endpoint */
- Endpoint_ConfigureEndpoint(GENERIC_OUT_EPNUM, EP_TYPE_INTERRUPT,
- ENDPOINT_DIR_OUT, GENERIC_EPSIZE,
- ENDPOINT_BANK_SINGLE);
-
- /* Indicate USB connected and ready */
- UpdateStatus(Status_USBReady);
+ if (!(USB_HID_ConfigureEndpoints(&Generic_HID_Interface)))
+ LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- * control requests that are not handled internally by the USB library (including the HID commands, which are
- * all issued via the control endpoint), so that they can be handled appropriately for the application.
- */
void EVENT_USB_UnhandledControlPacket(void)
{
- /* Handle HID Class specific requests */
- switch (USB_ControlRequest.bRequest)
- {
- case REQ_GetReport:
- if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- uint8_t GenericData[GENERIC_REPORT_SIZE];
-
- Endpoint_ClearSETUP();
-
- CreateGenericHIDReport(GenericData);
-
- /* Write the report data to the control endpoint */
- Endpoint_Write_Control_Stream_LE(&GenericData, sizeof(GenericData));
-
- /* Finalize the stream transfer to send the last packet or clear the host abort */
- Endpoint_ClearOUT();
- }
-
- break;
- case REQ_SetReport:
- if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- uint8_t GenericData[GENERIC_REPORT_SIZE];
-
- Endpoint_ClearSETUP();
-
- /* Wait until the generic report has been sent by the host */
- while (!(Endpoint_IsOUTReceived()));
-
- Endpoint_Read_Control_Stream_LE(&GenericData, sizeof(GenericData));
-
- ProcessGenericHIDReport(GenericData);
-
- /* Clear the endpoint data */
- Endpoint_ClearOUT();
-
- /* Wait until the host is ready to receive the request confirmation */
- while (!(Endpoint_IsINReady()));
-
- /* Handshake the request by sending an empty IN packet */
- Endpoint_ClearIN();
- }
-
- break;
- }
+ USB_HID_ProcessControlPacket(&Generic_HID_Interface);
}
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- * log to a serial port, or anything else that is suitable for status updates.
- *
- * \param CurrentStatus Current status of the system, from the GenericHID_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
+void EVENT_USB_StartOfFrame(void)
{
- uint8_t LEDMask = LEDS_NO_LEDS;
-
- /* Set the LED mask to the appropriate LED mask based on the given status code */
- switch (CurrentStatus)
- {
- case Status_USBNotReady:
- LEDMask = (LEDS_LED1);
- break;
- case Status_USBEnumerating:
- LEDMask = (LEDS_LED1 | LEDS_LED2);
- break;
- case Status_USBReady:
- LEDMask = (LEDS_LED2 | LEDS_LED4);
- break;
- }
-
- /* Set the board LEDs to the new LED mask */
- LEDs_SetAllLEDs(LEDMask);
+ USB_HID_RegisterStartOfFrame(&Generic_HID_Interface);
}
-/** Function to process the lest received report from the host.
- *
- * \param DataArray Pointer to a buffer where the last report data is stored
- */
-void ProcessGenericHIDReport(uint8_t* DataArray)
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)
{
- /*
- This is where you need to process the reports being sent from the host to the device.
- DataArray is an array holding the last report from the host. This function is called
- each time the host has sent a report to the device.
- */
+ // Create generic HID report here
- for (uint8_t i = 0; i < GENERIC_REPORT_SIZE; i++)
- LastReceived[i] = DataArray[i];
+ return 0;
}
-/** Function to create the next report to send back to the host at the next reporting interval.
- *
- * \param DataArray Pointer to a buffer where the next report data should be stored
- */
-void CreateGenericHIDReport(uint8_t* DataArray)
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)
{
- /*
- This is where you need to create reports to be sent to the host from the device. This
- function is called each time the host is ready to accept a new report. DataArray is
- an array to hold the report to the host.
- */
-
- for (uint8_t i = 0; i < GENERIC_REPORT_SIZE; i++)
- DataArray[i] = LastReceived[i];
-}
-
-TASK(USB_HID_Report)
-{
- /* Check if the USB system is connected to a host */
- if (USB_IsConnected)
- {
- Endpoint_SelectEndpoint(GENERIC_OUT_EPNUM);
-
- /* Check to see if a packet has been sent from the host */
- if (Endpoint_IsOUTReceived())
- {
- /* Check to see if the packet contains data */
- if (Endpoint_IsReadWriteAllowed())
- {
- /* Create a temporary buffer to hold the read in report from the host */
- uint8_t GenericData[GENERIC_REPORT_SIZE];
-
- /* Read Generic Report Data */
- Endpoint_Read_Stream_LE(&GenericData, sizeof(GenericData));
-
- /* Process Generic Report Data */
- ProcessGenericHIDReport(GenericData);
- }
-
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearOUT();
- }
-
- Endpoint_SelectEndpoint(GENERIC_IN_EPNUM);
-
- /* Check to see if the host is ready to accept another packet */
- if (Endpoint_IsINReady())
- {
- /* Create a temporary buffer to hold the report to send to the host */
- uint8_t GenericData[GENERIC_REPORT_SIZE];
-
- /* Create Generic Report Data */
- CreateGenericHIDReport(GenericData);
-
- /* Write Generic Report Data */
- Endpoint_Write_Stream_LE(&GenericData, sizeof(GenericData));
-
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearIN();
- }
- }
+ // Process received generic HID report here
}
diff --git a/Demos/Device/GenericHID/GenericHID.h b/Demos/Device/GenericHID/GenericHID.h
index 30354b756..27426431c 100644
--- a/Demos/Device/GenericHID/GenericHID.h
+++ b/Demos/Device/GenericHID/GenericHID.h
@@ -46,38 +46,28 @@
#include "Descriptors.h"
- #include <LUFA/Version.h> // Library Version Information
- #include <LUFA/Scheduler/Scheduler.h> // Simple scheduler for task management
- #include <LUFA/Drivers/USB/USB.h> // USB Functionality
- #include <LUFA/Drivers/Board/LEDs.h> // LEDs driver
-
- /* Macros: */
- /** HID Class specific request to get the next HID report from the device. */
- #define REQ_GetReport 0x01
-
- /** HID Class specific request to send the next HID report to the device. */
- #define REQ_SetReport 0x09
-
- /* Enums: */
- /** Enum for the possible status codes for passing to the UpdateStatus() function. */
- enum GenericHID_StatusCodes_t
- {
- Status_USBNotReady = 0, /**< USB is not ready (disconnected from a USB host) */
- Status_USBEnumerating = 1, /**< USB interface is enumerating */
- Status_USBReady = 2, /**< USB interface is connected and ready */
- };
+ #include <LUFA/Version.h>
+ #include <LUFA/Drivers/Board/LEDs.h>
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/HID.h>
- /* Task Definitions: */
- TASK(USB_HID_Report);
+ /* Macros: */
+ #define LEDMASK_USB_NOTREADY LEDS_LED1
+ #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
+ #define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
+ #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/* Function Prototypes: */
+ void SetupHardware(void);
+
void EVENT_USB_Connect(void);
void EVENT_USB_Disconnect(void);
void EVENT_USB_ConfigurationChanged(void);
void EVENT_USB_UnhandledControlPacket(void);
+ void EVENT_USB_StartOfFrame(void);
- void UpdateStatus(uint8_t CurrentStatus);
- void ProcessGenericHIDReport(uint8_t* DataArray);
- void CreateGenericHIDReport(uint8_t* DataArray);
+ uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);
+ void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,
+ void* ReportData, uint16_t ReportSize);
#endif
diff --git a/Demos/Device/GenericHID/makefile b/Demos/Device/GenericHID/makefile
index 9c6c891cd..5cc4b4a43 100644
--- a/Demos/Device/GenericHID/makefile
+++ b/Demos/Device/GenericHID/makefile
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
Descriptors.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 \
@@ -136,7 +135,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.)
@@ -183,7 +182,7 @@ CSTANDARD = -std=gnu99
# Place -D or -U options here for C sources
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
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
diff --git a/Demos/Device/Joystick/Descriptors.h b/Demos/Device/Joystick/Descriptors.h
index 6121295fa..1241ad14e 100644
--- a/Demos/Device/Joystick/Descriptors.h
+++ b/Demos/Device/Joystick/Descriptors.h
@@ -37,30 +37,12 @@
#define _DESCRIPTORS_H_
/* Includes: */
- #include <LUFA/Drivers/USB/USB.h>
-
#include <avr/pgmspace.h>
- /* Type Defines: */
- /** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID
- * specification for details on the structure elements.
- */
- typedef struct
- {
- USB_Descriptor_Header_t Header;
-
- uint16_t HIDSpec;
- uint8_t CountryCode;
-
- uint8_t TotalReportDescriptors;
-
- uint8_t HIDReportType;
- uint16_t HIDReportLength;
- } USB_Descriptor_HID_t;
-
- /** Type define for the data type used to store HID report descriptor elements. */
- typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/HID.h>
+ /* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host.
@@ -80,12 +62,6 @@
/** Size in bytes of the Joystick HID reporting IN endpoint. */
#define JOYSTICK_EPSIZE 8
- /** Descriptor header type value, to indicate a HID class HID descriptor. */
- #define DTYPE_HID 0x21
-
- /** Descriptor header type value, to indicate a HID class HID report descriptor. */
- #define DTYPE_Report 0x22
-
/* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
diff --git a/Demos/Device/Joystick/Joystick.c b/Demos/Device/Joystick/Joystick.c
index 8c50a2c16..e073a87fd 100644
--- a/Demos/Device/Joystick/Joystick.c
+++ b/Demos/Device/Joystick/Joystick.c
@@ -28,26 +28,35 @@
this software.
*/
-/** \file
- *
- * Main source file for the Joystick demo. This file contains the main tasks of the demo and
- * is responsible for the initial application hardware configuration.
- */
-
#include "Joystick.h"
-/* Scheduler Task List */
-TASK_LIST
-{
- { .Task = USB_USBTask , .TaskStatus = TASK_STOP },
- { .Task = USB_Joystick_Report , .TaskStatus = TASK_STOP },
-};
+USB_ClassInfo_HID_t Joystick_HID_Interface =
+ {
+ .InterfaceNumber = 0,
+
+ .ReportINEndpointNumber = JOYSTICK_EPNUM,
+ .ReportINEndpointSize = JOYSTICK_EPSIZE,
+
+ .ReportBufferSize = sizeof(USB_JoystickReport_Data_t),
+
+ .UsingReportProtocol = true,
+ };
-/** Main program entry point. This routine configures the hardware required by the application, then
- * starts the scheduler to run the application tasks.
- */
int main(void)
{
+ SetupHardware();
+
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+
+ for (;;)
+ {
+ USB_HID_USBTask(&Joystick_HID_Interface);
+ USB_USBTask();
+ }
+}
+
+void SetupHardware(void)
+{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
wdt_disable();
@@ -59,188 +68,64 @@ int main(void)
Joystick_Init();
LEDs_Init();
Buttons_Init();
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
-
- /* Initialize Scheduler so that it can be used */
- Scheduler_Init();
-
- /* Initialize USB Subsystem */
USB_Init();
-
- /* Scheduling - routine never returns, so put this last in the main function */
- Scheduler_Start();
}
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
- * starts the library USB task to begin the enumeration and USB management process.
- */
void EVENT_USB_Connect(void)
{
- /* Start USB management task */
- Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
- /* Indicate USB enumerating */
- UpdateStatus(Status_USBEnumerating);
+ LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- * the status LEDs and stops the USB management and joystick reporting tasks.
- */
void EVENT_USB_Disconnect(void)
{
- /* Stop running joystick reporting and USB management tasks */
- Scheduler_SetTaskMode(USB_Joystick_Report, TASK_STOP);
- Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration
- * of the USB device after enumeration - the device endpoints are configured and the joystick reporting task started.
- */
void EVENT_USB_ConfigurationChanged(void)
{
- /* Setup Joystick Report Endpoint */
- Endpoint_ConfigureEndpoint(JOYSTICK_EPNUM, EP_TYPE_INTERRUPT,
- ENDPOINT_DIR_IN, JOYSTICK_EPSIZE,
- ENDPOINT_BANK_SINGLE);
+ LEDs_SetAllLEDs(LEDMASK_USB_READY);
- /* Indicate USB connected and ready */
- UpdateStatus(Status_USBReady);
-
- /* Start joystick reporting task */
- Scheduler_SetTaskMode(USB_Joystick_Report, TASK_RUN);
+ if (!(USB_HID_ConfigureEndpoints(&Joystick_HID_Interface)))
+ LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- * control requests that are not handled internally by the USB library (including the HID commands, which are
- * all issued via the control endpoint), so that they can be handled appropriately for the application.
- */
void EVENT_USB_UnhandledControlPacket(void)
{
- /* Handle HID Class specific requests */
- switch (USB_ControlRequest.bRequest)
- {
- case REQ_GetReport:
- if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- USB_JoystickReport_Data_t JoystickReportData;
-
- Endpoint_ClearSETUP();
-
- /* Create the next HID report to send to the host */
- GetNextReport(&JoystickReportData);
-
- /* Write the report data to the control endpoint */
- Endpoint_Write_Control_Stream_LE(&JoystickReportData, sizeof(JoystickReportData));
-
- /* Finalize the stream transfer to send the last packet or clear the host abort */
- Endpoint_ClearOUT();
- }
-
- break;
- }
+ USB_HID_ProcessControlPacket(&Joystick_HID_Interface);
}
-/** Fills the given HID report data structure with the next HID report to send to the host.
- *
- * \param ReportData Pointer to a HID report data structure to be filled
- *
- * \return Boolean true if the new report differs from the last report, false otherwise
- */
-bool GetNextReport(USB_JoystickReport_Data_t* ReportData)
+void EVENT_USB_StartOfFrame(void)
{
- static uint8_t PrevJoyStatus = 0;
- static uint8_t PrevButtonStatus = 0;
- uint8_t JoyStatus_LCL = Joystick_GetStatus();
- uint8_t ButtonStatus_LCL = Buttons_GetStatus();
- bool InputChanged = false;
+ USB_HID_RegisterStartOfFrame(&Joystick_HID_Interface);
+}
- /* Clear the report contents */
- memset(ReportData, 0, sizeof(USB_JoystickReport_Data_t));
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)
+{
+ USB_JoystickReport_Data_t* JoystickReport = (USB_JoystickReport_Data_t*)ReportData;
+
+ uint8_t JoyStatus_LCL = Joystick_GetStatus();
+ uint8_t ButtonStatus_LCL = Buttons_GetStatus();
if (JoyStatus_LCL & JOY_UP)
- ReportData->Y = -100;
+ JoystickReport->Y = -100;
else if (JoyStatus_LCL & JOY_DOWN)
- ReportData->Y = 100;
+ JoystickReport->Y = 100;
if (JoyStatus_LCL & JOY_RIGHT)
- ReportData->X = 100;
+ JoystickReport->X = 100;
else if (JoyStatus_LCL & JOY_LEFT)
- ReportData->X = -100;
+ JoystickReport->X = -100;
if (JoyStatus_LCL & JOY_PRESS)
- ReportData->Button = (1 << 1);
+ JoystickReport->Button = (1 << 1);
if (ButtonStatus_LCL & BUTTONS_BUTTON1)
- ReportData->Button |= (1 << 0);
+ JoystickReport->Button |= (1 << 0);
- /* Check if the new report is different to the previous report */
- InputChanged = (uint8_t)(PrevJoyStatus ^ JoyStatus_LCL) | (uint8_t)(PrevButtonStatus ^ ButtonStatus_LCL);
-
- /* Save the current joystick status for later comparison */
- PrevJoyStatus = JoyStatus_LCL;
- PrevButtonStatus = ButtonStatus_LCL;
-
- /* Return whether the new report is different to the previous report or not */
- return InputChanged;
+ return sizeof(USB_JoystickReport_Data_t);
}
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- * log to a serial port, or anything else that is suitable for status updates.
- *
- * \param CurrentStatus Current status of the system, from the Joystick_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)
{
- uint8_t LEDMask = LEDS_NO_LEDS;
-
- /* Set the LED mask to the appropriate LED mask based on the given status code */
- switch (CurrentStatus)
- {
- case Status_USBNotReady:
- LEDMask = (LEDS_LED1);
- break;
- case Status_USBEnumerating:
- LEDMask = (LEDS_LED1 | LEDS_LED2);
- break;
- case Status_USBReady:
- LEDMask = (LEDS_LED2 | LEDS_LED4);
- break;
- }
-
- /* Set the board LEDs to the new LED mask */
- LEDs_SetAllLEDs(LEDMask);
-}
-
-/** Function to manage HID report generation and transmission to the host. */
-TASK(USB_Joystick_Report)
-{
- /* Check if the USB System is connected to a Host */
- if (USB_IsConnected)
- {
- /* Select the Joystick Report Endpoint */
- Endpoint_SelectEndpoint(JOYSTICK_EPNUM);
-
- /* Check to see if the host is ready for another packet */
- if (Endpoint_IsINReady())
- {
- USB_JoystickReport_Data_t JoystickReportData;
-
- /* Create the next HID report to send to the host */
- GetNextReport(&JoystickReportData);
-
- /* Write Joystick Report Data */
- Endpoint_Write_Stream_LE(&JoystickReportData, sizeof(JoystickReportData));
-
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearIN();
-
- /* Clear the report data afterwards */
- memset(&JoystickReportData, 0, sizeof(JoystickReportData));
- }
- }
+ // Unused (but mandatory for the HID class driver) in this demo, since there are no Host->Device reports
}
diff --git a/Demos/Device/Joystick/Joystick.h b/Demos/Device/Joystick/Joystick.h
index 9763cada3..461d0d0cc 100644
--- a/Demos/Device/Joystick/Joystick.h
+++ b/Demos/Device/Joystick/Joystick.h
@@ -44,19 +44,12 @@
#include "Descriptors.h"
- #include <LUFA/Version.h> // Library Version Information
- #include <LUFA/Drivers/USB/USB.h> // USB Functionality
- #include <LUFA/Drivers/Board/Joystick.h> // Joystick driver
- #include <LUFA/Drivers/Board/LEDs.h> // LEDs driver
- #include <LUFA/Drivers/Board/Buttons.h> // Board Buttons driver
- #include <LUFA/Scheduler/Scheduler.h> // Simple scheduler for task management
-
- /* Task Definitions: */
- TASK(USB_Joystick_Report);
-
- /* Macros: */
- /** HID Class specific request to get the next HID report from the device. */
- #define REQ_GetReport 0x01
+ #include <LUFA/Version.h>
+ #include <LUFA/Drivers/Board/Joystick.h>
+ #include <LUFA/Drivers/Board/LEDs.h>
+ #include <LUFA/Drivers/Board/Buttons.h>
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/HID.h>
/* Type Defines: */
/** Type define for the joystick HID report structure, for creating and sending HID reports to the host PC.
@@ -69,22 +62,23 @@
uint8_t Button; /**< Bit mask of the currently pressed joystick buttons */
} USB_JoystickReport_Data_t;
- /* Enums: */
- /** Enum for the possible status codes for passing to the UpdateStatus() function. */
- enum Joystick_StatusCodes_t
- {
- Status_USBNotReady = 0, /**< USB is not ready (disconnected from a USB host) */
- Status_USBEnumerating = 1, /**< USB interface is enumerating */
- Status_USBReady = 2, /**< USB interface is connected and ready */
- };
+ /* Macros: */
+ #define LEDMASK_USB_NOTREADY LEDS_LED1
+ #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
+ #define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
+ #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/* Function Prototypes: */
+ void SetupHardware(void);
+
void EVENT_USB_Connect(void);
void EVENT_USB_Disconnect(void);
void EVENT_USB_ConfigurationChanged(void);
void EVENT_USB_UnhandledControlPacket(void);
+ void EVENT_USB_StartOfFrame(void);
- bool GetNextReport(USB_JoystickReport_Data_t* ReportData);
- void UpdateStatus(uint8_t CurrentStatus);
+ uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);
+ void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,
+ void* ReportData, uint16_t ReportSize);
#endif
diff --git a/Demos/Device/Joystick/makefile b/Demos/Device/Joystick/makefile
index aaf69e80b..826766c30 100644
--- a/Demos/Device/Joystick/makefile
+++ b/Demos/Device/Joystick/makefile
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
Descriptors.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 \
@@ -136,7 +135,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.)
@@ -183,7 +182,7 @@ CSTANDARD = -std=gnu99
# Place -D or -U options here for C sources
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
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
diff --git a/Demos/Device/Keyboard/Descriptors.h b/Demos/Device/Keyboard/Descriptors.h
index 92eb7b884..0a95ca06e 100644
--- a/Demos/Device/Keyboard/Descriptors.h
+++ b/Demos/Device/Keyboard/Descriptors.h
@@ -38,30 +38,12 @@
#define _DESCRIPTORS_H_
/* Includes: */
- #include <LUFA/Drivers/USB/USB.h>
-
#include <avr/pgmspace.h>
- /* Type Defines: */
- /** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID
- * specification for details on the structure elements.
- */
- typedef struct
- {
- USB_Descriptor_Header_t Header;
-
- uint16_t HIDSpec;
- uint8_t CountryCode;
-
- uint8_t TotalReportDescriptors;
-
- uint8_t HIDReportType;
- uint16_t HIDReportLength;
- } USB_Descriptor_HID_t;
-
- /** Type define for the data type used to store HID report descriptor elements. */
- typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/HID.h>
+ /* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host.
@@ -85,12 +67,6 @@
/** Size in bytes of the Keyboard HID reporting IN and OUT endpoints. */
#define KEYBOARD_EPSIZE 8
- /** Descriptor header type value, to indicate a HID class HID descriptor. */
- #define DTYPE_HID 0x21
-
- /** Descriptor header type value, to indicate a HID class HID report descriptor. */
- #define DTYPE_Report 0x22
-
/* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
diff --git a/Demos/Device/Keyboard/Keyboard.c b/Demos/Device/Keyboard/Keyboard.c
index 6abd193f4..d8893bfaa 100644
--- a/Demos/Device/Keyboard/Keyboard.c
+++ b/Demos/Device/Keyboard/Keyboard.c
@@ -28,397 +28,120 @@
arising out of or in connection with the use or performance of
this software.
*/
-
-/** \file
- *
- * Main source file for the Keyboard demo. This file contains the main tasks of the demo and
- * is responsible for the initial application hardware configuration.
- */
#include "Keyboard.h"
-/* Scheduler Task List */
-TASK_LIST
-{
- { .Task = USB_USBTask , .TaskStatus = TASK_STOP },
- { .Task = USB_Keyboard_Report , .TaskStatus = TASK_STOP },
-};
-
-/* Global Variables */
-/** Indicates what report mode the host has requested, true for normal HID reporting mode, false for special boot
- * protocol reporting mode.
- */
-bool UsingReportProtocol = true;
+USB_ClassInfo_HID_t Keyboard_HID_Interface =
+ {
+ .InterfaceNumber = 0,
-/** Current Idle period. This is set by the host via a Set Idle HID class request to silence the device's reports
- * for either the entire idle duration, or until the report status changes (e.g. the user presses a key).
- */
-uint16_t IdleCount = 500;
+ .ReportINEndpointNumber = KEYBOARD_EPNUM,
+ .ReportINEndpointSize = KEYBOARD_EPSIZE,
-/** Current Idle period remaining. When the IdleCount value is set, this tracks the remaining number of idle
- * milliseconds. This is separate to the IdleCount timer and is incremented and compared as the host may request
- * the current idle period via a Get Idle HID class request, thus its value must be preserved.
- */
-uint16_t IdleMSRemaining = 0;
+ .ReportOUTEndpointNumber = KEYBOARD_LEDS_EPNUM,
+ .ReportOUTEndpointSize = KEYBOARD_EPSIZE,
+
+ .ReportBufferSize = sizeof(USB_KeyboardReport_Data_t),
+ .IdleCount = 500,
+ };
-/** Main program entry point. This routine configures the hardware required by the application, then
- * starts the scheduler to run the USB management task.
- */
int main(void)
{
- /* Disable watchdog if enabled by bootloader/fuses */
- MCUSR &= ~(1 << WDRF);
- wdt_disable();
-
- /* Disable clock division */
- clock_prescale_set(clock_div_1);
-
- /* Hardware Initialization */
- Joystick_Init();
- LEDs_Init();
-
- /* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */
- OCR0A = 0x7D;
- TCCR0A = (1 << WGM01);
- TCCR0B = ((1 << CS01) | (1 << CS00));
- TIMSK0 = (1 << OCIE0A);
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
-
- /* Initialize Scheduler so that it can be used */
- Scheduler_Init();
+ SetupHardware();
+
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+
+ for (;;)
+ {
+ USB_HID_USBTask(&Keyboard_HID_Interface);
+ USB_USBTask();
+ }
+}
- /* Initialize USB Subsystem */
- USB_Init();
-
- /* Scheduling - routine never returns, so put this last in the main function */
- Scheduler_Start();
+void SetupHardware()
+{
+ /* Disable watchdog if enabled by bootloader/fuses */
+ MCUSR &= ~(1 << WDRF);
+ wdt_disable();
+
+ /* Disable clock division */
+ clock_prescale_set(clock_div_1);
+
+ /* Hardware Initialization */
+ Joystick_Init();
+ LEDs_Init();
+ Buttons_Init();
+ USB_Init();
}
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
- * starts the library USB task to begin the enumeration and USB management process.
- */
void EVENT_USB_Connect(void)
{
- /* Start USB management task */
- Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
- /* Indicate USB enumerating */
- UpdateStatus(Status_USBEnumerating);
-
- /* Default to report protocol on connect */
- UsingReportProtocol = true;
+ LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- * the status LEDs.
- */
void EVENT_USB_Disconnect(void)
{
- /* Stop running keyboard reporting and USB management tasks */
- Scheduler_SetTaskMode(USB_Keyboard_Report, TASK_STOP);
- Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host sets the current configuration
- * of the USB device after enumeration, and configures the keyboard device endpoints.
- */
void EVENT_USB_ConfigurationChanged(void)
{
- /* Setup Keyboard Keycode Report Endpoint */
- Endpoint_ConfigureEndpoint(KEYBOARD_EPNUM, EP_TYPE_INTERRUPT,
- ENDPOINT_DIR_IN, KEYBOARD_EPSIZE,
- ENDPOINT_BANK_SINGLE);
-
- /* Setup Keyboard LED Report Endpoint */
- Endpoint_ConfigureEndpoint(KEYBOARD_LEDS_EPNUM, EP_TYPE_INTERRUPT,
- ENDPOINT_DIR_OUT, KEYBOARD_EPSIZE,
- ENDPOINT_BANK_SINGLE);
+ LEDs_SetAllLEDs(LEDMASK_USB_READY);
- /* Indicate USB connected and ready */
- UpdateStatus(Status_USBReady);
-
- /* Start running keyboard reporting task */
- Scheduler_SetTaskMode(USB_Keyboard_Report, TASK_RUN);
+ if (!(USB_HID_ConfigureEndpoints(&Keyboard_HID_Interface)))
+ LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- * control requests that are not handled internally by the USB library (including the HID commands, which are
- * all issued via the control endpoint), so that they can be handled appropriately for the application.
- */
void EVENT_USB_UnhandledControlPacket(void)
{
- /* Handle HID Class specific requests */
- switch (USB_ControlRequest.bRequest)
- {
- case REQ_GetReport:
- if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- USB_KeyboardReport_Data_t KeyboardReportData;
-
- Endpoint_ClearSETUP();
-
- /* Create the next keyboard report for transmission to the host */
- CreateKeyboardReport(&KeyboardReportData);
-
- /* Write the report data to the control endpoint */
- Endpoint_Write_Control_Stream_LE(&KeyboardReportData, sizeof(KeyboardReportData));
-
- /* Finalize the stream transfer to send the last packet or clear the host abort */
- Endpoint_ClearOUT();
- }
-
- break;
- case REQ_SetReport:
- if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- Endpoint_ClearSETUP();
-
- /* Wait until the LED report has been sent by the host */
- while (!(Endpoint_IsOUTReceived()));
-
- /* Read in the LED report from the host */
- uint8_t LEDStatus = Endpoint_Read_Byte();
-
- /* Process the incoming LED report */
- ProcessLEDReport(LEDStatus);
-
- /* Clear the endpoint data */
- Endpoint_ClearOUT();
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsINReady()));
- Endpoint_ClearIN();
- }
-
- break;
- case REQ_GetProtocol:
- if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- Endpoint_ClearSETUP();
-
- /* Write the current protocol flag to the host */
- Endpoint_Write_Byte(UsingReportProtocol);
-
- /* Send the flag to the host */
- Endpoint_ClearIN();
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsOUTReceived()));
- Endpoint_ClearOUT();
- }
-
- break;
- case REQ_SetProtocol:
- if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- Endpoint_ClearSETUP();
-
- /* Set or clear the flag depending on what the host indicates that the current Protocol should be */
- UsingReportProtocol = (USB_ControlRequest.wValue != 0);
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsINReady()));
- Endpoint_ClearIN();
- }
-
- break;
- case REQ_SetIdle:
- if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- Endpoint_ClearSETUP();
-
- /* Get idle period in MSB */
- IdleCount = (USB_ControlRequest.wValue >> 8);
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsINReady()));
- Endpoint_ClearIN();
- }
-
- break;
- case REQ_GetIdle:
- if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- Endpoint_ClearSETUP();
-
- /* Write the current idle duration to the host */
- Endpoint_Write_Byte(IdleCount);
-
- /* Send the flag to the host */
- Endpoint_ClearIN();
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsOUTReceived()));
- Endpoint_ClearOUT();
- }
-
- break;
- }
+ USB_HID_ProcessControlPacket(&Keyboard_HID_Interface);
}
-/** ISR for the timer 0 compare vector. This ISR fires once each millisecond, and increments the
- * scheduler elapsed idle period counter when the host has set an idle period.
- */
-ISR(TIMER0_COMPA_vect, ISR_BLOCK)
+void EVENT_USB_StartOfFrame(void)
{
- /* One millisecond has elapsed, decrement the idle time remaining counter if it has not already elapsed */
- if (IdleMSRemaining)
- IdleMSRemaining--;
-}
-
-/** Fills the given HID report data structure with the next HID report to send to the host.
- *
- * \param ReportData Pointer to a HID report data structure to be filled
- */
-void CreateKeyboardReport(USB_KeyboardReport_Data_t* ReportData)
-{
- uint8_t JoyStatus_LCL = Joystick_GetStatus();
-
- /* Clear the report contents */
- memset(ReportData, 0, sizeof(USB_KeyboardReport_Data_t));
-
- if (JoyStatus_LCL & JOY_UP)
- ReportData->KeyCode[0] = 0x04; // A
- else if (JoyStatus_LCL & JOY_DOWN)
- ReportData->KeyCode[0] = 0x05; // B
-
- if (JoyStatus_LCL & JOY_LEFT)
- ReportData->KeyCode[0] = 0x06; // C
- else if (JoyStatus_LCL & JOY_RIGHT)
- ReportData->KeyCode[0] = 0x07; // D
-
- if (JoyStatus_LCL & JOY_PRESS)
- ReportData->KeyCode[0] = 0x08; // E
-}
-
-/** Processes a received LED report, and updates the board LEDs states to match.
- *
- * \param LEDReport LED status report from the host
- */
-void ProcessLEDReport(uint8_t LEDReport)
-{
- uint8_t LEDMask = LEDS_LED2;
-
- if (LEDReport & 0x01) // NUM Lock
- LEDMask |= LEDS_LED1;
-
- if (LEDReport & 0x02) // CAPS Lock
- LEDMask |= LEDS_LED3;
-
- if (LEDReport & 0x04) // SCROLL Lock
- LEDMask |= LEDS_LED4;
-
- /* Set the status LEDs to the current Keyboard LED status */
- LEDs_SetAllLEDs(LEDMask);
-}
-
-/** Sends the next HID report to the host, via the keyboard data endpoint. */
-void SendNextReport(void)
-{
- static USB_KeyboardReport_Data_t PrevKeyboardReportData;
- USB_KeyboardReport_Data_t KeyboardReportData;
- bool SendReport = true;
-
- /* Create the next keyboard report for transmission to the host */
- CreateKeyboardReport(&KeyboardReportData);
-
- /* Check to see if the report data has changed - if so a report MUST be sent */
- SendReport = (memcmp(&PrevKeyboardReportData, &KeyboardReportData, sizeof(USB_KeyboardReport_Data_t)) != 0);
-
- /* Save the current report data for later comparison to check for changes */
- PrevKeyboardReportData = KeyboardReportData;
-
- /* Check if the idle period is set and has elapsed */
- if ((IdleCount != HID_IDLE_CHANGESONLY) && (!(IdleMSRemaining)))
- {
- /* Reset the idle time remaining counter, must multiply by 4 to get the duration in milliseconds */
- IdleMSRemaining = (IdleCount << 2);
-
- /* Idle period is set and has elapsed, must send a report to the host */
- SendReport = true;
- }
-
- /* Select the Keyboard Report Endpoint */
- Endpoint_SelectEndpoint(KEYBOARD_EPNUM);
-
- /* Check if Keyboard Endpoint Ready for Read/Write and if we should send a new report */
- if (Endpoint_IsReadWriteAllowed() && SendReport)
- {
- /* Write Keyboard Report Data */
- Endpoint_Write_Stream_LE(&KeyboardReportData, sizeof(KeyboardReportData));
-
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearIN();
- }
-}
-
-/** Reads the next LED status report from the host from the LED data endpoint, if one has been sent. */
-void ReceiveNextReport(void)
-{
- /* Select the Keyboard LED Report Endpoint */
- Endpoint_SelectEndpoint(KEYBOARD_LEDS_EPNUM);
-
- /* Check if Keyboard LED Endpoint contains a packet */
- if (Endpoint_IsOUTReceived())
- {
- /* Check to see if the packet contains data */
- if (Endpoint_IsReadWriteAllowed())
- {
- /* Read in the LED report from the host */
- uint8_t LEDReport = Endpoint_Read_Byte();
-
- /* Process the read LED report from the host */
- ProcessLEDReport(LEDReport);
- }
-
- /* Handshake the OUT Endpoint - clear endpoint and ready for next report */
- Endpoint_ClearOUT();
- }
+ USB_HID_RegisterStartOfFrame(&Keyboard_HID_Interface);
}
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- * log to a serial port, or anything else that is suitable for status updates.
- *
- * \param CurrentStatus Current status of the system, from the Keyboard_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)
{
- uint8_t LEDMask = LEDS_NO_LEDS;
-
- /* Set the LED mask to the appropriate LED mask based on the given status code */
- switch (CurrentStatus)
- {
- case Status_USBNotReady:
- LEDMask = (LEDS_LED1);
- break;
- case Status_USBEnumerating:
- LEDMask = (LEDS_LED1 | LEDS_LED2);
- break;
- case Status_USBReady:
- LEDMask = (LEDS_LED2 | LEDS_LED4);
- break;
- }
-
- /* Set the board LEDs to the new LED mask */
- LEDs_SetAllLEDs(LEDMask);
+ USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
+
+ uint8_t JoyStatus_LCL = Joystick_GetStatus();
+ uint8_t ButtonStatus_LCL = Buttons_GetStatus();
+
+ if (JoyStatus_LCL & JOY_UP)
+ KeyboardReport->KeyCode[0] = 0x04; // A
+ else if (JoyStatus_LCL & JOY_DOWN)
+ KeyboardReport->KeyCode[0] = 0x05; // B
+
+ if (JoyStatus_LCL & JOY_LEFT)
+ KeyboardReport->KeyCode[0] = 0x06; // C
+ else if (JoyStatus_LCL & JOY_RIGHT)
+ KeyboardReport->KeyCode[0] = 0x07; // D
+
+ if (JoyStatus_LCL & JOY_PRESS)
+ KeyboardReport->KeyCode[0] = 0x08; // E
+
+ if (ButtonStatus_LCL & BUTTONS_BUTTON1)
+ KeyboardReport->KeyCode[0] = 0x09; // F
+
+ return sizeof(USB_KeyboardReport_Data_t);
}
-/** Function to manage HID report generation and transmission to the host, when in report mode. */
-TASK(USB_Keyboard_Report)
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)
{
- /* Check if the USB system is connected to a host */
- if (USB_IsConnected)
- {
- /* Send the next keypress report to the host */
- SendNextReport();
-
- /* Process the LED report sent from the host */
- ReceiveNextReport();
- }
+ uint8_t LEDMask = LEDS_NO_LEDS;
+ uint8_t* LEDReport = (uint8_t*)ReportData;
+
+ if (*LEDReport & 0x01) // NUM Lock
+ LEDMask |= LEDS_LED1;
+
+ if (*LEDReport & 0x02) // CAPS Lock
+ LEDMask |= LEDS_LED3;
+
+ if (*LEDReport & 0x04) // SCROLL Lock
+ LEDMask |= LEDS_LED4;
+
+ LEDs_SetAllLEDs(LEDMask);
}
diff --git a/Demos/Device/Keyboard/Keyboard.h b/Demos/Device/Keyboard/Keyboard.h
index c4ed6e07c..eeb7be9b7 100644
--- a/Demos/Device/Keyboard/Keyboard.h
+++ b/Demos/Device/Keyboard/Keyboard.h
@@ -47,36 +47,12 @@
#include "Descriptors.h"
- #include <LUFA/Version.h> // Library Version Information
- #include <LUFA/Scheduler/Scheduler.h> // Simple scheduler for task management
- #include <LUFA/Drivers/USB/USB.h> // USB Functionality
- #include <LUFA/Drivers/Board/Joystick.h> // Joystick driver
- #include <LUFA/Drivers/Board/LEDs.h> // LEDs driver
-
- /* Macros: */
- /** Idle period indicating that reports should be sent only when the inputs have changed */
- #define HID_IDLE_CHANGESONLY 0
-
- /** HID Class specific request to get the next HID report from the device. */
- #define REQ_GetReport 0x01
-
- /** HID Class specific request to get the idle timeout period of the device. */
- #define REQ_GetIdle 0x02
-
- /** HID Class specific request to send the next HID report to the device. */
- #define REQ_SetReport 0x09
-
- /** HID Class specific request to set the idle timeout period of the device. */
- #define REQ_SetIdle 0x0A
-
- /** HID Class specific request to get the current HID protocol in use, either report or boot. */
- #define REQ_GetProtocol 0x03
-
- /** HID Class specific request to set the current HID protocol in use, either report or boot. */
- #define REQ_SetProtocol 0x0B
-
- /* Task Definitions: */
- TASK(USB_Keyboard_Report);
+ #include <LUFA/Version.h>
+ #include <LUFA/Drivers/Board/Joystick.h>
+ #include <LUFA/Drivers/Board/LEDs.h>
+ #include <LUFA/Drivers/Board/Buttons.h>
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/HID.h>
/* Type Defines: */
/** Type define for the keyboard HID report structure, for creating and sending HID reports to the host PC.
@@ -89,25 +65,23 @@
uint8_t KeyCode[6]; /**< Array of up to six simultaneous key codes of pressed keys */
} USB_KeyboardReport_Data_t;
- /* Enums: */
- /** Enum for the possible status codes for passing to the UpdateStatus() function. */
- enum Keyboard_StatusCodes_t
- {
- Status_USBNotReady = 0, /**< USB is not ready (disconnected from a USB host) */
- Status_USBEnumerating = 1, /**< USB interface is enumerating */
- Status_USBReady = 2, /**< USB interface is connected and ready */
- };
+ /* Macros: */
+ #define LEDMASK_USB_NOTREADY LEDS_LED1
+ #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
+ #define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
+ #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/* Function Prototypes: */
+ void SetupHardware(void);
+
void EVENT_USB_Connect(void);
void EVENT_USB_Disconnect(void);
void EVENT_USB_ConfigurationChanged(void);
void EVENT_USB_UnhandledControlPacket(void);
+ void EVENT_USB_StartOfFrame(void);
- void CreateKeyboardReport(USB_KeyboardReport_Data_t* ReportData);
- void ProcessLEDReport(uint8_t LEDReport);
- void SendNextReport(void);
- void ReceiveNextReport(void);
- void UpdateStatus(uint8_t CurrentStatus);
+ uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);
+ void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,
+ void* ReportData, uint16_t ReportSize);
#endif
diff --git a/Demos/Device/Keyboard/makefile b/Demos/Device/Keyboard/makefile
index 88e4de0e6..98cda2f89 100644
--- a/Demos/Device/Keyboard/makefile
+++ b/Demos/Device/Keyboard/makefile
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
Descriptors.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 \
@@ -136,7 +135,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.)
@@ -183,7 +182,7 @@ CSTANDARD = -std=gnu99
# Place -D or -U options here for C sources
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
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
diff --git a/Demos/Device/KeyboardMouse/Descriptors.h b/Demos/Device/KeyboardMouse/Descriptors.h
index 43c345a21..152e5111a 100644
--- a/Demos/Device/KeyboardMouse/Descriptors.h
+++ b/Demos/Device/KeyboardMouse/Descriptors.h
@@ -38,30 +38,12 @@
#define _DESCRIPTORS_H_
/* Includes: */
- #include <LUFA/Drivers/USB/USB.h>
-
#include <avr/pgmspace.h>
- /* Type Defines: */
- /** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID
- * specification for details on the structure elements.
- */
- typedef struct
- {
- USB_Descriptor_Header_t Header;
-
- uint16_t HIDSpec;
- uint8_t CountryCode;
-
- uint8_t TotalReportDescriptors;
-
- uint8_t HIDReportType;
- uint16_t HIDReportLength;
- } USB_Descriptor_HID_t;
-
- /** Type define for the data type used to store HID report descriptor elements. */
- typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/HID.h>
+ /* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host.
@@ -91,12 +73,6 @@
/** Size in bytes of each of the HID reporting IN and OUT endpoints. */
#define HID_EPSIZE 8
- /** Descriptor header type value, to indicate a HID class HID descriptor. */
- #define DTYPE_HID 0x21
-
- /** Descriptor header type value, to indicate a HID class HID report descriptor. */
- #define DTYPE_Report 0x22
-
/* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
diff --git a/Demos/Device/KeyboardMouse/KeyboardMouse.c b/Demos/Device/KeyboardMouse/KeyboardMouse.c
index 25d633e43..8f6a573a6 100644
--- a/Demos/Device/KeyboardMouse/KeyboardMouse.c
+++ b/Demos/Device/KeyboardMouse/KeyboardMouse.c
@@ -28,35 +28,53 @@
arising out of or in connection with the use or performance of
this software.
*/
-
-/** \file
- *
- * Main source file for the KeyboardMouse demo. This file contains the main tasks of the demo and
- * is responsible for the initial application hardware configuration.
- */
#include "KeyboardMouse.h"
-/* Scheduler Task List */
-TASK_LIST
-{
- { .Task = USB_USBTask , .TaskStatus = TASK_STOP },
- { .Task = USB_Mouse , .TaskStatus = TASK_RUN },
- { .Task = USB_Keyboard , .TaskStatus = TASK_RUN },
-};
+USB_ClassInfo_HID_t Keyboard_HID_Interface =
+ {
+ .InterfaceNumber = 0,
+
+ .ReportINEndpointNumber = KEYBOARD_IN_EPNUM,
+ .ReportINEndpointSize = HID_EPSIZE,
+
+ .ReportOUTEndpointNumber = KEYBOARD_OUT_EPNUM,
+ .ReportOUTEndpointSize = HID_EPSIZE,
+
+ .ReportBufferSize = sizeof(USB_KeyboardReport_Data_t),
+
+ .IdleCount = 500,
+ };
+
+USB_ClassInfo_HID_t Mouse_HID_Interface =
+ {
+ .InterfaceNumber = 0,
-/* Global Variables */
-/** Global structure to hold the current keyboard interface HID report, for transmission to the host */
-USB_KeyboardReport_Data_t KeyboardReportData;
+ .ReportINEndpointNumber = MOUSE_IN_EPNUM,
+ .ReportINEndpointSize = HID_EPSIZE,
-/** Global structure to hold the current mouse interface HID report, for transmission to the host */
-USB_MouseReport_Data_t MouseReportData;
+ .ReportBufferSize = sizeof(USB_MouseReport_Data_t),
-/** Main program entry point. This routine configures the hardware required by the application, then
- * starts the scheduler to run the USB management task.
- */
+ .ReportOUTEndpointNumber = 0,
+ .ReportOUTEndpointSize = 0,
+ };
+
int main(void)
{
+ SetupHardware();
+
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+
+ for (;;)
+ {
+ USB_HID_USBTask(&Keyboard_HID_Interface);
+ USB_HID_USBTask(&Mouse_HID_Interface);
+ USB_USBTask();
+ }
+}
+
+void SetupHardware()
+{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
wdt_disable();
@@ -67,284 +85,111 @@ int main(void)
/* Hardware Initialization */
Joystick_Init();
LEDs_Init();
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
-
- /* Initialize Scheduler so that it can be used */
- Scheduler_Init();
-
- /* Initialize USB Subsystem */
- USB_Init();
-
- /* Scheduling - routine never returns, so put this last in the main function */
- Scheduler_Start();
+ USB_Init();
}
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
- * starts the library USB task to begin the enumeration and USB management process.
- */
void EVENT_USB_Connect(void)
{
- /* Start USB management task */
- Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
- /* Indicate USB enumerating */
- UpdateStatus(Status_USBEnumerating);
+ LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- * the status LEDs and stops the USB management task.
- */
void EVENT_USB_Disconnect(void)
{
- /* Stop running HID reporting and USB management tasks */
- Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host sets the current configuration
- * of the USB device after enumeration, and configures the keyboard and mouse device endpoints.
- */
void EVENT_USB_ConfigurationChanged(void)
{
- /* Setup Keyboard Report Endpoint */
- Endpoint_ConfigureEndpoint(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT,
- ENDPOINT_DIR_IN, HID_EPSIZE,
- ENDPOINT_BANK_SINGLE);
-
- /* Setup Keyboard LED Report Endpoint */
- Endpoint_ConfigureEndpoint(KEYBOARD_OUT_EPNUM, EP_TYPE_INTERRUPT,
- ENDPOINT_DIR_OUT, HID_EPSIZE,
- ENDPOINT_BANK_SINGLE);
+ LEDs_SetAllLEDs(LEDMASK_USB_READY);
- /* Setup Mouse Report Endpoint */
- Endpoint_ConfigureEndpoint(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT,
- ENDPOINT_DIR_IN, HID_EPSIZE,
- ENDPOINT_BANK_SINGLE);
-
- /* Indicate USB connected and ready */
- UpdateStatus(Status_USBReady);
+ if (!(USB_HID_ConfigureEndpoints(&Keyboard_HID_Interface)))
+ LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+
+ if (!(USB_HID_ConfigureEndpoints(&Mouse_HID_Interface)))
+ LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- * control requests that are not handled internally by the USB library (including the HID commands, which are
- * all issued via the control endpoint), so that they can be handled appropriately for the application.
- */
void EVENT_USB_UnhandledControlPacket(void)
{
- uint8_t* ReportData;
- uint8_t ReportSize;
-
- /* Handle HID Class specific requests */
- switch (USB_ControlRequest.bRequest)
- {
- case REQ_GetReport:
- if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- Endpoint_ClearSETUP();
-
- /* Determine if it is the mouse or the keyboard data that is being requested */
- if (!(USB_ControlRequest.wIndex))
- {
- ReportData = (uint8_t*)&KeyboardReportData;
- ReportSize = sizeof(KeyboardReportData);
- }
- else
- {
- ReportData = (uint8_t*)&MouseReportData;
- ReportSize = sizeof(MouseReportData);
- }
-
- /* Write the report data to the control endpoint */
- Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
-
- /* Clear the report data afterwards */
- memset(ReportData, 0, ReportSize);
-
- /* Finalize the stream transfer to send the last packet or clear the host abort */
- Endpoint_ClearOUT();
- }
-
- break;
- case REQ_SetReport:
- if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- Endpoint_ClearSETUP();
-
- /* Wait until the LED report has been sent by the host */
- while (!(Endpoint_IsOUTReceived()));
-
- /* Read in the LED report from the host */
- uint8_t LEDStatus = Endpoint_Read_Byte();
- uint8_t LEDMask = LEDS_LED2;
-
- if (LEDStatus & 0x01) // NUM Lock
- LEDMask |= LEDS_LED1;
-
- if (LEDStatus & 0x02) // CAPS Lock
- LEDMask |= LEDS_LED3;
-
- if (LEDStatus & 0x04) // SCROLL Lock
- LEDMask |= LEDS_LED4;
-
- /* Set the status LEDs to the current HID LED status */
- LEDs_SetAllLEDs(LEDMask);
-
- /* Clear the endpoint data */
- Endpoint_ClearOUT();
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsINReady()));
- Endpoint_ClearIN();
- }
-
- break;
- }
+ USB_HID_ProcessControlPacket(&Keyboard_HID_Interface);
+ USB_HID_ProcessControlPacket(&Mouse_HID_Interface);
}
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- * log to a serial port, or anything else that is suitable for status updates.
- *
- * \param CurrentStatus Current status of the system, from the KeyboardMouse_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
+void EVENT_USB_StartOfFrame(void)
{
- uint8_t LEDMask = LEDS_NO_LEDS;
-
- /* Set the LED mask to the appropriate LED mask based on the given status code */
- switch (CurrentStatus)
- {
- case Status_USBNotReady:
- LEDMask = (LEDS_LED1);
- break;
- case Status_USBEnumerating:
- LEDMask = (LEDS_LED1 | LEDS_LED2);
- break;
- case Status_USBReady:
- LEDMask = (LEDS_LED2 | LEDS_LED4);
- break;
- }
-
- /* Set the board LEDs to the new LED mask */
- LEDs_SetAllLEDs(LEDMask);
+ USB_HID_RegisterStartOfFrame(&Keyboard_HID_Interface);
+ USB_HID_RegisterStartOfFrame(&Mouse_HID_Interface);
}
-/** Keyboard task. This generates the next keyboard HID report for the host, and transmits it via the
- * keyboard IN endpoint when the host is ready for more data. Additionally, it processes host LED status
- * reports sent to the device via the keyboard OUT reporting endpoint.
- */
-TASK(USB_Keyboard)
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)
{
- uint8_t JoyStatus_LCL = Joystick_GetStatus();
+ uint8_t JoyStatus_LCL = Joystick_GetStatus();
+ uint8_t ButtonStatus_LCL = Buttons_GetStatus();
- /* Check if board button is not pressed, if so mouse mode enabled */
- if (!(Buttons_GetStatus() & BUTTONS_BUTTON1))
+ if (HIDInterfaceInfo == &Keyboard_HID_Interface)
{
+ USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
+
+ /* If first board button not being held down, no keyboard report */
+ if (!(ButtonStatus_LCL & BUTTONS_BUTTON1))
+ return 0;
+
if (JoyStatus_LCL & JOY_UP)
- KeyboardReportData.KeyCode[0] = 0x04; // A
+ KeyboardReport->KeyCode[0] = 0x04; // A
else if (JoyStatus_LCL & JOY_DOWN)
- KeyboardReportData.KeyCode[0] = 0x05; // B
+ KeyboardReport->KeyCode[0] = 0x05; // B
if (JoyStatus_LCL & JOY_LEFT)
- KeyboardReportData.KeyCode[0] = 0x06; // C
+ KeyboardReport->KeyCode[0] = 0x06; // C
else if (JoyStatus_LCL & JOY_RIGHT)
- KeyboardReportData.KeyCode[0] = 0x07; // D
+ KeyboardReport->KeyCode[0] = 0x07; // D
if (JoyStatus_LCL & JOY_PRESS)
- KeyboardReportData.KeyCode[0] = 0x08; // E
+ KeyboardReport->KeyCode[0] = 0x08; // E
+
+ return sizeof(USB_KeyboardReport_Data_t);
}
-
- /* Check if the USB system is connected to a host and report protocol mode is enabled */
- if (USB_IsConnected)
+ else
{
- /* Select the Keyboard Report Endpoint */
- Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
-
- /* Check if Keyboard Endpoint Ready for Read/Write */
- if (Endpoint_IsReadWriteAllowed())
- {
- /* Write Keyboard Report Data */
- Endpoint_Write_Stream_LE(&KeyboardReportData, sizeof(KeyboardReportData));
-
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearIN();
-
- /* Clear the report data afterwards */
- memset(&KeyboardReportData, 0, sizeof(KeyboardReportData));
- }
+ USB_MouseReport_Data_t* MouseReport = (USB_MouseReport_Data_t*)ReportData;
- /* Select the Keyboard LED Report Endpoint */
- Endpoint_SelectEndpoint(KEYBOARD_OUT_EPNUM);
-
- /* Check if Keyboard LED Endpoint Ready for Read/Write */
- if (Endpoint_IsReadWriteAllowed())
- {
- /* Read in the LED report from the host */
- uint8_t LEDStatus = Endpoint_Read_Byte();
- uint8_t LEDMask = LEDS_LED2;
-
- if (LEDStatus & 0x01) // NUM Lock
- LEDMask |= LEDS_LED1;
-
- if (LEDStatus & 0x02) // CAPS Lock
- LEDMask |= LEDS_LED3;
-
- if (LEDStatus & 0x04) // SCROLL Lock
- LEDMask |= LEDS_LED4;
-
- /* Set the status LEDs to the current Keyboard LED status */
- LEDs_SetAllLEDs(LEDMask);
-
- /* Handshake the OUT Endpoint - clear endpoint and ready for next report */
- Endpoint_ClearOUT();
- }
- }
-}
-
-/** Mouse task. This generates the next mouse HID report for the host, and transmits it via the
- * mouse IN endpoint when the host is ready for more data.
- */
-TASK(USB_Mouse)
-{
- uint8_t JoyStatus_LCL = Joystick_GetStatus();
-
- /* Check if board button is pressed, if so mouse mode enabled */
- if (Buttons_GetStatus() & BUTTONS_BUTTON1)
- {
+ /* If first board button being held down, no mouse report */
+ if (ButtonStatus_LCL & BUTTONS_BUTTON1)
+ return 0;
+
if (JoyStatus_LCL & JOY_UP)
- MouseReportData.Y = 1;
+ MouseReport->Y = -1;
else if (JoyStatus_LCL & JOY_DOWN)
- MouseReportData.Y = -1;
+ MouseReport->Y = 1;
if (JoyStatus_LCL & JOY_RIGHT)
- MouseReportData.X = 1;
+ MouseReport->X = 1;
else if (JoyStatus_LCL & JOY_LEFT)
- MouseReportData.X = -1;
+ MouseReport->X = -1;
if (JoyStatus_LCL & JOY_PRESS)
- MouseReportData.Button = (1 << 0);
+ MouseReport->Button = (1 << 0);
+
+ return sizeof(USB_MouseReport_Data_t);
}
+}
- /* Check if the USB system is connected to a host and report protocol mode is enabled */
- if (USB_IsConnected)
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)
+{
+ if (HIDInterfaceInfo == &Keyboard_HID_Interface)
{
- /* Select the Mouse Report Endpoint */
- Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
-
- /* Check if Mouse Endpoint Ready for Read/Write */
- if (Endpoint_IsReadWriteAllowed())
- {
- /* Write Mouse Report Data */
- Endpoint_Write_Stream_LE(&MouseReportData, sizeof(MouseReportData));
+ uint8_t LEDMask = LEDS_NO_LEDS;
+ uint8_t* LEDReport = (uint8_t*)ReportData;
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearIN();
+ if (*LEDReport & 0x01) // NUM Lock
+ LEDMask |= LEDS_LED1;
+
+ if (*LEDReport & 0x02) // CAPS Lock
+ LEDMask |= LEDS_LED3;
- /* Clear the report data afterwards */
- memset(&MouseReportData, 0, sizeof(MouseReportData));
- }
+ if (*LEDReport & 0x04) // SCROLL Lock
+ LEDMask |= LEDS_LED4;
+
+ LEDs_SetAllLEDs(LEDMask);
}
-}
+} \ No newline at end of file
diff --git a/Demos/Device/KeyboardMouse/KeyboardMouse.h b/Demos/Device/KeyboardMouse/KeyboardMouse.h
index e3f943402..a5c3c5db2 100644
--- a/Demos/Device/KeyboardMouse/KeyboardMouse.h
+++ b/Demos/Device/KeyboardMouse/KeyboardMouse.h
@@ -41,38 +41,18 @@
#include "Descriptors.h"
- #include <LUFA/Version.h> // Library Version Information
- #include <LUFA/Drivers/USB/USB.h> // USB Functionality
- #include <LUFA/Drivers/Board/Joystick.h> // Joystick driver
- #include <LUFA/Drivers/Board/LEDs.h> // LEDs driver
- #include <LUFA/Drivers/Board/Buttons.h> // Board Buttons driver
- #include <LUFA/Scheduler/Scheduler.h> // Simple scheduler for task management
-
- /* Task Definitions: */
- TASK(USB_Keyboard);
- TASK(USB_Mouse);
+ #include <LUFA/Version.h>
+ #include <LUFA/Drivers/Board/Joystick.h>
+ #include <LUFA/Drivers/Board/LEDs.h>
+ #include <LUFA/Drivers/Board/Buttons.h>
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/HID.h>
- /* Enums: */
- /** Enum for the possible status codes for passing to the UpdateStatus() function. */
- enum KeyboardMouse_StatusCodes_t
- {
- Status_USBNotReady = 0, /**< USB is not ready (disconnected from a USB host) */
- Status_USBEnumerating = 1, /**< USB interface is enumerating */
- Status_USBReady = 2, /**< USB interface is connected and ready */
- };
-
/* Macros: */
- /** HID Class specific request to get the next HID report from the device. */
- #define REQ_GetReport 0x01
-
- /** HID Class specific request to send the next HID report to the device. */
- #define REQ_SetReport 0x09
-
- /** HID Class specific request to get the current HID protocol in use, either report or boot. */
- #define REQ_GetProtocol 0x03
-
- /** HID Class specific request to set the current HID protocol in use, either report or boot. */
- #define REQ_SetProtocol 0x0B
+ #define LEDMASK_USB_NOTREADY LEDS_LED1
+ #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
+ #define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
+ #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/* Type Defines: */
/** Type define for the keyboard HID report structure, for creating and sending HID reports to the host PC.
@@ -96,11 +76,16 @@
} USB_MouseReport_Data_t;
/* Function Prototypes: */
+ void SetupHardware(void);
+
void EVENT_USB_Connect(void);
void EVENT_USB_Disconnect(void);
void EVENT_USB_ConfigurationChanged(void);
void EVENT_USB_UnhandledControlPacket(void);
+ void EVENT_USB_StartOfFrame(void);
- void UpdateStatus(uint8_t CurrentStatus);
+ uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);
+ void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,
+ void* ReportData, uint16_t ReportSize);
#endif
diff --git a/Demos/Device/KeyboardMouse/makefile b/Demos/Device/KeyboardMouse/makefile
index c6b34d96e..ddad7d24b 100644
--- a/Demos/Device/KeyboardMouse/makefile
+++ b/Demos/Device/KeyboardMouse/makefile
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
Descriptors.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 \
@@ -136,7 +135,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.)
@@ -183,7 +182,7 @@ CSTANDARD = -std=gnu99
# Place -D or -U options here for C sources
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
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
diff --git a/Demos/Device/MIDI/makefile b/Demos/Device/MIDI/makefile
index 18fc3b154..485cdc710 100644
--- a/Demos/Device/MIDI/makefile
+++ b/Demos/Device/MIDI/makefile
@@ -183,7 +183,7 @@ CSTANDARD = -std=gnu99
# Place -D or -U options here for C sources
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
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
diff --git a/Demos/Device/MassStorage/Lib/DataflashManager.c b/Demos/Device/MassStorage/Lib/DataflashManager.c
index 4b624190f..87edef12b 100644
--- a/Demos/Device/MassStorage/Lib/DataflashManager.c
+++ b/Demos/Device/MassStorage/Lib/DataflashManager.c
@@ -46,7 +46,7 @@
* \param BlockAddress Data block starting address for the write sequence
* \param TotalBlocks Number of blocks of data to write
*/
-void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks)
+void DataflashManager_WriteBlocks(USB_ClassInfo_MS_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks)
{
uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
@@ -142,7 +142,7 @@ void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlo
BytesInBlockDiv16++;
/* Check if the current command is being aborted by the host */
- if (IsMassStoreReset)
+ if (MSInterfaceInfo->IsMassStoreReset)
return;
}
@@ -171,7 +171,7 @@ void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlo
* \param BlockAddress Data block starting address for the read sequence
* \param TotalBlocks Number of blocks of data to read
*/
-void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks)
+void DataflashManager_ReadBlocks(USB_ClassInfo_MS_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks)
{
uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
@@ -250,7 +250,7 @@ void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBloc
BytesInBlockDiv16++;
/* Check if the current command is being aborted by the host */
- if (IsMassStoreReset)
+ if (MSInterfaceInfo->IsMassStoreReset)
return;
}
@@ -341,11 +341,7 @@ void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t Tota
CurrDFPageByteDiv16++;
/* Increment the block 16 byte block counter */
- BytesInBlockDiv16++;
-
- /* Check if the current command is being aborted by the host */
- if (IsMassStoreReset)
- return;
+ BytesInBlockDiv16++;
}
/* Decrement the blocks remaining counter and reset the sub block counter */
@@ -421,10 +417,6 @@ void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t Total
/* Increment the block 16 byte block counter */
BytesInBlockDiv16++;
-
- /* Check if the current command is being aborted by the host */
- if (IsMassStoreReset)
- return;
}
/* Decrement the blocks remaining counter */
diff --git a/Demos/Device/MassStorage/Lib/DataflashManager.h b/Demos/Device/MassStorage/Lib/DataflashManager.h
index 1332fd3a3..b828051aa 100644
--- a/Demos/Device/MassStorage/Lib/DataflashManager.h
+++ b/Demos/Device/MassStorage/Lib/DataflashManager.h
@@ -64,8 +64,8 @@
#define VIRTUAL_MEMORY_BLOCKS (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE)
/* Function Prototypes: */
- void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks);
- void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks);
+ void DataflashManager_WriteBlocks(USB_ClassInfo_MS_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks);
+ void DataflashManager_ReadBlocks(USB_ClassInfo_MS_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks);
void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,
uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,
diff --git a/Demos/Device/MassStorage/Lib/SCSI.c b/Demos/Device/MassStorage/Lib/SCSI.c
index 5993a546d..8f3167a47 100644
--- a/Demos/Device/MassStorage/Lib/SCSI.c
+++ b/Demos/Device/MassStorage/Lib/SCSI.c
@@ -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
* a command failure due to a ILLEGAL REQUEST.
*/
-void SCSI_DecodeSCSICommand(void)
+bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_t* MSInterfaceInfo)
{
bool CommandSuccess = false;
/* Run the appropriate SCSI command hander function based on the passed command */
- switch (CommandBlock.SCSICommandData[0])
+ switch (MSInterfaceInfo->CommandBlock.SCSICommandData[0])
{
case SCSI_CMD_INQUIRY:
- CommandSuccess = SCSI_Command_Inquiry();
+ CommandSuccess = SCSI_Command_Inquiry(MSInterfaceInfo);
break;
case SCSI_CMD_REQUEST_SENSE:
- CommandSuccess = SCSI_Command_Request_Sense();
+ CommandSuccess = SCSI_Command_Request_Sense(MSInterfaceInfo);
break;
case SCSI_CMD_READ_CAPACITY_10:
- CommandSuccess = SCSI_Command_Read_Capacity_10();
+ CommandSuccess = SCSI_Command_Read_Capacity_10(MSInterfaceInfo);
break;
case SCSI_CMD_SEND_DIAGNOSTIC:
- CommandSuccess = SCSI_Command_Send_Diagnostic();
+ CommandSuccess = SCSI_Command_Send_Diagnostic(MSInterfaceInfo);
break;
case SCSI_CMD_WRITE_10:
- CommandSuccess = SCSI_Command_ReadWrite_10(DATA_WRITE);
+ CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_WRITE);
break;
case SCSI_CMD_READ_10:
- CommandSuccess = SCSI_Command_ReadWrite_10(DATA_READ);
+ CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_READ);
break;
case SCSI_CMD_TEST_UNIT_READY:
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
case SCSI_CMD_VERIFY_10:
/* These commands should just succeed, no handling required */
CommandSuccess = true;
- CommandBlock.DataTransferLength = 0;
+ MSInterfaceInfo->CommandBlock.DataTransferLength = 0;
break;
default:
/* Update the SENSE key to reflect the invalid command */
@@ -123,22 +123,18 @@ void SCSI_DecodeSCSICommand(void)
SCSI_ASENSEQ_NO_QUALIFIER);
break;
}
-
+
/* Check if command was successfully processed */
if (CommandSuccess)
{
- /* Command succeeded - set the CSW status and update the SENSE key */
- CommandStatus.Status = Command_Pass;
-
SCSI_SET_SENSE(SCSI_SENSE_KEY_GOOD,
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
- SCSI_ASENSEQ_NO_QUALIFIER);
- }
- else
- {
- /* Command failed - set the CSW status - failed command function updates the SENSE key */
- CommandStatus.Status = Command_Fail;
+ SCSI_ASENSEQ_NO_QUALIFIER);
+
+ return true;
}
+
+ return false;
}
/** Command processing for an issued SCSI INQUIRY command. This command returns information about the device's features
@@ -146,16 +142,16 @@ void SCSI_DecodeSCSICommand(void)
*
* \return Boolean true if the command completed successfully, false otherwise.
*/
-static bool SCSI_Command_Inquiry(void)
+static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_t* MSInterfaceInfo)
{
- uint16_t AllocationLength = (((uint16_t)CommandBlock.SCSICommandData[3] << 8) |
- CommandBlock.SCSICommandData[4]);
+ uint16_t AllocationLength = (((uint16_t)MSInterfaceInfo->CommandBlock.SCSICommandData[3] << 8) |
+ MSInterfaceInfo->CommandBlock.SCSICommandData[4]);
uint16_t BytesTransferred = (AllocationLength < sizeof(InquiryData))? AllocationLength :
sizeof(InquiryData);
/* Only the standard INQUIRY data is supported, check if any optional INQUIRY bits set */
- if ((CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) ||
- CommandBlock.SCSICommandData[2])
+ if ((MSInterfaceInfo->CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) ||
+ MSInterfaceInfo->CommandBlock.SCSICommandData[2])
{
/* Optional but unsupported bits set - update the SENSE key and fail the request */
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
@@ -164,20 +160,19 @@ static bool SCSI_Command_Inquiry(void)
return false;
}
-
- /* Write the INQUIRY data to the endpoint */
- Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, StreamCallback_AbortOnMassStoreReset);
+
+ Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, NO_STREAM_CALLBACK);
uint8_t PadBytes[AllocationLength - BytesTransferred];
/* Pad out remaining bytes with 0x00 */
- Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), StreamCallback_AbortOnMassStoreReset);
+ Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK);
/* Finalize the stream transfer to send the last packet */
Endpoint_ClearIN();
/* Succeed the command and update the bytes transferred counter */
- CommandBlock.DataTransferLength -= BytesTransferred;
+ MSInterfaceInfo->CommandBlock.DataTransferLength -= BytesTransferred;
return true;
}
@@ -187,24 +182,19 @@ static bool SCSI_Command_Inquiry(void)
*
* \return Boolean true if the command completed successfully, false otherwise.
*/
-static bool SCSI_Command_Request_Sense(void)
+static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_t* MSInterfaceInfo)
{
- uint8_t AllocationLength = CommandBlock.SCSICommandData[4];
+ uint8_t AllocationLength = MSInterfaceInfo->CommandBlock.SCSICommandData[4];
uint8_t BytesTransferred = (AllocationLength < sizeof(SenseData))? AllocationLength : sizeof(SenseData);
- /* Send the SENSE data - this indicates to the host the status of the last command */
- Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, StreamCallback_AbortOnMassStoreReset);
-
uint8_t PadBytes[AllocationLength - BytesTransferred];
-
- /* Pad out remaining bytes with 0x00 */
- Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), StreamCallback_AbortOnMassStoreReset);
- /* Finalize the stream transfer to send the last packet */
+ Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NO_STREAM_CALLBACK);
+ Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK);
Endpoint_ClearIN();
/* Succeed the command and update the bytes transferred counter */
- CommandBlock.DataTransferLength -= BytesTransferred;
+ MSInterfaceInfo->CommandBlock.DataTransferLength -= BytesTransferred;
return true;
}
@@ -214,23 +204,17 @@ static bool SCSI_Command_Request_Sense(void)
*
* \return Boolean true if the command completed successfully, false otherwise.
*/
-static bool SCSI_Command_Read_Capacity_10(void)
+static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_t* MSInterfaceInfo)
{
- /* Send the total number of logical blocks in the current LUN */
- Endpoint_Write_DWord_BE(LUN_MEDIA_BLOCKS - 1);
+ uint32_t TotalLUNs = (LUN_MEDIA_BLOCKS - 1);
+ uint32_t MediaBlockSize = VIRTUAL_MEMORY_BLOCK_SIZE;
- /* Send the logical block size of the device (must be 512 bytes) */
- Endpoint_Write_DWord_BE(VIRTUAL_MEMORY_BLOCK_SIZE);
-
- /* Check if the current command is being aborted by the host */
- if (IsMassStoreReset)
- return false;
-
- /* Send the endpoint data packet to the host */
+ Endpoint_Write_Stream_BE(&TotalLUNs, sizeof(TotalLUNs), NO_STREAM_CALLBACK);
+ Endpoint_Write_Stream_BE(&MediaBlockSize, sizeof(MediaBlockSize), NO_STREAM_CALLBACK);
Endpoint_ClearIN();
-
+
/* Succeed the command and update the bytes transferred counter */
- CommandBlock.DataTransferLength -= 8;
+ MSInterfaceInfo->CommandBlock.DataTransferLength -= 8;
return true;
}
@@ -241,12 +225,12 @@ static bool SCSI_Command_Read_Capacity_10(void)
*
* \return Boolean true if the command completed successfully, false otherwise.
*/
-static bool SCSI_Command_Send_Diagnostic(void)
+static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_t* MSInterfaceInfo)
{
uint8_t ReturnByte;
/* Check to see if the SELF TEST bit is not set */
- if (!(CommandBlock.SCSICommandData[1] & (1 << 2)))
+ if (!(MSInterfaceInfo->CommandBlock.SCSICommandData[1] & (1 << 2)))
{
/* Only self-test supported - update SENSE key and fail the command */
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
@@ -293,7 +277,7 @@ static bool SCSI_Command_Send_Diagnostic(void)
#endif
/* Succeed the command and update the bytes transferred counter */
- CommandBlock.DataTransferLength = 0;
+ MSInterfaceInfo->CommandBlock.DataTransferLength = 0;
return true;
}
@@ -306,20 +290,20 @@ static bool SCSI_Command_Send_Diagnostic(void)
*
* \return Boolean true if the command completed successfully, false otherwise.
*/
-static bool SCSI_Command_ReadWrite_10(const bool IsDataRead)
+static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_t* MSInterfaceInfo, const bool IsDataRead)
{
uint32_t BlockAddress;
uint16_t TotalBlocks;
/* Load in the 32-bit block address (SCSI uses big-endian, so have to do it byte-by-byte) */
- ((uint8_t*)&BlockAddress)[3] = CommandBlock.SCSICommandData[2];
- ((uint8_t*)&BlockAddress)[2] = CommandBlock.SCSICommandData[3];
- ((uint8_t*)&BlockAddress)[1] = CommandBlock.SCSICommandData[4];
- ((uint8_t*)&BlockAddress)[0] = CommandBlock.SCSICommandData[5];
+ ((uint8_t*)&BlockAddress)[3] = MSInterfaceInfo->CommandBlock.SCSICommandData[2];
+ ((uint8_t*)&BlockAddress)[2] = MSInterfaceInfo->CommandBlock.SCSICommandData[3];
+ ((uint8_t*)&BlockAddress)[1] = MSInterfaceInfo->CommandBlock.SCSICommandData[4];
+ ((uint8_t*)&BlockAddress)[0] = MSInterfaceInfo->CommandBlock.SCSICommandData[5];
/* Load in the 16-bit total blocks (SCSI uses big-endian, so have to do it byte-by-byte) */
- ((uint8_t*)&TotalBlocks)[1] = CommandBlock.SCSICommandData[7];
- ((uint8_t*)&TotalBlocks)[0] = CommandBlock.SCSICommandData[8];
+ ((uint8_t*)&TotalBlocks)[1] = MSInterfaceInfo->CommandBlock.SCSICommandData[7];
+ ((uint8_t*)&TotalBlocks)[0] = MSInterfaceInfo->CommandBlock.SCSICommandData[8];
/* Check if the block address is outside the maximum allowable value for the LUN */
if (BlockAddress >= LUN_MEDIA_BLOCKS)
@@ -334,17 +318,17 @@ static bool SCSI_Command_ReadWrite_10(const bool IsDataRead)
#if (TOTAL_LUNS > 1)
/* Adjust the given block address to the real media address based on the selected LUN */
- BlockAddress += ((uint32_t)CommandBlock.LUN * LUN_MEDIA_BLOCKS);
+ BlockAddress += ((uint32_t)MSInterfaceInfo->CommandBlock.LUN * LUN_MEDIA_BLOCKS);
#endif
/* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */
if (IsDataRead == DATA_READ)
- DataflashManager_ReadBlocks(BlockAddress, TotalBlocks);
+ DataflashManager_ReadBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
else
- DataflashManager_WriteBlocks(BlockAddress, TotalBlocks);
+ DataflashManager_WriteBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
/* Update the bytes transferred counter and succeed the command */
- CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);
+ MSInterfaceInfo->CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);
return true;
}
diff --git a/Demos/Device/MassStorage/Lib/SCSI.h b/Demos/Device/MassStorage/Lib/SCSI.h
index d7693cafb..3fd751dee 100644
--- a/Demos/Device/MassStorage/Lib/SCSI.h
+++ b/Demos/Device/MassStorage/Lib/SCSI.h
@@ -40,9 +40,8 @@
#include <avr/io.h>
#include <avr/pgmspace.h>
- #include <LUFA/Common/Common.h> // Function Attribute, Atomic, Debug and ISR Macros
- #include <LUFA/Drivers/USB/USB.h> // USB Functionality
- #include <LUFA/Drivers/Board/LEDs.h> // LEDs driver
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/MassStorage.h>
#include "MassStorage.h"
#include "Descriptors.h"
@@ -63,16 +62,16 @@
SenseData.AdditionalSenseQualifier = aqual; }MACROE
/** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be read from the storage medium. */
- #define DATA_READ true
+ #define DATA_READ true
/** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be written to the storage medium. */
- #define DATA_WRITE false
+ #define DATA_WRITE false
/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a Block Media device. */
- #define DEVICE_TYPE_BLOCK 0x00
+ #define DEVICE_TYPE_BLOCK 0x00
/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a CD-ROM device. */
- #define DEVICE_TYPE_CDROM 0x05
+ #define DEVICE_TYPE_CDROM 0x05
/* Type Defines: */
/** Type define for a SCSI response structure to a SCSI INQUIRY command. For details of the
@@ -136,14 +135,14 @@
} SCSI_Request_Sense_Response_t;
/* Function Prototypes: */
- void SCSI_DecodeSCSICommand(void);
+ bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_t* MSInterfaceInfo);
#if defined(INCLUDE_FROM_SCSI_C)
- static bool SCSI_Command_Inquiry(void);
- static bool SCSI_Command_Request_Sense(void);
- static bool SCSI_Command_Read_Capacity_10(void);
- static bool SCSI_Command_Send_Diagnostic(void);
- static bool SCSI_Command_ReadWrite_10(const bool IsDataRead);
+ static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_t* MSInterfaceInfo);
+ static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_t* MSInterfaceInfo);
+ static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_t* MSInterfaceInfo);
+ static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_t* MSInterfaceInfo);
+ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_t* MSInterfaceInfo, const bool IsDataRead);
#endif
#endif
diff --git a/Demos/Device/MassStorage/MassStorage.c b/Demos/Device/MassStorage/MassStorage.c
index 72a230219..8e2b9f450 100644
--- a/Demos/Device/MassStorage/MassStorage.c
+++ b/Demos/Device/MassStorage/MassStorage.c
@@ -28,36 +28,36 @@
this software.
*/
-/** \file
- *
- * Main source file for the Mass Storage demo. This file contains the main tasks of the demo and
- * is responsible for the initial application hardware configuration.
- */
-
-#define INCLUDE_FROM_MASSSTORAGE_C
#include "MassStorage.h"
-/* Scheduler Task List */
-TASK_LIST
-{
- { .Task = USB_MassStorage , .TaskStatus = TASK_STOP },
-};
+USB_ClassInfo_MS_t Disk_MS_Interface =
+ {
+ .InterfaceNumber = 0,
-/* Global Variables */
-/** Structure to hold the latest Command Block Wrapper issued by the host, containing a SCSI command to execute. */
-CommandBlockWrapper_t CommandBlock;
+ .DataINEndpointNumber = MASS_STORAGE_IN_EPNUM,
+ .DataINEndpointSize = MASS_STORAGE_IO_EPSIZE,
-/** Structure to hold the latest Command Status Wrapper to return to the host, containing the status of the last issued command. */
-CommandStatusWrapper_t CommandStatus = { .Signature = CSW_SIGNATURE };
+ .DataOUTEndpointNumber = MASS_STORAGE_OUT_EPNUM,
+ .DataOUTEndpointSize = MASS_STORAGE_IO_EPSIZE,
-/** Flag to asynchronously abort any in-progress data transfers upon the reception of a mass storage reset command. */
-volatile bool IsMassStoreReset = false;
+ .TotalLUNs = TOTAL_LUNS,
+ };
-/** Main program entry point. This routine configures the hardware required by the application, then
- * starts the scheduler to run the application tasks.
- */
int main(void)
{
+ SetupHardware();
+
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+
+ for (;;)
+ {
+ USB_MS_USBTask(&Disk_MS_Interface);
+ USB_USBTask();
+ }
+}
+
+void SetupHardware(void)
+{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
wdt_disable();
@@ -68,303 +68,42 @@ int main(void)
/* Hardware Initialization */
LEDs_Init();
Dataflash_Init(SPI_SPEED_FCPU_DIV_2);
+ USB_Init();
/* Clear Dataflash sector protections, if enabled */
DataflashManager_ResetDataflashProtections();
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
-
- /* Initialize Scheduler so that it can be used */
- Scheduler_Init();
-
- /* Initialize USB Subsystem */
- USB_Init();
-
- /* Scheduling - routine never returns, so put this last in the main function */
- Scheduler_Start();
}
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs. */
void EVENT_USB_Connect(void)
{
- /* Indicate USB enumerating */
- UpdateStatus(Status_USBEnumerating);
-
- /* Reset the MSReset flag upon connection */
- IsMassStoreReset = false;
+ LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- * the status LEDs and stops the Mass Storage management task.
- */
void EVENT_USB_Disconnect(void)
{
- /* Stop running mass storage task */
- Scheduler_SetTaskMode(USB_MassStorage, TASK_STOP);
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration
- * of the USB device after enumeration - the device endpoints are configured and the Mass Storage management task started.
- */
void EVENT_USB_ConfigurationChanged(void)
{
- /* Setup Mass Storage In and Out Endpoints */
- Endpoint_ConfigureEndpoint(MASS_STORAGE_IN_EPNUM, EP_TYPE_BULK,
- ENDPOINT_DIR_IN, MASS_STORAGE_IO_EPSIZE,
- ENDPOINT_BANK_DOUBLE);
-
- Endpoint_ConfigureEndpoint(MASS_STORAGE_OUT_EPNUM, EP_TYPE_BULK,
- ENDPOINT_DIR_OUT, MASS_STORAGE_IO_EPSIZE,
- ENDPOINT_BANK_DOUBLE);
+ LEDs_SetAllLEDs(LEDMASK_USB_READY);
- /* Indicate USB connected and ready */
- UpdateStatus(Status_USBReady);
-
- /* Start mass storage task */
- Scheduler_SetTaskMode(USB_MassStorage, TASK_RUN);
+ if (!(USB_MS_ConfigureEndpoints(&Disk_MS_Interface)))
+ LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- * control requests that are not handled internally by the USB library (including the Mass Storage class-specific
- * requests) so that they can be handled appropriately for the application.
- */
void EVENT_USB_UnhandledControlPacket(void)
{
- /* Process UFI specific control requests */
- switch (USB_ControlRequest.bRequest)
- {
- case REQ_MassStorageReset:
- if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- Endpoint_ClearSETUP();
-
- /* Indicate that the current transfer should be aborted */
- IsMassStoreReset = true;
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsINReady()));
- Endpoint_ClearIN();
- }
-
- break;
- case REQ_GetMaxLUN:
- if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- Endpoint_ClearSETUP();
-
- /* Indicate to the host the number of supported LUNs (virtual disks) on the device */
- Endpoint_Write_Byte(TOTAL_LUNS - 1);
-
- Endpoint_ClearIN();
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsOUTReceived()));
- Endpoint_ClearOUT();
- }
-
- break;
- }
-}
-
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- * log to a serial port, or anything else that is suitable for status updates.
- *
- * \param CurrentStatus Current status of the system, from the MassStorage_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
-{
- uint8_t LEDMask = LEDS_NO_LEDS;
-
- /* Set the LED mask to the appropriate LED mask based on the given status code */
- switch (CurrentStatus)
- {
- case Status_USBNotReady:
- LEDMask = (LEDS_LED1);
- break;
- case Status_USBEnumerating:
- LEDMask = (LEDS_LED1 | LEDS_LED2);
- break;
- case Status_USBReady:
- LEDMask = (LEDS_LED2 | LEDS_LED4);
- break;
- case Status_CommandBlockError:
- LEDMask = (LEDS_LED1);
- break;
- case Status_ProcessingCommandBlock:
- LEDMask = (LEDS_LED1 | LEDS_LED2);
- break;
- }
-
- /* Set the board LEDs to the new LED mask */
- LEDs_SetAllLEDs(LEDMask);
-}
-
-/** Task to manage the Mass Storage interface, reading in Command Block Wrappers from the host, processing the SCSI commands they
- * contain, and returning Command Status Wrappers back to the host to indicate the success or failure of the last issued command.
- */
-TASK(USB_MassStorage)
-{
- /* Check if the USB System is connected to a Host */
- if (USB_IsConnected)
- {
- /* Select the Data Out Endpoint */
- Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
-
- /* Check to see if a command from the host has been issued */
- if (Endpoint_IsReadWriteAllowed())
- {
- /* Indicate busy */
- UpdateStatus(Status_ProcessingCommandBlock);
-
- /* Process sent command block from the host */
- if (ReadInCommandBlock())
- {
- /* Check direction of command, select Data IN endpoint if data is from the device */
- if (CommandBlock.Flags & COMMAND_DIRECTION_DATA_IN)
- Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);
-
- /* Decode the received SCSI command */
- SCSI_DecodeSCSICommand();
-
- /* Load in the CBW tag into the CSW to link them together */
- CommandStatus.Tag = CommandBlock.Tag;
-
- /* Load in the data residue counter into the CSW */
- CommandStatus.DataTransferResidue = CommandBlock.DataTransferLength;
-
- /* Stall the selected data pipe if command failed (if data is still to be transferred) */
- if ((CommandStatus.Status == Command_Fail) && (CommandStatus.DataTransferResidue))
- Endpoint_StallTransaction();
-
- /* Return command status block to the host */
- ReturnCommandStatus();
-
- /* Check if a Mass Storage Reset occurred */
- if (IsMassStoreReset)
- {
- /* Reset the data endpoint banks */
- Endpoint_ResetFIFO(MASS_STORAGE_OUT_EPNUM);
- Endpoint_ResetFIFO(MASS_STORAGE_IN_EPNUM);
-
- Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
- Endpoint_ClearStall();
- Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);
- Endpoint_ClearStall();
-
- /* Clear the abort transfer flag */
- IsMassStoreReset = false;
- }
-
- /* Indicate ready */
- UpdateStatus(Status_USBReady);
- }
- else
- {
- /* Indicate error reading in the command block from the host */
- UpdateStatus(Status_CommandBlockError);
- }
- }
- }
-}
-
-/** Function to read in a command block from the host, via the bulk data OUT endpoint. This function reads in the next command block
- * if one has been issued, and performs validation to ensure that the block command is valid.
- *
- * \return Boolean true if a valid command block has been read in from the endpoint, false otherwise
- */
-static bool ReadInCommandBlock(void)
-{
- /* Select the Data Out endpoint */
- Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
-
- /* Read in command block header */
- Endpoint_Read_Stream_LE(&CommandBlock, (sizeof(CommandBlock) - sizeof(CommandBlock.SCSICommandData)),
- StreamCallback_AbortOnMassStoreReset);
-
- /* Check if the current command is being aborted by the host */
- if (IsMassStoreReset)
- return false;
-
- /* Verify the command block - abort if invalid */
- if ((CommandBlock.Signature != CBW_SIGNATURE) ||
- (CommandBlock.LUN >= TOTAL_LUNS) ||
- (CommandBlock.SCSICommandLength > MAX_SCSI_COMMAND_LENGTH))
- {
- /* Stall both data pipes until reset by host */
- Endpoint_StallTransaction();
- Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);
- Endpoint_StallTransaction();
-
- return false;
- }
-
- /* Read in command block command data */
- Endpoint_Read_Stream_LE(&CommandBlock.SCSICommandData,
- CommandBlock.SCSICommandLength,
- StreamCallback_AbortOnMassStoreReset);
-
- /* Check if the current command is being aborted by the host */
- if (IsMassStoreReset)
- return false;
-
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearOUT();
-
- return true;
+ USB_MS_ProcessControlPacket(&Disk_MS_Interface);
}
-/** Returns the filled Command Status Wrapper back to the host via the bulk data IN endpoint, waiting for the host to clear any
- * stalled data endpoints as needed.
- */
-static void ReturnCommandStatus(void)
+bool CALLBACK_USB_MS_SCSICommandReceived(USB_ClassInfo_MS_t* MSInterfaceInfo)
{
- /* Select the Data Out endpoint */
- Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
-
- /* While data pipe is stalled, wait until the host issues a control request to clear the stall */
- while (Endpoint_IsStalled())
- {
- /* Check if the current command is being aborted by the host */
- if (IsMassStoreReset)
- return;
- }
-
- /* Select the Data In endpoint */
- Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);
-
- /* While data pipe is stalled, wait until the host issues a control request to clear the stall */
- while (Endpoint_IsStalled())
- {
- /* Check if the current command is being aborted by the host */
- if (IsMassStoreReset)
- return;
- }
+ bool CommandSuccess;
- /* Write the CSW to the endpoint */
- Endpoint_Write_Stream_LE(&CommandStatus, sizeof(CommandStatus),
- StreamCallback_AbortOnMassStoreReset);
-
- /* Check if the current command is being aborted by the host */
- if (IsMassStoreReset)
- return;
-
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearIN();
-}
-
-/** Stream callback function for the Endpoint stream read and write functions. This callback will abort the current stream transfer
- * if a Mass Storage Reset request has been issued to the control endpoint.
- */
-uint8_t StreamCallback_AbortOnMassStoreReset(void)
-{
- /* Abort if a Mass Storage reset command was received */
- if (IsMassStoreReset)
- return STREAMCALLBACK_Abort;
+ LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
+ CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo);
+ LEDs_SetAllLEDs(LEDMASK_USB_READY);
- /* Continue with the current stream operation */
- return STREAMCALLBACK_Continue;
+ return CommandSuccess;
}
diff --git a/Demos/Device/MassStorage/MassStorage.h b/Demos/Device/MassStorage/MassStorage.h
index cbd3cd931..a50edac99 100644
--- a/Demos/Device/MassStorage/MassStorage.h
+++ b/Demos/Device/MassStorage/MassStorage.h
@@ -46,104 +46,33 @@
#include "Lib/SCSI.h"
#include "Lib/DataflashManager.h"
- #include <LUFA/Version.h> // Library Version Information
- #include <LUFA/Drivers/USB/USB.h> // USB Functionality
- #include <LUFA/Drivers/Board/LEDs.h> // LEDs driver
- #include <LUFA/Drivers/Board/Dataflash.h> // Dataflash chip driver
- #include <LUFA/Scheduler/Scheduler.h> // Simple scheduler for task management
+ #include <LUFA/Version.h>
+ #include <LUFA/Drivers/Board/Joystick.h>
+ #include <LUFA/Drivers/Board/LEDs.h>
+ #include <LUFA/Drivers/Board/Buttons.h>
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/MassStorage.h>
/* Macros: */
- /** Mass Storage Class specific request to reset the Mass Storage interface, ready for the next command. */
- #define REQ_MassStorageReset 0xFF
-
- /** Mass Storage Class specific request to retrieve the total number of Logical Units (drives) in the SCSI device. */
- #define REQ_GetMaxLUN 0xFE
-
- /** Maximum length of a SCSI command which can be issued by the device or host in a Mass Storage bulk wrapper. */
- #define MAX_SCSI_COMMAND_LENGTH 16
+ #define LEDMASK_USB_NOTREADY LEDS_LED1
+ #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
+ #define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
+ #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
+ #define LEDMASK_USB_BUSY LEDS_LED2
- /** Total number of Logical Units (drives) in the device. The total device capacity is shared equally between
- * each drive - this can be set to any positive non-zero amount.
- */
- #define TOTAL_LUNS 2
+ #define TOTAL_LUNS 2
/** Blocks in each LUN, calculated from the total capacity divided by the total number of Logical Units in the device. */
- #define LUN_MEDIA_BLOCKS (VIRTUAL_MEMORY_BLOCKS / TOTAL_LUNS)
-
- /** Magic signature for a Command Block Wrapper used in the Mass Storage Bulk-Only transport protocol. */
- #define CBW_SIGNATURE 0x43425355UL
-
- /** Magic signature for a Command Status Wrapper used in the Mass Storage Bulk-Only transport protocol. */
- #define CSW_SIGNATURE 0x53425355UL
-
- /** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from host-to-device. */
- #define COMMAND_DIRECTION_DATA_OUT (0 << 7)
-
- /** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from device-to-host. */
- #define COMMAND_DIRECTION_DATA_IN (1 << 7)
-
- /* Type defines: */
- /** Type define for a Command Block Wrapper, used in the Mass Storage Bulk-Only Transport protocol. */
- typedef struct
- {
- uint32_t Signature; /**< Command block signature, must be CBW_SIGNATURE to indicate a valid Command Block */
- uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper */
- uint32_t DataTransferLength; /** Length of the optional data portion of the issued command, in bytes */
- uint8_t Flags; /**< Command block flags, indicating command data direction */
- uint8_t LUN; /**< Logical Unit number this command is issued to */
- uint8_t SCSICommandLength; /**< Length of the issued SCSI command within the SCSI command data array */
- uint8_t SCSICommandData[MAX_SCSI_COMMAND_LENGTH]; /**< Issued SCSI command in the Command Block */
- } CommandBlockWrapper_t;
-
- /** Type define for a Command Status Wrapper, used in the Mass Storage Bulk-Only Transport protocol. */
- typedef struct
- {
- uint32_t Signature; /**< Status block signature, must be CSW_SIGNATURE to indicate a valid Command Status */
- uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper */
- uint32_t DataTransferResidue; /**< Number of bytes of data not processed in the SCSI command */
- uint8_t Status; /**< Status code of the issued command - a value from the MassStorage_CommandStatusCodes_t enum */
- } CommandStatusWrapper_t;
-
- /* Enums: */
- /** Enum for the possible command status wrapper return status codes. */
- enum MassStorage_CommandStatusCodes_t
- {
- Command_Pass = 0, /**< Command completed with no error */
- Command_Fail = 1, /**< Command failed to complete - host may check the exact error via a SCSI REQUEST SENSE command */
- Phase_Error = 2 /**< Command failed due to being invalid in the current phase */
- };
-
- /** Enum for the possible status codes for passing to the UpdateStatus() function. */
- enum MassStorage_StatusCodes_t
- {
- Status_USBNotReady = 0, /**< USB is not ready (disconnected from a USB host) */
- Status_USBEnumerating = 1, /**< USB interface is enumerating */
- Status_USBReady = 2, /**< USB interface is connected and ready */
- Status_CommandBlockError = 3, /**< Processing a SCSI command block from the host */
- Status_ProcessingCommandBlock = 4, /**< Error during the processing of a SCSI command block from the host */
- };
-
- /* Global Variables: */
- extern CommandBlockWrapper_t CommandBlock;
- extern CommandStatusWrapper_t CommandStatus;
- extern volatile bool IsMassStoreReset;
-
- /* Task Definitions: */
- TASK(USB_MassStorage);
+ #define LUN_MEDIA_BLOCKS (VIRTUAL_MEMORY_BLOCKS / TOTAL_LUNS)
/* Function Prototypes: */
+ void SetupHardware(void);
+
void EVENT_USB_Connect(void);
void EVENT_USB_Disconnect(void);
void EVENT_USB_ConfigurationChanged(void);
void EVENT_USB_UnhandledControlPacket(void);
- void UpdateStatus(uint8_t CurrentStatus);
-
- #if defined(INCLUDE_FROM_MASSSTORAGE_C)
- static bool ReadInCommandBlock(void);
- static void ReturnCommandStatus(void);
- #endif
-
- uint8_t StreamCallback_AbortOnMassStoreReset(void);
+ bool CALLBACK_USB_MS_SCSICommandReceived(USB_ClassInfo_MS_t* MSInterfaceInfo);
#endif
diff --git a/Demos/Device/MassStorage/makefile b/Demos/Device/MassStorage/makefile
index 93f895727..c4adfc9be 100644
--- a/Demos/Device/MassStorage/makefile
+++ b/Demos/Device/MassStorage/makefile
@@ -127,7 +127,6 @@ SRC = $(TARGET).c \
Descriptors.c \
Lib/SCSI.c \
Lib/DataflashManager.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 \
@@ -138,7 +137,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/MassStorage.c \
# List C++ source files here. (C dependencies are automatically generated.)
@@ -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
CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
-CDEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Place -D or -U options here for ASM sources
diff --git a/Demos/Device/Mouse/Descriptors.h b/Demos/Device/Mouse/Descriptors.h
index 883ef31e8..ef3215ca6 100644
--- a/Demos/Device/Mouse/Descriptors.h
+++ b/Demos/Device/Mouse/Descriptors.h
@@ -37,30 +37,12 @@
#define _DESCRIPTORS_H_
/* Includes: */
- #include <LUFA/Drivers/USB/USB.h>
-
#include <avr/pgmspace.h>
- /* Type Defines: */
- /** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID
- * specification for details on the structure elements.
- */
- typedef struct
- {
- USB_Descriptor_Header_t Header;
-
- uint16_t HIDSpec;
- uint8_t CountryCode;
-
- uint8_t TotalReportDescriptors;
-
- uint8_t HIDReportType;
- uint16_t HIDReportLength;
- } USB_Descriptor_HID_t;
-
- /** Type define for the data type used to store HID report descriptor elements. */
- typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/HID.h>
+ /* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host.
@@ -80,12 +62,6 @@
/** Size in bytes of the Mouse HID reporting IN endpoint. */
#define MOUSE_EPSIZE 8
- /** Descriptor header type value, to indicate a HID class HID descriptor. */
- #define DTYPE_HID 0x21
-
- /** Descriptor header type value, to indicate a HID class HID report descriptor. */
- #define DTYPE_Report 0x22
-
/* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
diff --git a/Demos/Device/Mouse/Mouse.c b/Demos/Device/Mouse/Mouse.c
index 32b12fc61..57c1aa114 100644
--- a/Demos/Device/Mouse/Mouse.c
+++ b/Demos/Device/Mouse/Mouse.c
@@ -27,44 +27,33 @@
arising out of or in connection with the use or performance of
this software.
*/
-
-/** \file
- *
- * Main source file for the Mouse demo. This file contains the main tasks of the demo and
- * is responsible for the initial application hardware configuration.
- */
#include "Mouse.h"
-/* Scheduler Task List */
-TASK_LIST
-{
- { .Task = USB_USBTask , .TaskStatus = TASK_STOP },
- { .Task = USB_Mouse_Report , .TaskStatus = TASK_STOP },
-};
+USB_ClassInfo_HID_t Mouse_HID_Interface =
+ {
+ .InterfaceNumber = 0,
-/* Global Variables */
-/** Indicates what report mode the host has requested, true for normal HID reporting mode, false for special boot
- * protocol reporting mode.
- */
-bool UsingReportProtocol = true;
+ .ReportINEndpointNumber = MOUSE_EPNUM,
+ .ReportINEndpointSize = MOUSE_EPSIZE,
-/** Current Idle period. This is set by the host via a Set Idle HID class request to silence the device's reports
- * for either the entire idle duration, or until the report status changes (e.g. the user moves the mouse).
- */
-uint16_t IdleCount = HID_IDLE_CHANGESONLY;
+ .ReportBufferSize = sizeof(USB_MouseReport_Data_t),
+ };
-/** Current Idle period remaining. When the IdleCount value is set, this tracks the remaining number of idle
- * milliseconds. This is separate to the IdleCount timer and is incremented and compared as the host may request
- * the current idle period via a Get Idle HID class request, thus its value must be preserved.
- */
-uint16_t IdleMSRemaining = 0;
+int main(void)
+{
+ SetupHardware();
+
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+ for (;;)
+ {
+ USB_HID_USBTask(&Mouse_HID_Interface);
+ USB_USBTask();
+ }
+}
-/** Main program entry point. This routine configures the hardware required by the application, then
- * starts the scheduler to run the application tasks.
- */
-int main(void)
+void SetupHardware(void)
{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
@@ -77,284 +66,64 @@ int main(void)
Joystick_Init();
LEDs_Init();
Buttons_Init();
-
- /* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */
- OCR0A = 0x7D;
- TCCR0A = (1 << WGM01);
- TCCR0B = ((1 << CS01) | (1 << CS00));
- TIMSK0 = (1 << OCIE0A);
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
-
- /* Initialize Scheduler so that it can be used */
- Scheduler_Init();
-
- /* Initialize USB Subsystem */
USB_Init();
-
- /* Scheduling - routine never returns, so put this last in the main function */
- Scheduler_Start();
}
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
- * starts the library USB task to begin the enumeration and USB management process.
- */
void EVENT_USB_Connect(void)
{
- /* Start USB management task */
- Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
- /* Indicate USB enumerating */
- UpdateStatus(Status_USBEnumerating);
-
- /* Default to report protocol on connect */
- UsingReportProtocol = true;
+ LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- * the status LEDs and stops the USB management and Mouse reporting tasks.
- */
void EVENT_USB_Disconnect(void)
{
- /* Stop running mouse reporting and USB management tasks */
- Scheduler_SetTaskMode(USB_Mouse_Report, TASK_STOP);
- Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host sets the current configuration
- * of the USB device after enumeration - the device endpoints are configured and the mouse reporting task started.
- */
void EVENT_USB_ConfigurationChanged(void)
{
- /* Setup Mouse Report Endpoint */
- Endpoint_ConfigureEndpoint(MOUSE_EPNUM, EP_TYPE_INTERRUPT,
- ENDPOINT_DIR_IN, MOUSE_EPSIZE,
- ENDPOINT_BANK_SINGLE);
-
- /* Indicate USB connected and ready */
- UpdateStatus(Status_USBReady);
+ LEDs_SetAllLEDs(LEDMASK_USB_READY);
- /* Start running mouse reporting task */
- Scheduler_SetTaskMode(USB_Mouse_Report, TASK_RUN);
+ if (!(USB_HID_ConfigureEndpoints(&Mouse_HID_Interface)))
+ LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- * control requests that are not handled internally by the USB library (including the HID commands, which are
- * all issued via the control endpoint), so that they can be handled appropriately for the application.
- */
void EVENT_USB_UnhandledControlPacket(void)
{
- /* Handle HID Class specific requests */
- switch (USB_ControlRequest.bRequest)
- {
- case REQ_GetReport:
- if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- USB_MouseReport_Data_t MouseReportData;
-
- Endpoint_ClearSETUP();
-
- /* Create the next mouse report for transmission to the host */
- CreateMouseReport(&MouseReportData);
-
- /* Write the report data to the control endpoint */
- Endpoint_Write_Control_Stream_LE(&MouseReportData, sizeof(MouseReportData));
-
- /* Clear the report data afterwards */
- memset(&MouseReportData, 0, sizeof(MouseReportData));
-
- /* Finalize the stream transfer to send the last packet or clear the host abort */
- Endpoint_ClearOUT();
- }
-
- break;
- case REQ_GetProtocol:
- if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- Endpoint_ClearSETUP();
-
- /* Write the current protocol flag to the host */
- Endpoint_Write_Byte(UsingReportProtocol);
-
- /* Send the flag to the host */
- Endpoint_ClearIN();
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsOUTReceived()));
- Endpoint_ClearOUT();
- }
-
- break;
- case REQ_SetProtocol:
- if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- Endpoint_ClearSETUP();
-
- /* Set or clear the flag depending on what the host indicates that the current Protocol should be */
- UsingReportProtocol = (USB_ControlRequest.wValue != 0);
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsINReady()));
- Endpoint_ClearIN();
- }
-
- break;
- case REQ_SetIdle:
- if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- Endpoint_ClearSETUP();
-
- /* Get idle period in MSB */
- IdleCount = (USB_ControlRequest.wValue >> 8);
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsINReady()));
- Endpoint_ClearIN();
- }
-
- break;
- case REQ_GetIdle:
- if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- Endpoint_ClearSETUP();
-
- /* Write the current idle duration to the host */
- Endpoint_Write_Byte(IdleCount);
-
- /* Send the flag to the host */
- Endpoint_ClearIN();
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsOUTReceived()));
- Endpoint_ClearOUT();
- }
-
- break;
- }
+ USB_HID_ProcessControlPacket(&Mouse_HID_Interface);
}
-/** ISR for the timer 0 compare vector. This ISR fires once each millisecond, and increments the
- * scheduler elapsed idle period counter when the host has set an idle period.
- */
-ISR(TIMER0_COMPA_vect, ISR_BLOCK)
+void EVENT_USB_StartOfFrame(void)
{
- /* One millisecond has elapsed, decrement the idle time remaining counter if it has not already elapsed */
- if (IdleMSRemaining)
- IdleMSRemaining--;
+ USB_HID_RegisterStartOfFrame(&Mouse_HID_Interface);
}
-/** Fills the given HID report data structure with the next HID report to send to the host.
- *
- * \param ReportData Pointer to a HID report data structure to be filled
- */
-void CreateMouseReport(USB_MouseReport_Data_t* ReportData)
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)
{
+ USB_MouseReport_Data_t* MouseReport = (USB_MouseReport_Data_t*)ReportData;
+
uint8_t JoyStatus_LCL = Joystick_GetStatus();
uint8_t ButtonStatus_LCL = Buttons_GetStatus();
-
- /* Clear the report contents */
- memset(ReportData, 0, sizeof(USB_MouseReport_Data_t));
if (JoyStatus_LCL & JOY_UP)
- ReportData->Y = -1;
+ MouseReport->Y = -1;
else if (JoyStatus_LCL & JOY_DOWN)
- ReportData->Y = 1;
+ MouseReport->Y = 1;
if (JoyStatus_LCL & JOY_RIGHT)
- ReportData->X = 1;
+ MouseReport->X = 1;
else if (JoyStatus_LCL & JOY_LEFT)
- ReportData->X = -1;
+ MouseReport->X = -1;
if (JoyStatus_LCL & JOY_PRESS)
- ReportData->Button = (1 << 0);
+ MouseReport->Button = (1 << 0);
if (ButtonStatus_LCL & BUTTONS_BUTTON1)
- ReportData->Button |= (1 << 1);
-}
-
-/** Sends the next HID report to the host, via the keyboard data endpoint. */
-void SendNextReport(void)
-{
- static USB_MouseReport_Data_t PrevMouseReportData;
- USB_MouseReport_Data_t MouseReportData;
- bool SendReport;
-
- /* Create the next mouse report for transmission to the host */
- CreateMouseReport(&MouseReportData);
-
- /* Check to see if the report data has changed - if so a report MUST be sent */
- SendReport = (memcmp(&PrevMouseReportData, &MouseReportData, sizeof(USB_MouseReport_Data_t)) != 0);
-
- /* Override the check if the Y or X values are non-zero - we want continuous movement while the joystick
- * is being held down (via continuous reports), otherwise the cursor will only move once per joystick toggle */
- if ((MouseReportData.Y != 0) || (MouseReportData.X != 0))
- SendReport = true;
-
- /* Save the current report data for later comparison to check for changes */
- PrevMouseReportData = MouseReportData;
-
- /* Check if the idle period is set and has elapsed */
- if ((IdleCount != HID_IDLE_CHANGESONLY) && (!(IdleMSRemaining)))
- {
- /* Reset the idle time remaining counter, must multiply by 4 to get the duration in milliseconds */
- IdleMSRemaining = (IdleCount << 2);
-
- /* Idle period is set and has elapsed, must send a report to the host */
- SendReport = true;
- }
+ MouseReport->Button |= (1 << 1);
- /* Select the Mouse Report Endpoint */
- Endpoint_SelectEndpoint(MOUSE_EPNUM);
-
- /* Check if Mouse Endpoint Ready for Read/Write and if we should send a new report */
- if (Endpoint_IsReadWriteAllowed() && SendReport)
- {
- /* Write Mouse Report Data */
- Endpoint_Write_Stream_LE(&MouseReportData, sizeof(MouseReportData));
-
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearIN();
- }
+ return sizeof(USB_MouseReport_Data_t);
}
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- * log to a serial port, or anything else that is suitable for status updates.
- *
- * \param CurrentStatus Current status of the system, from the Mouse_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)
{
- uint8_t LEDMask = LEDS_NO_LEDS;
-
- /* Set the LED mask to the appropriate LED mask based on the given status code */
- switch (CurrentStatus)
- {
- case Status_USBNotReady:
- LEDMask = (LEDS_LED1);
- break;
- case Status_USBEnumerating:
- LEDMask = (LEDS_LED1 | LEDS_LED2);
- break;
- case Status_USBReady:
- LEDMask = (LEDS_LED2 | LEDS_LED4);
- break;
- }
-
- /* Set the board LEDs to the new LED mask */
- LEDs_SetAllLEDs(LEDMask);
-}
-
-/** Task to manage HID report generation and transmission to the host, when in report mode. */
-TASK(USB_Mouse_Report)
-{
- /* Check if the USB system is connected to a host */
- if (USB_IsConnected)
- {
- /* Send the next mouse report to the host */
- SendNextReport();
- }
+ // Unused (but mandatory for the HID class driver) in this demo, since there are no Host->Device reports
}
diff --git a/Demos/Device/Mouse/Mouse.h b/Demos/Device/Mouse/Mouse.h
index 65879da8e..5c8049590 100644
--- a/Demos/Device/Mouse/Mouse.h
+++ b/Demos/Device/Mouse/Mouse.h
@@ -46,37 +46,12 @@
#include "Descriptors.h"
- #include <LUFA/Version.h> // Library Version Information
- #include <LUFA/Drivers/USB/USB.h> // USB Functionality
- #include <LUFA/Drivers/Board/Joystick.h> // Joystick driver
- #include <LUFA/Drivers/Board/LEDs.h> // LEDs driver
- #include <LUFA/Drivers/Board/Buttons.h> // Board Buttons driver
- #include <LUFA/Scheduler/Scheduler.h> // Simple scheduler for task management
-
- /* Task Definitions: */
- TASK(USB_Mouse_Report);
-
- /* Macros: */
- /** Idle period indicating that reports should be sent only when the inputs have changed */
- #define HID_IDLE_CHANGESONLY 0
-
- /** HID Class specific request to get the next HID report from the device. */
- #define REQ_GetReport 0x01
-
- /** HID Class specific request to get the idle timeout period of the device. */
- #define REQ_GetIdle 0x02
-
- /** HID Class specific request to send the next HID report to the device. */
- #define REQ_SetReport 0x09
-
- /** HID Class specific request to set the idle timeout period of the device. */
- #define REQ_SetIdle 0x0A
-
- /** HID Class specific request to get the current HID protocol in use, either report or boot. */
- #define REQ_GetProtocol 0x03
-
- /** HID Class specific request to set the current HID protocol in use, either report or boot. */
- #define REQ_SetProtocol 0x0B
+ #include <LUFA/Version.h>
+ #include <LUFA/Drivers/Board/Joystick.h>
+ #include <LUFA/Drivers/Board/LEDs.h>
+ #include <LUFA/Drivers/Board/Buttons.h>
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/HID.h>
/* Type Defines: */
/** Type define for the mouse HID report structure, for creating and sending HID reports to the host PC.
@@ -89,22 +64,23 @@
int8_t Y; /**< Current mouse delta Y movement, as a signed 8-bit integer */
} USB_MouseReport_Data_t;
- /* Enums: */
- /** Enum for the possible status codes for passing to the UpdateStatus() function. */
- enum Mouse_StatusCodes_t
- {
- Status_USBNotReady = 0, /**< USB is not ready (disconnected from a USB host) */
- Status_USBEnumerating = 1, /**< USB interface is enumerating */
- Status_USBReady = 2, /**< USB interface is connected and ready */
- };
+ /* Macros: */
+ #define LEDMASK_USB_NOTREADY LEDS_LED1
+ #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
+ #define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
+ #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/* Function Prototypes: */
+ void SetupHardware(void);
+
void EVENT_USB_Connect(void);
void EVENT_USB_Disconnect(void);
void EVENT_USB_ConfigurationChanged(void);
void EVENT_USB_UnhandledControlPacket(void);
+ void EVENT_USB_StartOfFrame(void);
- void CreateMouseReport(USB_MouseReport_Data_t* ReportData);
- void UpdateStatus(uint8_t CurrentStatus);
+ uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);
+ void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,
+ void* ReportData, uint16_t ReportSize);
#endif
diff --git a/Demos/Device/Mouse/makefile b/Demos/Device/Mouse/makefile
index 632bf91ae..4c18f9d4a 100644
--- a/Demos/Device/Mouse/makefile
+++ b/Demos/Device/Mouse/makefile
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
Descriptors.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 \
@@ -136,7 +135,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.)
CPPSRC =
@@ -182,7 +181,7 @@ CSTANDARD = -std=gnu99
# Place -D or -U options here for C sources
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
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
diff --git a/Demos/Device/RNDISEthernet/Lib/ARP.h b/Demos/Device/RNDISEthernet/Lib/ARP.h
index 8551df85b..f05d8f093 100644
--- a/Demos/Device/RNDISEthernet/Lib/ARP.h
+++ b/Demos/Device/RNDISEthernet/Lib/ARP.h
@@ -38,9 +38,7 @@
/* Includes: */
#include <avr/io.h>
- #include <string.h>
-
- #include <LUFA/Scheduler/Scheduler.h>
+ #include <string.h>
#include "EthernetProtocols.h"
#include "Ethernet.h"
diff --git a/Demos/Device/RNDISEthernet/Lib/Ethernet.c b/Demos/Device/RNDISEthernet/Lib/Ethernet.c
index 3d34f716a..57380a082 100644
--- a/Demos/Device/RNDISEthernet/Lib/Ethernet.c
+++ b/Demos/Device/RNDISEthernet/Lib/Ethernet.c
@@ -38,12 +38,6 @@
#include "Ethernet.h"
/* Global Variables: */
-/** Ethernet Frame buffer structure, to hold the incoming Ethernet frame from the host. */
-Ethernet_Frame_Info_t FrameIN;
-
-/** Ethernet Frame buffer structure, to hold the outgoing Ethernet frame to the host. */
-Ethernet_Frame_Info_t FrameOUT;
-
/** Constant for convenience when checking against or setting a MAC address to the virtual server MAC address. */
const MAC_Address_t ServerMACAddress = {SERVER_MAC_ADDRESS};
@@ -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
* frame buffer if the sub protocol handlers create a valid response.
*/
-void Ethernet_ProcessPacket(void)
+void Ethernet_ProcessPacket(Ethernet_Frame_Info_t* FrameIN, Ethernet_Frame_Info_t* FrameOUT)
{
- DecodeEthernetFrameHeader(FrameIN.FrameData);
+ DecodeEthernetFrameHeader(FrameIN->FrameData);
/* Cast the incoming Ethernet frame to the Ethernet header type */
- Ethernet_Frame_Header_t* FrameINHeader = (Ethernet_Frame_Header_t*)&FrameIN.FrameData;
- Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT.FrameData;
+ Ethernet_Frame_Header_t* FrameINHeader = (Ethernet_Frame_Header_t*)&FrameIN->FrameData;
+ Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT->FrameData;
int16_t RetSize = NO_RESPONSE;
/* Ensure frame is addressed to either all (broadcast) or the virtual webserver, and is a type II frame */
if ((MAC_COMPARE(&FrameINHeader->Destination, &ServerMACAddress) ||
- MAC_COMPARE(&FrameINHeader->Destination, &BroadcastMACAddress)) &&
- (SwapEndian_16(FrameIN.FrameLength) > ETHERNET_VER2_MINSIZE))
+ MAC_COMPARE(&FrameINHeader->Destination, &BroadcastMACAddress)))
{
/* Process the packet depending on its protocol */
switch (SwapEndian_16(FrameINHeader->EtherType))
{
case ETHERTYPE_ARP:
- RetSize = ARP_ProcessARPPacket(&FrameIN.FrameData[sizeof(Ethernet_Frame_Header_t)],
- &FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)]);
+ RetSize = ARP_ProcessARPPacket(&FrameIN->FrameData[sizeof(Ethernet_Frame_Header_t)],
+ &FrameOUT->FrameData[sizeof(Ethernet_Frame_Header_t)]);
break;
case ETHERTYPE_IPV4:
- RetSize = IP_ProcessIPPacket(&FrameIN.FrameData[sizeof(Ethernet_Frame_Header_t)],
- &FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)]);
+ RetSize = IP_ProcessIPPacket(FrameIN,
+ &FrameIN->FrameData[sizeof(Ethernet_Frame_Header_t)],
+ &FrameOUT->FrameData[sizeof(Ethernet_Frame_Header_t)]);
break;
}
@@ -100,8 +94,8 @@ void Ethernet_ProcessPacket(void)
FrameOUTHeader->EtherType = FrameINHeader->EtherType;
/* Set the response length in the buffer and indicate that a response is ready to be sent */
- FrameOUT.FrameLength = (sizeof(Ethernet_Frame_Header_t) + RetSize);
- FrameOUT.FrameInBuffer = true;
+ FrameOUT->FrameLength = (sizeof(Ethernet_Frame_Header_t) + RetSize);
+ FrameOUT->FrameInBuffer = true;
}
}
@@ -109,7 +103,7 @@ void Ethernet_ProcessPacket(void)
if (RetSize != NO_PROCESS)
{
/* Clear the frame buffer */
- FrameIN.FrameInBuffer = false;
+ FrameIN->FrameInBuffer = false;
}
}
diff --git a/Demos/Device/RNDISEthernet/Lib/Ethernet.h b/Demos/Device/RNDISEthernet/Lib/Ethernet.h
index b360f07ae..b3002523a 100644
--- a/Demos/Device/RNDISEthernet/Lib/Ethernet.h
+++ b/Demos/Device/RNDISEthernet/Lib/Ethernet.h
@@ -39,6 +39,8 @@
/* Includes: */
#include <avr/io.h>
#include <string.h>
+
+ #include <LUFA/Drivers/USB/Class/Device/RNDIS.h>
#include "EthernetProtocols.h"
#include "ProtocolDecoders.h"
@@ -50,6 +52,9 @@
#include "IP.h"
/* Macros: */
+ /** Physical MAC address of the USB RNDIS network adapter */
+ #define ADAPTER_MAC_ADDRESS {0x00, 0x02, 0x00, 0x02, 0x00, 0x02}
+
/** Physical MAC address of the virtual server on the network */
#define SERVER_MAC_ADDRESS {0x00, 0x01, 0x00, 0x01, 0x00, 0x01}
@@ -64,12 +69,6 @@
* \return True if the addresses match, false otherwise
*/
#define MAC_COMPARE(MAC1, MAC2) (memcmp(MAC1, MAC2, sizeof(MAC_Address_t)) == 0)
-
- /** Maximum size of an incoming or outgoing Ethernet frame in bytes */
- #define ETHERNET_FRAME_SIZE_MAX 1500
-
- /** Minimum size of an Ethernet packet in bytes, to conform to the Ethernet V2 packet standard */
- #define ETHERNET_VER2_MINSIZE 0x0600
/** Return value for all sub protocol handling routines, indicating that no response packet has been generated */
#define NO_RESPONSE 0
@@ -78,14 +77,6 @@
#define NO_PROCESS -1
/* Type Defines: */
- /** Type define for an Ethernet frame buffer. */
- typedef struct
- {
- uint8_t FrameData[ETHERNET_FRAME_SIZE_MAX]; /**< Ethernet frame contents */
- uint16_t FrameLength; /**< Length in bytes of the Ethernet frame stored in the buffer */
- bool FrameInBuffer; /**< Indicates if a frame is currently stored in the buffer */
- } Ethernet_Frame_Info_t;
-
/** Type define for an Ethernet frame header */
typedef struct
{
@@ -100,9 +91,6 @@
} Ethernet_Frame_Header_t;
/* External Variables: */
- extern Ethernet_Frame_Info_t FrameIN;
- extern Ethernet_Frame_Info_t FrameOUT;
-
extern const MAC_Address_t ServerMACAddress;
extern const IP_Address_t ServerIPAddress;
extern const MAC_Address_t BroadcastMACAddress;
@@ -110,7 +98,7 @@
extern const IP_Address_t ClientIPAddress;
/* Function Prototypes: */
- void Ethernet_ProcessPacket(void);
+ void Ethernet_ProcessPacket(Ethernet_Frame_Info_t* FrameIN, Ethernet_Frame_Info_t* FrameOUT);
uint16_t Ethernet_Checksum16(void* Data, uint16_t Bytes);
#endif
diff --git a/Demos/Device/RNDISEthernet/Lib/EthernetProtocols.h b/Demos/Device/RNDISEthernet/Lib/EthernetProtocols.h
index 3ff3433ae..1ec5961e1 100644
--- a/Demos/Device/RNDISEthernet/Lib/EthernetProtocols.h
+++ b/Demos/Device/RNDISEthernet/Lib/EthernetProtocols.h
@@ -71,13 +71,7 @@
#define PROTOCOL_OSPF 89
#define PROTOCOL_SCTP 132
- /* Type Defines: */
- /** Type define for a physical MAC address of a device on a network */
- typedef struct
- {
- uint8_t Octets[6]; /**< Individual bytes of a MAC address */
- } MAC_Address_t;
-
+ /* Type Defines: */
/** Type define for a protocol IP address of a device on a network */
typedef struct
{
diff --git a/Demos/Device/RNDISEthernet/Lib/ICMP.c b/Demos/Device/RNDISEthernet/Lib/ICMP.c
index da4ffcfa1..ba6e1db68 100644
--- a/Demos/Device/RNDISEthernet/Lib/ICMP.c
+++ b/Demos/Device/RNDISEthernet/Lib/ICMP.c
@@ -45,7 +45,7 @@
*
* \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise
*/
-int16_t ICMP_ProcessICMPPacket(void* InDataStart, void* OutDataStart)
+int16_t ICMP_ProcessICMPPacket(Ethernet_Frame_Info_t* FrameIN, void* InDataStart, void* OutDataStart)
{
ICMP_Header_t* ICMPHeaderIN = (ICMP_Header_t*)InDataStart;
ICMP_Header_t* ICMPHeaderOUT = (ICMP_Header_t*)OutDataStart;
@@ -62,7 +62,7 @@ int16_t ICMP_ProcessICMPPacket(void* InDataStart, void* OutDataStart)
ICMPHeaderOUT->Id = ICMPHeaderIN->Id;
ICMPHeaderOUT->Sequence = ICMPHeaderIN->Sequence;
- uint16_t DataSize = FrameIN.FrameLength - ((((uint16_t)InDataStart + sizeof(ICMP_Header_t)) - (uint16_t)FrameIN.FrameData));
+ uint16_t DataSize = FrameIN->FrameLength - ((((uint16_t)InDataStart + sizeof(ICMP_Header_t)) - (uint16_t)FrameIN->FrameData));
/* Copy the remaining payload to the response - echo requests should echo back any sent data */
memcpy(&((uint8_t*)OutDataStart)[sizeof(ICMP_Header_t)],
diff --git a/Demos/Device/RNDISEthernet/Lib/ICMP.h b/Demos/Device/RNDISEthernet/Lib/ICMP.h
index b20a557e9..56749c09c 100644
--- a/Demos/Device/RNDISEthernet/Lib/ICMP.h
+++ b/Demos/Device/RNDISEthernet/Lib/ICMP.h
@@ -75,6 +75,6 @@
} ICMP_Header_t;
/* Function Prototypes: */
- int16_t ICMP_ProcessICMPPacket(void* InDataStart, void* OutDataStart);
+ int16_t ICMP_ProcessICMPPacket(Ethernet_Frame_Info_t* FrameIN, void* InDataStart, void* OutDataStart);
#endif
diff --git a/Demos/Device/RNDISEthernet/Lib/IP.c b/Demos/Device/RNDISEthernet/Lib/IP.c
index 8fb0b446d..08500450c 100644
--- a/Demos/Device/RNDISEthernet/Lib/IP.c
+++ b/Demos/Device/RNDISEthernet/Lib/IP.c
@@ -46,7 +46,7 @@
* response was generated, NO_PROCESS if the packet processing was deferred until the
* next Ethernet packet handler iteration
*/
-int16_t IP_ProcessIPPacket(void* InDataStart, void* OutDataStart)
+int16_t IP_ProcessIPPacket(Ethernet_Frame_Info_t* FrameIN, void* InDataStart, void* OutDataStart)
{
DecodeIPHeader(InDataStart);
@@ -69,7 +69,8 @@ int16_t IP_ProcessIPPacket(void* InDataStart, void* OutDataStart)
switch (IPHeaderIN->Protocol)
{
case PROTOCOL_ICMP:
- RetSize = ICMP_ProcessICMPPacket(&((uint8_t*)InDataStart)[HeaderLengthBytes],
+ RetSize = ICMP_ProcessICMPPacket(FrameIN,
+ &((uint8_t*)InDataStart)[HeaderLengthBytes],
&((uint8_t*)OutDataStart)[sizeof(IP_Header_t)]);
break;
case PROTOCOL_TCP:
diff --git a/Demos/Device/RNDISEthernet/Lib/IP.h b/Demos/Device/RNDISEthernet/Lib/IP.h
index fc1a46aef..f77c772d8 100644
--- a/Demos/Device/RNDISEthernet/Lib/IP.h
+++ b/Demos/Device/RNDISEthernet/Lib/IP.h
@@ -88,6 +88,6 @@
} IP_Header_t;
/* Function Prototypes: */
- int16_t IP_ProcessIPPacket(void* InDataStart, void* OutDataStart);
+ int16_t IP_ProcessIPPacket(Ethernet_Frame_Info_t* FrameIN, void* InDataStart, void* OutDataStart);
#endif
diff --git a/Demos/Device/RNDISEthernet/Lib/RNDIS.c b/Demos/Device/RNDISEthernet/Lib/RNDIS.c
deleted file mode 100644
index c5202bcd1..000000000
--- a/Demos/Device/RNDISEthernet/Lib/RNDIS.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2009.
-
- dean [at] fourwalledcubicle [dot] com
- www.fourwalledcubicle.com
-*/
-
-/*
- Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, and distribute this software
- and its documentation for any purpose and without fee is hereby
- granted, provided that the above copyright notice appear in all
- copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaim all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * RNDIS command handler functions. This handles RNDIS commands according to
- * the Microsoft RNDIS specification, creating a USB Ethernet network adapter.
- */
-
-#define INCLUDE_FROM_RNDIS_C
-#include "RNDIS.h"
-
-/* Global Variables: */
-/** Physical MAC address of the network adapter, which becomes the MAC address of the host for packets sent to the adapter. */
-static MAC_Address_t PROGMEM AdapterMACAddress = {ADAPTER_MAC_ADDRESS};
-
-/** Vendor description of the adapter. This is overridden by the INF file required to install the appropriate RNDIS drivers for
- * the device, but may still be used by the OS in some circumstances.
- */
-static char PROGMEM AdapterVendorDescription[] = "LUFA RNDIS Adapter";
-
-/** List of RNDIS OID commands supported by this adapter. */
-static const uint32_t PROGMEM AdapterSupportedOIDList[] =
- {
- OID_GEN_SUPPORTED_LIST,
- OID_GEN_PHYSICAL_MEDIUM,
- OID_GEN_HARDWARE_STATUS,
- OID_GEN_MEDIA_SUPPORTED,
- OID_GEN_MEDIA_IN_USE,
- OID_GEN_MAXIMUM_FRAME_SIZE,
- OID_GEN_MAXIMUM_TOTAL_SIZE,
- OID_GEN_LINK_SPEED,
- OID_GEN_TRANSMIT_BLOCK_SIZE,
- OID_GEN_RECEIVE_BLOCK_SIZE,
- OID_GEN_VENDOR_ID,
- OID_GEN_VENDOR_DESCRIPTION,
- OID_GEN_CURRENT_PACKET_FILTER,
- OID_GEN_MAXIMUM_TOTAL_SIZE,
- OID_GEN_MEDIA_CONNECT_STATUS,
- OID_GEN_XMIT_OK,
- OID_GEN_RCV_OK,
- OID_GEN_XMIT_ERROR,
- OID_GEN_RCV_ERROR,
- OID_GEN_RCV_NO_BUFFER,
- OID_802_3_PERMANENT_ADDRESS,
- OID_802_3_CURRENT_ADDRESS,
- OID_802_3_MULTICAST_LIST,
- OID_802_3_MAXIMUM_LIST_SIZE,
- OID_802_3_RCV_ERROR_ALIGNMENT,
- OID_802_3_XMIT_ONE_COLLISION,
- OID_802_3_XMIT_MORE_COLLISIONS,
- };
-
-/** Buffer for RNDIS messages (as distinct from Ethernet frames sent through the adapter. This must be big enough to hold the entire
- * 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
- * reason, care must be taken when constructing RNDIS responses that unread data is not overwritten when writing in responses.
- */
-uint8_t RNDISMessageBuffer[sizeof(AdapterSupportedOIDList) + sizeof(RNDIS_QUERY_CMPLT_t)];
-
-/** Pointer to the RNDIS message header at the top of the RNDIS message buffer, for convenience. */
-RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISMessageBuffer;
-
-/** Indicates if a RNDIS message response is ready to be sent back to the host. */
-bool ResponseReady = false;
-
-/** Current RNDIS adapter state, a value from the RNDIS_States_t enum. */
-uint8_t CurrRNDISState = RNDIS_Uninitialized;
-
-/** Current Ethernet packet filter mask. This is non-zero when the adapter is initialized, or zero when disabled. */
-uint32_t CurrPacketFilter = 0;
-
-
-/** Processes the RNDIS message received by the host and stored in the RNDISMessageBuffer global buffer. If a response is
- * created, the ResponseReady global is updated so that the response is written back to the host upon request.
- */
-void ProcessRNDISControlMessage(void)
-{
- /* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of
- this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */
-
- switch (MessageHeader->MessageType)
- {
- case REMOTE_NDIS_INITIALIZE_MSG:
- /* Initialize the adapter - return information about the supported RNDIS version and buffer sizes */
-
- ResponseReady = true;
-
- RNDIS_INITIALIZE_MSG_t* INITIALIZE_Message = (RNDIS_INITIALIZE_MSG_t*)&RNDISMessageBuffer;
- RNDIS_INITIALIZE_CMPLT_t* INITIALIZE_Response = (RNDIS_INITIALIZE_CMPLT_t*)&RNDISMessageBuffer;
-
- INITIALIZE_Response->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
- INITIALIZE_Response->MessageLength = sizeof(RNDIS_INITIALIZE_CMPLT_t);
- INITIALIZE_Response->RequestId = INITIALIZE_Message->RequestId;
- INITIALIZE_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
-
- INITIALIZE_Response->MajorVersion = REMOTE_NDIS_VERSION_MAJOR;
- INITIALIZE_Response->MinorVersion = REMOTE_NDIS_VERSION_MINOR;
- INITIALIZE_Response->DeviceFlags = REMOTE_NDIS_DF_CONNECTIONLESS;
- INITIALIZE_Response->Medium = REMOTE_NDIS_MEDIUM_802_3;
- INITIALIZE_Response->MaxPacketsPerTransfer = 1;
- INITIALIZE_Response->MaxTransferSize = (sizeof(RNDIS_PACKET_MSG_t) + ETHERNET_FRAME_SIZE_MAX);
- INITIALIZE_Response->PacketAlignmentFactor = 0;
- INITIALIZE_Response->AFListOffset = 0;
- INITIALIZE_Response->AFListSize = 0;
-
- CurrRNDISState = RNDIS_Initialized;
-
- break;
- case REMOTE_NDIS_HALT_MSG:
- /* Halt the adapter, reset the adapter state - note that no response should be returned when completed */
-
- ResponseReady = false;
- MessageHeader->MessageLength = 0;
-
- CurrRNDISState = RNDIS_Uninitialized;
-
- break;
- case REMOTE_NDIS_QUERY_MSG:
- /* Request for information about a parameter about the adapter, specified as an OID token */
-
- ResponseReady = true;
-
- RNDIS_QUERY_MSG_t* QUERY_Message = (RNDIS_QUERY_MSG_t*)&RNDISMessageBuffer;
- RNDIS_QUERY_CMPLT_t* QUERY_Response = (RNDIS_QUERY_CMPLT_t*)&RNDISMessageBuffer;
- uint32_t Query_Oid = QUERY_Message->Oid;
-
- void* QueryData = &RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
- QUERY_Message->InformationBufferOffset];
- void* ResponseData = &RNDISMessageBuffer[sizeof(RNDIS_QUERY_CMPLT_t)];
- uint16_t ResponseSize;
-
- QUERY_Response->MessageType = REMOTE_NDIS_QUERY_CMPLT;
- QUERY_Response->MessageLength = sizeof(RNDIS_QUERY_CMPLT_t);
-
- if (ProcessNDISQuery(Query_Oid, QueryData, QUERY_Message->InformationBufferLength,
- ResponseData, &ResponseSize))
- {
- QUERY_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
- QUERY_Response->MessageLength += ResponseSize;
-
- QUERY_Response->InformationBufferLength = ResponseSize;
- QUERY_Response->InformationBufferOffset = (sizeof(RNDIS_QUERY_CMPLT_t) - sizeof(RNDIS_Message_Header_t));
- }
- else
- {
- QUERY_Response->Status = REMOTE_NDIS_STATUS_NOT_SUPPORTED;
-
- QUERY_Response->InformationBufferLength = 0;
- QUERY_Response->InformationBufferOffset = 0;
- }
-
- break;
- case REMOTE_NDIS_SET_MSG:
- /* Request to set a parameter of the adapter, specified as an OID token */
-
- ResponseReady = true;
-
- RNDIS_SET_MSG_t* SET_Message = (RNDIS_SET_MSG_t*)&RNDISMessageBuffer;
- RNDIS_SET_CMPLT_t* SET_Response = (RNDIS_SET_CMPLT_t*)&RNDISMessageBuffer;
- uint32_t SET_Oid = SET_Message->Oid;
-
- SET_Response->MessageType = REMOTE_NDIS_SET_CMPLT;
- SET_Response->MessageLength = sizeof(RNDIS_SET_CMPLT_t);
- SET_Response->RequestId = SET_Message->RequestId;
-
- void* SetData = &RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
- SET_Message->InformationBufferOffset];
-
- if (ProcessNDISSet(SET_Oid, SetData, SET_Message->InformationBufferLength))
- SET_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
- else
- SET_Response->Status = REMOTE_NDIS_STATUS_NOT_SUPPORTED;
-
- break;
- case REMOTE_NDIS_RESET_MSG:
- /* Soft reset the adapter */
-
- ResponseReady = true;
-
- RNDIS_RESET_CMPLT_t* RESET_Response = (RNDIS_RESET_CMPLT_t*)&RNDISMessageBuffer;
-
- RESET_Response->MessageType = REMOTE_NDIS_RESET_CMPLT;
- RESET_Response->MessageLength = sizeof(RNDIS_RESET_CMPLT_t);
- RESET_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
- RESET_Response->AddressingReset = 0;
-
- break;
- case REMOTE_NDIS_KEEPALIVE_MSG:
- /* Keep alive message sent to the adapter every 5 seconds when idle to ensure it is still responding */
-
- ResponseReady = true;
-
- RNDIS_KEEPALIVE_MSG_t* KEEPALIVE_Message = (RNDIS_KEEPALIVE_MSG_t*)&RNDISMessageBuffer;
- RNDIS_KEEPALIVE_CMPLT_t* KEEPALIVE_Response = (RNDIS_KEEPALIVE_CMPLT_t*)&RNDISMessageBuffer;
-
- KEEPALIVE_Response->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
- KEEPALIVE_Response->MessageLength = sizeof(RNDIS_KEEPALIVE_CMPLT_t);
- KEEPALIVE_Response->RequestId = KEEPALIVE_Message->RequestId;
- KEEPALIVE_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
-
- break;
- }
-}
-
-/** Processes RNDIS query commands, retrieving information from the adapter and reporting it back to the host. The requested
- * parameter is given as an OID value.
- *
- * \param OId OId value of the parameter being queried
- * \param QueryData Pointer to any extra query data being sent by the host to the device inside the RNDIS message buffer
- * \param QuerySize Size in bytes of the extra query data being sent by the host
- * \param ResponseData Pointer to the start of the query response inside the RNDIS message buffer
- * \param ResponseSize Pointer to the size in bytes of the response data being sent to the host
- *
- * \return Boolean true if the query was handled, false otherwise
- */
-static bool ProcessNDISQuery(uint32_t OId, void* QueryData, uint16_t QuerySize,
- void* ResponseData, uint16_t* ResponseSize)
-{
- /* Handler for REMOTE_NDIS_QUERY_MSG messages */
-
- switch (OId)
- {
- case OID_GEN_SUPPORTED_LIST:
- *ResponseSize = sizeof(AdapterSupportedOIDList);
-
- /* Copy the list of supported NDIS OID tokens to the response buffer */
- memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList));
-
- return true;
- case OID_GEN_PHYSICAL_MEDIUM:
- *ResponseSize = sizeof(uint32_t);
-
- /* Indicate that the device is a true ethernet link */
- *((uint32_t*)ResponseData) = 0;
-
- return true;
- case OID_GEN_HARDWARE_STATUS:
- *ResponseSize = sizeof(uint32_t);
-
- /* Always indicate hardware ready */
- *((uint32_t*)ResponseData) = NdisHardwareStatusReady;
-
- return true;
- case OID_GEN_MEDIA_SUPPORTED:
- case OID_GEN_MEDIA_IN_USE:
- *ResponseSize = sizeof(uint32_t);
-
- /* Indicate 802.3 (Ethernet) supported by the adapter */
- *((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIUM_802_3;
-
- return true;
- case OID_GEN_VENDOR_ID:
- *ResponseSize = sizeof(uint32_t);
-
- /* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */
- *((uint32_t*)ResponseData) = 0x00FFFFFF;
-
- return true;
- case OID_GEN_MAXIMUM_FRAME_SIZE:
- case OID_GEN_TRANSMIT_BLOCK_SIZE:
- case OID_GEN_RECEIVE_BLOCK_SIZE:
- *ResponseSize = sizeof(uint32_t);
-
- /* Indicate that the maximum frame size is the size of the ethernet frame buffer */
- *((uint32_t*)ResponseData) = ETHERNET_FRAME_SIZE_MAX;
-
- return true;
- case OID_GEN_VENDOR_DESCRIPTION:
- *ResponseSize = sizeof(AdapterVendorDescription);
-
- /* Copy vendor description string to the response buffer */
- memcpy_P(ResponseData, AdapterVendorDescription, sizeof(AdapterVendorDescription));
-
- return true;
- case OID_GEN_MEDIA_CONNECT_STATUS:
- *ResponseSize = sizeof(uint32_t);
-
- /* Always indicate that the adapter is connected to a network */
- *((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIA_STATE_CONNECTED;
-
- return true;
- case OID_GEN_LINK_SPEED:
- *ResponseSize = sizeof(uint32_t);
-
- /* Indicate 10Mb/s link speed */
- *((uint32_t*)ResponseData) = 100000;
-
- return true;
- case OID_802_3_PERMANENT_ADDRESS:
- case OID_802_3_CURRENT_ADDRESS:
- *ResponseSize = sizeof(MAC_Address_t);
-
- /* Copy over the fixed adapter MAC to the response buffer */
- memcpy_P(ResponseData, &AdapterMACAddress, sizeof(MAC_Address_t));
-
- return true;
- case OID_802_3_MAXIMUM_LIST_SIZE:
- *ResponseSize = sizeof(uint32_t);
-
- /* Indicate only one multicast address supported */
- *((uint32_t*)ResponseData) = 1;
-
- return true;
- case OID_GEN_CURRENT_PACKET_FILTER:
- *ResponseSize = sizeof(uint32_t);
-
- /* Indicate the current packet filter mask */
- *((uint32_t*)ResponseData) = CurrPacketFilter;
-
- return true;
- case OID_GEN_XMIT_OK:
- case OID_GEN_RCV_OK:
- case OID_GEN_XMIT_ERROR:
- case OID_GEN_RCV_ERROR:
- case OID_GEN_RCV_NO_BUFFER:
- case OID_802_3_RCV_ERROR_ALIGNMENT:
- case OID_802_3_XMIT_ONE_COLLISION:
- case OID_802_3_XMIT_MORE_COLLISIONS:
- *ResponseSize = sizeof(uint32_t);
-
- /* Unused statistic OIDs - always return 0 for each */
- *((uint32_t*)ResponseData) = 0;
-
- return true;
- case OID_GEN_MAXIMUM_TOTAL_SIZE:
- *ResponseSize = sizeof(uint32_t);
-
- /* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */
- *((uint32_t*)ResponseData) = (sizeof(RNDISMessageBuffer) + ETHERNET_FRAME_SIZE_MAX);
-
- return true;
- default:
- return false;
- }
-}
-
-/** Processes RNDIS set commands, setting adapter parameters to values given by the host. The requested parameter is given
- * as an OID value.
- *
- * \param OId OId value of the parameter being set
- * \param SetData Pointer to the parameter value in the RNDIS message buffer
- * \param SetSize Size in bytes of the parameter value being sent by the host
- *
- * \return Boolean true if the set was handled, false otherwise
- */
-static bool ProcessNDISSet(uint32_t OId, void* SetData, uint16_t SetSize)
-{
- /* Handler for REMOTE_NDIS_SET_MSG messages */
-
- switch (OId)
- {
- case OID_GEN_CURRENT_PACKET_FILTER:
- /* Save the packet filter mask in case the host queries it again later */
- CurrPacketFilter = *((uint32_t*)SetData);
-
- /* Set the RNDIS state to initialized if the packet filter is non-zero */
- CurrRNDISState = ((CurrPacketFilter) ? RNDIS_Data_Initialized : RNDIS_Data_Initialized);
-
- return true;
- case OID_802_3_MULTICAST_LIST:
- /* Do nothing - throw away the value from the host as it is unused */
-
- return true;
- default:
- return false;
- }
-}
diff --git a/Demos/Device/RNDISEthernet/Lib/TCP.c b/Demos/Device/RNDISEthernet/Lib/TCP.c
index f259aad02..1ebd15435 100644
--- a/Demos/Device/RNDISEthernet/Lib/TCP.c
+++ b/Demos/Device/RNDISEthernet/Lib/TCP.c
@@ -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
* buffer for later transmission.
*/
-TASK(TCP_Task)
+void TCP_TCPTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
{
/* Task to hand off TCP packets to and from the listening applications. */
@@ -76,7 +76,7 @@ TASK(TCP_Task)
}
/* Bail out early if there is already a frame waiting to be sent in the Ethernet OUT buffer */
- if (FrameOUT.FrameInBuffer)
+ if (RNDISInterfaceInfo->FrameOUT.FrameInBuffer)
return;
/* Send response packets from each application as the TCP packet buffers are filled by the applications */
@@ -86,13 +86,13 @@ TASK(TCP_Task)
if ((ConnectionStateTable[CSTableEntry].Info.Buffer.Direction == TCP_PACKETDIR_OUT) &&
(ConnectionStateTable[CSTableEntry].Info.Buffer.Ready))
{
- Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT.FrameData;
- IP_Header_t* IPHeaderOUT = (IP_Header_t*)&FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)];
- TCP_Header_t* TCPHeaderOUT = (TCP_Header_t*)&FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +
- sizeof(IP_Header_t)];
- void* TCPDataOUT = &FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +
- sizeof(IP_Header_t) +
- sizeof(TCP_Header_t)];
+ Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&RNDISInterfaceInfo->FrameOUT.FrameData;
+ IP_Header_t* IPHeaderOUT = (IP_Header_t*)&RNDISInterfaceInfo->FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)];
+ TCP_Header_t* TCPHeaderOUT = (TCP_Header_t*)&RNDISInterfaceInfo->FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +
+ sizeof(IP_Header_t)];
+ void* TCPDataOUT = &RNDISInterfaceInfo->FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +
+ sizeof(IP_Header_t) +
+ sizeof(TCP_Header_t)];
uint16_t PacketSize = ConnectionStateTable[CSTableEntry].Info.Buffer.Length;
@@ -145,8 +145,8 @@ TASK(TCP_Task)
PacketSize += sizeof(Ethernet_Frame_Header_t);
/* Set the response length in the buffer and indicate that a response is ready to be sent */
- FrameOUT.FrameLength = PacketSize;
- FrameOUT.FrameInBuffer = true;
+ RNDISInterfaceInfo->FrameOUT.FrameLength = PacketSize;
+ RNDISInterfaceInfo->FrameOUT.FrameInBuffer = true;
ConnectionStateTable[CSTableEntry].Info.Buffer.Ready = false;
diff --git a/Demos/Device/RNDISEthernet/Lib/TCP.h b/Demos/Device/RNDISEthernet/Lib/TCP.h
index d4b72a519..3448245ed 100644
--- a/Demos/Device/RNDISEthernet/Lib/TCP.h
+++ b/Demos/Device/RNDISEthernet/Lib/TCP.h
@@ -38,9 +38,7 @@
/* Includes: */
#include <avr/io.h>
- #include <stdbool.h>
-
- #include <LUFA/Scheduler/Scheduler.h>
+ #include <stdbool.h>
#include "EthernetProtocols.h"
#include "Ethernet.h"
@@ -229,14 +227,12 @@
uint16_t Checksum; /**< TCP checksum */
uint16_t UrgentPointer; /**< Urgent data pointer */
} TCP_Header_t;
-
- /* Tasks: */
- TASK(TCP_Task);
/* External Variables: */
TCP_PortState_t PortStateTable[MAX_OPEN_TCP_PORTS];
/* Function Prototypes: */
+ void TCP_TCPTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
void TCP_Init(void);
bool TCP_SetPortState(uint16_t Port, uint8_t State, void (*Handler)(TCP_ConnectionState_t*, TCP_ConnectionBuffer_t*));
uint8_t TCP_GetPortState(uint16_t Port);
diff --git a/Demos/Device/RNDISEthernet/RNDISEthernet.c b/Demos/Device/RNDISEthernet/RNDISEthernet.c
index b046f7870..3246cd8bc 100644
--- a/Demos/Device/RNDISEthernet/RNDISEthernet.c
+++ b/Demos/Device/RNDISEthernet/RNDISEthernet.c
@@ -28,28 +28,51 @@
this software.
*/
-/** \file
- *
- * Main source file for the RNDISEthernet demo. This file contains the main tasks of the demo and
- * is responsible for the initial application hardware configuration.
- */
-
#include "RNDISEthernet.h"
-/* Scheduler Task List */
-TASK_LIST
-{
- { .Task = USB_USBTask , .TaskStatus = TASK_STOP },
- { .Task = Ethernet_Task , .TaskStatus = TASK_STOP },
- { .Task = TCP_Task , .TaskStatus = TASK_STOP },
- { .Task = RNDIS_Task , .TaskStatus = TASK_STOP },
-};
+USB_ClassInfo_RNDIS_t Ethernet_RNDIS_Interface =
+ {
+ .ControlInterfaceNumber = 0,
-/** Main program entry point. This routine configures the hardware required by the application, then
- * starts the scheduler to run the USB management task.
- */
+ .DataINEndpointNumber = CDC_TX_EPNUM,
+ .DataINEndpointSize = CDC_TXRX_EPSIZE,
+
+ .DataOUTEndpointNumber = CDC_RX_EPNUM,
+ .DataOUTEndpointSize = CDC_TXRX_EPSIZE,
+
+ .NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
+ .NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
+
+ .AdapterVendorDescription = "LUFA RNDIS Demo Adapter",
+ .AdapterMACAddress = {ADAPTER_MAC_ADDRESS},
+ };
+
int main(void)
{
+ SetupHardware();
+
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+
+ printf_P(PSTR("\r\n\r\n****** RNDIS Demo running. ******\r\n"));
+
+ for (;;)
+ {
+ if (Ethernet_RNDIS_Interface.FrameIN.FrameInBuffer)
+ {
+ LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
+ Ethernet_ProcessPacket(&Ethernet_RNDIS_Interface.FrameIN, &Ethernet_RNDIS_Interface.FrameOUT);
+ LEDs_SetAllLEDs(LEDMASK_USB_READY);
+ }
+
+ TCP_TCPTask(&Ethernet_RNDIS_Interface);
+
+ USB_RNDIS_USBTask(&Ethernet_RNDIS_Interface);
+ USB_USBTask();
+ }
+}
+
+void SetupHardware(void)
+{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
wdt_disable();
@@ -60,279 +83,32 @@ int main(void)
/* Hardware Initialization */
LEDs_Init();
SerialStream_Init(9600, false);
-
- /* Webserver Initialization */
- TCP_Init();
- Webserver_Init();
-
- printf_P(PSTR("\r\n\r\n****** RNDIS Demo running. ******\r\n"));
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
-
- /* Initialize Scheduler so that it can be used */
- Scheduler_Init();
-
- /* Initialize USB Subsystem */
USB_Init();
- /* Scheduling - routine never returns, so put this last in the main function */
- Scheduler_Start();
+ /* Initialize TCP and Webserver modules */
+ TCP_Init();
+ Webserver_Init();
}
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
- * starts the library USB task to begin the enumeration and USB management process.
- */
void EVENT_USB_Connect(void)
{
- /* Start USB management task */
- Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
- /* Indicate USB enumerating */
- UpdateStatus(Status_USBEnumerating);
+ LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- * the status LEDs and stops all the relevant tasks.
- */
void EVENT_USB_Disconnect(void)
{
- /* Stop running TCP/IP and USB management tasks */
- Scheduler_SetTaskMode(RNDIS_Task, TASK_STOP);
- Scheduler_SetTaskMode(Ethernet_Task, TASK_STOP);
- Scheduler_SetTaskMode(TCP_Task, TASK_STOP);
- Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host sets the current configuration
- * of the USB device after enumeration, and configures the RNDIS device endpoints and starts the relevant tasks.
- */
void EVENT_USB_ConfigurationChanged(void)
{
- /* Setup CDC Notification, Rx and Tx Endpoints */
- Endpoint_ConfigureEndpoint(CDC_TX_EPNUM, EP_TYPE_BULK,
- ENDPOINT_DIR_IN, CDC_TXRX_EPSIZE,
- ENDPOINT_BANK_SINGLE);
+ LEDs_SetAllLEDs(LEDMASK_USB_READY);
- Endpoint_ConfigureEndpoint(CDC_RX_EPNUM, EP_TYPE_BULK,
- ENDPOINT_DIR_OUT, CDC_TXRX_EPSIZE,
- ENDPOINT_BANK_SINGLE);
-
- Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,
- ENDPOINT_DIR_IN, CDC_NOTIFICATION_EPSIZE,
- ENDPOINT_BANK_SINGLE);
-
- /* Indicate USB connected and ready */
- UpdateStatus(Status_USBReady);
-
- /* Start TCP/IP tasks */
- Scheduler_SetTaskMode(RNDIS_Task, TASK_RUN);
- Scheduler_SetTaskMode(Ethernet_Task, TASK_RUN);
- Scheduler_SetTaskMode(TCP_Task, TASK_RUN);
+ if (!(USB_RNDIS_ConfigureEndpoints(&Ethernet_RNDIS_Interface)))
+ LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- * control requests that are not handled internally by the USB library (including the RNDIS control commands,
- * which set up the USB RNDIS network adapter), so that they can be handled appropriately for the application.
- */
void EVENT_USB_UnhandledControlPacket(void)
{
- /* Process RNDIS class commands */
- switch (USB_ControlRequest.bRequest)
- {
- case REQ_SendEncapsulatedCommand:
- if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- /* Clear the SETUP packet, ready for data transfer */
- Endpoint_ClearSETUP();
-
- /* Read in the RNDIS message into the message buffer */
- Endpoint_Read_Control_Stream_LE(RNDISMessageBuffer, USB_ControlRequest.wLength);
-
- /* Finalize the stream transfer to clear the last packet from the host */
- Endpoint_ClearIN();
-
- /* Process the RNDIS message */
- ProcessRNDISControlMessage();
- }
-
- break;
- case REQ_GetEncapsulatedResponse:
- if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- /* Clear the SETUP packet, ready for data transfer */
- Endpoint_ClearSETUP();
-
- /* Check if a response to the last message is ready */
- if (!(MessageHeader->MessageLength))
- {
- /* Set the response to a single 0x00 byte to indicate that no response is ready */
- RNDISMessageBuffer[0] = 0;
- MessageHeader->MessageLength = 1;
- }
-
- /* Write the message response data to the endpoint */
- Endpoint_Write_Control_Stream_LE(RNDISMessageBuffer, MessageHeader->MessageLength);
-
- /* Finalize the stream transfer to send the last packet or clear the host abort */
- Endpoint_ClearOUT();
-
- /* Reset the message header once again after transmission */
- MessageHeader->MessageLength = 0;
- }
-
- break;
- }
-}
-
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- * log to a serial port, or anything else that is suitable for status updates.
- *
- * \param CurrentStatus Current status of the system, from the RNDISEthernet_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
-{
- uint8_t LEDMask = LEDS_NO_LEDS;
-
- /* Set the LED mask to the appropriate LED mask based on the given status code */
- switch (CurrentStatus)
- {
- case Status_USBNotReady:
- LEDMask = (LEDS_LED1);
- break;
- case Status_USBEnumerating:
- LEDMask = (LEDS_LED1 | LEDS_LED2);
- break;
- case Status_USBReady:
- LEDMask = (LEDS_LED2 | LEDS_LED4);
- break;
- case Status_ProcessingEthernetFrame:
- LEDMask = (LEDS_LED2 | LEDS_LED3);
- break;
- }
-
- /* Set the board LEDs to the new LED mask */
- LEDs_SetAllLEDs(LEDMask);
-}
-
-/** Task to manage the sending and receiving of encapsulated RNDIS data and notifications. This removes the RNDIS
- * wrapper from received Ethernet frames and places them in the FrameIN global buffer, or adds the RNDIS wrapper
- * to a frame in the FrameOUT global before sending the buffer contents to the host.
- */
-TASK(RNDIS_Task)
-{
- /* Select the notification endpoint */
- Endpoint_SelectEndpoint(CDC_NOTIFICATION_EPNUM);
-
- /* Check if a message response is ready for the host */
- if (Endpoint_IsINReady() && ResponseReady)
- {
- USB_Notification_t Notification = (USB_Notification_t)
- {
- .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
- .bNotification = NOTIF_RESPONSE_AVAILABLE,
- .wValue = 0,
- .wIndex = 0,
- .wLength = 0,
- };
-
- /* Indicate that a message response is ready for the host */
- Endpoint_Write_Stream_LE(&Notification, sizeof(Notification));
-
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearIN();
-
- /* Indicate a response is no longer ready */
- ResponseReady = false;
- }
-
- /* Don't process the data endpoints until the system is in the data initialized state, and the buffer is free */
- if ((CurrRNDISState == RNDIS_Data_Initialized) && !(MessageHeader->MessageLength))
- {
- /* Create a new packet header for reading/writing */
- RNDIS_PACKET_MSG_t RNDISPacketHeader;
-
- /* Select the data OUT endpoint */
- Endpoint_SelectEndpoint(CDC_RX_EPNUM);
-
- /* Check if the data OUT endpoint contains data, and that the IN buffer is empty */
- if (Endpoint_IsOUTReceived() && !(FrameIN.FrameInBuffer))
- {
- /* Read in the packet message header */
- Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_PACKET_MSG_t));
-
- /* Stall the request if the data is too large */
- if (RNDISPacketHeader.DataLength > ETHERNET_FRAME_SIZE_MAX)
- {
- Endpoint_StallTransaction();
- return;
- }
-
- /* Read in the Ethernet frame into the buffer */
- Endpoint_Read_Stream_LE(FrameIN.FrameData, RNDISPacketHeader.DataLength);
-
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearOUT();
-
- /* Store the size of the Ethernet frame */
- FrameIN.FrameLength = RNDISPacketHeader.DataLength;
-
- /* Indicate Ethernet IN buffer full */
- FrameIN.FrameInBuffer = true;
- }
-
- /* Select the data IN endpoint */
- Endpoint_SelectEndpoint(CDC_TX_EPNUM);
-
- /* Check if the data IN endpoint is ready for more data, and that the IN buffer is full */
- if (Endpoint_IsINReady() && FrameOUT.FrameInBuffer)
- {
- /* Clear the packet header with all 0s so that the relevant fields can be filled */
- memset(&RNDISPacketHeader, 0, sizeof(RNDIS_PACKET_MSG_t));
-
- /* Construct the required packet header fields in the buffer */
- RNDISPacketHeader.MessageType = REMOTE_NDIS_PACKET_MSG;
- RNDISPacketHeader.MessageLength = (sizeof(RNDIS_PACKET_MSG_t) + FrameOUT.FrameLength);
- RNDISPacketHeader.DataOffset = (sizeof(RNDIS_PACKET_MSG_t) - sizeof(RNDIS_Message_Header_t));
- RNDISPacketHeader.DataLength = FrameOUT.FrameLength;
-
- /* Send the packet header to the host */
- Endpoint_Write_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_PACKET_MSG_t));
-
- /* Send the Ethernet frame data to the host */
- Endpoint_Write_Stream_LE(FrameOUT.FrameData, RNDISPacketHeader.DataLength);
-
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearIN();
-
- /* Indicate Ethernet OUT buffer no longer full */
- FrameOUT.FrameInBuffer = false;
- }
- }
-}
-
-/** Ethernet frame processing task. This task checks to see if a frame has been received, and if so hands off the processing
- * of the frame to the Ethernet processing routines.
- */
-TASK(Ethernet_Task)
-{
- /* Task for Ethernet processing. Incoming ethernet frames are loaded into the FrameIN structure, and
- outgoing frames should be loaded into the FrameOUT structure. Both structures can only hold a single
- Ethernet frame at a time, so the FrameInBuffer bool is used to indicate when the buffers contain data. */
-
- /* Check if a frame has been written to the IN frame buffer */
- if (FrameIN.FrameInBuffer)
- {
- /* Indicate packet processing started */
- UpdateStatus(Status_ProcessingEthernetFrame);
-
- /* Process the ethernet frame - replace this with your own Ethernet handler code as desired */
- Ethernet_ProcessPacket();
-
- /* Indicate packet processing complete */
- UpdateStatus(Status_USBReady);
- }
+ USB_RNDIS_ProcessControlPacket(&Ethernet_RNDIS_Interface);
}
diff --git a/Demos/Device/RNDISEthernet/RNDISEthernet.h b/Demos/Device/RNDISEthernet/RNDISEthernet.h
index 703af4003..bc5004205 100644
--- a/Demos/Device/RNDISEthernet/RNDISEthernet.h
+++ b/Demos/Device/RNDISEthernet/RNDISEthernet.h
@@ -45,56 +45,34 @@
#include <stdio.h>
#include "Descriptors.h"
-
- #include "Lib/RNDIS.h"
+
#include "Lib/Ethernet.h"
#include "Lib/TCP.h"
#include "Lib/ARP.h"
#include "Lib/Webserver.h"
- #include <LUFA/Version.h> // Library Version Information
- #include <LUFA/Drivers/USB/USB.h> // USB Functionality
- #include <LUFA/Drivers/Board/LEDs.h> // LEDs driver
- #include <LUFA/Scheduler/Scheduler.h> // Simple scheduler for task management
- #include <LUFA/Drivers/Peripheral/SerialStream.h> // Serial stream driver
-
- /* Macros: */
- /** Notification value to indicate that a frame is ready to be read by the host. */
- #define NOTIF_RESPONSE_AVAILABLE 0x01
+ #include <LUFA/Version.h>
+ #include <LUFA/Drivers/Board/LEDs.h>
+ #include <LUFA/Drivers/Board/Joystick.h>
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/RNDIS.h>
- /* Type Defines: */
- /** Type define for a RNDIS notification message, for transmission to the RNDIS host via the notification
- * Endpoint.
- */
- typedef struct
- {
- uint8_t bmRequestType; /**< Notification type, a mask of values from SrdRequestType.h */
- uint8_t bNotification; /**< Notification index, indicating what the RNDIS notification relates to */
- uint16_t wValue; /**< Two byte notification value parameter */
- uint16_t wIndex; /**< Two byte notification index parameter */
- uint16_t wLength; /**< Size of data payload following the notification header */
- } USB_Notification_t;
-
- /* Enums: */
- /** Enum for the possible status codes for passing to the UpdateStatus() function. */
- enum RNDISEthernet_StatusCodes_t
- {
- Status_USBNotReady = 0, /**< USB is not ready (disconnected from a USB host) */
- Status_USBEnumerating = 1, /**< USB interface is enumerating */
- Status_USBReady = 2, /**< USB interface is connected and ready */
- Status_ProcessingEthernetFrame = 3, /**< Currently processing an ethernet frame from the host */
- };
+ /* Macros: */
+ #define LEDMASK_USB_NOTREADY LEDS_LED1
+ #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
+ #define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
+ #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
+ #define LEDMASK_USB_BUSY LEDS_LED2
- /* Tasks: */
- TASK(RNDIS_Task);
- TASK(Ethernet_Task);
-
/* Function Prototypes: */
+ void SetupHardware(void);
+
void EVENT_USB_Connect(void);
void EVENT_USB_Disconnect(void);
void EVENT_USB_ConfigurationChanged(void);
void EVENT_USB_UnhandledControlPacket(void);
-
- void UpdateStatus(uint8_t CurrentStatus);
+ void EVENT_USB_StartOfFrame(void);
+
+ void CALLBACK_USB_RNDIS_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
#endif
diff --git a/Demos/Device/RNDISEthernet/makefile b/Demos/Device/RNDISEthernet/makefile
index f40c37b05..3bcc37c8e 100644
--- a/Demos/Device/RNDISEthernet/makefile
+++ b/Demos/Device/RNDISEthernet/makefile
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
Descriptors.c \
- Lib/RNDIS.c \
Lib/Ethernet.c \
Lib/ProtocolDecoders.c \
Lib/ICMP.c \
@@ -135,7 +134,6 @@ SRC = $(TARGET).c \
Lib/ARP.c \
Lib/IP.c \
Lib/Webserver.c \
- $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c \
$(LUFA_PATH)/LUFA/Drivers/Peripheral/SerialStream.c \
$(LUFA_PATH)/LUFA/Drivers/Peripheral/Serial.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c \
@@ -148,7 +146,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/RNDIS.c \
# List C++ source files here. (C dependencies are automatically generated.)
@@ -195,7 +193,7 @@ CSTANDARD = -std=gnu99
# Place -D or -U options here for C sources
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
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
CDEFS += -DNO_DECODE_ETHERNET -DNO_DECODE_ARP -DNO_DECODE_ICMP -DNO_DECODE_IP -DNO_DECODE_TCP -DNO_DECODE_UDP -DNO_DECODE_DHCP
diff --git a/Demos/Device/USBtoSerial/Descriptors.h b/Demos/Device/USBtoSerial/Descriptors.h
index 41b44300a..9e372e35b 100644
--- a/Demos/Device/USBtoSerial/Descriptors.h
+++ b/Demos/Device/USBtoSerial/Descriptors.h
@@ -37,26 +37,12 @@
#define _DESCRIPTORS_H_
/* Includes: */
- #include <LUFA/Drivers/USB/USB.h>
-
#include <avr/pgmspace.h>
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/CDC.h>
+
/* Macros: */
- /** Macro to define a CDC class-specific functional descriptor. CDC functional descriptors have a
- * uniform structure but variable sized data payloads, thus cannot be represented accurately by
- * a single typedef struct. A macro is used instead so that functional descriptors can be created
- * easily by specifying the size of the payload. This allows sizeof() to work correctly.
- *
- * \param DataSize Size in bytes of the CDC functional descriptor's data payload
- */
- #define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \
- struct \
- { \
- USB_Descriptor_Header_t Header; \
- uint8_t SubType; \
- uint8_t Data[DataSize]; \
- }
-
/** Endpoint number of the CDC device-to-host notification IN endpoint. */
#define CDC_NOTIFICATION_EPNUM 2
diff --git a/Demos/Device/USBtoSerial/USBtoSerial.c b/Demos/Device/USBtoSerial/USBtoSerial.c
index 7cef56560..7c89278ef 100644
--- a/Demos/Device/USBtoSerial/USBtoSerial.c
+++ b/Demos/Device/USBtoSerial/USBtoSerial.c
@@ -30,38 +30,55 @@
#include "USBtoSerial.h"
-/* Scheduler Task List */
-TASK_LIST
-{
- { .Task = USB_USBTask , .TaskStatus = TASK_STOP },
- { .Task = CDC_Task , .TaskStatus = TASK_STOP },
-};
+RingBuff_t Rx_Buffer;
+RingBuff_t Tx_Buffer;
-/* Globals: */
-/** Contains the current baud rate and other settings of the virtual serial port.
- *
- * These values are set by the host via a class-specific request, and the physical USART should be reconfigured to match the
- * new settings each time they are changed by the host.
- */
-CDC_Line_Coding_t LineCoding = { .BaudRateBPS = 9600,
- .CharFormat = OneStopBit,
- .ParityType = Parity_None,
- .DataBits = 8 };
+USB_ClassInfo_CDC_t VirtualSerial_CDC_Interface =
+ {
+ .ControlInterfaceNumber = 0,
-/** Ring (circular) buffer to hold the RX data - data from the host to the attached device on the serial port. */
-RingBuff_t Rx_Buffer;
+ .DataINEndpointNumber = CDC_TX_EPNUM,
+ .DataINEndpointSize = CDC_TXRX_EPSIZE,
-/** Ring (circular) buffer to hold the TX data - data from the attached device on the serial port to the host. */
-RingBuff_t Tx_Buffer;
+ .DataOUTEndpointNumber = CDC_RX_EPNUM,
+ .DataOUTEndpointSize = CDC_TXRX_EPSIZE,
-/** Flag to indicate if the USART is currently transmitting data from the Rx_Buffer circular buffer. */
-volatile bool Transmitting = false;
+ .NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
+ .NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
+ };
-/** Main program entry point. This routine configures the hardware required by the application, then
- * starts the scheduler to run the application tasks.
- */
int main(void)
{
+ SetupHardware();
+
+ Buffer_Initialize(&Rx_Buffer);
+ Buffer_Initialize(&Tx_Buffer);
+
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+
+ for (;;)
+ {
+ for (uint8_t DataBytesRem = USB_CDC_BytesReceived(&VirtualSerial_CDC_Interface); DataBytesRem != 0; DataBytesRem--)
+ {
+ if (!(BUFF_STATICSIZE - Rx_Buffer.Elements))
+ break;
+
+ Buffer_StoreElement(&Rx_Buffer, USB_CDC_ReceiveByte(&VirtualSerial_CDC_Interface));
+ }
+
+ if (Tx_Buffer.Elements)
+ USB_CDC_SendByte(&VirtualSerial_CDC_Interface, Buffer_GetElement(&Rx_Buffer));
+
+ if (Rx_Buffer.Elements)
+ Serial_TxByte(Buffer_GetElement(&Rx_Buffer));
+
+ USB_CDC_USBTask(&VirtualSerial_CDC_Interface);
+ USB_USBTask();
+ }
+}
+
+void SetupHardware(void)
+{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
wdt_disable();
@@ -70,304 +87,61 @@ int main(void)
clock_prescale_set(clock_div_1);
/* Hardware Initialization */
+ Joystick_Init();
LEDs_Init();
- ReconfigureUSART();
-
- /* Ring buffer Initialization */
- Buffer_Initialize(&Rx_Buffer);
- Buffer_Initialize(&Tx_Buffer);
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
-
- /* Initialize Scheduler so that it can be used */
- Scheduler_Init();
-
- /* Initialize USB Subsystem */
USB_Init();
-
- /* Scheduling - routine never returns, so put this last in the main function */
- Scheduler_Start();
}
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
- * starts the library USB task to begin the enumeration and USB management process.
- */
void EVENT_USB_Connect(void)
{
- /* Start USB management task */
- Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
- /* Indicate USB enumerating */
- UpdateStatus(Status_USBEnumerating);
+ LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- * the status LEDs and stops the USB management and CDC management tasks.
- */
void EVENT_USB_Disconnect(void)
{
- /* Stop running CDC and USB management tasks */
- Scheduler_SetTaskMode(CDC_Task, TASK_STOP);
- Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-
- /* Reset Tx and Rx buffers, device disconnected */
- Buffer_Initialize(&Rx_Buffer);
- Buffer_Initialize(&Tx_Buffer);
-
- /* Indicate USB not ready */
- UpdateStatus(Status_USBNotReady);
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration
- * of the USB device after enumeration - the device endpoints are configured and the CDC management task started.
- */
void EVENT_USB_ConfigurationChanged(void)
{
- /* Setup CDC Notification, Rx and Tx Endpoints */
- Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,
- ENDPOINT_DIR_IN, CDC_NOTIFICATION_EPSIZE,
- ENDPOINT_BANK_SINGLE);
-
- Endpoint_ConfigureEndpoint(CDC_TX_EPNUM, EP_TYPE_BULK,
- ENDPOINT_DIR_IN, CDC_TXRX_EPSIZE,
- ENDPOINT_BANK_SINGLE);
+ LEDs_SetAllLEDs(LEDMASK_USB_READY);
- Endpoint_ConfigureEndpoint(CDC_RX_EPNUM, EP_TYPE_BULK,
- ENDPOINT_DIR_OUT, CDC_TXRX_EPSIZE,
- ENDPOINT_BANK_SINGLE);
-
- /* Indicate USB connected and ready */
- UpdateStatus(Status_USBReady);
-
- /* Start CDC task */
- Scheduler_SetTaskMode(CDC_Task, TASK_RUN);
+ if (!(USB_CDC_ConfigureEndpoints(&VirtualSerial_CDC_Interface)))
+ LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- * control requests that are not handled internally by the USB library (including the CDC control commands,
- * which are all issued via the control endpoint), so that they can be handled appropriately for the application.
- */
void EVENT_USB_UnhandledControlPacket(void)
{
- uint8_t* LineCodingData = (uint8_t*)&LineCoding;
-
- /* Process CDC specific control requests */
- switch (USB_ControlRequest.bRequest)
- {
- case REQ_GetLineEncoding:
- if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- /* Acknowledge the SETUP packet, ready for data transfer */
- Endpoint_ClearSETUP();
-
- /* Write the line coding data to the control endpoint */
- Endpoint_Write_Control_Stream_LE(LineCodingData, sizeof(LineCoding));
-
- /* Finalize the stream transfer to send the last packet or clear the host abort */
- Endpoint_ClearOUT();
- }
-
- break;
- case REQ_SetLineEncoding:
- if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- /* Acknowledge the SETUP packet, ready for data transfer */
- Endpoint_ClearSETUP();
-
- /* Read the line coding data in from the host into the global struct */
- Endpoint_Read_Control_Stream_LE(LineCodingData, sizeof(LineCoding));
-
- /* Finalize the stream transfer to clear the last packet from the host */
- Endpoint_ClearIN();
-
- /* Reconfigure the USART with the new settings */
- ReconfigureUSART();
- }
-
- break;
- case REQ_SetControlLineState:
- if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- /* Acknowledge the SETUP packet, ready for data transfer */
- Endpoint_ClearSETUP();
-
- /* NOTE: Here you can read in the line state mask from the host, to get the current state of the output handshake
- lines. The mask is read in from the wValue parameter in USB_ControlRequest, and can be masked against the
- CONTROL_LINE_OUT_* masks to determine the RTS and DTR line states using the following code:
- */
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsINReady()));
- Endpoint_ClearIN();
- }
-
- break;
- }
-}
-
-/** Task to manage CDC data transmission and reception to and from the host, from and to the physical USART. */
-TASK(CDC_Task)
-{
- if (USB_IsConnected)
- {
-#if 0
- /* NOTE: Here you can use the notification endpoint to send back line state changes to the host, for the special RS-232
- handshake signal lines (and some error states), via the CONTROL_LINE_IN_* masks and the following code:
- */
-
- USB_Notification_Header_t Notification = (USB_Notification_Header_t)
- {
- .NotificationType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
- .Notification = NOTIF_SerialState,
- .wValue = 0,
- .wIndex = 0,
- .wLength = sizeof(uint16_t),
- };
-
- uint16_t LineStateMask;
-
- // Set LineStateMask here to a mask of CONTROL_LINE_IN_* masks to set the input handshake line states to send to the host
-
- Endpoint_SelectEndpoint(CDC_NOTIFICATION_EPNUM);
- Endpoint_Write_Stream_LE(&Notification, sizeof(Notification));
- Endpoint_Write_Stream_LE(&LineStateMask, sizeof(LineStateMask));
- Endpoint_ClearIN();
-#endif
-
- /* Select the Serial Rx Endpoint */
- Endpoint_SelectEndpoint(CDC_RX_EPNUM);
-
- /* Check to see if a packet has been received from the host */
- if (Endpoint_IsOUTReceived())
- {
- /* Read the bytes in from the endpoint into the buffer while space is available */
- while (Endpoint_BytesInEndpoint() && (BUFF_STATICSIZE - Rx_Buffer.Elements))
- {
- /* Store each character from the endpoint */
- Buffer_StoreElement(&Rx_Buffer, Endpoint_Read_Byte());
- }
-
- /* Check to see if all bytes in the current packet have been read */
- if (!(Endpoint_BytesInEndpoint()))
- {
- /* Clear the endpoint buffer */
- Endpoint_ClearOUT();
- }
- }
-
- /* Check if Rx buffer contains data - if so, send it */
- if (Rx_Buffer.Elements)
- Serial_TxByte(Buffer_GetElement(&Rx_Buffer));
-
- /* Select the Serial Tx Endpoint */
- Endpoint_SelectEndpoint(CDC_TX_EPNUM);
-
- /* Check if the Tx buffer contains anything to be sent to the host */
- if (Tx_Buffer.Elements)
- {
- /* Wait until Serial Tx Endpoint Ready for Read/Write */
- while (!(Endpoint_IsReadWriteAllowed()));
-
- /* Write the bytes from the buffer to the endpoint while space is available */
- while (Tx_Buffer.Elements && (Endpoint_BytesInEndpoint() < CDC_TXRX_EPSIZE))
- {
- /* Write each byte retreived from the buffer to the endpoint */
- Endpoint_Write_Byte(Buffer_GetElement(&Tx_Buffer));
- }
-
- /* Remember if the packet to send completely fills the endpoint */
- bool IsFull = (Endpoint_BytesInEndpoint() == CDC_TXRX_EPSIZE);
-
- /* Send the data */
- Endpoint_ClearIN();
-
- /* If no more data to send and the last packet filled the endpoint, send an empty packet to release
- * the buffer on the receiver (otherwise all data will be cached until a non-full packet is received) */
- if (IsFull && !(Tx_Buffer.Elements))
- {
- /* Wait until Serial Tx Endpoint Ready for Read/Write */
- while (!(Endpoint_IsReadWriteAllowed()));
-
- /* Send an empty packet to terminate the transfer */
- Endpoint_ClearIN();
- }
- }
- }
+ USB_CDC_ProcessControlPacket(&VirtualSerial_CDC_Interface);
}
-/** ISR to handle the USART receive complete interrupt, fired each time the USART has received a character. This stores the received
- * character into the Tx_Buffer circular buffer for later transmission to the host.
- */
ISR(USART1_RX_vect, ISR_BLOCK)
{
- /* Only store received characters if the USB interface is connected */
if (USB_IsConnected)
- {
- /* Character received, store it into the buffer */
- Buffer_StoreElement(&Tx_Buffer, UDR1);
- }
+ Buffer_StoreElement(&Tx_Buffer, UDR1);
}
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- * log to a serial port, or anything else that is suitable for status updates.
- *
- * \param CurrentStatus Current status of the system, from the USBtoSerial_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
-{
- uint8_t LEDMask = LEDS_NO_LEDS;
-
- /* Set the LED mask to the appropriate LED mask based on the given status code */
- switch (CurrentStatus)
- {
- case Status_USBNotReady:
- LEDMask = (LEDS_LED1);
- break;
- case Status_USBEnumerating:
- LEDMask = (LEDS_LED1 | LEDS_LED2);
- break;
- case Status_USBReady:
- LEDMask = (LEDS_LED2 | LEDS_LED4);
- break;
- }
-
- /* Set the board LEDs to the new LED mask */
- LEDs_SetAllLEDs(LEDMask);
-}
-
-/** Reconfigures the USART to match the current serial port settings issued by the host as closely as possible. */
-void ReconfigureUSART(void)
+void EVENT_USB_CDC_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
{
uint8_t ConfigMask = 0;
- /* Determine parity - non odd/even parity mode defaults to no parity */
- if (LineCoding.ParityType == Parity_Odd)
+ if (CDCInterfaceInfo->LineEncoding.ParityType == Parity_Odd)
ConfigMask = ((1 << UPM11) | (1 << UPM10));
- else if (LineCoding.ParityType == Parity_Even)
+ else if (CDCInterfaceInfo->LineEncoding.ParityType == Parity_Even)
ConfigMask = (1 << UPM11);
- /* Determine stop bits - 1.5 stop bits is set as 1 stop bit due to hardware limitations */
- if (LineCoding.CharFormat == TwoStopBits)
+ if (CDCInterfaceInfo->LineEncoding.CharFormat == TwoStopBits)
ConfigMask |= (1 << USBS1);
- /* Determine data size - 5, 6, 7, or 8 bits are supported */
- if (LineCoding.DataBits == 6)
+ if (CDCInterfaceInfo->LineEncoding.DataBits == 6)
ConfigMask |= (1 << UCSZ10);
- else if (LineCoding.DataBits == 7)
+ else if (CDCInterfaceInfo->LineEncoding.DataBits == 7)
ConfigMask |= (1 << UCSZ11);
- else if (LineCoding.DataBits == 8)
+ else if (CDCInterfaceInfo->LineEncoding.DataBits == 8)
ConfigMask |= ((1 << UCSZ11) | (1 << UCSZ10));
- /* Enable double speed, gives better error percentages at 8MHz */
- UCSR1A = (1 << U2X1);
-
- /* Enable transmit and receive modules and interrupts */
+ UCSR1A = (1 << U2X1);
UCSR1B = ((1 << RXCIE1) | (1 << TXEN1) | (1 << RXEN1));
-
- /* Set the USART mode to the mask generated by the Line Coding options */
- UCSR1C = ConfigMask;
-
- /* Set the USART baud rate register to the desired baud rate value */
- UBRR1 = SERIAL_2X_UBBRVAL((uint16_t)LineCoding.BaudRateBPS);
+ UCSR1C = ConfigMask;
+ UBRR1 = SERIAL_2X_UBBRVAL((uint16_t)CDCInterfaceInfo->LineEncoding.BaudRateBPS);
}
diff --git a/Demos/Device/USBtoSerial/USBtoSerial.h b/Demos/Device/USBtoSerial/USBtoSerial.h
index 8e7e8aed8..7ff796e70 100644
--- a/Demos/Device/USBtoSerial/USBtoSerial.h
+++ b/Demos/Device/USBtoSerial/USBtoSerial.h
@@ -46,140 +46,28 @@
#include "Lib/RingBuff.h"
- #include <LUFA/Version.h> // Library Version Information
- #include <LUFA/Drivers/USB/USB.h> // USB Functionality
- #include <LUFA/Drivers/Peripheral/Serial.h> // USART driver
- #include <LUFA/Drivers/Board/LEDs.h> // LEDs driver
- #include <LUFA/Scheduler/Scheduler.h> // Simple scheduler for task management
+ #include <LUFA/Version.h>
+ #include <LUFA/Drivers/Board/LEDs.h>
+ #include <LUFA/Drivers/Board/Joystick.h>
+ #include <LUFA/Drivers/Peripheral/Serial.h>
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/CDC.h>
/* Macros: */
- /** CDC Class specific request to get the current virtual serial port configuration settings. */
- #define REQ_GetLineEncoding 0x21
-
- /** CDC Class specific request to set the current virtual serial port configuration settings. */
- #define REQ_SetLineEncoding 0x20
-
- /** CDC Class specific request to set the current virtual serial port handshake line states. */
- #define REQ_SetControlLineState 0x22
-
- /** Notification type constant for a change in the virtual serial port handshake line states, for
- * use with a USB_Notification_Header_t notification structure when sent to the host via the CDC
- * notification endpoint.
- */
- #define NOTIF_SerialState 0x20
-
- /** Mask for the DTR handshake line for use with the REQ_SetControlLineState class specific request
- * from the host, to indicate that the DTR line state should be high.
- */
- #define CONTROL_LINE_OUT_DTR (1 << 0)
-
- /** Mask for the RTS handshake line for use with the REQ_SetControlLineState class specific request
- * from the host, to indicate that theRTS line state should be high.
- */
- #define CONTROL_LINE_OUT_RTS (1 << 1)
+ #define LEDMASK_USB_NOTREADY LEDS_LED1
+ #define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
+ #define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
+ #define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
- /** Mask for the DCD handshake line for use with the a NOTIF_SerialState class specific notification
- * from the device to the host, to indicate that the DCD line state is currently high.
- */
- #define CONTROL_LINE_IN_DCD (1 << 0)
-
- /** Mask for the DSR handshake line for use with the a NOTIF_SerialState class specific notification
- * from the device to the host, to indicate that the DSR line state is currently high.
- */
- #define CONTROL_LINE_IN_DSR (1 << 1)
-
- /** Mask for the BREAK handshake line for use with the a NOTIF_SerialState class specific notification
- * from the device to the host, to indicate that the BREAK line state is currently high.
- */
- #define CONTROL_LINE_IN_BREAK (1 << 2)
-
- /** Mask for the RING handshake line for use with the a NOTIF_SerialState class specific notification
- * from the device to the host, to indicate that the RING line state is currently high.
- */
- #define CONTROL_LINE_IN_RING (1 << 3)
-
- /** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
- * to indicate that a framing error has occurred on the virtual serial port.
- */
- #define CONTROL_LINE_IN_FRAMEERROR (1 << 4)
-
- /** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
- * to indicate that a parity error has occurred on the virtual serial port.
- */
- #define CONTROL_LINE_IN_PARITYERROR (1 << 5)
-
- /** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
- * to indicate that a data overrun error has occurred on the virtual serial port.
- */
- #define CONTROL_LINE_IN_OVERRUNERROR (1 << 6)
-
- /* Type Defines: */
- /** Type define for the virtual serial port line encoding settings, for storing the current USART configuration
- * as set by the host via a class specific request.
- */
- typedef struct
- {
- uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */
- uint8_t CharFormat; /**< Character format of the virtual serial port, a value from the
- * CDCDevice_CDC_LineCodingFormats_t enum
- */
- uint8_t ParityType; /**< Parity setting of the virtual serial port, a value from the
- * CDCDevice_LineCodingParity_t enum
- */
- uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
- } CDC_Line_Coding_t;
-
- /** Type define for a CDC notification, sent to the host via the CDC notification endpoint to indicate a
- * change in the device state asynchronously.
- */
- typedef struct
- {
- uint8_t NotificationType; /**< Notification type, a mask of REQDIR_*, REQTYPE_* and REQREC_* constants
- * from the library StdRequestType.h header
- */
- uint8_t Notification; /**< Notification value, a NOTIF_* constant */
- uint16_t wValue; /**< Notification wValue, notification-specific */
- uint16_t wIndex; /**< Notification wIndex, notification-specific */
- uint16_t wLength; /**< Notification wLength, notification-specific */
- } USB_Notification_Header_t;
-
- /* Enums: */
- /** Enum for the possible line encoding formats of a virtual serial port. */
- enum CDCDevice_CDC_LineCodingFormats_t
- {
- OneStopBit = 0, /**< Each frame contains one stop bit */
- OneAndAHalfStopBits = 1, /**< Each frame contains one and a half stop bits */
- TwoStopBits = 2, /**< Each frame contains two stop bits */
- };
-
- /** Enum for the possible line encoding parity settings of a virtual serial port. */
- enum CDCDevice_LineCodingParity_t
- {
- Parity_None = 0, /**< No parity bit mode on each frame */
- Parity_Odd = 1, /**< Odd parity bit mode on each frame */
- Parity_Even = 2, /**< Even parity bit mode on each frame */
- Parity_Mark = 3, /**< Mark parity bit mode on each frame */
- Parity_Space = 4, /**< Space parity bit mode on each frame */
- };
-
- /** Enum for the possible status codes for passing to the UpdateStatus() function. */
- enum USBtoSerial_StatusCodes_t
- {
- Status_USBNotReady = 0, /**< USB is not ready (disconnected from a USB host) */
- Status_USBEnumerating = 1, /**< USB interface is enumerating */
- Status_USBReady = 2, /**< USB interface is connected and ready */
- };
-
- /* Tasks: */
- TASK(CDC_Task);
-
/* Function Prototypes: */
+ void SetupHardware(void);
+
void EVENT_USB_Connect(void);
void EVENT_USB_Disconnect(void);
void EVENT_USB_ConfigurationChanged(void);
void EVENT_USB_UnhandledControlPacket(void);
-
- void ReconfigureUSART(void);
- void UpdateStatus(uint8_t CurrentStatus);
+ void EVENT_USB_StartOfFrame(void);
+
+ void EVENT_USB_CDC_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
#endif
diff --git a/Demos/Device/USBtoSerial/makefile b/Demos/Device/USBtoSerial/makefile
index 708e87246..5cf9c617e 100644
--- a/Demos/Device/USBtoSerial/makefile
+++ b/Demos/Device/USBtoSerial/makefile
@@ -126,7 +126,6 @@ LUFA_PATH = ../../..
SRC = $(TARGET).c \
Descriptors.c \
Lib/RingBuff.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/CDC.c \
# List C++ source files here. (C dependencies are automatically generated.)
@@ -184,7 +183,7 @@ CSTANDARD = -std=gnu99
# Place -D or -U options here for C sources
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
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
diff --git a/Demos/Host/GenericHIDHost/makefile b/Demos/Host/GenericHIDHost/makefile
index b17ae1641..b912b2ff8 100644
--- a/Demos/Host/GenericHIDHost/makefile
+++ b/Demos/Host/GenericHIDHost/makefile
@@ -138,7 +138,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/Host/HIDParser.c \
# List C++ source files here. (C dependencies are automatically generated.)
diff --git a/Demos/Host/MassStorageHost/Lib/MassStoreCommands.c b/Demos/Host/MassStorageHost/Lib/MassStoreCommands.c
index 95aafca8c..f47e9f5ed 100644
--- a/Demos/Host/MassStorageHost/Lib/MassStoreCommands.c
+++ b/Demos/Host/MassStorageHost/Lib/MassStoreCommands.c
@@ -119,10 +119,10 @@ static uint8_t MassStore_WaitForDataReceived(void)
while (!(Pipe_IsINReceived()))
{
/* Check to see if a new frame has been issued (1ms elapsed) */
- if (USB_INT_HasOccurred(USB_INT_HSOFI))
+ if (FrameElapsed)
{
/* Clear the flag and decrement the timeout period counter */
- USB_INT_Clear(USB_INT_HSOFI);
+ FrameElapsed = false;
TimeoutMSRem--;
/* Check to see if the timeout period for the command has elapsed */
diff --git a/Demos/Host/StillImageHost/Lib/StillImageCommands.c b/Demos/Host/StillImageHost/Lib/StillImageCommands.c
index 8f05e48f4..f2f666bd1 100644
--- a/Demos/Host/StillImageHost/Lib/StillImageCommands.c
+++ b/Demos/Host/StillImageHost/Lib/StillImageCommands.c
@@ -109,10 +109,10 @@ uint8_t SImage_RecieveBlockHeader(void)
while (!(Pipe_IsReadWriteAllowed()))
{
/* Check to see if a new frame has been issued (1ms elapsed) */
- if (USB_INT_HasOccurred(USB_INT_HSOFI))
+ if (FrameElapsed)
{
/* Clear the flag and decrement the timeout period counter */
- USB_INT_Clear(USB_INT_HSOFI);
+ FrameElapsed = false;
TimeoutMSRem--;
/* Check to see if the timeout period for the command has elapsed */
diff --git a/Demos/OTG/TestApp/TestApp.h b/Demos/OTG/TestApp/TestApp.h
index de4d52612..7ae5663d9 100644
--- a/Demos/OTG/TestApp/TestApp.h
+++ b/Demos/OTG/TestApp/TestApp.h
@@ -45,7 +45,6 @@
#include <LUFA/Version.h> // Library Version Information
#include <LUFA/Drivers/USB/USB.h> // USB Functionality
#include <LUFA/Scheduler/Scheduler.h> // Simple scheduler for task management
- #include <LUFA/MemoryAllocator/DynAlloc.h> // Auto-defragmenting Dynamic Memory allocation
#include <LUFA/Drivers/Misc/TerminalCodes.h> // ANSI Terminal Escape Codes
#include <LUFA/Drivers/Peripheral/ADC.h> // ADC driver
#include <LUFA/Drivers/Peripheral/SerialStream.h> // USART Stream driver
diff --git a/Demos/OTG/TestApp/makefile b/Demos/OTG/TestApp/makefile
index dd6d8f43f..a8bf4ac42 100644
--- a/Demos/OTG/TestApp/makefile
+++ b/Demos/OTG/TestApp/makefile
@@ -127,7 +127,6 @@ SRC = $(TARGET).c \
TestEvents.c \
Descriptors.c \
$(LUFA_PATH)/LUFA/Scheduler/Scheduler.c \
- $(LUFA_PATH)/LUFA/MemoryAllocator/DynAlloc.c \
$(LUFA_PATH)/LUFA/Drivers/Board/Temperature.c \
$(LUFA_PATH)/LUFA/Drivers/Peripheral/SerialStream.c \
$(LUFA_PATH)/LUFA/Drivers/Peripheral/Serial.c \
@@ -141,7 +140,6 @@ 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 \
# List C++ source files here. (C dependencies are automatically generated.)
@@ -189,7 +187,6 @@ CSTANDARD = -std=gnu99
# Place -D or -U options here for C sources
CDEFS = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)
CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES
-CDEFS += -DNUM_BLOCKS=100 -DBLOCK_SIZE=8 -DNUM_HANDLES=20
# Place -D or -U options here for ASM sources
diff --git a/LUFA.pnproj b/LUFA.pnproj
index 235ccfa3b..ae38c0bb9 100644
--- a/LUFA.pnproj
+++ b/LUFA.pnproj
@@ -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
diff --git a/LUFA/ChangeLog.txt b/LUFA/ChangeLog.txt
index ac675348b..fe3b63360 100644
--- a/LUFA/ChangeLog.txt
+++ b/LUFA/ChangeLog.txt
@@ -4,6 +4,14 @@
* documentation pages. It is not a project source file.
*/
+========== TODO: ===========
+ - Document new class drivers
+ - Re-document all demos now that they have changed
+ - Add standardized descriptor names to class driver structures, controlled by USE_NONSTANDARD_DESCRIPTOR_NAMES
+ - Add C++ compatibility to class drivers
+ - Disable JTAG in demos
+============================
+
/** \page Page_ChangeLog Project Changelog
*
* \section Sec_ChangeLogXXXXXX Version XXXXXX
@@ -30,6 +38,8 @@
* LUFA/Drivers/USB/Class/ directory to LUFA/Drivers/USB/HighLevel/ in preperation for the new USB class APIs
* - Moved out each demos' functionality library files (e.g. Ring Buffer library) to /Lib directories for a better directory structure
* - Removed Tx interrupt from the USBtoSerial demo; now sends characters via polling to ensure more time for the Rx interrupt
+ * - Added new EVENT_USB_StartOfFrame event in the library to indicate the start of each USB frame (when generated)
+ * - Removed psuedo-scheduler, dynamic memory block allocator from the library (no longer needed and not used respectively)
*
*
* \section Sec_ChangeLog090510 Version 090510
diff --git a/LUFA/DirectorySummaries.txt b/LUFA/DirectorySummaries.txt
index f43984760..3fae9c18e 100644
--- a/LUFA/DirectorySummaries.txt
+++ b/LUFA/DirectorySummaries.txt
@@ -10,19 +10,6 @@
* This folder contains header files which are common to all parts of the LUFA library. They may be used freely in
* user applications.
*
- * \dir MemoryAllocator
- * \brief Auto-defragmenting dynamic memory allocation library.
- *
- * This folder contains a simple handle-based dynamic memory allocation library, capable of handing out memory in
- * block chunks. As new memory is allocated, the library will defragment the already allocated memory to ensure
- * optimal memory usage. It is not used within the LUFA library, and is provided as a convenience for user applications.
- *
- * \dir Scheduler
- * \brief Simple round-robbin scheduler.
- *
- * This folder contains the simple LUFA round-robbin scheduler, provided as a convenience for user applications. It
- * is very simple in design, and is intended to make code easier to read, rather than providing a complete RTOS kernel.
- *
* \dir Drivers
* \brief Library hardware and software drivers.
*
diff --git a/LUFA/Drivers/USB/Class/Device/Audio.c b/LUFA/Drivers/USB/Class/Device/Audio.c
new file mode 100644
index 000000000..b0800ba0f
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/Audio.c
@@ -0,0 +1,154 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#include "Audio.h"
+
+void USB_Audio_ProcessControlPacket(USB_ClassInfo_Audio_t* AudioInterfaceInfo)
+{
+ if (!(Endpoint_IsSETUPReceived()))
+ return;
+
+// if (USB_ControlRequest.wIndex != AudioInterfaceInfo->InterfaceNumber)
+// return;
+
+ switch (USB_ControlRequest.bRequest)
+ {
+ case REQ_SetInterface:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ AudioInterfaceInfo->InterfaceEnabled = (USB_ControlRequest.wValue != 0);
+
+ while (!(Endpoint_IsINReady()));
+ Endpoint_ClearIN();
+ }
+
+ break;
+ }
+}
+
+bool USB_Audio_ConfigureEndpoints(USB_ClassInfo_Audio_t* AudioInterfaceInfo)
+{
+ if (AudioInterfaceInfo->DataINEndpointNumber)
+ {
+ if (!(Endpoint_ConfigureEndpoint(AudioInterfaceInfo->DataINEndpointNumber, EP_TYPE_ISOCHRONOUS,
+ ENDPOINT_DIR_IN, AudioInterfaceInfo->DataINEndpointSize,
+ ENDPOINT_BANK_DOUBLE)))
+ {
+ return false;
+ }
+ }
+
+ if (AudioInterfaceInfo->DataOUTEndpointNumber)
+ {
+ if (!(Endpoint_ConfigureEndpoint(AudioInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_ISOCHRONOUS,
+ ENDPOINT_DIR_OUT, AudioInterfaceInfo->DataOUTEndpointSize,
+ ENDPOINT_BANK_DOUBLE)))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+int8_t USB_Audio_ReadSample8(void)
+{
+ int8_t Sample;
+
+ Sample = Endpoint_Read_Byte();
+
+ if (!(Endpoint_IsReadWriteAllowed()))
+ Endpoint_ClearOUT();
+
+ return Sample;
+}
+
+int16_t USB_Audio_ReadSample16(void)
+{
+ int16_t Sample;
+
+ Sample = (int16_t)Endpoint_Read_Word_LE();
+
+ if (!(Endpoint_IsReadWriteAllowed()))
+ Endpoint_ClearOUT();
+
+ return Sample;
+}
+
+int32_t USB_Audio_ReadSample24(void)
+{
+ int32_t Sample;
+
+ Sample = (((uint32_t)Endpoint_Read_Byte() << 16) | Endpoint_Read_Word_LE());
+
+ if (!(Endpoint_IsReadWriteAllowed()))
+ Endpoint_ClearOUT();
+
+ return Sample;
+}
+
+void USB_Audio_WriteSample8(int8_t Sample)
+{
+ Endpoint_Write_Byte(Sample);
+
+ if (!(Endpoint_IsReadWriteAllowed()))
+ Endpoint_ClearIN();
+}
+
+void USB_Audio_WriteSample16(int16_t Sample)
+{
+ Endpoint_Write_Word_LE(Sample);
+
+ if (!(Endpoint_IsReadWriteAllowed()))
+ Endpoint_ClearIN();
+}
+
+void USB_Audio_WriteSample24(int32_t Sample)
+{
+ Endpoint_Write_Byte(Sample >> 16);
+ Endpoint_Write_Word_LE(Sample);
+
+ if (!(Endpoint_IsReadWriteAllowed()))
+ Endpoint_ClearIN();
+}
+
+bool USB_Audio_IsSampleReceived(USB_ClassInfo_Audio_t* AudioInterfaceInfo)
+{
+ Endpoint_SelectEndpoint(AudioInterfaceInfo->DataOUTEndpointNumber);
+ return Endpoint_IsOUTReceived();
+}
+
+bool USB_Audio_IsReadyForNextSample(USB_ClassInfo_Audio_t* AudioInterfaceInfo)
+{
+ Endpoint_SelectEndpoint(AudioInterfaceInfo->DataINEndpointNumber);
+ return Endpoint_IsINReady();
+}
diff --git a/LUFA/Drivers/USB/Class/Device/Audio.h b/LUFA/Drivers/USB/Class/Device/Audio.h
new file mode 100644
index 000000000..aa7b4069c
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/Audio.h
@@ -0,0 +1,70 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#ifndef _AUDIO_CLASS_H_
+#define _AUDIO_CLASS_H_
+
+ /* Includes: */
+ #include "../../USB.h"
+
+ #include <string.h>
+
+ /* Macros: */
+
+ /* Enums: */
+
+ /* Type Defines: */
+ typedef struct
+ {
+ uint8_t InterfaceNumber;
+
+ uint8_t DataINEndpointNumber;
+ uint16_t DataINEndpointSize;
+
+ uint8_t DataOUTEndpointNumber;
+ uint16_t DataOUTEndpointSize;
+
+ bool InterfaceEnabled;
+ } USB_ClassInfo_Audio_t;
+
+ /* Function Prototypes: */
+ bool USB_Audio_ConfigureEndpoints(USB_ClassInfo_Audio_t* AudioInterfaceInfo);
+ void USB_Audio_ProcessControlPacket(USB_ClassInfo_Audio_t* AudioInterfaceInfo);
+ void USB_Audio_USBTask(USB_ClassInfo_Audio_t* AudioInterfaceInfo);
+
+ int8_t USB_Audio_ReadSample8(void);
+ int16_t USB_Audio_ReadSample16(void);
+ int32_t USB_Audio_ReadSample24(void);
+ void USB_Audio_WriteSample8(int8_t Sample);
+ void USB_Audio_WriteSample16(int16_t Sample);
+ void USB_Audio_WriteSample24(int32_t Sample);
+ bool USB_Audio_IsSampleReceived(USB_ClassInfo_Audio_t* AudioInterfaceInfo);
+ bool USB_Audio_IsReadyForNextSample(USB_ClassInfo_Audio_t* AudioInterfaceInfo);
+#endif
diff --git a/LUFA/Drivers/USB/Class/Device/CDC.c b/LUFA/Drivers/USB/Class/Device/CDC.c
new file mode 100644
index 000000000..8acaac7a1
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/CDC.c
@@ -0,0 +1,185 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define INCLUDE_FROM_CDC_CLASS_C
+#include "CDC.h"
+
+void USB_CDC_Event_Stub(void)
+{
+
+}
+
+void USB_CDC_ProcessControlPacket(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
+{
+ if (!(Endpoint_IsSETUPReceived()))
+ return;
+
+ if (USB_ControlRequest.wIndex != CDCInterfaceInfo->ControlInterfaceNumber)
+ return;
+
+ switch (USB_ControlRequest.bRequest)
+ {
+ case REQ_GetLineEncoding:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+ Endpoint_Write_Control_Stream_LE(&CDCInterfaceInfo->LineEncoding, sizeof(CDCInterfaceInfo->LineEncoding));
+ Endpoint_ClearOUT();
+ }
+
+ break;
+ case REQ_SetLineEncoding:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+ Endpoint_Read_Control_Stream_LE(&CDCInterfaceInfo->LineEncoding, sizeof(CDCInterfaceInfo->LineEncoding));
+ Endpoint_ClearIN();
+
+ EVENT_USB_CDC_LineEncodingChanged(CDCInterfaceInfo);
+ }
+
+ break;
+ case REQ_SetControlLineState:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ CDCInterfaceInfo->ControlLineState = USB_ControlRequest.wValue;
+
+ EVENT_USB_CDC_ControLineStateChanged();
+
+ while (!(Endpoint_IsINReady()));
+ Endpoint_ClearIN();
+ }
+
+ break;
+ }
+}
+
+bool USB_CDC_ConfigureEndpoints(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
+{
+ if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->DataINEndpointNumber, EP_TYPE_BULK,
+ ENDPOINT_DIR_IN, CDCInterfaceInfo->DataINEndpointSize,
+ ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+
+ if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_BULK,
+ ENDPOINT_DIR_OUT, CDCInterfaceInfo->DataOUTEndpointSize,
+ ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+
+ if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->NotificationEndpointNumber, EP_TYPE_INTERRUPT,
+ ENDPOINT_DIR_IN, CDCInterfaceInfo->NotificationEndpointSize,
+ ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void USB_CDC_USBTask(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
+{
+ if (!(USB_IsConnected))
+ return;
+
+ Endpoint_SelectEndpoint(CDCInterfaceInfo->DataINEndpointNumber);
+
+ if (!(Endpoint_BytesInEndpoint()))
+ return;
+
+ if (!(Endpoint_IsReadWriteAllowed()))
+ {
+ Endpoint_ClearIN();
+ while (!(Endpoint_IsReadWriteAllowed()));
+ }
+
+ Endpoint_ClearIN();
+}
+
+void USB_CDC_SendString(USB_ClassInfo_CDC_t* CDCInterfaceInfo, char* Data, uint16_t Length)
+{
+ Endpoint_SelectEndpoint(CDCInterfaceInfo->DataINEndpointNumber);
+ Endpoint_Write_Stream_LE(Data, Length, NO_STREAM_CALLBACK);
+}
+
+void USB_CDC_SendByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint8_t Data)
+{
+ Endpoint_SelectEndpoint(CDCInterfaceInfo->DataINEndpointNumber);
+
+ if (!(Endpoint_IsReadWriteAllowed()))
+ {
+ Endpoint_ClearIN();
+ while (!(Endpoint_IsReadWriteAllowed()));
+ }
+
+ Endpoint_Write_Byte(Data);
+}
+
+uint16_t USB_CDC_BytesReceived(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
+{
+ Endpoint_SelectEndpoint(CDCInterfaceInfo->DataOUTEndpointNumber);
+
+ return Endpoint_BytesInEndpoint();
+}
+
+uint8_t USB_CDC_ReceiveByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
+{
+ Endpoint_SelectEndpoint(CDCInterfaceInfo->DataOUTEndpointNumber);
+
+ uint8_t DataByte = Endpoint_Read_Byte();
+
+ if (!(Endpoint_BytesInEndpoint()))
+ Endpoint_ClearOUT();
+
+ return DataByte;
+}
+
+void USB_CDC_SendSerialLineStateChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint16_t LineStateMask)
+{
+ Endpoint_SelectEndpoint(CDCInterfaceInfo->NotificationEndpointNumber);
+
+ USB_Request_Header_t Notification = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = NOTIF_SerialState,
+ .wValue = 0,
+ .wIndex = 0,
+ .wLength = sizeof(uint16_t),
+ };
+
+ Endpoint_Write_Stream_LE(&Notification, sizeof(Notification), NO_STREAM_CALLBACK);
+ Endpoint_Write_Stream_LE(&LineStateMask, sizeof(LineStateMask), NO_STREAM_CALLBACK);
+ Endpoint_ClearIN();
+}
diff --git a/LUFA/Drivers/USB/Class/Device/CDC.h b/LUFA/Drivers/USB/Class/Device/CDC.h
new file mode 100644
index 000000000..bbe1c9838
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/CDC.h
@@ -0,0 +1,188 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#ifndef _CDC_CLASS_H_
+#define _CDC_CLASS_H_
+
+ /* Includes: */
+ #include "../../USB.h"
+
+ #include <string.h>
+
+ /* Macros: */
+ /** CDC Class specific request to get the current virtual serial port configuration settings. */
+ #define REQ_GetLineEncoding 0x21
+
+ /** CDC Class specific request to set the current virtual serial port configuration settings. */
+ #define REQ_SetLineEncoding 0x20
+
+ /** CDC Class specific request to set the current virtual serial port handshake line states. */
+ #define REQ_SetControlLineState 0x22
+
+ /** Notification type constant for a change in the virtual serial port handshake line states, for
+ * use with a USB_Notification_Header_t notification structure when sent to the host via the CDC
+ * notification endpoint.
+ */
+ #define NOTIF_SerialState 0x20
+
+ /** Mask for the DTR handshake line for use with the REQ_SetControlLineState class specific request
+ * from the host, to indicate that the DTR line state should be high.
+ */
+ #define CONTROL_LINE_OUT_DTR (1 << 0)
+
+ /** Mask for the RTS handshake line for use with the REQ_SetControlLineState class specific request
+ * from the host, to indicate that theRTS line state should be high.
+ */
+ #define CONTROL_LINE_OUT_RTS (1 << 1)
+
+ /** Mask for the DCD handshake line for use with the a NOTIF_SerialState class specific notification
+ * from the device to the host, to indicate that the DCD line state is currently high.
+ */
+ #define CONTROL_LINE_IN_DCD (1 << 0)
+
+ /** Mask for the DSR handshake line for use with the a NOTIF_SerialState class specific notification
+ * from the device to the host, to indicate that the DSR line state is currently high.
+ */
+ #define CONTROL_LINE_IN_DSR (1 << 1)
+
+ /** Mask for the BREAK handshake line for use with the a NOTIF_SerialState class specific notification
+ * from the device to the host, to indicate that the BREAK line state is currently high.
+ */
+ #define CONTROL_LINE_IN_BREAK (1 << 2)
+
+ /** Mask for the RING handshake line for use with the a NOTIF_SerialState class specific notification
+ * from the device to the host, to indicate that the RING line state is currently high.
+ */
+ #define CONTROL_LINE_IN_RING (1 << 3)
+
+ /** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
+ * to indicate that a framing error has occurred on the virtual serial port.
+ */
+ #define CONTROL_LINE_IN_FRAMEERROR (1 << 4)
+
+ /** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
+ * to indicate that a parity error has occurred on the virtual serial port.
+ */
+ #define CONTROL_LINE_IN_PARITYERROR (1 << 5)
+
+ /** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
+ * to indicate that a data overrun error has occurred on the virtual serial port.
+ */
+ #define CONTROL_LINE_IN_OVERRUNERROR (1 << 6)
+
+ /** Macro to define a CDC class-specific functional descriptor. CDC functional descriptors have a
+ * uniform structure but variable sized data payloads, thus cannot be represented accurately by
+ * a single typedef struct. A macro is used instead so that functional descriptors can be created
+ * easily by specifying the size of the payload. This allows sizeof() to work correctly.
+ *
+ * \param DataSize Size in bytes of the CDC functional descriptor's data payload
+ */
+ #define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \
+ struct \
+ { \
+ USB_Descriptor_Header_t Header; \
+ uint8_t SubType; \
+ uint8_t Data[DataSize]; \
+ }
+
+ /* Enums: */
+ /** Enum for the possible line encoding formats of a virtual serial port. */
+ enum CDCDevice_CDC_LineCodingFormats_t
+ {
+ OneStopBit = 0, /**< Each frame contains one stop bit */
+ OneAndAHalfStopBits = 1, /**< Each frame contains one and a half stop bits */
+ TwoStopBits = 2, /**< Each frame contains two stop bits */
+ };
+
+ /** Enum for the possible line encoding parity settings of a virtual serial port. */
+ enum CDCDevice_LineCodingParity_t
+ {
+ Parity_None = 0, /**< No parity bit mode on each frame */
+ Parity_Odd = 1, /**< Odd parity bit mode on each frame */
+ Parity_Even = 2, /**< Even parity bit mode on each frame */
+ Parity_Mark = 3, /**< Mark parity bit mode on each frame */
+ Parity_Space = 4, /**< Space parity bit mode on each frame */
+ };
+
+ /* Type Defines: */
+ /** Type define for the virtual serial port line encoding settings, for storing the current USART configuration
+ * as set by the host via a class specific request.
+ */
+ typedef struct
+ {
+ uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device */
+
+ uint8_t DataINEndpointNumber; /**< Endpoint number of the CDC interface's IN data endpoint */
+ uint16_t DataINEndpointSize; /**< Size in bytes of the CDC interface's IN data endpoint */
+
+ uint8_t DataOUTEndpointNumber; /**< Endpoint number of the CDC interface's OUT data endpoint */
+ uint16_t DataOUTEndpointSize; /**< Size in bytes of the CDC interface's OUT data endpoint */
+
+ uint8_t NotificationEndpointNumber; /**< Endpoint number of the CDC interface's IN notification endpoint, if used */
+ uint16_t NotificationEndpointSize; /**< Size in bytes of the CDC interface's IN notification endpoint, if used */
+
+ uint8_t ControlLineState;
+
+ struct
+ {
+ uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */
+ uint8_t CharFormat; /**< Character format of the virtual serial port, a value from the
+ * CDCDevice_CDC_LineCodingFormats_t enum
+ */
+ uint8_t ParityType; /**< Parity setting of the virtual serial port, a value from the
+ * CDCDevice_LineCodingParity_t enum
+ */
+ uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
+ } LineEncoding;
+ } USB_ClassInfo_CDC_t;
+
+ /* Function Prototypes: */
+ #if defined(INCLUDE_FROM_CDC_CLASS_C)
+ void USB_CDC_Event_Stub(void);
+ void EVENT_USB_CDC_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
+ ATTR_WEAK ATTR_ALIAS(USB_CDC_Event_Stub);
+ void EVENT_USB_CDC_ControLineStateChanged(void) ATTR_WEAK ATTR_ALIAS(USB_CDC_Event_Stub);;
+ #endif
+
+ void USB_CDC_USBTask(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+ bool USB_CDC_ConfigureEndpoints(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+ void USB_CDC_ProcessControlPacket(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+ void USB_CDC_USBTask(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+
+ void EVENT_USB_CDC_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+ void EVENT_USB_CDC_ControLineStateChanged(void);
+
+ void USB_CDC_SendString(USB_ClassInfo_CDC_t* CDCInterfaceInfo, char* Data, uint16_t Length);
+ void USB_CDC_SendByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint8_t Data);
+ uint16_t USB_CDC_BytesReceived(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+ uint8_t USB_CDC_ReceiveByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+ void USB_CDC_SendSerialLineStateChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint16_t LineStateMask);
+
+#endif
diff --git a/LUFA/Drivers/USB/Class/Device/HID.c b/LUFA/Drivers/USB/Class/Device/HID.c
new file mode 100644
index 000000000..fbc5e3a5c
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/HID.c
@@ -0,0 +1,211 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#include "HID.h"
+
+void USB_HID_ProcessControlPacket(USB_ClassInfo_HID_t* HIDInterfaceInfo)
+{
+ if (!(Endpoint_IsSETUPReceived()))
+ return;
+
+ if (USB_ControlRequest.wIndex != HIDInterfaceInfo->InterfaceNumber)
+ return;
+
+ switch (USB_ControlRequest.bRequest)
+ {
+ case REQ_GetReport:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ uint8_t ReportINData[HIDInterfaceInfo->ReportBufferSize];
+ uint16_t ReportINSize;
+
+ memset(ReportINData, 0, sizeof(ReportINData));
+
+ ReportINSize = CALLBACK_USB_HID_CreateNextHIDReport(HIDInterfaceInfo, ReportINData);
+
+ Endpoint_Write_Control_Stream_LE(ReportINData, ReportINSize);
+ Endpoint_ClearOUT();
+ }
+
+ break;
+ case REQ_SetReport:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ uint16_t ReportOUTSize = USB_ControlRequest.wLength;
+ uint8_t ReportOUTData[ReportOUTSize];
+
+ Endpoint_Read_Control_Stream_LE(ReportOUTData, ReportOUTSize);
+ Endpoint_ClearIN();
+
+ CALLBACK_USB_HID_ProcessReceivedHIDReport(HIDInterfaceInfo, ReportOUTData, ReportOUTSize);
+ }
+
+ break;
+ case REQ_GetProtocol:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ Endpoint_Write_Byte(HIDInterfaceInfo->UsingReportProtocol);
+ Endpoint_ClearIN();
+
+ while (!(Endpoint_IsOUTReceived()));
+ Endpoint_ClearOUT();
+ }
+
+ break;
+ case REQ_SetProtocol:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ HIDInterfaceInfo->UsingReportProtocol = (USB_ControlRequest.wValue != 0x0000);
+
+ while (!(Endpoint_IsINReady()));
+ Endpoint_ClearIN();
+ }
+
+ break;
+ case REQ_SetIdle:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ HIDInterfaceInfo->IdleCount = ((USB_ControlRequest.wValue >> 8) << 2);
+
+ while (!(Endpoint_IsINReady()));
+ Endpoint_ClearIN();
+ }
+
+ break;
+ case REQ_GetIdle:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ Endpoint_Write_Byte(HIDInterfaceInfo->IdleCount >> 2);
+ Endpoint_ClearIN();
+
+ while (!(Endpoint_IsOUTReceived()));
+ Endpoint_ClearOUT();
+ }
+
+ break;
+ }
+}
+
+bool USB_HID_ConfigureEndpoints(USB_ClassInfo_HID_t* HIDInterfaceInfo)
+{
+ HIDInterfaceInfo->UsingReportProtocol = true;
+
+ if (!(Endpoint_ConfigureEndpoint(HIDInterfaceInfo->ReportINEndpointNumber, EP_TYPE_INTERRUPT,
+ ENDPOINT_DIR_IN, HIDInterfaceInfo->ReportINEndpointSize, ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+
+ if (HIDInterfaceInfo->ReportOUTEndpointNumber)
+ {
+ if (!(Endpoint_ConfigureEndpoint(HIDInterfaceInfo->ReportOUTEndpointNumber, EP_TYPE_INTERRUPT,
+ ENDPOINT_DIR_OUT, HIDInterfaceInfo->ReportOUTEndpointSize, ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void USB_HID_RegisterStartOfFrame(USB_ClassInfo_HID_t* HIDInterfaceInfo)
+{
+ if (HIDInterfaceInfo->IdleMSRemaining)
+ HIDInterfaceInfo->IdleMSRemaining--;
+}
+
+void USB_HID_USBTask(USB_ClassInfo_HID_t* HIDInterfaceInfo)
+{
+ if (!(USB_IsConnected))
+ return;
+
+ Endpoint_SelectEndpoint(HIDInterfaceInfo->ReportINEndpointNumber);
+
+ if (Endpoint_IsReadWriteAllowed() &&
+ !(HIDInterfaceInfo->IdleCount && HIDInterfaceInfo->IdleMSRemaining))
+ {
+ if (HIDInterfaceInfo->IdleCount && !(HIDInterfaceInfo->IdleMSRemaining))
+ HIDInterfaceInfo->IdleMSRemaining = HIDInterfaceInfo->IdleCount;
+
+ uint8_t ReportINData[HIDInterfaceInfo->ReportBufferSize];
+ uint16_t ReportINSize;
+
+ memset(ReportINData, 0, sizeof(ReportINData));
+
+ ReportINSize = CALLBACK_USB_HID_CreateNextHIDReport(HIDInterfaceInfo, ReportINData);
+
+ if (ReportINSize)
+ {
+ Endpoint_Write_Stream_LE(ReportINData, ReportINSize
+ #if !defined(NO_STREAM_CALLBACKS)
+ , NO_STREAM_CALLBACK
+ #endif
+ );
+ }
+
+ Endpoint_ClearIN();
+ }
+
+ if (HIDInterfaceInfo->ReportOUTEndpointNumber)
+ {
+ Endpoint_SelectEndpoint(HIDInterfaceInfo->ReportOUTEndpointNumber);
+
+ if (Endpoint_IsOUTReceived())
+ {
+ uint16_t ReportOUTSize = Endpoint_BytesInEndpoint();
+ uint8_t ReportOUTData[ReportOUTSize];
+
+ if (ReportOUTSize)
+ {
+ Endpoint_Read_Stream_LE(ReportOUTData, ReportOUTSize
+ #if !defined(NO_STREAM_CALLBACKS)
+ , NO_STREAM_CALLBACK
+ #endif
+ );
+ }
+
+ CALLBACK_USB_HID_ProcessReceivedHIDReport(HIDInterfaceInfo, ReportOUTData, ReportOUTSize);
+
+ Endpoint_ClearOUT();
+ }
+ }
+}
diff --git a/LUFA/Drivers/USB/Class/Device/HID.h b/LUFA/Drivers/USB/Class/Device/HID.h
new file mode 100644
index 000000000..8fdeb064a
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/HID.h
@@ -0,0 +1,115 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#ifndef _HID_CLASS_H_
+#define _HID_CLASS_H_
+
+ /* Includes: */
+ #include "../../USB.h"
+
+ #include <string.h>
+
+ /* Macros: */
+ /** HID Class Specific Request to get the current HID report from the device. */
+ #define REQ_GetReport 0x01
+
+ /** HID Class Specific Request to get the current device idle count. */
+ #define REQ_GetIdle 0x02
+
+ /** HID Class Specific Request to set the current HID report to the device. */
+ #define REQ_SetReport 0x09
+
+ /** HID Class Specific Request to set the device's idle count. */
+ #define REQ_SetIdle 0x0A
+
+ /** HID Class Specific Request to get the current HID report protocol mode. */
+ #define REQ_GetProtocol 0x03
+
+ /** HID Class Specific Request to set the current HID report protocol mode. */
+ #define REQ_SetProtocol 0x0B
+
+ /** Descriptor header type value, to indicate a HID class HID descriptor. */
+ #define DTYPE_HID 0x21
+
+ /** Descriptor header type value, to indicate a HID class HID report descriptor. */
+ #define DTYPE_Report 0x22
+
+ /* Type Defines: */
+ /** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID
+ * specification for details on the structure elements.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Header_t Header;
+
+ uint16_t HIDSpec;
+ uint8_t CountryCode;
+
+ uint8_t TotalReportDescriptors;
+
+ uint8_t HIDReportType;
+ uint16_t HIDReportLength;
+ } USB_Descriptor_HID_t;
+
+ /** Type define for the data type used to store HID report descriptor elements. */
+ typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
+
+ /** Class state structure. An instance of this structure should be made for each HID interface
+ * within the user application, and passed to each of the HID class driver functions as the
+ * HIDInterfaceInfo parameter. The contents of this structure should be set to their correct
+ * values when used, or ommitted to force the library to use default values.
+ */
+ typedef struct
+ {
+ uint8_t InterfaceNumber; /**< Interface number of the HID interface within the device */
+
+ uint8_t ReportINEndpointNumber; /**< Endpoint number of the HID interface's IN report endpoint */
+ uint16_t ReportINEndpointSize; /**< Size in bytes of the HID interface's IN report endpoint */
+
+ uint8_t ReportOUTEndpointNumber; /**< Endpoint number of the HID interface's OUT report endpoint, if used */
+ uint16_t ReportOUTEndpointSize; /**< Size in bytes of the HID interface's OUT report endpoint, if used */
+
+ uint8_t ReportBufferSize;
+
+ bool UsingReportProtocol; /**< Indicates if the HID interface is set to Boot or Report protocol mode */
+ uint16_t IdleCount; /**< Report idle period, in ms, set by the host */
+ uint16_t IdleMSRemaining; /**< Total number of ms remaining before the idle period elapses */
+ } USB_ClassInfo_HID_t;
+
+ /* Function Prototypes: */
+ bool USB_HID_ConfigureEndpoints(USB_ClassInfo_HID_t* HIDInterfaceInfo);
+ void USB_HID_ProcessControlPacket(USB_ClassInfo_HID_t* HIDInterfaceInfo);
+ void USB_HID_RegisterStartOfFrame(USB_ClassInfo_HID_t* HIDInterfaceInfo);
+ void USB_HID_USBTask(USB_ClassInfo_HID_t* HIDInterfaceInfo);
+
+ uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);
+ void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize);
+
+#endif
diff --git a/LUFA/Drivers/USB/Class/Device/MassStorage.c b/LUFA/Drivers/USB/Class/Device/MassStorage.c
new file mode 100644
index 000000000..1c41f6046
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/MassStorage.c
@@ -0,0 +1,208 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define INCLUDE_FROM_MS_CLASS_C
+#include "MassStorage.h"
+
+static USB_ClassInfo_MS_t* CallbackMSInterfaceInfo;
+
+void USB_MS_ProcessControlPacket(USB_ClassInfo_MS_t* MSInterfaceInfo)
+{
+ if (!(Endpoint_IsSETUPReceived()))
+ return;
+
+ if (USB_ControlRequest.wIndex != MSInterfaceInfo->InterfaceNumber)
+ return;
+
+ switch (USB_ControlRequest.bRequest)
+ {
+ case REQ_MassStorageReset:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ MSInterfaceInfo->IsMassStoreReset = true;
+
+ while (!(Endpoint_IsINReady()));
+ Endpoint_ClearIN();
+ }
+
+ break;
+ case REQ_GetMaxLUN:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ Endpoint_Write_Byte(MSInterfaceInfo->TotalLUNs - 1);
+
+ Endpoint_ClearIN();
+
+ while (!(Endpoint_IsOUTReceived()));
+ Endpoint_ClearOUT();
+ }
+
+ break;
+ }
+}
+
+bool USB_MS_ConfigureEndpoints(USB_ClassInfo_MS_t* MSInterfaceInfo)
+{
+ if (!(Endpoint_ConfigureEndpoint(MSInterfaceInfo->DataINEndpointNumber, EP_TYPE_BULK,
+ ENDPOINT_DIR_IN, MSInterfaceInfo->DataINEndpointSize,
+ ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+
+ if (!(Endpoint_ConfigureEndpoint(MSInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_BULK,
+ ENDPOINT_DIR_OUT, MSInterfaceInfo->DataOUTEndpointSize,
+ ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void USB_MS_USBTask(USB_ClassInfo_MS_t* MSInterfaceInfo)
+{
+ if (!(USB_IsConnected))
+ return;
+
+ Endpoint_SelectEndpoint(MSInterfaceInfo->DataOUTEndpointNumber);
+
+ if (Endpoint_IsReadWriteAllowed())
+ {
+ if (USB_MS_ReadInCommandBlock(MSInterfaceInfo))
+ {
+ if (MSInterfaceInfo->CommandBlock.Flags & COMMAND_DIRECTION_DATA_IN)
+ Endpoint_SelectEndpoint(MSInterfaceInfo->DataINEndpointNumber);
+
+ MSInterfaceInfo->CommandStatus.Status = CALLBACK_USB_MS_SCSICommandReceived(MSInterfaceInfo) ?
+ Command_Pass : Command_Fail;
+ MSInterfaceInfo->CommandStatus.Signature = CSW_SIGNATURE;
+ MSInterfaceInfo->CommandStatus.Tag = MSInterfaceInfo->CommandBlock.Tag;
+ MSInterfaceInfo->CommandStatus.DataTransferResidue = MSInterfaceInfo->CommandBlock.DataTransferLength;
+
+ if ((MSInterfaceInfo->CommandStatus.Status == Command_Fail) && (MSInterfaceInfo->CommandStatus.DataTransferResidue))
+ Endpoint_StallTransaction();
+
+ USB_MS_ReturnCommandStatus(MSInterfaceInfo);
+
+ if (MSInterfaceInfo->IsMassStoreReset)
+ {
+ Endpoint_ResetFIFO(MSInterfaceInfo->DataOUTEndpointNumber);
+ Endpoint_ResetFIFO(MSInterfaceInfo->DataINEndpointNumber);
+
+ Endpoint_SelectEndpoint(MSInterfaceInfo->DataOUTEndpointNumber);
+ Endpoint_ClearStall();
+ Endpoint_SelectEndpoint(MSInterfaceInfo->DataINEndpointNumber);
+ Endpoint_ClearStall();
+
+ MSInterfaceInfo->IsMassStoreReset = false;
+ }
+ }
+ }
+}
+
+static bool USB_MS_ReadInCommandBlock(USB_ClassInfo_MS_t* MSInterfaceInfo)
+{
+ Endpoint_SelectEndpoint(MSInterfaceInfo->DataOUTEndpointNumber);
+
+ CallbackMSInterfaceInfo = MSInterfaceInfo;
+ Endpoint_Read_Stream_LE(&MSInterfaceInfo->CommandBlock,
+ (sizeof(CommandBlockWrapper_t) - MAX_SCSI_COMMAND_LENGTH),
+ StreamCallback_AbortOnMassStoreReset);
+
+ if ((MSInterfaceInfo->CommandBlock.Signature != CBW_SIGNATURE) ||
+ (MSInterfaceInfo->CommandBlock.LUN >= MSInterfaceInfo->TotalLUNs) ||
+ (MSInterfaceInfo->CommandBlock.SCSICommandLength > MAX_SCSI_COMMAND_LENGTH))
+ {
+ Endpoint_StallTransaction();
+ Endpoint_SelectEndpoint(MSInterfaceInfo->DataINEndpointNumber);
+ Endpoint_StallTransaction();
+
+ return false;
+ }
+
+ CallbackMSInterfaceInfo = MSInterfaceInfo;
+ Endpoint_Read_Stream_LE(&MSInterfaceInfo->CommandBlock.SCSICommandData,
+ MSInterfaceInfo->CommandBlock.SCSICommandLength,
+ StreamCallback_AbortOnMassStoreReset);
+
+ Endpoint_ClearOUT();
+
+ if (MSInterfaceInfo->IsMassStoreReset)
+ return false;
+
+ return true;
+}
+
+static void USB_MS_ReturnCommandStatus(USB_ClassInfo_MS_t* MSInterfaceInfo)
+{
+ Endpoint_SelectEndpoint(MSInterfaceInfo->DataOUTEndpointNumber);
+
+ while (Endpoint_IsStalled())
+ {
+ USB_USBTask();
+
+ if (MSInterfaceInfo->IsMassStoreReset)
+ return;
+ }
+
+ Endpoint_SelectEndpoint(MSInterfaceInfo->DataINEndpointNumber);
+
+ while (Endpoint_IsStalled())
+ {
+ USB_USBTask();
+
+ if (MSInterfaceInfo->IsMassStoreReset)
+ return;
+ }
+
+ CallbackMSInterfaceInfo = MSInterfaceInfo;
+ Endpoint_Write_Stream_LE(&MSInterfaceInfo->CommandStatus, sizeof(CommandStatusWrapper_t),
+ StreamCallback_AbortOnMassStoreReset);
+
+ Endpoint_ClearIN();
+
+ if (MSInterfaceInfo->IsMassStoreReset)
+ return;
+}
+
+static uint8_t StreamCallback_AbortOnMassStoreReset(void)
+{
+ USB_MS_USBTask(CallbackMSInterfaceInfo);
+
+ if (CallbackMSInterfaceInfo->IsMassStoreReset)
+ return STREAMCALLBACK_Abort;
+ else
+ return STREAMCALLBACK_Continue;
+}
diff --git a/LUFA/Drivers/USB/Class/Device/MassStorage.h b/LUFA/Drivers/USB/Class/Device/MassStorage.h
new file mode 100644
index 000000000..c1874b218
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/MassStorage.h
@@ -0,0 +1,127 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#ifndef _MS_CLASS_H_
+#define _MS_CLASS_H_
+
+ /* Includes: */
+ #include "../../USB.h"
+
+ #include <string.h>
+
+ /* Macros: */
+ /** Mass Storage Class specific request to reset the Mass Storage interface, ready for the next command. */
+ #define REQ_MassStorageReset 0xFF
+
+ /** Mass Storage Class specific request to retrieve the total number of Logical Units (drives) in the SCSI device. */
+ #define REQ_GetMaxLUN 0xFE
+
+ /** Maximum length of a SCSI command which can be issued by the device or host in a Mass Storage bulk wrapper. */
+ #define MAX_SCSI_COMMAND_LENGTH 16
+
+ /** Magic signature for a Command Block Wrapper used in the Mass Storage Bulk-Only transport protocol. */
+ #define CBW_SIGNATURE 0x43425355UL
+
+ /** Magic signature for a Command Status Wrapper used in the Mass Storage Bulk-Only transport protocol. */
+ #define CSW_SIGNATURE 0x53425355UL
+
+ /** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from host-to-device. */
+ #define COMMAND_DIRECTION_DATA_OUT (0 << 7)
+
+ /** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from device-to-host. */
+ #define COMMAND_DIRECTION_DATA_IN (1 << 7)
+
+ /* Type defines: */
+ /** Type define for a Command Block Wrapper, used in the Mass Storage Bulk-Only Transport protocol. */
+ typedef struct
+ {
+ uint32_t Signature; /**< Command block signature, must be CBW_SIGNATURE to indicate a valid Command Block */
+ uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper */
+ uint32_t DataTransferLength; /** Length of the optional data portion of the issued command, in bytes */
+ uint8_t Flags; /**< Command block flags, indicating command data direction */
+ uint8_t LUN; /**< Logical Unit number this command is issued to */
+ uint8_t SCSICommandLength; /**< Length of the issued SCSI command within the SCSI command data array */
+ uint8_t SCSICommandData[MAX_SCSI_COMMAND_LENGTH]; /**< Issued SCSI command in the Command Block */
+ } CommandBlockWrapper_t;
+
+ /** Type define for a Command Status Wrapper, used in the Mass Storage Bulk-Only Transport protocol. */
+ typedef struct
+ {
+ uint32_t Signature; /**< Status block signature, must be CSW_SIGNATURE to indicate a valid Command Status */
+ uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper */
+ uint32_t DataTransferResidue; /**< Number of bytes of data not processed in the SCSI command */
+ uint8_t Status; /**< Status code of the issued command - a value from the MassStorage_CommandStatusCodes_t enum */
+ } CommandStatusWrapper_t;
+
+ /* Enums: */
+ /** Enum for the possible command status wrapper return status codes. */
+ enum MassStorage_CommandStatusCodes_t
+ {
+ Command_Pass = 0, /**< Command completed with no error */
+ Command_Fail = 1, /**< Command failed to complete - host may check the exact error via a SCSI REQUEST SENSE command */
+ Phase_Error = 2 /**< Command failed due to being invalid in the current phase */
+ };
+
+ /* Type Defines: */
+ /** Type define for the virtual serial port line encoding settings, for storing the current USART configuration
+ * as set by the host via a class specific request.
+ */
+ typedef struct
+ {
+ uint8_t InterfaceNumber; /**< Interface number of the Mass Storage interface within the device */
+
+ uint8_t DataINEndpointNumber; /**< Endpoint number of the Mass Storage interface's IN data endpoint */
+ uint16_t DataINEndpointSize; /**< Size in bytes of the Mass Storage interface's IN data endpoint */
+
+ uint8_t DataOUTEndpointNumber; /**< Endpoint number of the Mass Storage interface's OUT data endpoint */
+ uint16_t DataOUTEndpointSize; /**< Size in bytes of the Mass Storage interface's OUT data endpoint */
+
+ uint8_t TotalLUNs;
+
+ CommandBlockWrapper_t CommandBlock;
+ CommandStatusWrapper_t CommandStatus;
+
+ bool IsMassStoreReset;
+ } USB_ClassInfo_MS_t;
+
+ /* Function Prototypes: */
+ #if defined(INCLUDE_FROM_MS_CLASS_C)
+ static void USB_MS_ReturnCommandStatus(USB_ClassInfo_MS_t* MSInterfaceInfo);
+ static bool USB_MS_ReadInCommandBlock(USB_ClassInfo_MS_t* MSInterfaceInfo);
+ static uint8_t StreamCallback_AbortOnMassStoreReset(void);
+ #endif
+
+ void USB_MS_USBTask(USB_ClassInfo_MS_t* MSInterfaceInfo);
+ bool USB_MS_ConfigureEndpoints(USB_ClassInfo_MS_t* MSInterfaceInfo);
+ void USB_MS_ProcessControlPacket(USB_ClassInfo_MS_t* MSInterfaceInfo);
+
+ bool CALLBACK_USB_MS_SCSICommandReceived(USB_ClassInfo_MS_t* MSInterfaceInfo);
+
+#endif
diff --git a/LUFA/Drivers/USB/Class/Device/RNDIS.c b/LUFA/Drivers/USB/Class/Device/RNDIS.c
new file mode 100644
index 000000000..49c7df01d
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/RNDIS.c
@@ -0,0 +1,456 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2009.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.fourwalledcubicle.com
+*/
+
+/*
+ Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, and distribute this software
+ and its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+#define INCLUDE_FROM_RNDIS_CLASS_C
+#include "RNDIS.h"
+
+static const uint32_t PROGMEM AdapterSupportedOIDList[] =
+ {
+ OID_GEN_SUPPORTED_LIST,
+ OID_GEN_PHYSICAL_MEDIUM,
+ OID_GEN_HARDWARE_STATUS,
+ OID_GEN_MEDIA_SUPPORTED,
+ OID_GEN_MEDIA_IN_USE,
+ OID_GEN_MAXIMUM_FRAME_SIZE,
+ OID_GEN_MAXIMUM_TOTAL_SIZE,
+ OID_GEN_LINK_SPEED,
+ OID_GEN_TRANSMIT_BLOCK_SIZE,
+ OID_GEN_RECEIVE_BLOCK_SIZE,
+ OID_GEN_VENDOR_ID,
+ OID_GEN_VENDOR_DESCRIPTION,
+ OID_GEN_CURRENT_PACKET_FILTER,
+ OID_GEN_MAXIMUM_TOTAL_SIZE,
+ OID_GEN_MEDIA_CONNECT_STATUS,
+ OID_GEN_XMIT_OK,
+ OID_GEN_RCV_OK,
+ OID_GEN_XMIT_ERROR,
+ OID_GEN_RCV_ERROR,
+ OID_GEN_RCV_NO_BUFFER,
+ OID_802_3_PERMANENT_ADDRESS,
+ OID_802_3_CURRENT_ADDRESS,
+ OID_802_3_MULTICAST_LIST,
+ OID_802_3_MAXIMUM_LIST_SIZE,
+ OID_802_3_RCV_ERROR_ALIGNMENT,
+ OID_802_3_XMIT_ONE_COLLISION,
+ OID_802_3_XMIT_MORE_COLLISIONS,
+ };
+
+void USB_RNDIS_ProcessControlPacket(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
+{
+ if (!(Endpoint_IsSETUPReceived()))
+ return;
+
+ if (USB_ControlRequest.wIndex != RNDISInterfaceInfo->ControlInterfaceNumber)
+ return;
+
+ switch (USB_ControlRequest.bRequest)
+ {
+ case REQ_SendEncapsulatedCommand:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->RNDISMessageBuffer, USB_ControlRequest.wLength);
+ Endpoint_ClearIN();
+
+ USB_RNDIS_ProcessRNDISControlMessage(RNDISInterfaceInfo);
+ }
+
+ break;
+ case REQ_GetEncapsulatedResponse:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+ {
+ Endpoint_ClearSETUP();
+
+ RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+
+ if (!(MessageHeader->MessageLength))
+ {
+ RNDISInterfaceInfo->RNDISMessageBuffer[0] = 0;
+ MessageHeader->MessageLength = 1;
+ }
+
+ Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->RNDISMessageBuffer, MessageHeader->MessageLength);
+ Endpoint_ClearOUT();
+
+ MessageHeader->MessageLength = 0;
+ }
+
+ break;
+ }
+}
+
+bool USB_RNDIS_ConfigureEndpoints(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
+{
+ if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->DataINEndpointNumber, EP_TYPE_BULK,
+ ENDPOINT_DIR_IN, RNDISInterfaceInfo->DataINEndpointSize,
+ ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+
+ if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_BULK,
+ ENDPOINT_DIR_OUT, RNDISInterfaceInfo->DataOUTEndpointSize,
+ ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+
+ if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->NotificationEndpointNumber, EP_TYPE_INTERRUPT,
+ ENDPOINT_DIR_IN, RNDISInterfaceInfo->NotificationEndpointSize,
+ ENDPOINT_BANK_SINGLE)))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void USB_RNDIS_USBTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
+{
+ if (!(USB_IsConnected))
+ return;
+
+ RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+
+ Endpoint_SelectEndpoint(RNDISInterfaceInfo->NotificationEndpointNumber);
+
+ if (Endpoint_IsINReady() && RNDISInterfaceInfo->ResponseReady)
+ {
+ USB_Request_Header_t Notification = (USB_Request_Header_t)
+ {
+ .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
+ .bRequest = NOTIF_ResponseAvailable,
+ .wValue = 0,
+ .wIndex = 0,
+ .wLength = 0,
+ };
+
+ Endpoint_Write_Stream_LE(&Notification, sizeof(Notification), NO_STREAM_CALLBACK);
+
+ Endpoint_ClearIN();
+
+ RNDISInterfaceInfo->ResponseReady = false;
+ }
+
+ if ((RNDISInterfaceInfo->CurrRNDISState == RNDIS_Data_Initialized) && !(MessageHeader->MessageLength))
+ {
+ RNDIS_PACKET_MSG_t RNDISPacketHeader;
+
+ Endpoint_SelectEndpoint(RNDISInterfaceInfo->DataOUTEndpointNumber);
+
+ if (Endpoint_IsOUTReceived() && !(RNDISInterfaceInfo->FrameIN.FrameInBuffer))
+ {
+ Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_PACKET_MSG_t), NO_STREAM_CALLBACK);
+
+ if (RNDISPacketHeader.DataLength > ETHERNET_FRAME_SIZE_MAX)
+ {
+ Endpoint_StallTransaction();
+ return;
+ }
+
+ Endpoint_Read_Stream_LE(RNDISInterfaceInfo->FrameIN.FrameData, RNDISPacketHeader.DataLength, NO_STREAM_CALLBACK);
+
+ Endpoint_ClearOUT();
+
+ RNDISInterfaceInfo->FrameIN.FrameLength = RNDISPacketHeader.DataLength;
+
+ RNDISInterfaceInfo->FrameIN.FrameInBuffer = true;
+ }
+
+ Endpoint_SelectEndpoint(RNDISInterfaceInfo->DataINEndpointNumber);
+
+ if (Endpoint_IsINReady() && RNDISInterfaceInfo->FrameOUT.FrameInBuffer)
+ {
+ memset(&RNDISPacketHeader, 0, sizeof(RNDIS_PACKET_MSG_t));
+
+ RNDISPacketHeader.MessageType = REMOTE_NDIS_PACKET_MSG;
+ RNDISPacketHeader.MessageLength = (sizeof(RNDIS_PACKET_MSG_t) + RNDISInterfaceInfo->FrameOUT.FrameLength);
+ RNDISPacketHeader.DataOffset = (sizeof(RNDIS_PACKET_MSG_t) - sizeof(RNDIS_Message_Header_t));
+ RNDISPacketHeader.DataLength = RNDISInterfaceInfo->FrameOUT.FrameLength;
+
+ Endpoint_Write_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_PACKET_MSG_t), NO_STREAM_CALLBACK);
+ Endpoint_Write_Stream_LE(RNDISInterfaceInfo->FrameOUT.FrameData, RNDISPacketHeader.DataLength, NO_STREAM_CALLBACK);
+ Endpoint_ClearIN();
+
+ RNDISInterfaceInfo->FrameOUT.FrameInBuffer = false;
+ }
+ }
+}
+
+void USB_RNDIS_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
+{
+ /* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of
+ this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */
+
+ RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+
+ switch (MessageHeader->MessageType)
+ {
+ case REMOTE_NDIS_INITIALIZE_MSG:
+ RNDISInterfaceInfo->ResponseReady = true;
+
+ RNDIS_INITIALIZE_MSG_t* INITIALIZE_Message = (RNDIS_INITIALIZE_MSG_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+ RNDIS_INITIALIZE_CMPLT_t* INITIALIZE_Response = (RNDIS_INITIALIZE_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+
+ INITIALIZE_Response->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
+ INITIALIZE_Response->MessageLength = sizeof(RNDIS_INITIALIZE_CMPLT_t);
+ INITIALIZE_Response->RequestId = INITIALIZE_Message->RequestId;
+ INITIALIZE_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
+
+ INITIALIZE_Response->MajorVersion = REMOTE_NDIS_VERSION_MAJOR;
+ INITIALIZE_Response->MinorVersion = REMOTE_NDIS_VERSION_MINOR;
+ INITIALIZE_Response->DeviceFlags = REMOTE_NDIS_DF_CONNECTIONLESS;
+ INITIALIZE_Response->Medium = REMOTE_NDIS_MEDIUM_802_3;
+ INITIALIZE_Response->MaxPacketsPerTransfer = 1;
+ INITIALIZE_Response->MaxTransferSize = (sizeof(RNDIS_PACKET_MSG_t) + ETHERNET_FRAME_SIZE_MAX);
+ INITIALIZE_Response->PacketAlignmentFactor = 0;
+ INITIALIZE_Response->AFListOffset = 0;
+ INITIALIZE_Response->AFListSize = 0;
+
+ RNDISInterfaceInfo->CurrRNDISState = RNDIS_Initialized;
+
+ break;
+ case REMOTE_NDIS_HALT_MSG:
+ RNDISInterfaceInfo->ResponseReady = false;
+ MessageHeader->MessageLength = 0;
+
+ RNDISInterfaceInfo->CurrRNDISState = RNDIS_Uninitialized;
+
+ break;
+ case REMOTE_NDIS_QUERY_MSG:
+ RNDISInterfaceInfo->ResponseReady = true;
+
+ RNDIS_QUERY_MSG_t* QUERY_Message = (RNDIS_QUERY_MSG_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+ RNDIS_QUERY_CMPLT_t* QUERY_Response = (RNDIS_QUERY_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+ uint32_t Query_Oid = QUERY_Message->Oid;
+
+ void* QueryData = &RNDISInterfaceInfo->RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
+ QUERY_Message->InformationBufferOffset];
+ void* ResponseData = &RNDISInterfaceInfo->RNDISMessageBuffer[sizeof(RNDIS_QUERY_CMPLT_t)];
+ uint16_t ResponseSize;
+
+ QUERY_Response->MessageType = REMOTE_NDIS_QUERY_CMPLT;
+ QUERY_Response->MessageLength = sizeof(RNDIS_QUERY_CMPLT_t);
+
+ if (USB_RNDIS_ProcessNDISQuery(RNDISInterfaceInfo, Query_Oid, QueryData, QUERY_Message->InformationBufferLength,
+ ResponseData, &ResponseSize))
+ {
+ QUERY_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
+ QUERY_Response->MessageLength += ResponseSize;
+
+ QUERY_Response->InformationBufferLength = ResponseSize;
+ QUERY_Response->InformationBufferOffset = (sizeof(RNDIS_QUERY_CMPLT_t) - sizeof(RNDIS_Message_Header_t));
+ }
+ else
+ {
+ QUERY_Response->Status = REMOTE_NDIS_STATUS_NOT_SUPPORTED;
+
+ QUERY_Response->InformationBufferLength = 0;
+ QUERY_Response->InformationBufferOffset = 0;
+ }
+
+ break;
+ case REMOTE_NDIS_SET_MSG:
+ RNDISInterfaceInfo->ResponseReady = true;
+
+ RNDIS_SET_MSG_t* SET_Message = (RNDIS_SET_MSG_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+ RNDIS_SET_CMPLT_t* SET_Response = (RNDIS_SET_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+ uint32_t SET_Oid = SET_Message->Oid;
+
+ SET_Response->MessageType = REMOTE_NDIS_SET_CMPLT;
+ SET_Response->MessageLength = sizeof(RNDIS_SET_CMPLT_t);
+ SET_Response->RequestId = SET_Message->RequestId;
+
+ void* SetData = &RNDISInterfaceInfo->RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
+ SET_Message->InformationBufferOffset];
+
+ if (USB_RNDIS_ProcessNDISSet(RNDISInterfaceInfo, SET_Oid, SetData, SET_Message->InformationBufferLength))
+ SET_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
+ else
+ SET_Response->Status = REMOTE_NDIS_STATUS_NOT_SUPPORTED;
+
+ break;
+ case REMOTE_NDIS_RESET_MSG:
+ RNDISInterfaceInfo->ResponseReady = true;
+
+ RNDIS_RESET_CMPLT_t* RESET_Response = (RNDIS_RESET_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+
+ RESET_Response->MessageType = REMOTE_NDIS_RESET_CMPLT;
+ RESET_Response->MessageLength = sizeof(RNDIS_RESET_CMPLT_t);
+ RESET_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
+ RESET_Response->AddressingReset = 0;
+
+ break;
+ case REMOTE_NDIS_KEEPALIVE_MSG:
+ RNDISInterfaceInfo->ResponseReady = true;
+
+ RNDIS_KEEPALIVE_MSG_t* KEEPALIVE_Message = (RNDIS_KEEPALIVE_MSG_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+ RNDIS_KEEPALIVE_CMPLT_t* KEEPALIVE_Response = (RNDIS_KEEPALIVE_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+
+ KEEPALIVE_Response->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
+ KEEPALIVE_Response->MessageLength = sizeof(RNDIS_KEEPALIVE_CMPLT_t);
+ KEEPALIVE_Response->RequestId = KEEPALIVE_Message->RequestId;
+ KEEPALIVE_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
+
+ break;
+ }
+}
+
+static bool USB_RNDIS_ProcessNDISQuery(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo,
+ uint32_t OId, void* QueryData, uint16_t QuerySize,
+ void* ResponseData, uint16_t* ResponseSize)
+{
+ switch (OId)
+ {
+ case OID_GEN_SUPPORTED_LIST:
+ *ResponseSize = sizeof(AdapterSupportedOIDList);
+
+ memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList));
+
+ return true;
+ case OID_GEN_PHYSICAL_MEDIUM:
+ *ResponseSize = sizeof(uint32_t);
+
+ /* Indicate that the device is a true ethernet link */
+ *((uint32_t*)ResponseData) = 0;
+
+ return true;
+ case OID_GEN_HARDWARE_STATUS:
+ *ResponseSize = sizeof(uint32_t);
+
+ *((uint32_t*)ResponseData) = NdisHardwareStatusReady;
+
+ return true;
+ case OID_GEN_MEDIA_SUPPORTED:
+ case OID_GEN_MEDIA_IN_USE:
+ *ResponseSize = sizeof(uint32_t);
+
+ *((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIUM_802_3;
+
+ return true;
+ case OID_GEN_VENDOR_ID:
+ *ResponseSize = sizeof(uint32_t);
+
+ /* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */
+ *((uint32_t*)ResponseData) = 0x00FFFFFF;
+
+ return true;
+ case OID_GEN_MAXIMUM_FRAME_SIZE:
+ case OID_GEN_TRANSMIT_BLOCK_SIZE:
+ case OID_GEN_RECEIVE_BLOCK_SIZE:
+ *ResponseSize = sizeof(uint32_t);
+
+ *((uint32_t*)ResponseData) = ETHERNET_FRAME_SIZE_MAX;
+
+ return true;
+ case OID_GEN_VENDOR_DESCRIPTION:
+ *ResponseSize = (strlen(RNDISInterfaceInfo->AdapterVendorDescription) + 1);
+
+ memcpy(ResponseData, RNDISInterfaceInfo->AdapterVendorDescription, *ResponseSize);
+
+ return true;
+ case OID_GEN_MEDIA_CONNECT_STATUS:
+ *ResponseSize = sizeof(uint32_t);
+
+ *((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIA_STATE_CONNECTED;
+
+ return true;
+ case OID_GEN_LINK_SPEED:
+ *ResponseSize = sizeof(uint32_t);
+
+ /* Indicate 10Mb/s link speed */
+ *((uint32_t*)ResponseData) = 100000;
+
+ return true;
+ case OID_802_3_PERMANENT_ADDRESS:
+ case OID_802_3_CURRENT_ADDRESS:
+ *ResponseSize = sizeof(MAC_Address_t);
+
+ memcpy(ResponseData, &RNDISInterfaceInfo->AdapterMACAddress, sizeof(MAC_Address_t));
+
+ return true;
+ case OID_802_3_MAXIMUM_LIST_SIZE:
+ *ResponseSize = sizeof(uint32_t);
+
+ /* Indicate only one multicast address supported */
+ *((uint32_t*)ResponseData) = 1;
+
+ return true;
+ case OID_GEN_CURRENT_PACKET_FILTER:
+ *ResponseSize = sizeof(uint32_t);
+
+ *((uint32_t*)ResponseData) = RNDISInterfaceInfo->CurrPacketFilter;
+
+ return true;
+ case OID_GEN_XMIT_OK:
+ case OID_GEN_RCV_OK:
+ case OID_GEN_XMIT_ERROR:
+ case OID_GEN_RCV_ERROR:
+ case OID_GEN_RCV_NO_BUFFER:
+ case OID_802_3_RCV_ERROR_ALIGNMENT:
+ case OID_802_3_XMIT_ONE_COLLISION:
+ case OID_802_3_XMIT_MORE_COLLISIONS:
+ *ResponseSize = sizeof(uint32_t);
+
+ /* Unused statistic OIDs - always return 0 for each */
+ *((uint32_t*)ResponseData) = 0;
+
+ return true;
+ case OID_GEN_MAXIMUM_TOTAL_SIZE:
+ *ResponseSize = sizeof(uint32_t);
+
+ /* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */
+ *((uint32_t*)ResponseData) = (RNDIS_MESSAGE_BUFFER_SIZE + ETHERNET_FRAME_SIZE_MAX);
+
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool USB_RNDIS_ProcessNDISSet(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo, uint32_t OId, void* SetData, uint16_t SetSize)
+{
+ switch (OId)
+ {
+ case OID_GEN_CURRENT_PACKET_FILTER:
+ RNDISInterfaceInfo->CurrPacketFilter = *((uint32_t*)SetData);
+ RNDISInterfaceInfo->CurrRNDISState = ((RNDISInterfaceInfo->CurrPacketFilter) ?
+ RNDIS_Data_Initialized : RNDIS_Data_Initialized);
+
+ return true;
+ case OID_802_3_MULTICAST_LIST:
+ /* Do nothing - throw away the value from the host as it is unused */
+
+ return true;
+ default:
+ return false;
+ }
+}
diff --git a/Demos/Device/RNDISEthernet/Lib/RNDIS.h b/LUFA/Drivers/USB/Class/Device/RNDIS.h
index 88c9a9eb9..73622a4dc 100644
--- a/Demos/Device/RNDISEthernet/Lib/RNDIS.h
+++ b/LUFA/Drivers/USB/Class/Device/RNDIS.h
@@ -28,26 +28,16 @@
this software.
*/
-/** \file
- *
- * Header file for RNDIS.c.
- */
-
-#ifndef _RNDIS_H_
-#define _RNDIS_H_
+#ifndef _RNDIS_CLASS_H_
+#define _RNDIS_CLASS_H_
/* Includes: */
- #include <avr/io.h>
- #include <stdbool.h>
-
- #include "RNDISEthernet.h"
+ #include <string.h>
+
+ #include "../../USB.h"
#include "RNDISConstants.h"
- #include "Ethernet.h"
-
+
/* Macros: */
- /** Physical MAC Address of the USB network adapter */
- #define ADAPTER_MAC_ADDRESS {0x02, 0x00, 0x02, 0x00, 0x02, 0x00}
-
/** Implemented RNDIS Version Major */
#define REMOTE_NDIS_VERSION_MAJOR 0x01
@@ -60,6 +50,12 @@
/** RNDIS request to issue a device-to-host NDIS response */
#define REQ_GetEncapsulatedResponse 0x01
+ #define RNDIS_MESSAGE_BUFFER_SIZE 128
+
+ #define ETHERNET_FRAME_SIZE_MAX 1500
+
+ #define NOTIF_ResponseAvailable 1
+
/* Enums: */
/** Enum for the possible NDIS adapter states. */
enum RNDIS_States_t
@@ -78,8 +74,14 @@
NdisHardwareStatusClosing, /**< Hardware currently closing */
NdisHardwareStatusNotReady /**< Hardware not ready to accept commands from the host */
};
-
+
/* Type Defines: */
+ /** Type define for a physical MAC address of a device on a network */
+ typedef struct
+ {
+ uint8_t Octets[6]; /**< Individual bytes of a MAC address */
+ } MAC_Address_t;
+
/** Type define for a RNDIS message header, sent before RNDIS messages */
typedef struct
{
@@ -87,6 +89,14 @@
uint32_t MessageLength; /**< Total length of the RNDIS message, in bytes */
} RNDIS_Message_Header_t;
+ /** Type define for an Ethernet frame buffer. */
+ typedef struct
+ {
+ uint8_t FrameData[ETHERNET_FRAME_SIZE_MAX]; /**< Ethernet frame contents */
+ uint16_t FrameLength; /**< Length in bytes of the Ethernet frame stored in the buffer */
+ bool FrameInBuffer; /**< Indicates if a frame is currently stored in the buffer */
+ } Ethernet_Frame_Info_t;
+
/** Type define for a RNDIS packet message, used to encapsulate Ethernet packets sent to and from the adapter */
typedef struct
{
@@ -102,7 +112,31 @@
uint32_t VcHandle;
uint32_t Reserved;
} RNDIS_PACKET_MSG_t;
-
+
+ typedef struct
+ {
+ uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device */
+
+ uint8_t DataINEndpointNumber; /**< Endpoint number of the CDC interface's IN data endpoint */
+ uint16_t DataINEndpointSize; /**< Size in bytes of the CDC interface's IN data endpoint */
+
+ uint8_t DataOUTEndpointNumber; /**< Endpoint number of the CDC interface's OUT data endpoint */
+ uint16_t DataOUTEndpointSize; /**< Size in bytes of the CDC interface's OUT data endpoint */
+
+ uint8_t NotificationEndpointNumber; /**< Endpoint number of the CDC interface's IN notification endpoint, if used */
+ uint16_t NotificationEndpointSize; /**< Size in bytes of the CDC interface's IN notification endpoint, if used */
+
+ char* AdapterVendorDescription;
+ MAC_Address_t AdapterMACAddress;
+
+ uint8_t RNDISMessageBuffer[RNDIS_MESSAGE_BUFFER_SIZE];
+ bool ResponseReady;
+ uint8_t CurrRNDISState;
+ uint32_t CurrPacketFilter;
+ Ethernet_Frame_Info_t FrameIN;
+ Ethernet_Frame_Info_t FrameOUT;
+ } USB_ClassInfo_RNDIS_t;
+
/** Type define for a RNDIS Initialize command message */
typedef struct
{
@@ -208,19 +242,19 @@
uint32_t InformationBufferOffset;
} RNDIS_QUERY_CMPLT_t;
- /* External Variables: */
- extern uint8_t RNDISMessageBuffer[];
- extern RNDIS_Message_Header_t* MessageHeader;
- extern bool ResponseReady;
- extern uint8_t CurrRNDISState;
-
/* Function Prototypes: */
- void ProcessRNDISControlMessage(void);
-
- #if defined(INCLUDE_FROM_RNDIS_C)
- static bool ProcessNDISQuery(uint32_t OId, void* QueryData, uint16_t QuerySize,
- void* ResponseData, uint16_t* ResponseSize);
- static bool ProcessNDISSet(uint32_t OId, void* SetData, uint16_t SetSize);
+ #if defined(INCLUDE_FROM_RNDIS_CLASS_C)
+ static void USB_RNDIS_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
+ static bool USB_RNDIS_ProcessNDISQuery(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo,
+ uint32_t OId, void* QueryData, uint16_t QuerySize,
+ void* ResponseData, uint16_t* ResponseSize);
+ static bool USB_RNDIS_ProcessNDISSet(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo, uint32_t OId,
+ void* SetData, uint16_t SetSize);
#endif
+
+ void USB_RNDIS_USBTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
+ bool USB_RNDIS_ConfigureEndpoints(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
+ void USB_RNDIS_ProcessControlPacket(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
+ void USB_RNDIS_USBTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
#endif
diff --git a/Demos/Device/RNDISEthernet/Lib/RNDISConstants.h b/LUFA/Drivers/USB/Class/Device/RNDISConstants.h
index ad66f62db..ad66f62db 100644
--- a/Demos/Device/RNDISEthernet/Lib/RNDISConstants.h
+++ b/LUFA/Drivers/USB/Class/Device/RNDISConstants.h
diff --git a/LUFA/Drivers/USB/Class/HIDParser.c b/LUFA/Drivers/USB/Class/Host/HIDParser.c
index 5fb29aa0a..5fb29aa0a 100644
--- a/LUFA/Drivers/USB/Class/HIDParser.c
+++ b/LUFA/Drivers/USB/Class/Host/HIDParser.c
diff --git a/LUFA/Drivers/USB/Class/HIDParser.h b/LUFA/Drivers/USB/Class/Host/HIDParser.h
index 49e57c295..4acce2462 100644
--- a/LUFA/Drivers/USB/Class/HIDParser.h
+++ b/LUFA/Drivers/USB/Class/Host/HIDParser.h
@@ -63,7 +63,7 @@
#include "HIDReportData.h"
- #include "../../../Common/Common.h"
+ #include "../../../../Common/Common.h"
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
diff --git a/LUFA/Drivers/USB/Class/HIDReportData.h b/LUFA/Drivers/USB/Class/Host/HIDReportData.h
index eee38be04..eee38be04 100644
--- a/LUFA/Drivers/USB/Class/HIDReportData.h
+++ b/LUFA/Drivers/USB/Class/Host/HIDReportData.h
diff --git a/LUFA/Drivers/USB/HighLevel/Events.h b/LUFA/Drivers/USB/HighLevel/Events.h
index e6d2beaa7..ded027b12 100644
--- a/LUFA/Drivers/USB/HighLevel/Events.h
+++ b/LUFA/Drivers/USB/HighLevel/Events.h
@@ -267,6 +267,11 @@
* \ref Group_USBManagement documentation).
*/
void EVENT_USB_Reset(void);
+
+ /** Event for the USB start of frame interrupt, firing once each millisecond in either device or host
+ * mode, while USB frames are being generated or recieved.
+ */
+ void EVENT_USB_StartOfFrame(void);
#endif
/* Private Interface - For use in library only: */
@@ -303,6 +308,7 @@
void EVENT_USB_Suspend(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);
void EVENT_USB_WakeUp(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);
void EVENT_USB_Reset(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);
+ void EVENT_USB_StartOfFrame(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);
#endif
#endif
diff --git a/LUFA/Drivers/USB/HighLevel/USBInterrupt.c b/LUFA/Drivers/USB/HighLevel/USBInterrupt.c
index 0b9d08223..0ccbe6155 100644
--- a/LUFA/Drivers/USB/HighLevel/USBInterrupt.c
+++ b/LUFA/Drivers/USB/HighLevel/USBInterrupt.c
@@ -180,6 +180,15 @@ ISR(USB_GEN_vect, ISR_BLOCK)
EVENT_USB_Reset();
}
+
+ if (USB_INT_HasOccurred(USB_INT_SOFI) && USB_INT_IsEnabled(USB_INT_SOFI))
+ {
+ USB_INT_Clear(USB_INT_SOFI);
+
+ FrameElapsed = true;
+
+ EVENT_USB_StartOfFrame();
+ }
#endif
#if defined(USB_CAN_BE_HOST)
@@ -232,6 +241,15 @@ ISR(USB_GEN_vect, ISR_BLOCK)
USB_ResetInterface();
}
+
+ if (USB_INT_HasOccurred(USB_INT_HSOFI) && USB_INT_IsEnabled(USB_INT_HSOFI))
+ {
+ USB_INT_Clear(USB_INT_HSOFI);
+
+ FrameElapsed = true;
+
+ EVENT_USB_StartOfFrame();
+ }
#endif
#if defined(USB_CAN_BE_BOTH)
diff --git a/LUFA/Drivers/USB/HighLevel/USBTask.c b/LUFA/Drivers/USB/HighLevel/USBTask.c
index e2b7e91d5..46fcd5709 100644
--- a/LUFA/Drivers/USB/HighLevel/USBTask.c
+++ b/LUFA/Drivers/USB/HighLevel/USBTask.c
@@ -42,7 +42,7 @@ USB_Request_Header_t USB_ControlRequest;
volatile uint8_t USB_HostState;
#endif
-TASK(USB_USBTask)
+void USB_USBTask(void)
{
#if defined(USB_HOST_ONLY)
USB_HostTask();
diff --git a/LUFA/Drivers/USB/HighLevel/USBTask.h b/LUFA/Drivers/USB/HighLevel/USBTask.h
index 1e1209a5f..e4c8a02ae 100644
--- a/LUFA/Drivers/USB/HighLevel/USBTask.h
+++ b/LUFA/Drivers/USB/HighLevel/USBTask.h
@@ -38,7 +38,6 @@
#include <stdbool.h>
#include <stddef.h>
- #include "../../../Scheduler/Scheduler.h"
#include "../LowLevel/LowLevel.h"
#include "StdRequestType.h"
#include "USBMode.h"
@@ -122,11 +121,11 @@
extern volatile uint8_t USB_HostState;
#endif
- /* Tasks: */
+ /* Function Prototypes: */
/** This is the main USB management task. The USB driver requires that this task be executed
* continuously when the USB system is active (device attached in host mode, or attached to a host
* in device mode) in order to manage USB communications. This task may be executed inside an RTOS,
- * scheduler (e.g. the simple LUFA Scheduler), fast timer ISR or the main user application loop.
+ * fast timer ISR or the main user application loop.
*
* The USB task must be serviced within 30ms while in device mode, or within 1ms while in host mode.
* The task may be serviced at all times, or (for minimum CPU consumption):
@@ -145,7 +144,7 @@
*
* \ingroup Group_USBManagement
*/
- TASK(USB_USBTask);
+ void USB_USBTask(void);
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
diff --git a/LUFA/Drivers/USB/LowLevel/Endpoint.c b/LUFA/Drivers/USB/LowLevel/Endpoint.c
index 099022c1c..d02071bbd 100644
--- a/LUFA/Drivers/USB/LowLevel/Endpoint.c
+++ b/LUFA/Drivers/USB/LowLevel/Endpoint.c
@@ -80,8 +80,6 @@ uint8_t Endpoint_WaitUntilReady(void)
uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
#endif
- USB_INT_Clear(USB_INT_SOFI);
-
for (;;)
{
if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN)
@@ -100,9 +98,9 @@ uint8_t Endpoint_WaitUntilReady(void)
else if (Endpoint_IsStalled())
return ENDPOINT_READYWAIT_EndpointStalled;
- if (USB_INT_HasOccurred(USB_INT_SOFI))
+ if (FrameElapsed)
{
- USB_INT_Clear(USB_INT_SOFI);
+ FrameElapsed = false;
if (!(TimeoutMSRem--))
return ENDPOINT_READYWAIT_Timeout;
diff --git a/LUFA/Drivers/USB/LowLevel/Host.c b/LUFA/Drivers/USB/LowLevel/Host.c
index b606515e6..02a1c2171 100644
--- a/LUFA/Drivers/USB/LowLevel/Host.c
+++ b/LUFA/Drivers/USB/LowLevel/Host.c
@@ -210,14 +210,13 @@ uint8_t USB_Host_WaitMS(uint8_t MS)
bool BusSuspended = USB_Host_IsBusSuspended();
uint8_t ErrorCode = HOST_WAITERROR_Successful;
- USB_INT_Clear(USB_INT_HSOFI);
USB_Host_ResumeBus();
while (MS)
{
- if (USB_INT_HasOccurred(USB_INT_HSOFI))
+ if (FrameElapsed)
{
- USB_INT_Clear(USB_INT_HSOFI);
+ FrameElapsed = false;
MS--;
}
@@ -260,9 +259,10 @@ static void USB_Host_ResetDevice(void)
USB_Host_ResetBus();
while (!(USB_Host_IsBusResetComplete()));
- USB_INT_Clear(USB_INT_HSOFI);
USB_Host_ResumeBus();
+ FrameElapsed = false;
+
for (uint8_t MSRem = 10; MSRem != 0; MSRem--)
{
/* Workaround for powerless-pull-up devices. After a USB bus reset,
@@ -270,8 +270,10 @@ static void USB_Host_ResetDevice(void)
looked for - if it is found within 10ms, the device is still
present. */
- if (USB_INT_HasOccurred(USB_INT_HSOFI))
+ if (FrameElapsed)
{
+ FrameElapsed = false;
+
USB_INT_Clear(USB_INT_DDISCI);
break;
}
diff --git a/LUFA/Drivers/USB/LowLevel/LowLevel.c b/LUFA/Drivers/USB/LowLevel/LowLevel.c
index 8b395be98..255a6ef29 100644
--- a/LUFA/Drivers/USB/LowLevel/LowLevel.c
+++ b/LUFA/Drivers/USB/LowLevel/LowLevel.c
@@ -38,6 +38,8 @@ volatile uint8_t USB_CurrentMode = USB_MODE_NONE;
volatile uint8_t USB_Options;
#endif
+volatile bool FrameElapsed;
+
void USB_Init(
#if defined(USB_CAN_BE_BOTH)
const uint8_t Mode
@@ -150,6 +152,8 @@ void USB_ResetInterface(void)
USB_INT_DisableAllInterrupts();
USB_INT_ClearAllInterrupts();
+ FrameElapsed = false;
+
USB_IsConnected = false;
#if defined(USB_CAN_BE_HOST)
@@ -224,6 +228,7 @@ void USB_ResetInterface(void)
#if defined(USB_DEVICE_ONLY)
USB_INT_Enable(USB_INT_SUSPEND);
USB_INT_Enable(USB_INT_EORSTI);
+ USB_INT_Enable(USB_INT_SOFI);
#if defined(CONTROL_ONLY_DEVICE)
UENUM = ENDPOINT_CONTROLEP;
@@ -240,11 +245,13 @@ void USB_ResetInterface(void)
USB_INT_Enable(USB_INT_SRPI);
USB_INT_Enable(USB_INT_BCERRI);
+ USB_INT_Enable(USB_INT_HSOFI);
#else
if (USB_CurrentMode == USB_MODE_DEVICE)
{
USB_INT_Enable(USB_INT_SUSPEND);
USB_INT_Enable(USB_INT_EORSTI);
+ USB_INT_Enable(USB_INT_SOFI);
#if defined(CONTROL_ONLY_DEVICE)
UENUM = ENDPOINT_CONTROLEP;
@@ -262,6 +269,7 @@ void USB_ResetInterface(void)
USB_INT_Enable(USB_INT_SRPI);
USB_INT_Enable(USB_INT_BCERRI);
+ USB_INT_Enable(USB_INT_HSOFI);
}
#endif
}
diff --git a/LUFA/Drivers/USB/LowLevel/LowLevel.h b/LUFA/Drivers/USB/LowLevel/LowLevel.h
index 41b0ff5f6..4279ca315 100644
--- a/LUFA/Drivers/USB/LowLevel/LowLevel.h
+++ b/LUFA/Drivers/USB/LowLevel/LowLevel.h
@@ -350,6 +350,9 @@
return USB_MODE_HOST;
}
#endif
+
+ /* External Variables: */
+ extern volatile bool FrameElapsed;
#endif
diff --git a/LUFA/Drivers/USB/LowLevel/Pipe.c b/LUFA/Drivers/USB/LowLevel/Pipe.c
index 71a33d62f..720da1772 100644
--- a/LUFA/Drivers/USB/LowLevel/Pipe.c
+++ b/LUFA/Drivers/USB/LowLevel/Pipe.c
@@ -76,8 +76,6 @@ uint8_t Pipe_WaitUntilReady(void)
uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
#endif
- USB_INT_Clear(USB_INT_HSOFI);
-
for (;;)
{
if (Pipe_GetPipeToken() == PIPE_TOKEN_IN)
@@ -96,9 +94,9 @@ uint8_t Pipe_WaitUntilReady(void)
else if (!(USB_IsConnected))
return PIPE_READYWAIT_DeviceDisconnected;
- if (USB_INT_HasOccurred(USB_INT_HSOFI))
+ if (FrameElapsed)
{
- USB_INT_Clear(USB_INT_HSOFI);
+ FrameElapsed = false;
if (!(TimeoutMSRem--))
return PIPE_READYWAIT_Timeout;
diff --git a/LUFA/Drivers/USB/USB.h b/LUFA/Drivers/USB/USB.h
index 6d66c4d14..3c8f06237 100644
--- a/LUFA/Drivers/USB/USB.h
+++ b/LUFA/Drivers/USB/USB.h
@@ -49,7 +49,6 @@
* - LUFA/Drivers/USB/HighLevel/USBInterrupt.c
* - LUFA/Drivers/USB/HighLevel/USBTask.c
* - LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c
- * - LUFA/Drivers/USB/Class/HIDParser.c
*
* \section Module Description
* Functions, macros, variables, enums and types related to the management of USB communications.
@@ -97,7 +96,6 @@
#endif
#include "HighLevel/ConfigDescriptor.h"
- #include "Class/HIDParser.h"
#endif
diff --git a/LUFA/MemoryAllocator/DynAlloc.c b/LUFA/MemoryAllocator/DynAlloc.c
deleted file mode 100644
index 4f1c82241..000000000
--- a/LUFA/MemoryAllocator/DynAlloc.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2009.
-
- dean [at] fourwalledcubicle [dot] com
- www.fourwalledcubicle.com
-*/
-
-/*
- Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, and distribute this software
- and its documentation for any purpose and without fee is hereby
- granted, provided that the above copyright notice appear in all
- copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaim all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-#define INCLUDE_FROM_DYNALLOC_C
-#include "DynAlloc.h"
-
-struct
-{
- char Mem_Heap[NUM_BLOCKS * BLOCK_SIZE];
- void* Mem_Handles[NUM_HANDLES];
- uint8_t Mem_Block_Flags[(NUM_BLOCKS / 4) + ((NUM_BLOCKS % 4) ? 1 : 0)];
- uint8_t FlagMaskLookupMask[4];
- uint8_t FlagMaskLookupNum[4];
-} Mem_MemData = {.FlagMaskLookupMask = {(3 << 0), (3 << 2), (3 << 4), (3 << 6)},
- .FlagMaskLookupNum = { 0, 2, 4, 6}};
-
-static uint8_t Mem_GetBlockFlags(const Block_Number_t BlockNum)
-{
- const Block_Number_t BlockIndex = (BlockNum >> 2);
- const uint8_t FlagMask = Mem_MemData.FlagMaskLookupMask[BlockNum & 0x03];
- const uint8_t FlagMaskShift = Mem_MemData.FlagMaskLookupNum[BlockNum & 0x03];
-
- return ((Mem_MemData.Mem_Block_Flags[BlockIndex] & FlagMask) >> FlagMaskShift);
-}
-
-static void Mem_SetBlockFlags(const Block_Number_t BlockNum, const uint8_t Flags)
-{
- const Block_Number_t BlockIndex = (BlockNum >> 2);
- const uint8_t FlagMask = Mem_MemData.FlagMaskLookupMask[BlockNum & 0x03];
- const uint8_t FlagMaskShift = Mem_MemData.FlagMaskLookupNum[BlockNum & 0x03];
-
- Mem_MemData.Mem_Block_Flags[BlockIndex] &= ~FlagMask;
- Mem_MemData.Mem_Block_Flags[BlockIndex] |= (Flags << FlagMaskShift);
-}
-
-static inline void Mem_Defrag(void)
-{
- Block_Number_t FreeStartBlock = 0;
- char* FreeStartPtr = NULL;
- char* UsedStartPtr = NULL;
- Block_Number_t CurrBlock;
-
- for (CurrBlock = 0; CurrBlock < NUM_BLOCKS; CurrBlock++)
- {
- if (!(Mem_GetBlockFlags(CurrBlock) & BLOCK_USED_MASK))
- {
- FreeStartPtr = &Mem_MemData.Mem_Heap[CurrBlock * BLOCK_SIZE];
- FreeStartBlock = CurrBlock;
- break;
- }
- }
-
- if (FreeStartPtr == NULL)
- return;
-
- while (++CurrBlock < NUM_BLOCKS)
- {
- uint8_t CurrBlockFlags = Mem_GetBlockFlags(CurrBlock);
-
- if (CurrBlockFlags & BLOCK_USED_MASK)
- {
- UsedStartPtr = &Mem_MemData.Mem_Heap[CurrBlock * BLOCK_SIZE];
-
- for (Handle_Number_t HandleNum = 0; HandleNum < NUM_HANDLES; HandleNum++)
- {
- if (Mem_MemData.Mem_Handles[HandleNum] == UsedStartPtr)
- {
- Mem_MemData.Mem_Handles[HandleNum] = FreeStartPtr;
- break;
- }
- }
-
- memcpy(FreeStartPtr, UsedStartPtr, BLOCK_SIZE);
- FreeStartPtr += BLOCK_SIZE;
-
- Mem_SetBlockFlags(FreeStartBlock++, CurrBlockFlags);
- Mem_SetBlockFlags(CurrBlock, 0);
- }
- }
-}
-
-static inline bool Mem_FindFreeBlocks(Block_Number_t* const RetStartPtr, const Block_Number_t Blocks)
-{
- Block_Number_t FreeInCurrSec = 0;
-
- for (Block_Number_t CurrBlock = 0; CurrBlock < NUM_BLOCKS; CurrBlock++)
- {
- if (Mem_GetBlockFlags(CurrBlock) & BLOCK_USED_MASK)
- FreeInCurrSec = 0;
- else
- FreeInCurrSec++;
-
- if (FreeInCurrSec >= Blocks)
- {
- *RetStartPtr = CurrBlock;
- return true;
- }
- }
-
- return false;
-}
-
-Mem_Handle_t Mem_Alloc(const Alloc_Size_t Bytes)
-{
- Block_Number_t ReqBlocks = (Bytes / BLOCK_SIZE);
- Block_Number_t StartBlock;
-
- if (Bytes % BLOCK_SIZE)
- ReqBlocks++;
-
- if (!(Mem_FindFreeBlocks(&StartBlock, ReqBlocks)))
- {
- Mem_Defrag();
-
- if (!(Mem_FindFreeBlocks(&StartBlock, ReqBlocks)))
- return NULL;
- }
-
- for (Block_Number_t UsedBlock = 0; UsedBlock < (ReqBlocks - 1); UsedBlock++)
- Mem_SetBlockFlags((StartBlock + UsedBlock), (BLOCK_USED_MASK | BLOCK_LINKED_MASK));
-
- Mem_SetBlockFlags((StartBlock + (ReqBlocks - 1)), BLOCK_USED_MASK);
-
- for (Handle_Number_t AllocEntry = 0; AllocEntry < NUM_HANDLES; AllocEntry++)
- {
- Mem_Handle_t CurrHdl = (Mem_Handle_t)&Mem_MemData.Mem_Handles[AllocEntry];
-
- if (DEREF(CurrHdl, void*) == NULL)
- {
- DEREF(CurrHdl, void*) = &Mem_MemData.Mem_Heap[StartBlock * BLOCK_SIZE];
- return CurrHdl;
- }
- }
-
- return NULL;
-}
-
-Mem_Handle_t Mem_Realloc(Mem_Handle_t CurrAllocHdl, const Alloc_Size_t Bytes)
-{
- Mem_Free(CurrAllocHdl);
- return Mem_Alloc(Bytes);
-}
-
-Mem_Handle_t Mem_Calloc(const Alloc_Size_t Bytes)
-{
- Mem_Handle_t AllocHdl = Mem_Alloc(Bytes);
-
- if (AllocHdl != NULL)
- memset(DEREF(AllocHdl, void*), 0x00, Bytes);
-
- return AllocHdl;
-}
-
-void Mem_Free(Mem_Handle_t CurrAllocHdl)
-{
- char* MemBlockPtr = DEREF(CurrAllocHdl, char*);
- Block_Number_t CurrBlock = ((uint16_t)(MemBlockPtr - Mem_MemData.Mem_Heap) / BLOCK_SIZE);
- uint8_t CurrBlockFlags;
-
- if ((CurrAllocHdl == NULL) || (MemBlockPtr == NULL))
- return;
-
- do
- {
- CurrBlockFlags = Mem_GetBlockFlags(CurrBlock);
- Mem_SetBlockFlags(CurrBlock, 0);
-
- CurrBlock++;
- }
- while (CurrBlockFlags & BLOCK_LINKED_MASK);
-
- DEREF(CurrAllocHdl, void*) = NULL;
-}
-
-Block_Number_t Mem_TotalFreeBlocks(void)
-{
- Block_Number_t FreeBlocks = 0;
-
- for (Block_Number_t CurrBlock = 0; CurrBlock < NUM_BLOCKS; CurrBlock++)
- {
- if (!(Mem_GetBlockFlags(CurrBlock) & BLOCK_USED_MASK))
- FreeBlocks++;
- }
-
- return FreeBlocks;
-}
-
-Handle_Number_t Mem_TotalFreeHandles(void)
-{
- Handle_Number_t FreeHandles = 0;
-
- for (Handle_Number_t CurrHandle = 0; CurrHandle < NUM_HANDLES; CurrHandle++)
- {
- if (Mem_MemData.Mem_Handles[CurrHandle] == NULL)
- FreeHandles++;
- }
-
- return FreeHandles;
-}
diff --git a/LUFA/MemoryAllocator/DynAlloc.h b/LUFA/MemoryAllocator/DynAlloc.h
deleted file mode 100644
index acbfbd18a..000000000
--- a/LUFA/MemoryAllocator/DynAlloc.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2009.
-
- dean [at] fourwalledcubicle [dot] com
- www.fourwalledcubicle.com
-*/
-
-/*
- Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, and distribute this software
- and its documentation for any purpose and without fee is hereby
- granted, provided that the above copyright notice appear in all
- copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaim all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Dynamic, auto-defragmenting block memory allocator library. This library provides a convenient replacement for
- * the standard avr-libc dynamic memory allocation routines. Memory is handed out in block chunks, to reduce the
- * management memory overhead.
- */
-
-/** @defgroup Group_MemoryAllocator Dynamic Block Memory Allocator - LUFA/MemoryAllocator/DynAlloc.h
- *
- * \section Sec_Dependencies Module Source Dependencies
- * The following files must be built with any user project that uses this module:
- * - LUFA/MemoryAllocator/DynAlloc.c
- *
- * \section Module Description
- * Dynamic, auto-defragmenting block memory allocator library. This library provides a convenient replacement for
- * the standard avr-libc dynamic memory allocation routines. Memory is handed out in block chunks, to reduce the
- * management memory overhead.
- *
- * Unlike the normal memory allocation routines, this library gives out handles to memory which must be dereferenced
- * at the exact time of use, rather than handing back direct memory pointers. By using library managed handles
- * instead of pointers, allocated memory blocks can be shifted around as needed transparently to defragment the
- * memory as more blocks are requested.
- *
- * The memory heap is static, thus the total memory usage of the compiled application (as reported by the avr-size
- * tool of the AVR-GCC toolchain) includes the dynamic memory heap.
- *
- * The constants NUM_BLOCKS, BLOCK_SIZE and NUM_HANDLES must be defined in the project makefile (and passed to the
- * preprocessor via the -D GCC switch) for this library to compile.
- *
- * NUM_BLOCKS indicates the number of memory blocks in the memory psudoheap which can be chained together and handed
- * to the application via a memory handle. NUM_HANDLES is the maximum number of memory handles (pointing to one or
- * more chained memory blocks) which can be handed out simultaneously before requiring a handle (and its associated
- * memory) to be freed. BLOCK_SIZE gives the number of bytes in each memory block.
- *
- * @{
- */
-
-#ifndef __DYN_ALLOC__
-#define __DYN_ALLOC__
-
- /* Includes : */
- #include <avr/io.h>
- #include <stdbool.h>
- #include <string.h>
-
- /* Preprocessor Checks: */
- #if (!defined(NUM_BLOCKS) || !defined(BLOCK_SIZE) || !defined(NUM_HANDLES))
- #error NUM_BLOCKS, BLOCK_SIZE and NUM_HANDLES must be defined before use via makefile.
- #endif
-
- /* Public Interface - May be used in end-application: */
- /* Macros: */
- /** Macro to dereference a given memory handle into the given type. The given type should be a pointer
- * if the memory is to contain an array of items, or should be a standard type (such as a primitive or
- * structure) if the memory is to hold a single item of a single type. */
- #define DEREF(handle, type) (*(type*)handle)
-
- /** Constant, giving the total heap size in bytes. */
- #define ALLOCABLE_BYTES (1UL * NUM_BLOCKS * BLOCK_SIZE)
-
- /* Type Defines: */
- /** Memory handle type, used to store handles given by the library functions. */
- typedef const void** Mem_Handle_t;
-
- #if (ALLOCABLE_BYTES > 0xFFFF) || defined(__DOXYGEN__)
- /** Type define for the size (in bytes) for an allocation for passing to the library functions.
- * The exact type width varies depending on the value of ALLOCABLE_BYTES to ensure that a single
- * allocation can request the entire heap if needed.
- */
- typedef uint32_t Alloc_Size_t;
- #elif (ALLOCABLE_BYTES > 0xFF)
- typedef uint16_t Alloc_Size_t;
- #else
- typedef uint8_t Alloc_Size_t;
- #endif
-
- #if (NUM_BLOCKS > 0xFFFF) || defined(__DOXYGEN__)
- /** Type define for a block number in the heap. The exact type width varies depending on the
- * value of NUM_BLOCKS to ensure that the type can store an index to any block in the block pool.
- */
- typedef uint32_t Block_Number_t;
- #elif (NUM_BLOCKS > 0xFF)
- typedef uint16_t Block_Number_t;
- #else
- typedef uint8_t Block_Number_t;
- #endif
-
- #if (NUM_HANDLES > 0xFFFF) || defined(__DOXYGEN__)
- /** Type define for a handle number. The exact type width varies depending on the value of NUM_HANDLES
- * to ensure that the type can store the index of any handle in the handle pool.
- */
- typedef uint32_t Handle_Number_t;
- #elif (NUM_HANDLES > 0xFF)
- typedef uint16_t Handle_Number_t;
- #else
- typedef uint8_t Handle_Number_t;
- #endif
-
- /* Function Prototypes: */
- /** Allocates a given number of blocks from the heap (calculated from the requested number of bytes) and
- * returns a handle to the newly allocated memory.
- *
- * \param Bytes The number of bytes requested to be allocated from the heap
- *
- * \return NULL handle if the allocation fails, or handle to the allocated memory if the allocation succeeds
- */
- Mem_Handle_t Mem_Alloc(const Alloc_Size_t Bytes);
-
- /** Allocates a given number of blocks from the heap (calculated from the requested number of bytes) and
- * returns a handle to the newly allocated memory. Calloced memory is automatically cleared to all 0x00
- * values at the time of allocation.
- *
- * \param Bytes The number of pre-cleared bytes requested to be allocated from the heap
- *
- * \return NULL handle if the allocation fails, or handle to the allocated memory if the allocation succeeds
- */
- Mem_Handle_t Mem_Calloc(const Alloc_Size_t Bytes);
-
- /** Deallocates a given memory handle, and attempts to allocates the given number of blocks from the heap
- * (calculated from the requested number of bytes) immediately following the deallocation. The new memory
- * may be located in the same area as the previous memory, but this is not guaranteed.
- *
- * \param CurrAllocHdl Handle to an already allocated section of memory in the heap to deallocate
- * \param Bytes The number of bytes requested to be allocated from the heap following the
- * deallocation
- *
- * \return NULL handle if the allocation fails, or handle to the allocated memory if the allocation succeeds
- *
- * \warning Even if the allocation fails, the deallocation will still occur. Care should be taken to ensure
- * that the previously allocated memory is not used following an unsuccessful realloc().
- */
- Mem_Handle_t Mem_Realloc(Mem_Handle_t CurrAllocHdl, const Alloc_Size_t Bytes);
-
- /** Deallocates a given previously allocated section of memory from the heap.
- *
- * \param CurrAllocHdl Handle to a previously allocated section of memory in the heap
- */
- void Mem_Free(Mem_Handle_t CurrAllocHdl);
-
- /** Returns the total number of unallocated blocks in the heap.
- *
- * \return Number of free blocks in the heap, as a Block_Number_t integer
- */
- Block_Number_t Mem_TotalFreeBlocks(void);
-
- /** Returns the total number of unallocated handles in the handle pool.
- *
- * \return Number of free handles in the handle pool, as a Handle_Number_t integer
- */
- Handle_Number_t Mem_TotalFreeHandles(void);
-
- /* Private Interface - For use in library only: */
- #if !defined(__DOXYGEN__)
- /* Macros: */
- #define BLOCK_USED_MASK (1 << 0)
- #define BLOCK_LINKED_MASK (1 << 1)
-
- /* Function Prototypes: */
- #if defined(INCLUDE_FROM_DYNALLOC_C)
- static uint8_t Mem_GetBlockFlags(const Block_Number_t BlockNum);
- static void Mem_SetBlockFlags(const Block_Number_t BlockNum, const uint8_t Flags);
- static void Mem_Defrag(void);
- #endif
- #endif
-
-#endif
-
-/** @} */
diff --git a/LUFA/Scheduler/Scheduler.c b/LUFA/Scheduler/Scheduler.c
deleted file mode 100644
index ff8946a0d..000000000
--- a/LUFA/Scheduler/Scheduler.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2009.
-
- dean [at] fourwalledcubicle [dot] com
- www.fourwalledcubicle.com
-*/
-
-/*
- Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, and distribute this software
- and its documentation for any purpose and without fee is hereby
- granted, provided that the above copyright notice appear in all
- copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaim all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-#include "Scheduler.h"
-
-volatile SchedulerDelayCounter_t Scheduler_TickCounter;
-volatile uint8_t Scheduler_TotalTasks;
-
-bool Scheduler_HasDelayElapsed(const uint16_t Delay, SchedulerDelayCounter_t* const DelayCounter)
-{
- SchedulerDelayCounter_t CurrentTickValue_LCL;
- SchedulerDelayCounter_t DelayCounter_LCL;
-
- ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
- {
- CurrentTickValue_LCL = Scheduler_TickCounter;
- }
-
- DelayCounter_LCL = *DelayCounter;
-
- if (CurrentTickValue_LCL >= DelayCounter_LCL)
- {
- if ((CurrentTickValue_LCL - DelayCounter_LCL) >= Delay)
- {
- *DelayCounter = CurrentTickValue_LCL;
- return true;
- }
- }
- else
- {
- if (((MAX_DELAYCTR_COUNT - DelayCounter_LCL) + CurrentTickValue_LCL) >= Delay)
- {
- *DelayCounter = CurrentTickValue_LCL;
- return true;
- }
- }
-
- return false;
-}
-
-void Scheduler_SetTaskMode(const TaskPtr_t Task, const bool TaskStatus)
-{
- TaskEntry_t* CurrTask = &Scheduler_TaskList[0];
-
- while (CurrTask != &Scheduler_TaskList[Scheduler_TotalTasks])
- {
- if (CurrTask->Task == Task)
- {
- CurrTask->TaskStatus = TaskStatus;
- break;
- }
-
- CurrTask++;
- }
-}
-
-void Scheduler_SetGroupTaskMode(const uint8_t GroupID, const bool TaskStatus)
-{
- TaskEntry_t* CurrTask = &Scheduler_TaskList[0];
-
- while (CurrTask != &Scheduler_TaskList[Scheduler_TotalTasks])
- {
- if (CurrTask->GroupID == GroupID)
- CurrTask->TaskStatus = TaskStatus;
-
- CurrTask++;
- }
-}
diff --git a/LUFA/Scheduler/Scheduler.h b/LUFA/Scheduler/Scheduler.h
deleted file mode 100644
index 0da80bb27..000000000
--- a/LUFA/Scheduler/Scheduler.h
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2009.
-
- dean [at] fourwalledcubicle [dot] com
- www.fourwalledcubicle.com
-*/
-
-/*
- Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
- Permission to use, copy, modify, and distribute this software
- and its documentation for any purpose and without fee is hereby
- granted, provided that the above copyright notice appear in all
- copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- The author disclaim all warranties with regard to this
- software, including all implied warranties of merchantability
- and fitness. In no event shall the author be liable for any
- special, indirect or consequential damages or any damages
- whatsoever resulting from loss of use, data or profits, whether
- in an action of contract, negligence or other tortious action,
- arising out of or in connection with the use or performance of
- this software.
-*/
-
-/** \file
- *
- * Simple round-robbin cooperative scheduler for use in basic projects where non real-time tasks need
- * to be executed. Each task is executed in sequence, and can be enabled or disabled individually or as a group.
- */
-
-/** @defgroup Group_Scheduler Simple Task Scheduler - LUFA/Scheduler/Scheduler.h
- *
- * \section Sec_Dependencies Module Source Dependencies
- * The following files must be built with any user project that uses this module:
- * - LUFA/Scheduler/Scheduler.c
- *
- * \section Module Description
- * Simple round-robbin cooperative scheduler for use in basic projects where non real-time tasks need
- * to be executed. Each task is executed in sequence, and can be enabled or disabled individually or as a group.
- *
- * For a task to yield it must return, thus each task should have persistent data marked with the static attribute.
- *
- * Usage Example:
- * \code
- * #include <LUFA/Scheduler/Scheduler.h>
- *
- * TASK(MyTask1);
- * TASK(MyTask2);
- *
- * TASK_LIST
- * {
- * { .Task = MyTask1, .TaskStatus = TASK_RUN, .GroupID = 1 },
- * { .Task = MyTask2, .TaskStatus = TASK_RUN, .GroupID = 1 },
- * }
- *
- * int main(void)
- * {
- * Scheduler_Start();
- * }
- *
- * TASK(MyTask1)
- * {
- * // Implementation Here
- * }
- *
- * TASK(MyTask2)
- * {
- * // Implementation Here
- * }
- * \endcode
- *
- * @{
- */
-
-#ifndef __SCHEDULER_H__
-#define __SCHEDULER_H__
-
- /* Includes: */
- #include <avr/io.h>
- #include <stdbool.h>
-
- #include <util/atomic.h>
-
- #include "../Common/Common.h"
-
- /* Enable C linkage for C++ Compilers: */
- #if defined(__cplusplus)
- extern "C" {
- #endif
-
- /* Public Interface - May be used in end-application: */
- /* Macros: */
- /** Creates a new scheduler task body or prototype. Should be used in the form:
- * \code
- * TASK(TaskName); // Prototype
- *
- * TASK(TaskName)
- * {
- * // Task body
- * }
- * \endcode
- */
- #define TASK(name) void name (void)
-
- /** Defines a task list array, containing one or more task entries of the type TaskEntry_t. Each task list
- * should be encased in curly braces and ended with a comma.
- *
- * Usage Example:
- * \code
- * TASK_LIST
- * {
- * { .Task = MyTask1, .TaskStatus = TASK_RUN, .GroupID = 1 },
- * // More task entries here
- * }
- * \endcode
- */
- #define TASK_LIST TaskEntry_t Scheduler_TaskList[] =
-
- /** Constant, giving the maximum delay in scheduler ticks which can be stored in a variable of type
- * SchedulerDelayCounter_t.
- */
- #define TASK_MAX_DELAY (MAX_DELAYCTR_COUNT - 1)
-
- /** Task status mode constant, for passing to Scheduler_SetTaskMode() or Scheduler_SetGroupTaskMode(). */
- #define TASK_RUN true
-
- /** Task status mode constant, for passing to Scheduler_SetTaskMode() or Scheduler_SetGroupTaskMode(). */
- #define TASK_STOP false
-
- /* Pseudo-Function Macros: */
- #if defined(__DOXYGEN__)
- /** Starts the scheduler in its infinite loop, executing running tasks. This should be placed at the end
- * of the user application's main() function, as it can never return to the calling function.
- */
- void Scheduler_Start(void);
-
- /** Initializes the scheduler so that the scheduler functions can be called before the scheduler itself
- * is started. This must be executed before any scheduler function calls other than Scheduler_Start(),
- * and can be omitted if no such functions could be called before the scheduler is started.
- */
- void Scheduler_Init(void);
- #else
- #define Scheduler_Start() Scheduler_GoSchedule(TOTAL_TASKS);
-
- #define Scheduler_Init() Scheduler_InitScheduler(TOTAL_TASKS);
- #endif
-
- /* Type Defines: */
- /** Type define for a pointer to a scheduler task. */
- typedef void (*TaskPtr_t)(void);
-
- /** Type define for a variable which can hold a tick delay value for the scheduler up to the maximum delay
- * possible.
- */
- typedef uint16_t SchedulerDelayCounter_t;
-
- /** Structure for holding a single task's information in the scheduler task list. */
- typedef struct
- {
- TaskPtr_t Task; /**< Pointer to the task to execute. */
- bool TaskStatus; /**< Status of the task (either TASK_RUN or TASK_STOP). */
- uint8_t GroupID; /**< Group ID of the task so that its status can be changed as a group. */
- } TaskEntry_t;
-
- /* Global Variables: */
- /** Task entry list, containing the scheduler tasks, task statuses and group IDs. Each entry is of type
- * TaskEntry_t and can be manipulated as desired, although it is preferential that the proper Scheduler
- * functions should be used instead of direct manipulation.
- */
- extern TaskEntry_t Scheduler_TaskList[];
-
- /** Contains the total number of tasks in the task list, irrespective of if the task's status is set to
- * TASK_RUN or TASK_STOP.
- *
- * \note This value should be treated as read-only, and never altered in user-code.
- */
- extern volatile uint8_t Scheduler_TotalTasks;
-
- /** Contains the current scheduler tick count, for use with the delay functions. If the delay functions
- * are used in the user code, this should be incremented each tick period so that the delays can be
- * calculated.
- */
- extern volatile SchedulerDelayCounter_t Scheduler_TickCounter;
-
- /* Inline Functions: */
- /** Resets the delay counter value to the current tick count. This should be called to reset the period
- * for a delay in a task which is dependant on the current tick value.
- *
- * \param DelayCounter Counter which is storing the starting tick count for a given delay.
- */
- static inline void Scheduler_ResetDelay(SchedulerDelayCounter_t* const DelayCounter)
- ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
- static inline void Scheduler_ResetDelay(SchedulerDelayCounter_t* const DelayCounter)
- {
- ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
- {
- *DelayCounter = Scheduler_TickCounter;
- }
- }
-
- /* Function Prototypes: */
- /** Determines if the given tick delay has elapsed, based on the given .
- *
- * \param Delay The delay to test for, measured in ticks
- * \param DelayCounter The counter which is storing the starting tick value for the delay
- *
- * \return Boolean true if the delay has elapsed, false otherwise
- *
- * Usage Example:
- * \code
- * static SchedulerDelayCounter_t DelayCounter = 10000; // Force immediate run on start-up
- *
- * // Task runs every 10000 ticks, 10 seconds for this demo
- * if (Scheduler_HasDelayElapsed(10000, &DelayCounter))
- * {
- * // Code to execute after delay interval elapsed here
- * }
- * \endcode
- */
- bool Scheduler_HasDelayElapsed(const uint16_t Delay,
- SchedulerDelayCounter_t* const DelayCounter)
- ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(2);
-
- /** Sets the task mode for a given task.
- *
- * \param Task Name of the task whose status is to be changed
- * \param TaskStatus New task status for the task (TASK_RUN or TASK_STOP)
- */
- void Scheduler_SetTaskMode(const TaskPtr_t Task, const bool TaskStatus);
-
- /** Sets the task mode for a given task group ID, allowing for an entire group of tasks to have their
- * statuses changed at once.
- *
- * \param GroupID Value of the task group ID whose status is to be changed
- * \param TaskStatus New task status for tasks in the specified group (TASK_RUN or TASK_STOP)
- */
- void Scheduler_SetGroupTaskMode(const uint8_t GroupID, const bool TaskStatus);
-
- /* Private Interface - For use in library only: */
- #if !defined(__DOXYGEN__)
- /* Macros: */
- #define TOTAL_TASKS (sizeof(Scheduler_TaskList) / sizeof(TaskEntry_t))
- #define MAX_DELAYCTR_COUNT 0xFFFF
-
- /* Inline Functions: */
- static inline void Scheduler_InitScheduler(const uint8_t TotalTasks) ATTR_ALWAYS_INLINE;
- static inline void Scheduler_InitScheduler(const uint8_t TotalTasks)
- {
- Scheduler_TotalTasks = TotalTasks;
- }
-
- static inline void Scheduler_GoSchedule(const uint8_t TotalTasks) ATTR_NO_RETURN ATTR_ALWAYS_INLINE;
- static inline void Scheduler_GoSchedule(const uint8_t TotalTasks)
- {
- Scheduler_InitScheduler(TotalTasks);
-
- for (;;)
- {
- TaskEntry_t* CurrTask = &Scheduler_TaskList[0];
-
- while (CurrTask != &Scheduler_TaskList[TotalTasks])
- {
- if (CurrTask->TaskStatus == TASK_RUN)
- CurrTask->Task();
-
- CurrTask++;
- }
- }
- }
- #endif
-
- /* Disable C linkage for C++ Compilers: */
- #if defined(__cplusplus)
- }
- #endif
-
-#endif
-
-/** @} */
diff --git a/LUFA/SchedulerOverview.txt b/LUFA/SchedulerOverview.txt
deleted file mode 100644
index 5c031feac..000000000
--- a/LUFA/SchedulerOverview.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-/** \file
- *
- * This file contains special DoxyGen information for the generation of the main page and other special
- * documentation pages. It is not a project source file.
- */
-
-/** \page Page_SchedulerOverview LUFA Scheduler Overview
- *
- * The LUFA library comes with a small, basic round-robbin scheduler which allows for small "tasks" to be executed
- * continuously in sequence, and enabled/disabled at runtime. Unlike a conventional, complex RTOS scheduler, the
- * LUFA scheduler is very simple in design and operation and is essentially a loop conditionally executing a series
- * of functions.
- *
- * Each LUFA scheduler task should be written similar to an ISR; it should execute quickly (so that no one task
- * hogs the processor, preventing another from running before some sort of timeout is exceeded). Unlike normal RTOS
- * tasks, each LUFA scheduler task is a regular function, and thus must be designed to be called, and designed to
- * return to the calling scheduler function repeatedly. Data which must be preserved between task calls should be
- * declared as global or (preferably) as a static local variable inside the task.
- *
- * The scheduler consists of a task list, listing all the tasks which can be executed by the scheduler. Once started,
- * each task is then called one after another, unless the task is stopped by another running task or interrupt.
- *
- *
- * If desired, the LUFA scheduler <b>does not need to be used</b> in a LUFA powered application. A more conventional
- * approach to application design can be used, or a proper scheduling RTOS inserted in the place of the LUFA scheduler.
- * In the case of the former the USB task must be run manually repeatedly to maintain USB communications, and in the
- * case of the latter a proper RTOS task must be set up to do the same.
- *
- *
- * For more information on the LUFA scheduler, see the Scheduler.h file documentation.
- */
diff --git a/LUFA/makefile b/LUFA/makefile
index fc0009793..20f943aa0 100644
--- a/LUFA/makefile
+++ b/LUFA/makefile
@@ -15,13 +15,9 @@ LUFA_SRC_FILES = ./Drivers/USB/LowLevel/DevChapter9.c \
./Drivers/USB/LowLevel/LowLevel.c \
./Drivers/USB/LowLevel/Pipe.c \
./Drivers/USB/HighLevel/Events.c \
- ./Drivers/USB/HighLevel/StdDescriptors.c \
./Drivers/USB/HighLevel/USBInterrupt.c \
./Drivers/USB/HighLevel/USBTask.c \
- ./Drivers/USB/Class/ConfigDescriptor.c \
- ./Drivers/USB/Class/HIDParser.c \
- ./Scheduler/Scheduler.c \
- ./MemoryAllocator/DynAlloc.c \
+ ./Drivers/USB/HighLevel/ConfigDescriptor.c \
./Drivers/Board/Temperature.c \
./Drivers/Peripheral/Serial.c \
./Drivers/Peripheral/SerialStream.c \
diff --git a/Projects/Magstripe/Descriptors.c b/Projects/Magstripe/Descriptors.c
index 1dee58676..52b2c098f 100644
--- a/Projects/Magstripe/Descriptors.c
+++ b/Projects/Magstripe/Descriptors.c
@@ -142,7 +142,7 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.HIDSpec = VERSION_BCD(01.11),
.CountryCode = 0x00,
- .TotalHIDDescriptors = 1,
+ .TotalReportDescriptors = 1,
.HIDReportType = DTYPE_Report,
.HIDReportLength = sizeof(KeyboardReport)
},
diff --git a/Projects/Magstripe/Descriptors.h b/Projects/Magstripe/Descriptors.h
index 9948085a5..0fff2c2a8 100644
--- a/Projects/Magstripe/Descriptors.h
+++ b/Projects/Magstripe/Descriptors.h
@@ -38,34 +38,12 @@
#define _DESCRIPTORS_H_
/* Includes: */
- #include <LUFA/Drivers/USB/USB.h>
-
#include <avr/pgmspace.h>
- /* Type Defines: */
- /** Type define for the HID class specific HID descriptor. A HID descriptor is used in HID class devices
- * to give information about the HID device, including the HID specification used, and the report descriptors
- * the device contains to describe how the HID device should be controlled.
- */
- typedef struct
- {
- USB_Descriptor_Header_t Header; /**< Standard USB descriptor header */
-
- uint16_t HIDSpec; /**< HID specification implemented by the device, in BCD form */
- uint8_t CountryCode; /**< Country code for the country the HID device is localised for */
-
- uint8_t TotalHIDDescriptors; /**< Total number of HID reports linked to this HID interface */
-
- uint8_t HIDReportType; /**< Type of the first HID report descriptor */
- uint16_t HIDReportLength; /**< Length of the first HID report descriptor */
- } USB_Descriptor_HID_t;
-
- /** Type define for the data type used for the HID Report descriptor data elements. A HID report
- * descriptor contains an array of this data type, indicating how the reports from and to the
- * device are formatted and how the report data is to be used by the host.
- */
- typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/HID.h>
+ /* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host.
@@ -85,14 +63,8 @@
/** Size of the keyboard report endpoints, in bytes. */
#define KEYBOARD_EPSIZE 8
- /** Descriptor type value for a HID descriptor. */
- #define DTYPE_HID 0x21
-
- /** Descriptor type value for a HID report. */
- #define DTYPE_Report 0x22
-
/* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
- ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
+ ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif
diff --git a/Projects/Magstripe/Magstripe.c b/Projects/Magstripe/Magstripe.c
index e860d5aca..5cd107e9a 100644
--- a/Projects/Magstripe/Magstripe.c
+++ b/Projects/Magstripe/Magstripe.c
@@ -28,60 +28,37 @@
arising out of or in connection with the use or performance of
this software.
*/
-
-/** \file
- *
- * Main source file for the MagStripe application. This file contains the code which drives
- * the USB keyboard interface from the magnetic card stripe reader device.
- */
#include "Magstripe.h"
-/* Scheduler Task List */
-TASK_LIST
-{
- { .Task = USB_USBTask , .TaskStatus = TASK_STOP },
- { .Task = USB_Keyboard_Report , .TaskStatus = TASK_STOP },
- { .Task = Magstripe_Read , .TaskStatus = TASK_STOP },
-};
-
-/* Global Variables */
-/** Indicates if the device is using Report Protocol mode, instead of Boot Protocol mode. Boot Protocol mode
- * is a special reporting mode used by compatible PC BIOS to support USB keyboards before a full OS and USB
- * driver has been loaded, by using predefined report structures indicated in the USB HID standard.
- */
-bool UsingReportProtocol = true;
+BitBuffer_t TrackDataBuffers[3];
-/** Total idle period in milliseconds set by the host via a SetIdle request, used to silence the report endpoint
- * until the report data changes or the idle period elapsed. Generally used to implement hardware key repeats, or
- * by some BIOS to reduce the number of reports when in Boot Protocol mode.
- */
-uint8_t IdleCount = 0;
-
-/** Milliseconds remaining counter for the HID class SetIdle and GetIdle requests, used to silence the report
- * endpoint for an amount of time indicated by the host or until the report changes.
- */
-uint16_t IdleMSRemaining = 0;
-
-/** Circular buffer to hold the read bits from track 1 of the inserted magnetic card. */
-BitBuffer_t Track1Data;
+USB_ClassInfo_HID_t Keyboard_HID_Interface =
+ {
+ .InterfaceNumber = 0,
-/** Circular buffer to hold the read bits from track 2 of the inserted magnetic card. */
-BitBuffer_t Track2Data;
+ .ReportINEndpointNumber = KEYBOARD_EPNUM,
+ .ReportINEndpointSize = KEYBOARD_EPSIZE,
+ };
-/** Circular buffer to hold the read bits from track 3 of the inserted magnetic card. */
-BitBuffer_t Track3Data;
+int main(void)
+{
+ SetupHardware();
+
+ for (uint8_t Buffer = 0; Buffer < 3; Buffer++)
+ BitBuffer_Init(&TrackDataBuffers[Buffer]);
-/** Delay counter between successive key strokes. This is to prevent the OS from ignoring multiple keys in a short
- * period of time due to key repeats. Two milliseconds works for most OSes.
- */
-uint8_t KeyDelayRemaining;
+ for (;;)
+ {
+ if (Magstripe_GetStatus() & MAG_CARDPRESENT)
+ ReadMagstripeData();
+ USB_HID_USBTask(&Keyboard_HID_Interface);
+ USB_USBTask();
+ }
+}
-/** Main program entry point. This routine configures the hardware required by the application, then
- * starts the scheduler to run the application tasks.
- */
-int main(void)
+void SetupHardware(void)
{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
@@ -92,330 +69,97 @@ int main(void)
/* Hardware Initialization */
Magstripe_Init();
-
- /* Buffer Initialization */
- BitBuffer_Init(&Track1Data);
- BitBuffer_Init(&Track2Data);
- BitBuffer_Init(&Track3Data);
-
- /* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */
- OCR0A = 0xFA;
- TCCR0A = (1 << WGM01);
- TCCR0B = ((1 << CS01) | (1 << CS00));
- TIMSK0 = (1 << OCIE0A);
-
- /* Initialize Scheduler so that it can be used */
- Scheduler_Init();
-
- /* Initialize USB Subsystem */
USB_Init();
-
- /* Scheduling - routine never returns, so put this last in the main function */
- Scheduler_Start();
}
-/** Event handler for the USB_Connect event. This starts the USB task. */
-void EVENT_USB_Connect(void)
+void ReadMagstripeData(void)
{
- /* Start USB management task */
- Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-}
+ /* Arrays to hold the buffer pointers, clock and data bit masks for the separate card tracks */
+ const struct
+ {
+ uint8_t ClockMask;
+ uint8_t DataMask;
+ } TrackInfo[] = {{MAG_T1_CLOCK, MAG_T1_DATA},
+ {MAG_T2_CLOCK, MAG_T2_DATA},
+ {MAG_T3_CLOCK, MAG_T3_DATA}};
-/** Event handler for the USB_Disconnect event. This stops the USB and keyboard report tasks. */
-void EVENT_USB_Disconnect(void)
-{
- /* Stop running keyboard reporting, card reading and USB management tasks */
- Scheduler_SetTaskMode(USB_Keyboard_Report, TASK_STOP);
- Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
- Scheduler_SetTaskMode(Magstripe_Read, TASK_STOP);
+ uint8_t Magstripe_Prev = 0;
+ uint8_t Magstripe_LCL = Magstripe_GetStatus();
+
+ while (Magstripe_LCL & MAG_CARDPRESENT)
+ {
+ for (uint8_t Track = 0; Track < 3; Track++)
+ {
+ bool DataPinLevel = ((Magstripe_LCL & TrackInfo[Track].DataMask) != 0);
+ bool ClockPinLevel = ((Magstripe_LCL & TrackInfo[Track].ClockMask) != 0);
+ bool ClockLevelChanged = (((Magstripe_LCL ^ Magstripe_Prev) & TrackInfo[Track].ClockMask) != 0);
+
+ if (ClockPinLevel && ClockLevelChanged)
+ BitBuffer_StoreNextBit(&TrackDataBuffers[Track], DataPinLevel);
+ }
+
+ Magstripe_Prev = Magstripe_LCL;
+ Magstripe_LCL = Magstripe_GetStatus();
+ }
}
-/** Event handler for the USB_ConfigurationChanged event. This configures the device's endpoints ready
- * to relay reports to the host, and starts the keyboard report task.
- */
void EVENT_USB_ConfigurationChanged(void)
{
- /* Setup Keyboard Keycode Report Endpoint */
- Endpoint_ConfigureEndpoint(KEYBOARD_EPNUM, EP_TYPE_INTERRUPT,
- ENDPOINT_DIR_IN, KEYBOARD_EPSIZE,
- ENDPOINT_BANK_SINGLE);
-
- /* Default to report protocol on connect */
- UsingReportProtocol = true;
-
- /* Start Keyboard reporting and card reading tasks */
- Scheduler_SetTaskMode(USB_Keyboard_Report, TASK_RUN);
- Scheduler_SetTaskMode(Magstripe_Read, TASK_RUN);
+ USB_HID_ConfigureEndpoints(&Keyboard_HID_Interface);
}
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- * control requests that are not handled internally by the USB library, so that they can be handled appropriately
- * for the application.
- */
void EVENT_USB_UnhandledControlPacket(void)
{
- /* Handle HID Class specific requests */
- switch (USB_ControlRequest.bRequest)
- {
- case REQ_GetReport:
- if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- USB_KeyboardReport_Data_t KeyboardReportData;
-
- /* Create the next keyboard report for transmission to the host */
- GetNextReport(&KeyboardReportData);
-
- Endpoint_ClearSETUP();
-
- /* Write the report data to the control endpoint */
- Endpoint_Write_Control_Stream_LE(&KeyboardReportData, sizeof(KeyboardReportData));
-
- /* Finalize the stream transfer to send the last packet or clear the host abort */
- Endpoint_ClearOUT();
- }
-
- break;
- case REQ_GetProtocol:
- if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- Endpoint_ClearSETUP();
-
- /* Write the current protocol flag to the host */
- Endpoint_Write_Byte(UsingReportProtocol);
-
- /* Send the flag to the host */
- Endpoint_ClearIN();
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsOUTReceived()));
- Endpoint_ClearOUT();
- }
-
- break;
- case REQ_SetProtocol:
- if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- Endpoint_ClearSETUP();
-
- /* Set or clear the flag depending on what the host indicates that the current Protocol should be */
- UsingReportProtocol = (USB_ControlRequest.wValue != 0x0000);
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsINReady()));
- Endpoint_ClearIN();
- }
-
- break;
- case REQ_SetIdle:
- if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- Endpoint_ClearSETUP();
-
- /* Get idle period in MSB */
- IdleCount = (USB_ControlRequest.wValue >> 8);
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsINReady()));
- Endpoint_ClearIN();
- }
-
- break;
- case REQ_GetIdle:
- if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
- {
- Endpoint_ClearSETUP();
-
- /* Write the current idle duration to the host */
- Endpoint_Write_Byte(IdleCount);
-
- /* Send the flag to the host */
- Endpoint_ClearIN();
-
- /* Acknowledge status stage */
- while (!(Endpoint_IsOUTReceived()));
- Endpoint_ClearOUT();
- }
-
- break;
- }
+ USB_HID_ProcessControlPacket(&Keyboard_HID_Interface);
}
-/** ISR for the timer 0 compare vector. This ISR fires once each millisecond, and decrements the counter indicating
- * the number of milliseconds left to idle (not send the host reports) if the device has been instructed to idle
- * by the host via a SetIdle class specific request.
- */
-ISR(TIMER0_COMPA_vect, ISR_BLOCK)
+void EVENT_USB_StartOfFrame(void)
{
- /* One millisecond has elapsed, decrement the idle time remaining counter if it has not already elapsed */
- if (IdleMSRemaining)
- IdleMSRemaining--;
-
- if (KeyDelayRemaining)
- KeyDelayRemaining--;
+ USB_HID_RegisterStartOfFrame(&Keyboard_HID_Interface);
}
-/** Constructs a keyboard report indicating the currently pressed keyboard keys to the host.
- *
- * \param ReportData Pointer to a USB_KeyboardReport_Data_t report structure where the resulting report should
- * be stored
- *
- * \return Boolean true if the current report is different to the previous report, false otherwise
- */
-bool GetNextReport(USB_KeyboardReport_Data_t* ReportData)
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)
{
- static bool OddReport = false;
- static bool MustRelease = false;
-
- BitBuffer_t* Buffer = NULL;
-
- /* Clear the report contents */
- memset(ReportData, 0, sizeof(USB_KeyboardReport_Data_t));
+ static bool IsKeyReleaseReport;
+ static bool IsNewlineReport;
- /* Get the next non-empty track data buffer */
- if (Track1Data.Elements)
- Buffer = &Track1Data;
- else if (Track2Data.Elements)
- Buffer = &Track2Data;
- else if (Track3Data.Elements)
- Buffer = &Track3Data;
-
- if (Buffer != NULL)
- {
- /* Toggle the odd report number indicator */
- OddReport = !OddReport;
+ BitBuffer_t* Buffer = NULL;
+ USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
- /* Set the flag indicating that a null report must eventually be sent to release all pressed keys */
- MustRelease = true;
-
- /* Only send the next key on odd reports, so that they are interspersed with null reports to release keys */
- if (OddReport)
- {
- /* Set the report key code to the key code for the next data bit */
- ReportData->KeyCode = BitBuffer_GetNextBit(Buffer) ? KEY_1 : KEY_0;
-
- /* If buffer is now empty, a new line must be sent instead of the terminating bit */
- if (!(Buffer->Elements))
- {
- /* Set the keycode to the code for an enter key press */
- ReportData->KeyCode = KEY_ENTER;
- }
- }
+ /* Key reports must be interleaved with 0 Key Code reports to release the keys, or repeated keys will be ignored */
+ IsKeyReleaseReport = !IsKeyReleaseReport;
- return true;
- }
- else if (MustRelease)
+ if (IsKeyReleaseReport)
{
- /* Leave key code to null (0), to release all pressed keys */
- return true;
+ KeyboardReport->KeyCode = 0;
}
-
- return false;
-}
-
-/** Task to read out data from inserted magnetic cards and place the separate track data into their respective
- * data buffers for later sending to the host as keyboard key presses.
- */
-TASK(Magstripe_Read)
-{
- /* Arrays to hold the buffer pointers, clock and data bit masks for the separate card tracks */
- const struct
+ else if (IsNewlineReport)
{
- BitBuffer_t* Buffer;
- uint8_t ClockMask;
- uint8_t DataMask;
- } TrackInfo[] = {{&Track1Data, MAG_T1_CLOCK, MAG_T1_DATA},
- {&Track2Data, MAG_T2_CLOCK, MAG_T2_DATA},
- {&Track3Data, MAG_T3_CLOCK, MAG_T3_DATA}};
-
- /* Previous magnetic card control line' status, for later comparison */
- uint8_t Magstripe_Prev = 0;
-
- /* Buffered current card reader control line' status */
- uint8_t Magstripe_LCL = Magstripe_GetStatus();
-
- /* Exit the task early if no card is present in the reader */
- if (!(Magstripe_LCL & MAG_CARDPRESENT))
- return;
-
- /* Read out card data while a card is present */
- while (Magstripe_LCL & MAG_CARDPRESENT)
+ IsNewlineReport = false;
+ KeyboardReport->KeyCode = KEY_ENTER;
+ }
+ else
{
- /* Read out the next bit for each track of the card */
- for (uint8_t Track = 0; Track < 3; Track++)
- {
- /* Current data line status for the current card track */
- bool DataLevel = ((Magstripe_LCL & TrackInfo[Track].DataMask) != 0);
-
- /* Current clock line status for the current card track */
- bool ClockLevel = ((Magstripe_LCL & TrackInfo[Track].ClockMask) != 0);
-
- /* Current track clock transition check */
- bool ClockChanged = (((Magstripe_LCL ^ Magstripe_Prev) & TrackInfo[Track].ClockMask) != 0);
-
- /* Sample the next bit on the falling edge of the track's clock line, store key code into the track's buffer */
- if (ClockLevel && ClockChanged)
- BitBuffer_StoreNextBit(TrackInfo[Track].Buffer, DataLevel);
- }
-
- /* Retain the current card reader control line states for later edge detection */
- Magstripe_Prev = Magstripe_LCL;
+ if (TrackDataBuffers[0].Elements)
+ Buffer = &TrackDataBuffers[0];
+ else if (TrackDataBuffers[1].Elements)
+ Buffer = &TrackDataBuffers[1];
+ else if (TrackDataBuffers[2].Elements)
+ Buffer = &TrackDataBuffers[2];
+ else
+ return 0;
+
+ KeyboardReport->KeyCode = BitBuffer_GetNextBit(Buffer) ? KEY_1 : KEY_0;
- /* Retrieve the new card reader control line states */
- Magstripe_LCL = Magstripe_GetStatus();
+ /* If buffer now empty, next report must be a newline to seperate track data */
+ if (!(Buffer->Elements))
+ IsNewlineReport = true;
}
- /* Add terminators to the end of each track buffer */
- BitBuffer_StoreNextBit(&Track1Data, 0);
- BitBuffer_StoreNextBit(&Track2Data, 0);
- BitBuffer_StoreNextBit(&Track3Data, 0);
+ return sizeof(USB_KeyboardReport_Data_t);
}
-/** Task for the magnetic card reading and keyboard report generation. This task waits until a card is inserted,
- * then reads off the card data and sends it to the host as a series of keyboard key presses via keyboard reports.
- */
-TASK(USB_Keyboard_Report)
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)
{
- USB_KeyboardReport_Data_t KeyboardReportData;
- bool SendReport = false;
-
- /* Check if the USB system is connected to a host */
- if (USB_IsConnected)
- {
- /* Select the Keyboard Report Endpoint */
- Endpoint_SelectEndpoint(KEYBOARD_EPNUM);
-
- /* Check if Keyboard Endpoint Ready for Read/Write */
- if (Endpoint_IsReadWriteAllowed())
- {
- /* Only fetch the next key to send once the period between key presses has elapsed */
- if (!(KeyDelayRemaining))
- {
- /* Create the next keyboard report for transmission to the host */
- SendReport = GetNextReport(&KeyboardReportData);
- }
-
- /* Check if the idle period is set and has elapsed */
- if (IdleCount && !(IdleMSRemaining))
- {
- /* Idle period elapsed, indicate that a report must be sent */
- SendReport = true;
-
- /* Reset the idle time remaining counter, must multiply by 4 to get the duration in milliseconds */
- IdleMSRemaining = (IdleCount << 2);
- }
-
- /* Write the keyboard report if a report is to be sent to the host */
- if (SendReport)
- {
- /* Write Keyboard Report Data */
- Endpoint_Write_Stream_LE(&KeyboardReportData, sizeof(USB_KeyboardReport_Data_t));
-
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearIN();
-
- /* Reset the key delay period counter */
- KeyDelayRemaining = 2;
- }
- }
- }
+ // Unused (but mandatory for the HID class driver) in this demo, since there are no Host->Device reports
}
diff --git a/Projects/Magstripe/Magstripe.h b/Projects/Magstripe/Magstripe.h
index c700bcaff..b0e47d596 100644
--- a/Projects/Magstripe/Magstripe.h
+++ b/Projects/Magstripe/Magstripe.h
@@ -40,46 +40,17 @@
/* Includes: */
#include <avr/io.h>
#include <avr/wdt.h>
- #include <avr/interrupt.h>
#include <avr/power.h>
- #include <stdbool.h>
- #include <string.h>
#include "Descriptors.h"
-
#include "Lib/MagstripeHW.h"
#include "Lib/CircularBitBuffer.h"
- #include <LUFA/Version.h> // Library Version Information
- #include <LUFA/Drivers/USB/USB.h> // USB Functionality
- #include <LUFA/Scheduler/Scheduler.h> // Simple scheduler for task management
-
-
- /* Task Definitions: */
- /** Task definition for the keyboard and magnetic card reading task. */
- TASK(USB_Keyboard_Report);
-
- TASK(Magstripe_Read);
+ #include <LUFA/Version.h>
+ #include <LUFA/Drivers/USB/USB.h>
+ #include <LUFA/Drivers/USB/Class/Device/HID.h>
/* Macros: */
- /** HID Class Specific Request to get the current HID report from the device. */
- #define REQ_GetReport 0x01
-
- /** HID Class Specific Request to get the current device idle count. */
- #define REQ_GetIdle 0x02
-
- /** HID Class Specific Request to set the current HID report to the device. */
- #define REQ_SetReport 0x09
-
- /** HID Class Specific Request to set the device's idle count. */
- #define REQ_SetIdle 0x0A
-
- /** HID Class Specific Request to get the current HID report protocol mode. */
- #define REQ_GetProtocol 0x03
-
- /** HID Class Specific Request to set the current HID report protocol mode. */
- #define REQ_SetProtocol 0x0B
-
/** HID keyboard keycode to indicate that the "1" key is currently pressed. */
#define KEY_1 30
@@ -102,11 +73,15 @@
} USB_KeyboardReport_Data_t;
/* Function Prototypes: */
- void EVENT_USB_Connect(void);
- void EVENT_USB_Disconnect(void);
+ void SetupHardware(void);
+ void ReadMagstripeData(void);
+
void EVENT_USB_ConfigurationChanged(void);
void EVENT_USB_UnhandledControlPacket(void);
-
- bool GetNextReport(USB_KeyboardReport_Data_t* ReportData);
+ void EVENT_USB_StartOfFrame(void);
+
+ uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);
+ void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,
+ void* ReportData, uint16_t ReportSize);
#endif
diff --git a/Projects/Magstripe/makefile b/Projects/Magstripe/makefile
index 962c999b3..138456fe8 100644
--- a/Projects/Magstripe/makefile
+++ b/Projects/Magstripe/makefile
@@ -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.)