Added new EVENT_USB_Device_StartOfFrame() event, controlled by the new USB_Device_EnableSOFEvents() and USB_Device_DisableSOFEvents() macros to give bus-synchronised millisecond interrupts when in USB device mode.

pull/1469/head
Dean Camera 15 years ago
parent 25ddbb9e3b
commit b71ff7c8cd

@ -94,18 +94,12 @@ void SetupHardware(void)
/* Hardware Initialization */
LEDs_Init();
USB_Init();
/* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */
OCR0A = ((F_CPU / 64) / 1000);
TCCR0A = (1 << WGM01);
TCCR0B = ((1 << CS01) | (1 << CS00));
TIMSK0 = (1 << OCIE0A);
}
/** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
/** Event handler for the library USB Disconnection event. */
@ -121,6 +115,8 @@ void EVENT_USB_Device_ConfigurationChanged(void)
if (!(HID_Device_ConfigureEndpoints(&Generic_HID_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_Device_EnableSOFEvents();
}
/** Event handler for the library USB Unhandled Control Request event. */
@ -129,8 +125,8 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
HID_Device_ProcessControlRequest(&Generic_HID_Interface);
}
/** ISR to keep track of each millisecond interrupt, for determining the HID class idle period remaining when set. */
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
/** Event handler for the USB device Start Of Frame event. */
void EVENT_USB_Device_StartOfFrame(void)
{
HID_Device_MillisecondElapsed(&Generic_HID_Interface);
}

@ -40,8 +40,6 @@
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <string.h>
#include "Descriptors.h"
@ -71,6 +69,7 @@
void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void);
void EVENT_USB_Device_StartOfFrame(void);
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,
void* ReportData, uint16_t* ReportSize);

@ -88,12 +88,6 @@ void SetupHardware(void)
LEDs_Init();
Buttons_Init();
USB_Init();
/* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */
OCR0A = ((F_CPU / 64) / 1000);
TCCR0A = (1 << WGM01);
TCCR0B = ((1 << CS01) | (1 << CS00));
TIMSK0 = (1 << OCIE0A);
}
/** Event handler for the library USB Connection event. */
@ -115,6 +109,8 @@ void EVENT_USB_Device_ConfigurationChanged(void)
if (!(HID_Device_ConfigureEndpoints(&Joystick_HID_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_Device_EnableSOFEvents();
}
/** Event handler for the library USB Unhandled Control Request event. */
@ -123,8 +119,8 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
HID_Device_ProcessControlRequest(&Joystick_HID_Interface);
}
/** ISR to keep track of each millisecond interrupt, for determining the HID class idle period remaining when set. */
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
/** Event handler for the USB device Start Of Frame event. */
void EVENT_USB_Device_StartOfFrame(void)
{
HID_Device_MillisecondElapsed(&Joystick_HID_Interface);
}

@ -82,6 +82,7 @@
void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void);
void EVENT_USB_Device_StartOfFrame(void);
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,
void* ReportData, uint16_t* ReportSize);

@ -89,12 +89,6 @@ void SetupHardware()
LEDs_Init();
Buttons_Init();
USB_Init();
/* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */
OCR0A = ((F_CPU / 64) / 1000);
TCCR0A = (1 << WGM01);
TCCR0B = ((1 << CS01) | (1 << CS00));
TIMSK0 = (1 << OCIE0A);
}
/** Event handler for the library USB Connection event. */
@ -116,6 +110,8 @@ void EVENT_USB_Device_ConfigurationChanged(void)
if (!(HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_Device_EnableSOFEvents();
}
/** Event handler for the library USB Unhandled Control Request event. */
@ -124,8 +120,8 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
HID_Device_ProcessControlRequest(&Keyboard_HID_Interface);
}
/** ISR to keep track of each millisecond interrupt, for determining the HID class idle period remaining when set. */
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
/** Event handler for the USB device Start Of Frame event. */
void EVENT_USB_Device_StartOfFrame(void)
{
HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);
}

@ -85,6 +85,7 @@
void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void);
void EVENT_USB_Device_StartOfFrame(void);
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,
void* ReportData, uint16_t* ReportSize);

@ -112,12 +112,6 @@ void SetupHardware()
Joystick_Init();
LEDs_Init();
USB_Init();
/* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */
OCR0A = ((F_CPU / 64) / 1000);
TCCR0A = (1 << WGM01);
TCCR0B = ((1 << CS01) | (1 << CS00));
TIMSK0 = (1 << OCIE0A);
}
/** Event handler for the library USB Connection event. */
@ -142,6 +136,8 @@ void EVENT_USB_Device_ConfigurationChanged(void)
if (!(HID_Device_ConfigureEndpoints(&Mouse_HID_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_Device_EnableSOFEvents();
}
/** Event handler for the library USB Unhandled Control Request event. */
@ -151,8 +147,8 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
HID_Device_ProcessControlRequest(&Mouse_HID_Interface);
}
/** ISR to keep track of each millisecond interrupt, for determining the HID class idle period remaining when set. */
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
/** Event handler for the USB device Start Of Frame event. */
void EVENT_USB_Device_StartOfFrame(void)
{
HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);
HID_Device_MillisecondElapsed(&Mouse_HID_Interface);

@ -89,6 +89,7 @@
void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void);
void EVENT_USB_Device_StartOfFrame(void);
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,
void* ReportData, uint16_t* ReportSize);

@ -88,12 +88,6 @@ void SetupHardware(void)
LEDs_Init();
Buttons_Init();
USB_Init();
/* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */
OCR0A = ((F_CPU / 64) / 1000);
TCCR0A = (1 << WGM01);
TCCR0B = ((1 << CS01) | (1 << CS00));
TIMSK0 = (1 << OCIE0A);
}
/** Event handler for the library USB WakeUp event. */
@ -115,6 +109,8 @@ void EVENT_USB_Device_ConfigurationChanged(void)
if (!(HID_Device_ConfigureEndpoints(&Mouse_HID_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
USB_Device_EnableSOFEvents();
}
/** Event handler for the library USB Unhandled Control Request event. */
@ -123,8 +119,8 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
HID_Device_ProcessControlRequest(&Mouse_HID_Interface);
}
/** ISR to keep track of each millisecond interrupt, for determining the HID class idle period remaining when set. */
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
/** Event handler for the USB device Start Of Frame event. */
void EVENT_USB_Device_StartOfFrame(void)
{
HID_Device_MillisecondElapsed(&Mouse_HID_Interface);
}

@ -84,6 +84,7 @@
void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void);
void EVENT_USB_Device_StartOfFrame(void);
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,
void* ReportData, uint16_t* ReportSize);

@ -40,7 +40,6 @@
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <string.h>
@ -77,6 +76,7 @@
void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void);
void EVENT_USB_Device_StartOfFrame(void);
void ProcessGenericHIDReport(uint8_t* DataArray);
void CreateGenericHIDReport(uint8_t* DataArray);

@ -85,12 +85,6 @@ void SetupHardware(void)
Joystick_Init();
LEDs_Init();
USB_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);
}
/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
@ -137,6 +131,8 @@ void EVENT_USB_Device_ConfigurationChanged(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
USB_Device_EnableSOFEvents();
}
/** Event handler for the USB_UnhandledControlRequest event. This is used to catch standard and class specific
@ -248,10 +244,8 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
}
}
/** 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)
/** Event handler for the USB device Start Of Frame event. */
void EVENT_USB_Device_StartOfFrame(void)
{
/* One millisecond has elapsed, decrement the idle time remaining counter if it has not already elapsed */
if (IdleMSRemaining)

@ -40,7 +40,6 @@
/* Includes: */
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <avr/power.h>
#include <stdbool.h>
#include <string.h>
@ -105,6 +104,7 @@
void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void);
void EVENT_USB_Device_StartOfFrame(void);
void CreateKeyboardReport(USB_KeyboardReport_Data_t* ReportData);
void ProcessLEDReport(uint8_t LEDReport);

@ -102,5 +102,6 @@
void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void);
void EVENT_USB_Device_StartOfFrame(void);
#endif

@ -85,12 +85,6 @@ void SetupHardware(void)
LEDs_Init();
Buttons_Init();
USB_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);
}
/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
@ -129,6 +123,8 @@ void EVENT_USB_Device_ConfigurationChanged(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
USB_Device_EnableSOFEvents();
}
/** Event handler for the USB_UnhandledControlRequest event. This is used to catch standard and class specific
@ -218,10 +214,8 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
}
}
/** 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)
/** Event handler for the USB device Start Of Frame event. */
void EVENT_USB_Device_StartOfFrame(void)
{
/* One millisecond has elapsed, decrement the idle time remaining counter if it has not already elapsed */
if (IdleMSRemaining)

@ -39,7 +39,6 @@
/* Includes: */
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <avr/power.h>
#include <stdbool.h>
#include <string.h>
@ -105,6 +104,7 @@
void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void);
void EVENT_USB_Device_StartOfFrame(void);
void CreateMouseReport(USB_MouseReport_Data_t* ReportData);

@ -119,7 +119,9 @@
void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo);
/** Indicates that a millisecond of idle time has elapsed on the given HID interface, and the interface's idle count should be
* decremented. This should be called once per millisecond so that hardware key-repeats function correctly.
* decremented. This should be called once per millisecond so that hardware key-repeats function correctly. It is recommended
* that this be called by the \ref EVENT_USB_Device_StartOfFrame() event, once SOF events have been enabled via
* \ref USB_Device_EnableSOFEvents();.
*
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.
*/

@ -234,6 +234,18 @@
* \ref Group_USBManagement documentation).
*/
void EVENT_USB_Device_Reset(void);
/** Event for USB Start Of Frame detection, when enabled. This event fires at the start of each USB
* frame, once per millisecond, and is synchronised to the USB bus. This can be used as an accurate
* millisecond timer source when the USB bus is enumerated in device mode to a USB host.
*
* This event is not normally active - it must be manually enabled and disabled via the
* \ref USB_Device_EnableSOFEvents() and \ref USB_Device_DisableSOFEvents() commands after enumeration.
*
* \note This event does not exist if the USB_HOST_ONLY token is supplied to the compiler (see
* \ref Group_USBManagement documentation).
*/
void EVENT_USB_Device_StartOfFrame(void);
#endif
/* Private Interface - For use in library only: */
@ -264,6 +276,7 @@
void EVENT_USB_Device_Suspend(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);
void EVENT_USB_Device_WakeUp(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);
void EVENT_USB_Device_Reset(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);
void EVENT_USB_Device_StartOfFrame(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);
#endif
#endif
#endif

@ -153,6 +153,13 @@ ISR(USB_GEN_vect, ISR_BLOCK)
EVENT_USB_Device_Reset();
}
if (USB_INT_HasOccurred(USB_INT_SOFI) && USB_INT_IsEnabled(USB_INT_SOFI))
{
USB_INT_Clear(USB_INT_SOFI);
EVENT_USB_Device_StartOfFrame();
}
#endif
#if defined(USB_CAN_BE_HOST)

@ -111,12 +111,27 @@
* \return Boolean true if the USB communications have been suspended by the host, false otherwise.
*/
static inline bool USB_Device_IsUSBSuspended(void);
/** Enables the device mode Start Of Frame events. When enabled, this causes the
* \ref EVENT_USB_Device_StartOfFrame() event to fire once per millisecond, synchronised to the USB bus,
* at the start of each USB frame when enumerated in device mode.
*/
static inline bool USB_Device_EnableSOFEvents(void);
/** Disables the device mode Start Of Frame events. When disabled, this stop the firing of the
* \ref EVENT_USB_Device_StartOfFrame() event when enumerated in device mode.
*/
static inline bool USB_Device_DisableSOFEvents(void);
#else
#define USB_Device_SendRemoteWakeup() MACROS{ UDCON |= (1 << RMWKUP); }MACROE
#define USB_Device_IsRemoteWakeupSent() ((UDCON & (1 << RMWKUP)) ? false : true)
#define USB_Device_IsUSBSuspended() ((UDINT & (1 << SUSPI)) ? true : false)
#define USB_Device_EnableSOFEvents() MACROS{ USB_INT_Enable(USB_INT_SOFI); }MACROE
#define USB_Device_DisableSOFEvents() MACROS{ USB_INT_Disable(USB_INT_SOFI); }MACROE
#endif
/* Type Defines: */

@ -11,6 +11,8 @@
* <b>New:</b>
* - Added new host class drivers and matching demos to the library for rapid application development
* - Added flag to the HID report parser to indicate if a device has multiple reports
* - Added new EVENT_USB_Device_StartOfFrame() event, controlled by the new USB_Device_EnableSOFEvents() and
* USB_Device_DisableSOFEvents() macros to give bus-synchronised millisecond interrupts when in USB device mode
*
* <b>Changed:</b>
* - SetIdle requests to the HID device driver with a 0 idle period (send changes only) now only affect the requested

@ -99,12 +99,6 @@ void SetupHardware(void)
/* Hardware Initialization */
Magstripe_Init();
USB_Init();
/* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */
OCR0A = ((F_CPU / 64) / 1000);
TCCR0A = (1 << WGM01);
TCCR0B = ((1 << CS01) | (1 << CS00));
TIMSK0 = (1 << OCIE0A);
}
/** Determines if a card has been inserted, and if so reads in each track's contents into the bit buffers
@ -148,6 +142,8 @@ void ReadMagstripeData(void)
void EVENT_USB_Device_ConfigurationChanged(void)
{
HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface);
USB_Device_EnableSOFEvents();
}
/** Event handler for the library USB Unhandled Control Packet event. */
@ -156,8 +152,8 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
HID_Device_ProcessControlRequest(&Keyboard_HID_Interface);
}
/** Timer 0 CTC ISR, firing once each millisecond to keep track of elapsed idle time in the HID interface. */
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
/** Event handler for the USB device Start Of Frame event. */
void EVENT_USB_Device_StartOfFrame(void)
{
HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);
}

@ -84,6 +84,7 @@
void EVENT_USB_Device_ConfigurationChanged(void);
void EVENT_USB_Device_UnhandledControlRequest(void);
void EVENT_USB_Device_StartOfFrame(void);
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,
void* ReportData, uint16_t* ReportSize);

Loading…
Cancel
Save