/* Hardware Initialization */\r
LEDs_Init();\r
USB_Init();\r
-\r
- /* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */\r
- OCR0A = ((F_CPU / 64) / 1000);\r
- TCCR0A = (1 << WGM01);\r
- TCCR0B = ((1 << CS01) | (1 << CS00));\r
- TIMSK0 = (1 << OCIE0A);\r
}\r
\r
/** Event handler for the library USB Connection event. */\r
void EVENT_USB_Device_Connect(void)\r
{\r
- LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);\r
+ LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); \r
}\r
\r
/** Event handler for the library USB Disconnection event. */\r
\r
if (!(HID_Device_ConfigureEndpoints(&Generic_HID_Interface)))\r
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
+\r
+ USB_Device_EnableSOFEvents();\r
}\r
\r
/** Event handler for the library USB Unhandled Control Request event. */\r
HID_Device_ProcessControlRequest(&Generic_HID_Interface);\r
}\r
\r
-/** ISR to keep track of each millisecond interrupt, for determining the HID class idle period remaining when set. */\r
-ISR(TIMER0_COMPA_vect, ISR_BLOCK)\r
+/** Event handler for the USB device Start Of Frame event. */\r
+void EVENT_USB_Device_StartOfFrame(void)\r
{\r
HID_Device_MillisecondElapsed(&Generic_HID_Interface);\r
}\r
#include <avr/io.h>\r
#include <avr/wdt.h>\r
#include <avr/power.h>\r
- #include <avr/interrupt.h>\r
- #include <stdbool.h>\r
#include <string.h>\r
\r
#include "Descriptors.h"\r
void EVENT_USB_Device_Disconnect(void);\r
void EVENT_USB_Device_ConfigurationChanged(void);\r
void EVENT_USB_Device_UnhandledControlRequest(void);\r
+ void EVENT_USB_Device_StartOfFrame(void);\r
\r
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,\r
void* ReportData, uint16_t* ReportSize);\r
LEDs_Init();\r
Buttons_Init();\r
USB_Init();\r
-\r
- /* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */\r
- OCR0A = ((F_CPU / 64) / 1000);\r
- TCCR0A = (1 << WGM01);\r
- TCCR0B = ((1 << CS01) | (1 << CS00));\r
- TIMSK0 = (1 << OCIE0A);\r
}\r
\r
/** Event handler for the library USB Connection event. */\r
\r
if (!(HID_Device_ConfigureEndpoints(&Joystick_HID_Interface)))\r
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
+\r
+ USB_Device_EnableSOFEvents();\r
}\r
\r
/** Event handler for the library USB Unhandled Control Request event. */\r
HID_Device_ProcessControlRequest(&Joystick_HID_Interface);\r
}\r
\r
-/** ISR to keep track of each millisecond interrupt, for determining the HID class idle period remaining when set. */\r
-ISR(TIMER0_COMPA_vect, ISR_BLOCK)\r
+/** Event handler for the USB device Start Of Frame event. */\r
+void EVENT_USB_Device_StartOfFrame(void)\r
{\r
HID_Device_MillisecondElapsed(&Joystick_HID_Interface);\r
}\r
void EVENT_USB_Device_Disconnect(void);\r
void EVENT_USB_Device_ConfigurationChanged(void);\r
void EVENT_USB_Device_UnhandledControlRequest(void);\r
+ void EVENT_USB_Device_StartOfFrame(void);\r
\r
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,\r
void* ReportData, uint16_t* ReportSize);\r
LEDs_Init();\r
Buttons_Init();\r
USB_Init();\r
-\r
- /* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */\r
- OCR0A = ((F_CPU / 64) / 1000);\r
- TCCR0A = (1 << WGM01);\r
- TCCR0B = ((1 << CS01) | (1 << CS00));\r
- TIMSK0 = (1 << OCIE0A);\r
}\r
\r
/** Event handler for the library USB Connection event. */\r
\r
if (!(HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface)))\r
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
+\r
+ USB_Device_EnableSOFEvents();\r
}\r
\r
/** Event handler for the library USB Unhandled Control Request event. */\r
HID_Device_ProcessControlRequest(&Keyboard_HID_Interface);\r
}\r
\r
-/** ISR to keep track of each millisecond interrupt, for determining the HID class idle period remaining when set. */\r
-ISR(TIMER0_COMPA_vect, ISR_BLOCK)\r
+/** Event handler for the USB device Start Of Frame event. */\r
+void EVENT_USB_Device_StartOfFrame(void)\r
{\r
HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);\r
}\r
void EVENT_USB_Device_Disconnect(void);\r
void EVENT_USB_Device_ConfigurationChanged(void);\r
void EVENT_USB_Device_UnhandledControlRequest(void);\r
+ void EVENT_USB_Device_StartOfFrame(void);\r
\r
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,\r
void* ReportData, uint16_t* ReportSize);\r
Joystick_Init();\r
LEDs_Init();\r
USB_Init();\r
-\r
- /* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */\r
- OCR0A = ((F_CPU / 64) / 1000);\r
- TCCR0A = (1 << WGM01);\r
- TCCR0B = ((1 << CS01) | (1 << CS00));\r
- TIMSK0 = (1 << OCIE0A);\r
}\r
\r
/** Event handler for the library USB Connection event. */\r
\r
if (!(HID_Device_ConfigureEndpoints(&Mouse_HID_Interface)))\r
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
+\r
+ USB_Device_EnableSOFEvents();\r
}\r
\r
/** Event handler for the library USB Unhandled Control Request event. */\r
HID_Device_ProcessControlRequest(&Mouse_HID_Interface);\r
}\r
\r
-/** ISR to keep track of each millisecond interrupt, for determining the HID class idle period remaining when set. */\r
-ISR(TIMER0_COMPA_vect, ISR_BLOCK)\r
+/** Event handler for the USB device Start Of Frame event. */\r
+void EVENT_USB_Device_StartOfFrame(void)\r
{\r
HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);\r
HID_Device_MillisecondElapsed(&Mouse_HID_Interface);\r
void EVENT_USB_Device_Disconnect(void);\r
void EVENT_USB_Device_ConfigurationChanged(void);\r
void EVENT_USB_Device_UnhandledControlRequest(void);\r
+ void EVENT_USB_Device_StartOfFrame(void);\r
\r
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,\r
void* ReportData, uint16_t* ReportSize);\r
LEDs_Init();\r
Buttons_Init();\r
USB_Init();\r
-\r
- /* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */\r
- OCR0A = ((F_CPU / 64) / 1000);\r
- TCCR0A = (1 << WGM01);\r
- TCCR0B = ((1 << CS01) | (1 << CS00));\r
- TIMSK0 = (1 << OCIE0A);\r
}\r
\r
/** Event handler for the library USB WakeUp event. */\r
\r
if (!(HID_Device_ConfigureEndpoints(&Mouse_HID_Interface)))\r
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
+\r
+ USB_Device_EnableSOFEvents();\r
}\r
\r
/** Event handler for the library USB Unhandled Control Request event. */\r
HID_Device_ProcessControlRequest(&Mouse_HID_Interface);\r
}\r
\r
-/** ISR to keep track of each millisecond interrupt, for determining the HID class idle period remaining when set. */\r
-ISR(TIMER0_COMPA_vect, ISR_BLOCK)\r
+/** Event handler for the USB device Start Of Frame event. */\r
+void EVENT_USB_Device_StartOfFrame(void)\r
{\r
HID_Device_MillisecondElapsed(&Mouse_HID_Interface);\r
}\r
void EVENT_USB_Device_Disconnect(void);\r
void EVENT_USB_Device_ConfigurationChanged(void);\r
void EVENT_USB_Device_UnhandledControlRequest(void);\r
+ void EVENT_USB_Device_StartOfFrame(void);\r
\r
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,\r
void* ReportData, uint16_t* ReportSize);\r
#include <avr/io.h>\r
#include <avr/wdt.h>\r
#include <avr/power.h>\r
- #include <avr/interrupt.h>\r
#include <stdbool.h>\r
#include <string.h>\r
\r
void EVENT_USB_Device_Disconnect(void);\r
void EVENT_USB_Device_ConfigurationChanged(void);\r
void EVENT_USB_Device_UnhandledControlRequest(void);\r
+ void EVENT_USB_Device_StartOfFrame(void);\r
\r
void ProcessGenericHIDReport(uint8_t* DataArray);\r
void CreateGenericHIDReport(uint8_t* DataArray);\r
Joystick_Init();\r
LEDs_Init();\r
USB_Init();\r
- \r
- /* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */\r
- OCR0A = 0x7D;\r
- TCCR0A = (1 << WGM01);\r
- TCCR0B = ((1 << CS01) | (1 << CS00));\r
- TIMSK0 = (1 << OCIE0A);\r
}\r
\r
/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and\r
{\r
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
}\r
+ \r
+ USB_Device_EnableSOFEvents();\r
}\r
\r
/** Event handler for the USB_UnhandledControlRequest event. This is used to catch standard and class specific\r
}\r
}\r
\r
-/** ISR for the timer 0 compare vector. This ISR fires once each millisecond, and increments the\r
- * scheduler elapsed idle period counter when the host has set an idle period.\r
- */\r
-ISR(TIMER0_COMPA_vect, ISR_BLOCK)\r
+/** Event handler for the USB device Start Of Frame event. */\r
+void EVENT_USB_Device_StartOfFrame(void)\r
{\r
/* One millisecond has elapsed, decrement the idle time remaining counter if it has not already elapsed */\r
if (IdleMSRemaining)\r
/* Includes: */\r
#include <avr/io.h>\r
#include <avr/wdt.h>\r
- #include <avr/interrupt.h>\r
#include <avr/power.h>\r
#include <stdbool.h>\r
#include <string.h>\r
void EVENT_USB_Device_Disconnect(void);\r
void EVENT_USB_Device_ConfigurationChanged(void);\r
void EVENT_USB_Device_UnhandledControlRequest(void);\r
+ void EVENT_USB_Device_StartOfFrame(void);\r
\r
void CreateKeyboardReport(USB_KeyboardReport_Data_t* ReportData);\r
void ProcessLEDReport(uint8_t LEDReport);\r
void EVENT_USB_Device_Disconnect(void);\r
void EVENT_USB_Device_ConfigurationChanged(void);\r
void EVENT_USB_Device_UnhandledControlRequest(void);\r
+ void EVENT_USB_Device_StartOfFrame(void);\r
\r
#endif\r
LEDs_Init();\r
Buttons_Init();\r
USB_Init();\r
- \r
- /* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */\r
- OCR0A = 0x7D;\r
- TCCR0A = (1 << WGM01);\r
- TCCR0B = ((1 << CS01) | (1 << CS00));\r
- TIMSK0 = (1 << OCIE0A);\r
}\r
\r
/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and\r
{\r
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
}\r
+\r
+ USB_Device_EnableSOFEvents();\r
}\r
\r
/** Event handler for the USB_UnhandledControlRequest event. This is used to catch standard and class specific\r
}\r
}\r
\r
-/** ISR for the timer 0 compare vector. This ISR fires once each millisecond, and increments the\r
- * scheduler elapsed idle period counter when the host has set an idle period.\r
- */\r
-ISR(TIMER0_COMPA_vect, ISR_BLOCK)\r
+/** Event handler for the USB device Start Of Frame event. */\r
+void EVENT_USB_Device_StartOfFrame(void)\r
{\r
/* One millisecond has elapsed, decrement the idle time remaining counter if it has not already elapsed */\r
if (IdleMSRemaining)\r
/* Includes: */\r
#include <avr/io.h>\r
#include <avr/wdt.h>\r
- #include <avr/interrupt.h>\r
#include <avr/power.h>\r
#include <stdbool.h>\r
#include <string.h>\r
void EVENT_USB_Device_Disconnect(void);\r
void EVENT_USB_Device_ConfigurationChanged(void);\r
void EVENT_USB_Device_UnhandledControlRequest(void);\r
+ void EVENT_USB_Device_StartOfFrame(void);\r
\r
void CreateMouseReport(USB_MouseReport_Data_t* ReportData);\r
\r
void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* HIDInterfaceInfo);\r
\r
/** Indicates that a millisecond of idle time has elapsed on the given HID interface, and the interface's idle count should be\r
- * decremented. This should be called once per millisecond so that hardware key-repeats function correctly.\r
+ * decremented. This should be called once per millisecond so that hardware key-repeats function correctly. It is recommended\r
+ * that this be called by the \ref EVENT_USB_Device_StartOfFrame() event, once SOF events have been enabled via\r
+ * \ref USB_Device_EnableSOFEvents();.\r
*\r
* \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state.\r
*/\r
* \ref Group_USBManagement documentation).\r
*/\r
void EVENT_USB_Device_Reset(void);\r
+\r
+ /** Event for USB Start Of Frame detection, when enabled. This event fires at the start of each USB\r
+ * frame, once per millisecond, and is synchronised to the USB bus. This can be used as an accurate\r
+ * millisecond timer source when the USB bus is enumerated in device mode to a USB host.\r
+ *\r
+ * This event is not normally active - it must be manually enabled and disabled via the\r
+ * \ref USB_Device_EnableSOFEvents() and \ref USB_Device_DisableSOFEvents() commands after enumeration.\r
+ *\r
+ * \note This event does not exist if the USB_HOST_ONLY token is supplied to the compiler (see\r
+ * \ref Group_USBManagement documentation).\r
+ */\r
+ void EVENT_USB_Device_StartOfFrame(void);\r
#endif\r
\r
/* Private Interface - For use in library only: */\r
void EVENT_USB_Device_Suspend(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);\r
void EVENT_USB_Device_WakeUp(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);\r
void EVENT_USB_Device_Reset(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);\r
+ void EVENT_USB_Device_StartOfFrame(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);\r
#endif\r
#endif\r
#endif\r
\r
EVENT_USB_Device_Reset();\r
}\r
+ \r
+ if (USB_INT_HasOccurred(USB_INT_SOFI) && USB_INT_IsEnabled(USB_INT_SOFI))\r
+ {\r
+ USB_INT_Clear(USB_INT_SOFI);\r
+ \r
+ EVENT_USB_Device_StartOfFrame();\r
+ }\r
#endif\r
\r
#if defined(USB_CAN_BE_HOST)\r
* \return Boolean true if the USB communications have been suspended by the host, false otherwise.\r
*/\r
static inline bool USB_Device_IsUSBSuspended(void);\r
+ \r
+ /** Enables the device mode Start Of Frame events. When enabled, this causes the\r
+ * \ref EVENT_USB_Device_StartOfFrame() event to fire once per millisecond, synchronised to the USB bus,\r
+ * at the start of each USB frame when enumerated in device mode.\r
+ */\r
+ static inline bool USB_Device_EnableSOFEvents(void);\r
+ \r
+ /** Disables the device mode Start Of Frame events. When disabled, this stop the firing of the\r
+ * \ref EVENT_USB_Device_StartOfFrame() event when enumerated in device mode.\r
+ */\r
+ static inline bool USB_Device_DisableSOFEvents(void);\r
#else\r
#define USB_Device_SendRemoteWakeup() MACROS{ UDCON |= (1 << RMWKUP); }MACROE\r
\r
#define USB_Device_IsRemoteWakeupSent() ((UDCON & (1 << RMWKUP)) ? false : true)\r
\r
#define USB_Device_IsUSBSuspended() ((UDINT & (1 << SUSPI)) ? true : false)\r
+ \r
+ #define USB_Device_EnableSOFEvents() MACROS{ USB_INT_Enable(USB_INT_SOFI); }MACROE\r
+\r
+ #define USB_Device_DisableSOFEvents() MACROS{ USB_INT_Disable(USB_INT_SOFI); }MACROE\r
#endif\r
\r
/* Type Defines: */\r
* <b>New:</b>\r
* - Added new host class drivers and matching demos to the library for rapid application development\r
* - Added flag to the HID report parser to indicate if a device has multiple reports\r
+ * - Added new EVENT_USB_Device_StartOfFrame() event, controlled by the new USB_Device_EnableSOFEvents() and\r
+ * USB_Device_DisableSOFEvents() macros to give bus-synchronised millisecond interrupts when in USB device mode\r
* \r
* <b>Changed:</b>\r
* - SetIdle requests to the HID device driver with a 0 idle period (send changes only) now only affect the requested\r
/* Hardware Initialization */\r
Magstripe_Init();\r
USB_Init();\r
-\r
- /* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */\r
- OCR0A = ((F_CPU / 64) / 1000);\r
- TCCR0A = (1 << WGM01);\r
- TCCR0B = ((1 << CS01) | (1 << CS00));\r
- TIMSK0 = (1 << OCIE0A);\r
}\r
\r
/** Determines if a card has been inserted, and if so reads in each track's contents into the bit buffers\r
void EVENT_USB_Device_ConfigurationChanged(void)\r
{\r
HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface);\r
+ \r
+ USB_Device_EnableSOFEvents();\r
}\r
\r
/** Event handler for the library USB Unhandled Control Packet event. */\r
HID_Device_ProcessControlRequest(&Keyboard_HID_Interface);\r
}\r
\r
-/** Timer 0 CTC ISR, firing once each millisecond to keep track of elapsed idle time in the HID interface. */\r
-ISR(TIMER0_COMPA_vect, ISR_BLOCK)\r
+/** Event handler for the USB device Start Of Frame event. */\r
+void EVENT_USB_Device_StartOfFrame(void)\r
{\r
HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);\r
}\r
\r
void EVENT_USB_Device_ConfigurationChanged(void);\r
void EVENT_USB_Device_UnhandledControlRequest(void);\r
+ void EVENT_USB_Device_StartOfFrame(void);\r
\r
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID,\r
void* ReportData, uint16_t* ReportSize);\r