forked from mfulz_github/qmk_firmware
Removed all user pipe/endpoint interrupt APIs, added internal library support for interrupt driven control endpoints when in device mode by defining INTERRUPT_CONTROL_ENDPOINT token and passing it to the compiler via the -D switch.
This commit is contained in:
parent
0d5baf9bb3
commit
32f0f605ef
Demos
Device
GenericHID
Keyboard
MassStorage
Mouse
Host/GenericHIDHost
LUFA
|
@ -39,10 +39,7 @@
|
||||||
/* Scheduler Task List */
|
/* Scheduler Task List */
|
||||||
TASK_LIST
|
TASK_LIST
|
||||||
{
|
{
|
||||||
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
|
|
||||||
{ .Task = USB_USBTask , .TaskStatus = TASK_STOP },
|
{ .Task = USB_USBTask , .TaskStatus = TASK_STOP },
|
||||||
#endif
|
|
||||||
|
|
||||||
{ .Task = USB_HID_Report , .TaskStatus = TASK_STOP },
|
{ .Task = USB_HID_Report , .TaskStatus = TASK_STOP },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -75,30 +72,13 @@ int main(void)
|
||||||
Scheduler_Start();
|
Scheduler_Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Event handler for the USB_Reset event. This fires when the USB interface is reset by the USB host, before the
|
|
||||||
* enumeration process begins, and enables the control endpoint interrupt so that control requests can be handled
|
|
||||||
* asynchronously when they arrive rather than when the control endpoint is polled manually.
|
|
||||||
*/
|
|
||||||
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
|
/** 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.
|
* starts the library USB task to begin the enumeration and USB management process.
|
||||||
*/
|
*/
|
||||||
EVENT_HANDLER(USB_Connect)
|
EVENT_HANDLER(USB_Connect)
|
||||||
{
|
{
|
||||||
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
|
|
||||||
/* Start USB management task */
|
/* Start USB management task */
|
||||||
Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
|
Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Indicate USB enumerating */
|
/* Indicate USB enumerating */
|
||||||
UpdateStatus(Status_USBEnumerating);
|
UpdateStatus(Status_USBEnumerating);
|
||||||
|
@ -111,10 +91,7 @@ EVENT_HANDLER(USB_Disconnect)
|
||||||
{
|
{
|
||||||
/* Stop running HID reporting and USB management tasks */
|
/* Stop running HID reporting and USB management tasks */
|
||||||
Scheduler_SetTaskMode(USB_HID_Report, TASK_STOP);
|
Scheduler_SetTaskMode(USB_HID_Report, TASK_STOP);
|
||||||
|
|
||||||
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
|
|
||||||
Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
|
Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Indicate USB not ready */
|
/* Indicate USB not ready */
|
||||||
UpdateStatus(Status_USBNotReady);
|
UpdateStatus(Status_USBNotReady);
|
||||||
|
@ -298,32 +275,3 @@ TASK(USB_HID_Report)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(INTERRUPT_CONTROL_ENDPOINT)
|
|
||||||
/** 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
|
|
||||||
* controller.
|
|
||||||
*/
|
|
||||||
ISR(ENDPOINT_PIPE_vect, ISR_BLOCK)
|
|
||||||
{
|
|
||||||
/* Save previously selected endpoint before selecting a new endpoint */
|
|
||||||
uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint();
|
|
||||||
|
|
||||||
/* Check if the control endpoint has received a request */
|
|
||||||
if (Endpoint_HasEndpointInterrupted(ENDPOINT_CONTROLEP))
|
|
||||||
{
|
|
||||||
/* Clear the endpoint interrupt */
|
|
||||||
Endpoint_ClearEndpointInterrupt(ENDPOINT_CONTROLEP);
|
|
||||||
|
|
||||||
/* Process the control request */
|
|
||||||
USB_USBTask();
|
|
||||||
|
|
||||||
/* Handshake the endpoint setup interrupt - must be after the call to USB_USBTask() */
|
|
||||||
USB_INT_Clear(ENDPOINT_INT_SETUP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Restore previously selected endpoint */
|
|
||||||
Endpoint_SelectEndpoint(PrevSelectedEndpoint);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -68,9 +68,6 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Event Handlers: */
|
/* Event Handlers: */
|
||||||
/** Indicates that this module will catch the USB_Reset event when thrown by the library. */
|
|
||||||
HANDLES_EVENT(USB_Reset);
|
|
||||||
|
|
||||||
/** Indicates that this module will catch the USB_Connect event when thrown by the library. */
|
/** Indicates that this module will catch the USB_Connect event when thrown by the library. */
|
||||||
HANDLES_EVENT(USB_Connect);
|
HANDLES_EVENT(USB_Connect);
|
||||||
|
|
||||||
|
|
|
@ -60,12 +60,5 @@
|
||||||
* <td>This token defines the size of the device reports, both sent and received. The value must be an
|
* <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>
|
* integer ranging from 1 to 255.</td>
|
||||||
* </tr>
|
* </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>
|
|
||||||
* </table>
|
* </table>
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -40,10 +40,7 @@
|
||||||
/* Scheduler Task List */
|
/* Scheduler Task List */
|
||||||
TASK_LIST
|
TASK_LIST
|
||||||
{
|
{
|
||||||
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
|
|
||||||
{ .Task = USB_USBTask , .TaskStatus = TASK_STOP },
|
{ .Task = USB_USBTask , .TaskStatus = TASK_STOP },
|
||||||
#endif
|
|
||||||
|
|
||||||
{ .Task = USB_Keyboard_Report , .TaskStatus = TASK_STOP },
|
{ .Task = USB_Keyboard_Report , .TaskStatus = TASK_STOP },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -105,10 +102,8 @@ int main(void)
|
||||||
*/
|
*/
|
||||||
EVENT_HANDLER(USB_Connect)
|
EVENT_HANDLER(USB_Connect)
|
||||||
{
|
{
|
||||||
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
|
|
||||||
/* Start USB management task */
|
/* Start USB management task */
|
||||||
Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
|
Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Indicate USB enumerating */
|
/* Indicate USB enumerating */
|
||||||
UpdateStatus(Status_USBEnumerating);
|
UpdateStatus(Status_USBEnumerating);
|
||||||
|
@ -117,21 +112,6 @@ EVENT_HANDLER(USB_Connect)
|
||||||
UsingReportProtocol = true;
|
UsingReportProtocol = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Event handler for the USB_Reset event. This fires when the USB interface is reset by the USB host, before the
|
|
||||||
* enumeration process begins, and enables the control endpoint interrupt so that control requests can be handled
|
|
||||||
* asynchronously when they arrive rather than when the control endpoint is polled manually.
|
|
||||||
*/
|
|
||||||
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_Disconnect event. This indicates that the device is no longer connected to a host via
|
/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
|
||||||
* the status LEDs.
|
* the status LEDs.
|
||||||
*/
|
*/
|
||||||
|
@ -139,10 +119,7 @@ EVENT_HANDLER(USB_Disconnect)
|
||||||
{
|
{
|
||||||
/* Stop running keyboard reporting and USB management tasks */
|
/* Stop running keyboard reporting and USB management tasks */
|
||||||
Scheduler_SetTaskMode(USB_Keyboard_Report, TASK_STOP);
|
Scheduler_SetTaskMode(USB_Keyboard_Report, TASK_STOP);
|
||||||
|
|
||||||
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
|
|
||||||
Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
|
Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Indicate USB not ready */
|
/* Indicate USB not ready */
|
||||||
UpdateStatus(Status_USBNotReady);
|
UpdateStatus(Status_USBNotReady);
|
||||||
|
@ -445,30 +422,3 @@ TASK(USB_Keyboard_Report)
|
||||||
ReceiveNextReport();
|
ReceiveNextReport();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(INTERRUPT_CONTROL_ENDPOINT)
|
|
||||||
/** 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
|
|
||||||
* controller. It is also used to respond to standard and class specific requests send to the device on the control
|
|
||||||
* endpoint, by handing them off to the LUFA library when they are received.
|
|
||||||
*/
|
|
||||||
ISR(ENDPOINT_PIPE_vect, ISR_BLOCK)
|
|
||||||
{
|
|
||||||
/* Save previously selected endpoint before selecting a new endpoint */
|
|
||||||
uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint();
|
|
||||||
|
|
||||||
/* Check if the control endpoint has received a request */
|
|
||||||
if (Endpoint_HasEndpointInterrupted(ENDPOINT_CONTROLEP))
|
|
||||||
{
|
|
||||||
/* Process the control request */
|
|
||||||
USB_USBTask();
|
|
||||||
|
|
||||||
/* Handshake the endpoint setup interrupt - must be after the call to USB_USBTask() */
|
|
||||||
USB_INT_Clear(ENDPOINT_INT_SETUP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Restore previously selected endpoint */
|
|
||||||
Endpoint_SelectEndpoint(PrevSelectedEndpoint);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -105,9 +105,6 @@
|
||||||
/** Indicates that this module will catch the USB_Disconnect event when thrown by the library. */
|
/** Indicates that this module will catch the USB_Disconnect event when thrown by the library. */
|
||||||
HANDLES_EVENT(USB_Disconnect);
|
HANDLES_EVENT(USB_Disconnect);
|
||||||
|
|
||||||
/** Indicates that this module will catch the USB_Reset event when thrown by the library. */
|
|
||||||
HANDLES_EVENT(USB_Reset);
|
|
||||||
|
|
||||||
/** Indicates that this module will catch the USB_ConfigurationChanged event when thrown by the library. */
|
/** Indicates that this module will catch the USB_ConfigurationChanged event when thrown by the library. */
|
||||||
HANDLES_EVENT(USB_ConfigurationChanged);
|
HANDLES_EVENT(USB_ConfigurationChanged);
|
||||||
|
|
||||||
|
|
|
@ -52,16 +52,9 @@
|
||||||
*
|
*
|
||||||
* <table>
|
* <table>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <td><b>Define Name:</b></td>
|
* <td>
|
||||||
* <td><b>Location:</b></td>
|
* None
|
||||||
* <td><b>Description:</b></td>
|
* </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>
|
||||||
* </table>
|
* </table>
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -85,19 +85,6 @@ int main(void)
|
||||||
Scheduler_Start();
|
Scheduler_Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Event handler for the USB_Reset event. This fires when the USB interface is reset by the USB host, before the
|
|
||||||
* enumeration process begins, and enables the control endpoint interrupt so that control requests can be handled
|
|
||||||
* asynchronously when they arrive rather than when the control endpoint is polled manually.
|
|
||||||
*/
|
|
||||||
EVENT_HANDLER(USB_Reset)
|
|
||||||
{
|
|
||||||
/* Select the control endpoint */
|
|
||||||
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
|
|
||||||
|
|
||||||
/* Enable the endpoint SETUP interrupt ISR for the control endpoint */
|
|
||||||
USB_INT_Enable(ENDPOINT_INT_SETUP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs. */
|
/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs. */
|
||||||
EVENT_HANDLER(USB_Connect)
|
EVENT_HANDLER(USB_Connect)
|
||||||
{
|
{
|
||||||
|
@ -376,21 +363,3 @@ STREAM_CALLBACK(AbortOnMassStoreReset)
|
||||||
/* Continue with the current stream operation */
|
/* Continue with the current stream operation */
|
||||||
return STREAMCALLBACK_Continue;
|
return STREAMCALLBACK_Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** ISR for the general Pipe/Endpoint interrupt vector. This ISR fires when a control request has been issued to the control endpoint,
|
|
||||||
* so that the request can be processed. As several elements of the Mass Storage implementation require asynchronous control requests
|
|
||||||
* (such as endpoint stall clearing and Mass Storage Reset requests during data transfers) this is done via interrupts rather than
|
|
||||||
* polling so that they can be processed regardless of the rest of the application's state.
|
|
||||||
*/
|
|
||||||
ISR(ENDPOINT_PIPE_vect, ISR_BLOCK)
|
|
||||||
{
|
|
||||||
/* Check if the control endpoint has received a request */
|
|
||||||
if (Endpoint_HasEndpointInterrupted(ENDPOINT_CONTROLEP))
|
|
||||||
{
|
|
||||||
/* Process the control request */
|
|
||||||
USB_USBTask();
|
|
||||||
|
|
||||||
/* Handshake the endpoint setup interrupt - must be after the call to USB_USBTask() */
|
|
||||||
USB_INT_Clear(ENDPOINT_INT_SETUP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -134,9 +134,6 @@
|
||||||
STREAM_CALLBACK(AbortOnMassStoreReset);
|
STREAM_CALLBACK(AbortOnMassStoreReset);
|
||||||
|
|
||||||
/* Event Handlers: */
|
/* Event Handlers: */
|
||||||
/** Indicates that this module will catch the USB_Reset event when thrown by the library. */
|
|
||||||
HANDLES_EVENT(USB_Reset);
|
|
||||||
|
|
||||||
/** Indicates that this module will catch the USB_Connect event when thrown by the library. */
|
/** Indicates that this module will catch the USB_Connect event when thrown by the library. */
|
||||||
HANDLES_EVENT(USB_Connect);
|
HANDLES_EVENT(USB_Connect);
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,11 @@
|
||||||
* 255), with each LUN being allocated an equal portion of the available
|
* 255), with each LUN being allocated an equal portion of the available
|
||||||
* Dataflash memory.
|
* Dataflash memory.
|
||||||
*
|
*
|
||||||
|
* The USB control endpoint is managed entirely by the library using endpoint
|
||||||
|
* interrupts, as the INTERRUPT_CONTROL_ENDPOINT option is enabled. This allows for
|
||||||
|
* the host to reset the Mass Storage device state during long transfers without
|
||||||
|
* the need for complicated polling logic.
|
||||||
|
*
|
||||||
* \section SSec_Options Project Options
|
* \section SSec_Options Project Options
|
||||||
*
|
*
|
||||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||||
|
|
|
@ -189,6 +189,7 @@ CDEFS = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)
|
||||||
CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
|
CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
|
||||||
CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
|
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 += -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
|
# Place -D or -U options here for ASM sources
|
||||||
|
|
|
@ -39,10 +39,7 @@
|
||||||
/* Scheduler Task List */
|
/* Scheduler Task List */
|
||||||
TASK_LIST
|
TASK_LIST
|
||||||
{
|
{
|
||||||
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
|
|
||||||
{ .Task = USB_USBTask , .TaskStatus = TASK_STOP },
|
{ .Task = USB_USBTask , .TaskStatus = TASK_STOP },
|
||||||
#endif
|
|
||||||
|
|
||||||
{ .Task = USB_Mouse_Report , .TaskStatus = TASK_STOP },
|
{ .Task = USB_Mouse_Report , .TaskStatus = TASK_STOP },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -105,10 +102,8 @@ int main(void)
|
||||||
*/
|
*/
|
||||||
EVENT_HANDLER(USB_Connect)
|
EVENT_HANDLER(USB_Connect)
|
||||||
{
|
{
|
||||||
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
|
|
||||||
/* Start USB management task */
|
/* Start USB management task */
|
||||||
Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
|
Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Indicate USB enumerating */
|
/* Indicate USB enumerating */
|
||||||
UpdateStatus(Status_USBEnumerating);
|
UpdateStatus(Status_USBEnumerating);
|
||||||
|
@ -117,21 +112,6 @@ EVENT_HANDLER(USB_Connect)
|
||||||
UsingReportProtocol = true;
|
UsingReportProtocol = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Event handler for the USB_Reset event. This fires when the USB interface is reset by the USB host, before the
|
|
||||||
* enumeration process begins, and enables the control endpoint interrupt so that control requests can be handled
|
|
||||||
* asynchronously when they arrive rather than when the control endpoint is polled manually.
|
|
||||||
*/
|
|
||||||
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_Disconnect event. This indicates that the device is no longer connected to a host via
|
/** 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.
|
* the status LEDs and stops the USB management and Mouse reporting tasks.
|
||||||
*/
|
*/
|
||||||
|
@ -139,10 +119,7 @@ EVENT_HANDLER(USB_Disconnect)
|
||||||
{
|
{
|
||||||
/* Stop running mouse reporting and USB management tasks */
|
/* Stop running mouse reporting and USB management tasks */
|
||||||
Scheduler_SetTaskMode(USB_Mouse_Report, TASK_STOP);
|
Scheduler_SetTaskMode(USB_Mouse_Report, TASK_STOP);
|
||||||
|
|
||||||
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
|
|
||||||
Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
|
Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Indicate USB not ready */
|
/* Indicate USB not ready */
|
||||||
UpdateStatus(Status_USBNotReady);
|
UpdateStatus(Status_USBNotReady);
|
||||||
|
@ -381,30 +358,3 @@ TASK(USB_Mouse_Report)
|
||||||
SendNextReport();
|
SendNextReport();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(INTERRUPT_CONTROL_ENDPOINT)
|
|
||||||
/** 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
|
|
||||||
* controller. It is also used to respond to standard and class specific requests send to the device on the control
|
|
||||||
* endpoint, by handing them off to the LUFA library when they are received.
|
|
||||||
*/
|
|
||||||
ISR(ENDPOINT_PIPE_vect, ISR_BLOCK)
|
|
||||||
{
|
|
||||||
/* Save previously selected endpoint before selecting a new endpoint */
|
|
||||||
uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint();
|
|
||||||
|
|
||||||
/* Check if the control endpoint has received a request */
|
|
||||||
if (Endpoint_HasEndpointInterrupted(ENDPOINT_CONTROLEP))
|
|
||||||
{
|
|
||||||
/* Process the control request */
|
|
||||||
USB_USBTask();
|
|
||||||
|
|
||||||
/* Handshake the endpoint setup interrupt - must be after the call to USB_USBTask() */
|
|
||||||
USB_INT_Clear(ENDPOINT_INT_SETUP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Restore previously selected endpoint */
|
|
||||||
Endpoint_SelectEndpoint(PrevSelectedEndpoint);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -105,9 +105,6 @@
|
||||||
/** Indicates that this module will catch the USB_Disconnect event when thrown by the library. */
|
/** Indicates that this module will catch the USB_Disconnect event when thrown by the library. */
|
||||||
HANDLES_EVENT(USB_Disconnect);
|
HANDLES_EVENT(USB_Disconnect);
|
||||||
|
|
||||||
/** Indicates that this module will catch the USB_Reset event when thrown by the library. */
|
|
||||||
HANDLES_EVENT(USB_Reset);
|
|
||||||
|
|
||||||
/** Indicates that this module will catch the USB_ConfigurationChanged event when thrown by the library. */
|
/** Indicates that this module will catch the USB_ConfigurationChanged event when thrown by the library. */
|
||||||
HANDLES_EVENT(USB_ConfigurationChanged);
|
HANDLES_EVENT(USB_ConfigurationChanged);
|
||||||
|
|
||||||
|
|
|
@ -53,16 +53,9 @@
|
||||||
*
|
*
|
||||||
* <table>
|
* <table>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <td><b>Define Name:</b></td>
|
* <td>
|
||||||
* <td><b>Location:</b></td>
|
* None
|
||||||
* <td><b>Description:</b></td>
|
* </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>
|
||||||
* </table>
|
* </table>
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -331,12 +331,6 @@ TASK(USB_HID_Host)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(INTERRUPT_DATA_PIPE)
|
|
||||||
/* Select and unfreeze HID data IN pipe */
|
|
||||||
Pipe_SelectPipe(HID_DATA_IN_PIPE);
|
|
||||||
Pipe_Unfreeze();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
puts_P(PSTR("HID Device Enumerated.\r\n"));
|
puts_P(PSTR("HID Device Enumerated.\r\n"));
|
||||||
|
|
||||||
USB_HostState = HOST_STATE_Ready;
|
USB_HostState = HOST_STATE_Ready;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
* - Fixed Mouse and Keyboard device demos not acting in accordance with the HID specification for idle periods (thanks to Brian Dickman)
|
* - Fixed Mouse and Keyboard device demos not acting in accordance with the HID specification for idle periods (thanks to Brian Dickman)
|
||||||
* - Removed support for endpoint/pipe non-control interrupts; these did not act in the way users expected, and had many subtle issues
|
* - Removed support for endpoint/pipe non-control interrupts; these did not act in the way users expected, and had many subtle issues
|
||||||
* - Fixed Device Mode not handling Set Feature and Clear Feature Chapter 9 requests that are addressed to the device (thanks to Brian Dickman)
|
* - Fixed Device Mode not handling Set Feature and Clear Feature Chapter 9 requests that are addressed to the device (thanks to Brian Dickman)
|
||||||
|
* - Moved control endpoint interrupt handling into the library itself, enable via the new INTERRUPT_CONTROL_ENDPOINT token
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* \section Sec_ChangeLog090510 Version 090510
|
* \section Sec_ChangeLog090510 Version 090510
|
||||||
|
|
|
@ -158,4 +158,9 @@
|
||||||
* required, the VBUS line of the USB connector should be routed to an AVR pin to detect its level, so that the USB_IsConnected global
|
* required, the VBUS line of the USB connector should be routed to an AVR pin to detect its level, so that the USB_IsConnected global
|
||||||
* can be accurately set and the USB_Connect and USB_Disconnect events manually raised by the RAISE_EVENT macro. When defined, this token disables
|
* can be accurately set and the USB_Connect and USB_Disconnect events manually raised by the RAISE_EVENT macro. When defined, this token disables
|
||||||
* the library's auto-detection of the connection state by the aforementioned suspension and wake up events.
|
* the library's auto-detection of the connection state by the aforementioned suspension and wake up events.
|
||||||
|
*
|
||||||
|
* <b>INTERRUPT_CONTROL_ENDPOINT</b> - ( \ref Group_USBManagement ) \n
|
||||||
|
* Some applications prefer to not call the USB_USBTask() management task reguarly while in device mode, as it can complicate code significantly.
|
||||||
|
* Instead, when device mode is used this token can be passed to the library via the -D switch to allow the library to manage the USB control
|
||||||
|
* endpoint entirely via interrupts asynchronously to the user application.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -174,6 +174,10 @@ ISR(USB_GEN_vect, ISR_BLOCK)
|
||||||
ENDPOINT_DIR_OUT, USB_ControlEndpointSize,
|
ENDPOINT_DIR_OUT, USB_ControlEndpointSize,
|
||||||
ENDPOINT_BANK_SINGLE);
|
ENDPOINT_BANK_SINGLE);
|
||||||
|
|
||||||
|
#if defined(INTERRUPT_CONTROL_ENDPOINT)
|
||||||
|
USB_INT_Enable(USB_INT_ENDPOINT_SETUP);
|
||||||
|
#endif
|
||||||
|
|
||||||
RAISE_EVENT(USB_Reset);
|
RAISE_EVENT(USB_Reset);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -249,3 +253,16 @@ ISR(USB_GEN_vect, ISR_BLOCK)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(INTERRUPT_CONTROL_ENDPOINT)
|
||||||
|
ISR(USB_COM_vect, ISR_BLOCK)
|
||||||
|
{
|
||||||
|
uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint();
|
||||||
|
|
||||||
|
USB_USBTask();
|
||||||
|
|
||||||
|
USB_INT_Clear(USB_INT_ENDPOINT_SETUP);
|
||||||
|
|
||||||
|
Endpoint_SelectEndpoint(PrevSelectedEndpoint);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -28,16 +28,6 @@
|
||||||
this software.
|
this software.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \ingroup Group_USB
|
|
||||||
* @defgroup Group_USBInterrupt Endpoint and Pipe Interrupts
|
|
||||||
*
|
|
||||||
* This module manages the main USB interrupt vector, for handling such events as VBUS interrupts
|
|
||||||
* (on supported USB AVR models), device connections and disconnections, etc. as well as providing
|
|
||||||
* easy to use macros for the management of the unified Endpoint/Pipe interrupt vector.
|
|
||||||
*
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __USBINTERRUPT_H__
|
#ifndef __USBINTERRUPT_H__
|
||||||
#define __USBINTERRUPT_H__
|
#define __USBINTERRUPT_H__
|
||||||
|
|
||||||
|
@ -56,37 +46,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Public Interface - May be used in end-application: */
|
/* Public Interface - May be used in end-application: */
|
||||||
/* Macros: */
|
|
||||||
/** Vector name for the common endpoint and pipe vector. This can be used to write an ISR handler
|
|
||||||
* for the endpoint and pipe events, to make certain USB functions interrupt rather than poll
|
|
||||||
* driven.
|
|
||||||
*/
|
|
||||||
#define ENDPOINT_PIPE_vect USB_COM_vect
|
|
||||||
|
|
||||||
/** Enables the given USB interrupt vector (such as the ENDPOINT_INT_* and PIPE_INT_* vectors in
|
|
||||||
* Endpoint.h and Pipe.h).
|
|
||||||
*/
|
|
||||||
#define USB_INT_Enable(int) MACROS{ USB_INT_GET_EN_REG(int) |= USB_INT_GET_EN_MASK(int); }MACROE
|
|
||||||
|
|
||||||
/** Disables the given USB interrupt vector.
|
|
||||||
*
|
|
||||||
* \see \ref USB_INT_Enable()
|
|
||||||
*/
|
|
||||||
#define USB_INT_Disable(int) MACROS{ USB_INT_GET_EN_REG(int) &= ~(USB_INT_GET_EN_MASK(int)); }MACROE
|
|
||||||
|
|
||||||
/** Resets the given USB interrupt flag, so that the interrupt is re-primed for the next firing. */
|
|
||||||
#define USB_INT_Clear(int) MACROS{ USB_INT_GET_INT_REG(int) &= ~(USB_INT_GET_INT_MASK(int)); }MACROE
|
|
||||||
|
|
||||||
/** Returns boolean false if the given USB interrupt is disabled, or true if the interrupt is currently
|
|
||||||
* enabled.
|
|
||||||
*/
|
|
||||||
#define USB_INT_IsEnabled(int) ((USB_INT_GET_EN_REG(int) & USB_INT_GET_EN_MASK(int)) ? true : false)
|
|
||||||
|
|
||||||
/** Returns boolean true if the given interrupt flag is set (i.e. the condition for the interrupt has occurred,
|
|
||||||
* but the interrupt vector is not necessarily enabled), otherwise returns false.
|
|
||||||
*/
|
|
||||||
#define USB_INT_HasOccurred(int) ((USB_INT_GET_INT_REG(int) & USB_INT_GET_INT_MASK(int)) ? true : false)
|
|
||||||
|
|
||||||
/* Throwable Events: */
|
/* Throwable Events: */
|
||||||
/** This module raises the USB Connected interrupt when the AVR is attached to a host while in device
|
/** This module raises the USB Connected interrupt when the AVR is attached to a host while in device
|
||||||
* USB mode.
|
* USB mode.
|
||||||
|
@ -196,6 +155,12 @@
|
||||||
/* Private Interface - For use in library only: */
|
/* Private Interface - For use in library only: */
|
||||||
#if !defined(__DOXYGEN__)
|
#if !defined(__DOXYGEN__)
|
||||||
/* Macros: */
|
/* Macros: */
|
||||||
|
#define USB_INT_Enable(int) MACROS{ USB_INT_GET_EN_REG(int) |= USB_INT_GET_EN_MASK(int); }MACROE
|
||||||
|
#define USB_INT_Disable(int) MACROS{ USB_INT_GET_EN_REG(int) &= ~(USB_INT_GET_EN_MASK(int)); }MACROE
|
||||||
|
#define USB_INT_Clear(int) MACROS{ USB_INT_GET_INT_REG(int) &= ~(USB_INT_GET_INT_MASK(int)); }MACROE
|
||||||
|
#define USB_INT_IsEnabled(int) ((USB_INT_GET_EN_REG(int) & USB_INT_GET_EN_MASK(int)) ? true : false)
|
||||||
|
#define USB_INT_HasOccurred(int) ((USB_INT_GET_INT_REG(int) & USB_INT_GET_INT_MASK(int)) ? true : false)
|
||||||
|
|
||||||
#define USB_INT_GET_EN_REG(a, b, c, d) a
|
#define USB_INT_GET_EN_REG(a, b, c, d) a
|
||||||
#define USB_INT_GET_EN_MASK(a, b, c, d) b
|
#define USB_INT_GET_EN_MASK(a, b, c, d) b
|
||||||
#define USB_INT_GET_INT_REG(a, b, c, d) c
|
#define USB_INT_GET_INT_REG(a, b, c, d) c
|
||||||
|
@ -214,6 +179,7 @@
|
||||||
#define USB_INT_HSOFI UHIEN, (1 << HSOFE) , UHINT , (1 << HSOFI)
|
#define USB_INT_HSOFI UHIEN, (1 << HSOFE) , UHINT , (1 << HSOFI)
|
||||||
#define USB_INT_RSTI UHIEN , (1 << RSTE) , UHINT , (1 << RSTI)
|
#define USB_INT_RSTI UHIEN , (1 << RSTE) , UHINT , (1 << RSTI)
|
||||||
#define USB_INT_SRPI OTGIEN, (1 << SRPE) , OTGINT, (1 << SRPI)
|
#define USB_INT_SRPI OTGIEN, (1 << SRPE) , OTGINT, (1 << SRPI)
|
||||||
|
#define USB_INT_ENDPOINT_SETUP UEIENX, (1 << RXSTPE) , UEINTX, (1 << RXSTPI)
|
||||||
|
|
||||||
/* Function Prototypes: */
|
/* Function Prototypes: */
|
||||||
void USB_INT_ClearAllInterrupts(void);
|
void USB_INT_ClearAllInterrupts(void);
|
||||||
|
@ -226,5 +192,3 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
|
@ -183,6 +183,9 @@
|
||||||
* - In host mode, it may be disabled at start-up, enabled on the firing of the \ref USB_DeviceAttached
|
* - In host mode, it may be disabled at start-up, enabled on the firing of the \ref USB_DeviceAttached
|
||||||
* event and disabled again on the firing of the \ref USB_DeviceUnattached event.
|
* event and disabled again on the firing of the \ref USB_DeviceUnattached event.
|
||||||
*
|
*
|
||||||
|
* If in device mode (only), the control endpoint can instead be managed via interrupts entirely by the library
|
||||||
|
* by defining the INTERRUPT_CONTROL_ENDPOINT token and passing it to the compiler via the -D switch.
|
||||||
|
*
|
||||||
* \see \ref Group_Events for more information on the USB events.
|
* \see \ref Group_Events for more information on the USB events.
|
||||||
*
|
*
|
||||||
* \ingroup Group_USBManagement
|
* \ingroup Group_USBManagement
|
||||||
|
|
|
@ -141,19 +141,6 @@
|
||||||
#define ENDPOINT_TOTAL_ENDPOINTS 1
|
#define ENDPOINT_TOTAL_ENDPOINTS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Interrupt definition for the endpoint SETUP interrupt (for CONTROL type endpoints). Should be
|
|
||||||
* used with the USB_INT_* macros located in USBInterrupt.h.
|
|
||||||
*
|
|
||||||
* This interrupt will fire if enabled on a CONTROL type endpoint if a new control packet is
|
|
||||||
* received from the host.
|
|
||||||
*
|
|
||||||
* \note This interrupt must be enabled and cleared on *each* endpoint which requires it (after the
|
|
||||||
* endpoint is selected), and will fire the common endpoint interrupt vector.
|
|
||||||
*
|
|
||||||
* \see \ref ENDPOINT_PIPE_vect for more information on the common pipe and endpoint interrupt vector.
|
|
||||||
*/
|
|
||||||
#define ENDPOINT_INT_SETUP UEIENX, (1 << RXSTPE), UEINTX, (1 << RXSTPI)
|
|
||||||
|
|
||||||
/* Pseudo-Function Macros: */
|
/* Pseudo-Function Macros: */
|
||||||
#if defined(__DOXYGEN__)
|
#if defined(__DOXYGEN__)
|
||||||
/** Indicates the number of bytes currently stored in the current endpoint's selected bank.
|
/** Indicates the number of bytes currently stored in the current endpoint's selected bank.
|
||||||
|
|
|
@ -158,62 +158,6 @@
|
||||||
*/
|
*/
|
||||||
#define PIPE_EPSIZE_MASK 0x7FF
|
#define PIPE_EPSIZE_MASK 0x7FF
|
||||||
|
|
||||||
/** Interrupt definition for the pipe SETUP bank ready interrupt (for CONTROL type pipes). Should be
|
|
||||||
* used with the USB_INT_* macros located in USBInterrupt.h.
|
|
||||||
*
|
|
||||||
* This interrupt will fire if enabled on an CONTROL type pipe when the pipe is ready for a new
|
|
||||||
* control request.
|
|
||||||
*
|
|
||||||
* \note This interrupt must be enabled and cleared on *each* pipe which requires it (after the pipe
|
|
||||||
* is selected), and will fire the common pipe interrupt vector.
|
|
||||||
*
|
|
||||||
* \see \ref ENDPOINT_PIPE_vect for more information on the common pipe and endpoint interrupt vector.
|
|
||||||
*/
|
|
||||||
#define PIPE_INT_SETUP UPIENX, (1 << TXSTPE) , UPINTX, (1 << TXSTPI)
|
|
||||||
|
|
||||||
/** Interrupt definition for the pipe error interrupt. Should be used with the USB_INT_* macros
|
|
||||||
* located in USBInterrupt.h.
|
|
||||||
*
|
|
||||||
* This interrupt will fire if enabled on a particular pipe if an error occurs on that pipe, such
|
|
||||||
* as a CRC mismatch error.
|
|
||||||
*
|
|
||||||
* \note This interrupt must be enabled and cleared on *each* pipe which requires it (after the pipe
|
|
||||||
* is selected), and will fire the common pipe interrupt vector.
|
|
||||||
*
|
|
||||||
* \see \ref ENDPOINT_PIPE_vect for more information on the common pipe and endpoint interrupt vector.
|
|
||||||
*
|
|
||||||
* \see \ref Pipe_GetErrorFlags() for more information on the pipe errors.
|
|
||||||
*/
|
|
||||||
#define PIPE_INT_ERROR UPIENX, (1 << PERRE), UPINTX, (1 << PERRI)
|
|
||||||
|
|
||||||
/** Interrupt definition for the pipe NAK received interrupt. Should be used with the USB_INT_* macros
|
|
||||||
* located in USBInterrupt.h.
|
|
||||||
*
|
|
||||||
* This interrupt will fire if enabled on a particular pipe if an attached device returns a NAK in
|
|
||||||
* response to a sent packet.
|
|
||||||
*
|
|
||||||
* \note This interrupt must be enabled and cleared on *each* pipe which requires it (after the pipe
|
|
||||||
* is selected), and will fire the common pipe interrupt vector.
|
|
||||||
*
|
|
||||||
* \see \ref ENDPOINT_PIPE_vect for more information on the common pipe and endpoint interrupt vector.
|
|
||||||
*
|
|
||||||
* \see \ref Pipe_IsNAKReceived() for more information on pipe NAKs.
|
|
||||||
*/
|
|
||||||
#define PIPE_INT_NAK UPIENX, (1 << NAKEDE), UPINTX, (1 << NAKEDI)
|
|
||||||
|
|
||||||
/** Interrupt definition for the pipe STALL received interrupt. Should be used with the USB_INT_* macros
|
|
||||||
* located in USBInterrupt.h.
|
|
||||||
*
|
|
||||||
* This interrupt will fire if enabled on a particular pipe if an attached device returns a STALL on the
|
|
||||||
* currently selected pipe. This will also fire if the pipe is an isochronous pipe and a CRC error occurs.
|
|
||||||
*
|
|
||||||
* \note This interrupt must be enabled and cleared on *each* pipe which requires it (after the pipe
|
|
||||||
* is selected), and will fire the common pipe interrupt vector.
|
|
||||||
*
|
|
||||||
* \see \ref ENDPOINT_PIPE_vect for more information on the common pipe and endpoint interrupt vector.
|
|
||||||
*/
|
|
||||||
#define PIPE_INT_STALL UPIENX, (1 << RXSTALLE), UPINTX, (1 << RXSTALLI)
|
|
||||||
|
|
||||||
/* Pseudo-Function Macros: */
|
/* Pseudo-Function Macros: */
|
||||||
#if defined(__DOXYGEN__)
|
#if defined(__DOXYGEN__)
|
||||||
/** Indicates the number of bytes currently stored in the current pipes's selected bank.
|
/** Indicates the number of bytes currently stored in the current pipes's selected bank.
|
||||||
|
|
|
@ -14,7 +14,8 @@
|
||||||
*
|
*
|
||||||
* <b>Device Mode</b>
|
* <b>Device Mode</b>
|
||||||
* - Support for non-control data endpoint interrupts has been dropped due to many issues in the implementation. All existing
|
* - Support for non-control data endpoint interrupts has been dropped due to many issues in the implementation. All existing
|
||||||
* projects using interrupts on non-control endpoints should switch to polling.
|
* projects using interrupts on non-control endpoints should switch to polling. For control interrupts, the library can
|
||||||
|
* manage the control endpoint via interrupts automatically by compiling with the INTERRUPT_CONTROL_ENDPOINT token defined.
|
||||||
* - The Endpoint_ClearEndpointInterrupt() macro has been deleted and references to it should be removed.
|
* - The Endpoint_ClearEndpointInterrupt() macro has been deleted and references to it should be removed.
|
||||||
*
|
*
|
||||||
* <b>Device Mode</b>
|
* <b>Device Mode</b>
|
||||||
|
|
Loading…
Reference in New Issue