Commit ece9e3d5 authored by Dean Camera's avatar Dean Camera
Browse files

Changed GenericHID device demo to use the LUFA scheduler, added...

Changed GenericHID device demo to use the LUFA scheduler, added INTERRUPT_DATA_ENDPOINT and INTERRUPT_CONTROL_ENDPOINT compile time options.
parent 6198289b
......@@ -42,6 +42,18 @@ BUTTLOADTAG(BuildTime, __TIME__);
BUTTLOADTAG(BuildDate, __DATE__);
BUTTLOADTAG(LUFAVersion, "LUFA V" LUFA_VERSION_STRING);
/* Scheduler Task List */
TASK_LIST
{
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
{ Task: USB_USBTask , TaskStatus: TASK_STOP },
#endif
#if !defined(INTERRUPT_DATA_ENDPOINT)
{ Task: USB_HID_Report , TaskStatus: TASK_STOP },
#endif
};
/** 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];
......@@ -61,11 +73,14 @@ int main(void)
/* Indicate USB not ready */
UpdateStatus(Status_USBNotReady);
/* Initialize Scheduler so that it can be used */
Scheduler_Init();
/* Initialize USB Subsystem */
USB_Init();
/* >> APPLICATION INIT CODE HERE << */
for (;;);
/* Scheduling - routine never returns, so put this last in the main function */
Scheduler_Start();
}
/** Event handler for the USB_Reset event. This fires when the USB interface is reset by the USB host, before the
......@@ -74,11 +89,13 @@ int main(void)
*/
EVENT_HANDLER(USB_Reset)
{
#if defined(INTERRUPT_CONTROL_ENDPOINT)
/* Select the control endpoint */
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
/* Enable the endpoint SETUP interrupt ISR for the control endpoint */
USB_INT_Enable(ENDPOINT_INT_SETUP);
#endif
}
/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
......@@ -109,16 +126,20 @@ EVENT_HANDLER(USB_ConfigurationChanged)
ENDPOINT_DIR_IN, GENERIC_EPSIZE,
ENDPOINT_BANK_SINGLE);
#if defined(INTERRUPT_DATA_ENDPOINT)
/* Enable the endpoint IN interrupt ISR for the report endpoint */
USB_INT_Enable(ENDPOINT_INT_IN);
#endif
/* Setup Generic OUT Report Endpoint */
Endpoint_ConfigureEndpoint(GENERIC_OUT_EPNUM, EP_TYPE_INTERRUPT,
ENDPOINT_DIR_OUT, GENERIC_EPSIZE,
ENDPOINT_BANK_SINGLE);
#if defined(INTERRUPT_DATA_ENDPOINT)
/* Enable the endpoint OUT interrupt ISR for the report endpoint */
USB_INT_Enable(ENDPOINT_INT_OUT);
#endif
/* Indicate USB connected and ready */
UpdateStatus(Status_USBReady);
......@@ -237,6 +258,49 @@ void CreateGenericHIDReport(uint8_t* DataArray)
DataArray[i] = LastReceived[i];
}
#if !defined(INTERRUPT_DATA_ENDPOINT)
TASK(USB_HID_Report)
{
/* Check if the USB system is connected to a host */
if (USB_IsConnected)
{
Endpoint_SelectEndpoint(GENERIC_OUT_EPNUM);
if (Endpoint_ReadWriteAllowed())
{
/* Create a tempoary 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_ClearCurrentBank();
}
Endpoint_SelectEndpoint(GENERIC_IN_EPNUM);
if (Endpoint_ReadWriteAllowed())
{
/* Create a tempoary 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_ClearCurrentBank();
}
}
}
#endif
/** ISR for the general Pipe/Endpoint interrupt vector. This ISR fires when an endpoint's status changes (such as
* a packet has been received) on an endpoint with its corresponding ISR enabling bits set. This is used to send
* HID packets to the host each time the HID interrupt endpoints polling period elapses, as managed by the USB
......@@ -247,6 +311,7 @@ ISR(ENDPOINT_PIPE_vect, ISR_BLOCK)
/* Save previously selected endpoint before selecting a new endpoint */
uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint();
#if defined(INTERRUPT_CONTROL_ENDPOINT)
/* Check if the control endpoint has received a request */
if (Endpoint_HasEndpointInterrupted(ENDPOINT_CONTROLEP))
{
......@@ -259,7 +324,9 @@ ISR(ENDPOINT_PIPE_vect, ISR_BLOCK)
/* Handshake the endpoint setup interrupt - must be after the call to USB_USBTask() */
USB_INT_Clear(ENDPOINT_INT_SETUP);
}
#endif
#if defined(INTERRUPT_DATA_ENDPOINT)
/* Check if Generic IN endpoint has interrupted */
if (Endpoint_HasEndpointInterrupted(GENERIC_IN_EPNUM))
{
......@@ -272,7 +339,7 @@ ISR(ENDPOINT_PIPE_vect, ISR_BLOCK)
/* Clear the Generic IN Report endpoint interrupt and select the endpoint */
Endpoint_ClearEndpointInterrupt(GENERIC_IN_EPNUM);
/* Create a tempoary buffer to hold the report to send to the host */
/* Create a temporary buffer to hold the report to send to the host */
uint8_t GenericData[GENERIC_REPORT_SIZE];
/* Create Generic Report Data */
......@@ -297,7 +364,7 @@ ISR(ENDPOINT_PIPE_vect, ISR_BLOCK)
/* Clear the Generic OUT Report endpoint interrupt and select the endpoint */
Endpoint_ClearEndpointInterrupt(GENERIC_OUT_EPNUM);
/* Create a tempoary buffer to hold the read in report from the host */
/* Create a temporary buffer to hold the read in report from the host */
uint8_t GenericData[GENERIC_REPORT_SIZE];
/* Read Generic Report Data */
......@@ -309,6 +376,7 @@ ISR(ENDPOINT_PIPE_vect, ISR_BLOCK)
/* Finalize the stream transfer to send the last packet */
Endpoint_ClearCurrentBank();
}
#endif
/* Restore previously selected endpoint */
Endpoint_SelectEndpoint(PrevSelectedEndpoint);
......
......@@ -47,6 +47,7 @@
#include "Descriptors.h"
#include <LUFA/Version.h> // Library Version Information
#include <LUFA/Scheduler/Scheduler.h> // Simple scheduler for task management
#include <LUFA/Common/ButtLoadTag.h> // PROGMEM tags readable by the ButtLoad project
#include <LUFA/Drivers/USB/USB.h> // USB Functionality
#include <LUFA/Drivers/Board/LEDs.h> // LEDs driver
......@@ -79,6 +80,9 @@
/** Indicates that this module will catch the USB_ConfigurationChanged event when thrown by the library. */
HANDLES_EVENT(USB_ConfigurationChanged);
/* Task Definitions: */
TASK(USB_HID_Report);
/* Function Prototypes: */
void UpdateStatus(uint8_t CurrentStatus);
......
......@@ -60,5 +60,19 @@
* <td>This token defines the size of the device reports, both sent and received. The value must be an
* integer ranging from 1 to 255.</td>
* </tr>
* <tr>
* <td>INTERRUPT_CONTROL_ENDPOINT</td>
* <td>Makefile CDEFS</td>
* <td>When defined, this causes the demo to enable interrupts for the control endpoint,
* which services control requests from the host. If not defined, the control endpoint
* is serviced via polling using the task scheduler.</td>
* </tr>
* <tr>
* <td>INTERRUPT_DATA_ENDPOINT</td>
* <td>Makefile CDEFS</td>
* <td>When defined, this causes the demo to enable interrupts for the data endpoints,
* which services incomming LED reports and outgoing key status reports to and from the host.
* If not defined, the data endpoints are serviced via polling using the task scheduler.</td>
* </tr>
* </table>
*/
\ No newline at end of file
......@@ -545,4 +545,3 @@ ISR(ENDPOINT_PIPE_vect, ISR_BLOCK)
}
#endif
}
......@@ -350,6 +350,9 @@ TASK(USB_HID_Host)
*/
ISR(ENDPOINT_PIPE_vect, ISR_BLOCK)
{
/* Save previously selected pipe before selecting a new pipe */
uint8_t PrevSelectedPipe = Pipe_GetCurrentPipe();
/* Check to see if the HID data IN pipe has caused the interrupt */
if (Pipe_HasPipeInterrupted(HID_DATA_IN_PIPE))
{
......@@ -367,5 +370,8 @@ ISR(ENDPOINT_PIPE_vect, ISR_BLOCK)
ReadNextReport();
}
}
/* Restore previously selected pipe */
Pipe_SelectPipe(PrevSelectedPipe);
}
#endif
......@@ -350,6 +350,9 @@ TASK(USB_Keyboard_Host)
*/
ISR(ENDPOINT_PIPE_vect, ISR_BLOCK)
{
/* Save previously selected pipe before selecting a new pipe */
uint8_t PrevSelectedPipe = Pipe_GetCurrentPipe();
/* Check to see if the keyboard data pipe has caused the interrupt */
if (Pipe_HasPipeInterrupted(KEYBOARD_DATAPIPE))
{
......@@ -366,5 +369,8 @@ ISR(ENDPOINT_PIPE_vect, ISR_BLOCK)
/* Read and process the next report from the device */
ReadNextReport();
}
/* Restore previously selected pipe */
Pipe_SelectPipe(PrevSelectedPipe);
}
#endif
......@@ -346,6 +346,9 @@ TASK(USB_Mouse_Host)
*/
ISR(ENDPOINT_PIPE_vect, ISR_BLOCK)
{
/* Save previously selected pipe before selecting a new pipe */
uint8_t PrevSelectedPipe = Pipe_GetCurrentPipe();
/* Check to see if the mouse data pipe has caused the interrupt */
if (Pipe_HasPipeInterrupted(MOUSE_DATAPIPE))
{
......@@ -363,5 +366,8 @@ ISR(ENDPOINT_PIPE_vect, ISR_BLOCK)
ReadNextReport();
}
}
/* Restore previously selected pipe */
Pipe_SelectPipe(PrevSelectedPipe);
}
#endif
......@@ -7,8 +7,12 @@
/** \page Page_ChangeLog Project Changelog
*
* \section Sec_ChangeLogXXXXXX Version XXXXXX
*
* - Added new GenericHIDHost demo
* - Corrections to the KeyboardHost and MouseHost demos' pipe handling to freeze and unfreeze the data pipes at the point of use
* - KeyboardHost, MouseHost and GenericHIDHost demos now save and restore the currently selected pipe inside the pipe ISR
* - Changed GenericHID device demo to use the LUFA scheduler, added INTERRUPT_DATA_ENDPOINT and INTERRUPT_CONTROL_ENDPOINT compile
* time options
*
* \section Sec_ChangeLog090401 Version 090401
*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment