From b71ff7c8cd68209a74c8690f4d190cc634ef8fb3 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Sun, 16 Aug 2009 08:51:54 +0000 Subject: 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. --- LUFA/Drivers/USB/Class/Device/HID.h | 4 +++- LUFA/Drivers/USB/HighLevel/Events.h | 13 +++++++++++++ LUFA/Drivers/USB/HighLevel/USBInterrupt.c | 7 +++++++ LUFA/Drivers/USB/LowLevel/Device.h | 15 +++++++++++++++ LUFA/ManPages/ChangeLog.txt | 2 ++ 5 files changed, 40 insertions(+), 1 deletion(-) (limited to 'LUFA') diff --git a/LUFA/Drivers/USB/Class/Device/HID.h b/LUFA/Drivers/USB/Class/Device/HID.h index 0c141e62c..d995c09aa 100644 --- a/LUFA/Drivers/USB/Class/Device/HID.h +++ b/LUFA/Drivers/USB/Class/Device/HID.h @@ -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. */ diff --git a/LUFA/Drivers/USB/HighLevel/Events.h b/LUFA/Drivers/USB/HighLevel/Events.h index 1e638314c..4ed6537b7 100644 --- a/LUFA/Drivers/USB/HighLevel/Events.h +++ b/LUFA/Drivers/USB/HighLevel/Events.h @@ -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 diff --git a/LUFA/Drivers/USB/HighLevel/USBInterrupt.c b/LUFA/Drivers/USB/HighLevel/USBInterrupt.c index 00fe7d1dc..a8083c92a 100644 --- a/LUFA/Drivers/USB/HighLevel/USBInterrupt.c +++ b/LUFA/Drivers/USB/HighLevel/USBInterrupt.c @@ -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) diff --git a/LUFA/Drivers/USB/LowLevel/Device.h b/LUFA/Drivers/USB/LowLevel/Device.h index d66def438..f107407bf 100644 --- a/LUFA/Drivers/USB/LowLevel/Device.h +++ b/LUFA/Drivers/USB/LowLevel/Device.h @@ -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: */ diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index fd652217a..de2fa810c 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -11,6 +11,8 @@ * New: * - 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 * * Changed: * - SetIdle requests to the HID device driver with a 0 idle period (send changes only) now only affect the requested -- cgit v1.2.3