summaryrefslogtreecommitdiff
path: root/usb/device/hid-mouse
diff options
context:
space:
mode:
Diffstat (limited to 'usb/device/hid-mouse')
-rw-r--r--usb/device/hid-mouse/HIDDMouseDriver.c392
-rw-r--r--usb/device/hid-mouse/HIDDMouseDriver.h107
-rw-r--r--usb/device/hid-mouse/HIDDMouseDriverDescriptors.c385
-rw-r--r--usb/device/hid-mouse/HIDDMouseDriverDescriptors.h86
-rw-r--r--usb/device/hid-mouse/HIDDMouseInputReport.c72
-rw-r--r--usb/device/hid-mouse/HIDDMouseInputReport.h93
-rw-r--r--usb/device/hid-mouse/hid-mouse.dir544
7 files changed, 1679 insertions, 0 deletions
diff --git a/usb/device/hid-mouse/HIDDMouseDriver.c b/usb/device/hid-mouse/HIDDMouseDriver.c
new file mode 100644
index 0000000..dc2378c
--- /dev/null
+++ b/usb/device/hid-mouse/HIDDMouseDriver.c
@@ -0,0 +1,392 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include "HIDDMouseDriver.h"
+#include "HIDDMouseDriverDescriptors.h"
+#include "HIDDMouseInputReport.h"
+#include <utility/trace.h>
+#include <usb/common/core/USBGetDescriptorRequest.h>
+#include <usb/common/hid/HIDGenericDescriptor.h>
+#include <usb/common/hid/HIDDescriptor.h>
+#include <usb/common/hid/HIDGenericRequest.h>
+#include <usb/common/hid/HIDReportRequest.h>
+#include <usb/common/hid/HIDIdleRequest.h>
+#include <usb/device/core/USBD.h>
+#include <usb/device/core/USBDDriver.h>
+
+//------------------------------------------------------------------------------
+// Internal Defines
+//------------------------------------------------------------------------------
+
+/// Tag bit (Always 1)
+#define HIDDMouse_TAG (1 << 3)
+
+/// Xsign bit
+#define HIDDMouse_Xsign (1 << 4)
+
+/// Ysign bit
+#define HIDDMouse_Ysign (1 << 5)
+
+
+//------------------------------------------------------------------------------
+// Internal types
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Driver structure for an HID device implementing keyboard functionalities.
+//------------------------------------------------------------------------------
+typedef struct {
+
+ /// Standard USB device driver instance.
+ USBDDriver usbdDriver;
+ /// Idle rate (in milliseconds) of the input report.
+ unsigned char inputReportIdleRate;
+ ///
+ unsigned char inputProtocol;
+ /// Input report instance.
+ HIDDMouseInputReport inputReport;
+
+} HIDDMouseDriver;
+
+//------------------------------------------------------------------------------
+// Internal variables
+//------------------------------------------------------------------------------
+
+/// Static instance of the HID mouse device driver.
+static HIDDMouseDriver hiddMouseDriver;
+
+//------------------------------------------------------------------------------
+// Internal functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Returns the descriptor requested by the host.
+/// \param type Descriptor type.
+/// \param length Maximum number of bytes to send.
+/// \return 1 if the request has been handled by this function, otherwise 0.
+//------------------------------------------------------------------------------
+static unsigned char HIDDMouseDriver_GetDescriptor(unsigned char type,
+ unsigned char length)
+{
+ const USBConfigurationDescriptor *pConfiguration;
+ HIDDescriptor *hidDescriptors[2];
+
+ switch (type) {
+
+ case HIDGenericDescriptor_REPORT:
+ TRACE_INFO("Report ");
+
+ // Adjust length and send report descriptor
+ if (length > HIDDMouseDriverDescriptors_REPORTSIZE) {
+
+ length = HIDDMouseDriverDescriptors_REPORTSIZE;
+ }
+ USBD_Write(0, &hiddReportDescriptor, length, 0, 0);
+ break;
+
+ case HIDGenericDescriptor_HID:
+ TRACE_INFO("HID ");
+
+ // Configuration descriptor is different depending on configuration
+ if (USBD_IsHighSpeed()) {
+
+ pConfiguration =
+ hiddMouseDriver.usbdDriver.pDescriptors->pHsConfiguration;
+ }
+ else {
+
+ pConfiguration =
+ hiddMouseDriver.usbdDriver.pDescriptors->pFsConfiguration;
+ }
+
+ // Parse the device configuration to get the HID descriptor
+ USBConfigurationDescriptor_Parse(pConfiguration, 0, 0,
+ (USBGenericDescriptor **) &hidDescriptors[0]);
+
+ // Adjust length and send HID descriptor
+ if (length > sizeof(HIDDescriptor)) {
+
+ length = sizeof(HIDDescriptor);
+ }
+ USBD_Write(0, hidDescriptors[0], length, 0, 0);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+/// Sends the current Idle rate of the input report to the host.
+//------------------------------------------------------------------------------
+static void HIDDMouseDriver_GetIdle()
+{
+ TRACE_INFO("gIdle ");
+
+ USBD_Write(0, &(hiddMouseDriver.inputReportIdleRate), 1, 0, 0);
+}
+
+//------------------------------------------------------------------------------
+/// Retrieves the new idle rate of the input report from the USB host.
+/// \param idleRate New input report idle rate.
+//------------------------------------------------------------------------------
+static void HIDDMouseDriver_SetIdle(unsigned char idleRate)
+{
+ TRACE_INFO("sIdle(%d) ", idleRate);
+
+ hiddMouseDriver.inputReportIdleRate = idleRate;
+ USBD_Write(0, 0, 0, 0, 0);
+}
+
+//------------------------------------------------------------------------------
+/// Sends the requested report to the host.
+/// \param type Report type.
+/// \param length Maximum number of bytes to send.
+//------------------------------------------------------------------------------
+static void HIDDMouseDriver_GetReport(unsigned char type,
+ unsigned short length)
+{
+ TRACE_INFO("gReport ");
+
+ // Check report type
+ switch (type) {
+
+ case HIDReportRequest_INPUT:
+ TRACE_INFO("In ");
+
+ // Adjust size and send report
+ if (length > sizeof(HIDDMouseInputReport)) {
+
+ length = sizeof(HIDDMouseInputReport);
+ }
+ USBD_Write(0, // Endpoint #0
+ &(hiddMouseDriver.inputReport),
+ length,
+ 0, // No callback
+ 0);
+ break;
+
+ default:
+ USBD_Stall(0);
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Retrieves the new value of a report from the host and saves it.
+/// \param type Report type.
+/// \param length Report length.
+//------------------------------------------------------------------------------
+static void HIDDMouseDriver_SetReport(unsigned char type,
+ unsigned short length)
+{
+ TRACE_INFO("sReport ");
+
+ // Check report type
+ switch (type) {
+
+ case HIDReportRequest_INPUT:
+ // SET_REPORT requests on input reports are ignored
+ USBD_Stall(0);
+ break;
+
+ default:
+ USBD_Stall(0);
+ }
+}
+
+//------------------------------------------------------------------------------
+// Optional RequestReceived() callback re-implementation
+//------------------------------------------------------------------------------
+#if !defined(NOAUTOCALLBACK)
+
+//------------------------------------------------------------------------------
+/// Callback function when new request receivce from host
+/// \param request Pointer to the USBGenericRequest instance
+//------------------------------------------------------------------------------
+void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
+{
+ HIDDMouseDriver_RequestHandler(request);
+}
+
+#endif
+
+//------------------------------------------------------------------------------
+// ConfigurationChanged() callback re-implementation
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Callback function when configureation changed
+/// \param cfgnum New configuration number
+//------------------------------------------------------------------------------
+void USBDDriverCallbacks_ConfigurationChanged(unsigned char cfgnum)
+{
+ if (cfgnum > 0) {
+
+ }
+}
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Initializes the HID Mouse %device driver.
+//------------------------------------------------------------------------------
+void HIDDMouseDriver_Initialize(void)
+{
+ hiddMouseDriver.inputReportIdleRate = 0;
+ HIDDMouseInputReport_Initialize(&(hiddMouseDriver.inputReport));
+ USBDDriver_Initialize(&(hiddMouseDriver.usbdDriver),
+ &hiddMouseDriverDescriptors,
+ 0); // Multiple interface settings not supported
+ USBD_Init();
+}
+
+//------------------------------------------------------------------------------
+/// Handles HID-specific SETUP request sent by the host.
+/// \param request Pointer to a USBGenericRequest instance
+//------------------------------------------------------------------------------
+void HIDDMouseDriver_RequestHandler(const USBGenericRequest *request)
+{
+ TRACE_INFO("NewReq ");
+
+ // Check if this is a standard request
+ if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) {
+
+ // This is a standard request
+ switch (USBGenericRequest_GetRequest(request)) {
+
+ case USBGenericRequest_GETDESCRIPTOR:
+ // Check if this is a HID descriptor, otherwise forward it to
+ // the standard driver
+ if (!HIDDMouseDriver_GetDescriptor(
+ USBGetDescriptorRequest_GetDescriptorType(request),
+ USBGenericRequest_GetLength(request))) {
+
+ USBDDriver_RequestHandler(&(hiddMouseDriver.usbdDriver),
+ request);
+ }
+ break;
+
+ default:
+ USBDDriver_RequestHandler(&(hiddMouseDriver.usbdDriver),
+ request);
+ }
+ }
+ // Check if this is a class request
+ else if (USBGenericRequest_GetType(request) == USBGenericRequest_CLASS) {
+
+ // This is a class-specific request
+ switch (USBGenericRequest_GetRequest(request)) {
+
+ case HIDGenericRequest_GETIDLE:
+ HIDDMouseDriver_GetIdle();
+ break;
+
+ case HIDGenericRequest_SETIDLE:
+ HIDDMouseDriver_SetIdle(HIDIdleRequest_GetIdleRate(request));
+ break;
+
+ case HIDGenericRequest_GETREPORT:
+ HIDDMouseDriver_GetReport(
+ HIDReportRequest_GetReportType(request),
+ USBGenericRequest_GetLength(request));
+ break;
+
+ case HIDGenericRequest_SETREPORT:
+ HIDDMouseDriver_SetReport(
+ HIDReportRequest_GetReportType(request),
+ USBGenericRequest_GetLength(request));
+ break;
+
+ case HIDGenericRequest_GETPROTOCOL:
+ USBD_Write(0, &hiddMouseDriver.inputProtocol, 1, 0, 0);
+ break;
+
+ case HIDGenericRequest_SETPROTOCOL:
+ hiddMouseDriver.inputProtocol = request->wValue;
+ USBD_Write(0, 0, 0, 0, 0);
+ break;
+
+ default:
+ TRACE_WARNING(
+ "HIDDMouseDriver_RequestHandler: Unknown request 0x%02X\n\r",
+ USBGenericRequest_GetRequest(request));
+ USBD_Stall(0);
+ }
+ }
+ else {
+
+ // Vendor request ?
+ USBD_Stall(0);
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Update the Mouse button status and location changes via input report
+/// to host
+/// \param bmButtons Bit map of the button status
+/// \param deltaX Movment on X direction
+/// \param deltaY Movment on Y direction
+//------------------------------------------------------------------------------
+unsigned char HIDDMouseDriver_ChangePoints(unsigned char bmButtons,
+ signed char deltaX,
+ signed char deltaY)
+{
+ hiddMouseDriver.inputReport.bmButtons = (bmButtons & 0x07)
+ | HIDDMouse_TAG;
+ hiddMouseDriver.inputReport.bX = deltaX;
+ hiddMouseDriver.inputReport.bY = deltaY;
+ // Send input report through the interrupt IN endpoint
+ return USBD_Write(HIDDMouseDriverDescriptors_INTERRUPTIN,
+ &(hiddMouseDriver.inputReport),
+ sizeof(HIDDMouseInputReport),
+ 0,
+ 0);
+}
+
+//------------------------------------------------------------------------------
+/// Starts a remote wake-up sequence if the host has explicitely enabled it
+/// by sending the appropriate SET_FEATURE request.
+//------------------------------------------------------------------------------
+void HIDDMouseDriver_RemoteWakeUp(void)
+{
+ // Remote wake-up has been enabled
+ if (USBDDriver_IsRemoteWakeUpEnabled(&(hiddMouseDriver.usbdDriver))) {
+
+ USBD_RemoteWakeUp();
+ }
+}
+
diff --git a/usb/device/hid-mouse/HIDDMouseDriver.h b/usb/device/hid-mouse/HIDDMouseDriver.h
new file mode 100644
index 0000000..94dac3a
--- /dev/null
+++ b/usb/device/hid-mouse/HIDDMouseDriver.h
@@ -0,0 +1,107 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+/**
+ \unit
+
+ !!!Purpose
+
+ Definition of methods for using a HID mouse device driver.
+
+ !!!Usage
+
+ -# Re-implement the USBDCallbacks_RequestReceived callback to forward
+ requests to HIDDMouseDriver_RequestHandler. This is done
+ automatically unless the NOAUTOCALLBACK symbol is defined during
+ compilation.
+ -# Initialize the driver using HIDDMouseDriver_Initialize. The
+ USB driver is automatically initialized by this method.
+ -# Call the HIDDMouseDriver_ChangePoints method when one or more
+ keys are pressed/released.
+*/
+
+#ifndef HIDDKEYBOARDDRIVER_H
+#define HIDDKEYBOARDDRIVER_H
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <usb/common/core/USBGenericRequest.h>
+
+//------------------------------------------------------------------------------
+// Definitions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// \page "HID Mouse Button bitmaps"
+/// ...
+/// !Bits
+/// - HIDDMouse_LEFT_BUTTON
+/// - HIDDMouse_RIGHT_BUTTON
+/// - HIDDMouse_MIDDLE_BUTTON
+
+/// Left mouse button
+#define HIDDMouse_LEFT_BUTTON (1 << 0)
+
+/// Right mouse button
+#define HIDDMouse_RIGHT_BUTTON (1 << 1)
+
+/// Middle mouse button
+#define HIDDMouse_MIDDLE_BUTTON (1 << 2)
+
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+/*
+ Function: HIDDMouseDriver_Initialize
+ Initializes the HID keyboard device driver.
+*/
+extern void HIDDMouseDriver_Initialize(void);
+
+/*
+ Function: HIDDMouseDriver_RequestHandler
+ Handles HID-specific SETUP request sent by the host.
+
+ Parameters:
+ request - Pointer to a USBGenericRequest instance.
+*/
+extern void HIDDMouseDriver_RequestHandler(const USBGenericRequest *request);
+
+extern unsigned char HIDDMouseDriver_ChangePoints(unsigned char bmButtons,
+ signed char deltaX,
+ signed char deltaY);
+
+extern void HIDDMouseDriver_RemoteWakeUp(void);
+
+#endif //#ifndef HIDDKEYBOARDDRIVER_H
+
diff --git a/usb/device/hid-mouse/HIDDMouseDriverDescriptors.c b/usb/device/hid-mouse/HIDDMouseDriverDescriptors.c
new file mode 100644
index 0000000..6a66d83
--- /dev/null
+++ b/usb/device/hid-mouse/HIDDMouseDriverDescriptors.c
@@ -0,0 +1,385 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+/*
+ Title: HIDDMouseDriverDescriptors
+
+ About: Purpose
+ Declaration of the descriptors used by the HID device keyboard driver.
+*/
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include "HIDDMouseDriverDescriptors.h"
+#include "HIDDMouseInputReport.h"
+#include <board.h>
+#include <usb/common/core/USBDeviceDescriptor.h>
+#include <usb/common/core/USBConfigurationDescriptor.h>
+#include <usb/common/core/USBInterfaceDescriptor.h>
+#include <usb/common/core/USBEndpointDescriptor.h>
+#include <usb/common/core/USBStringDescriptor.h>
+#include <usb/common/hid/HIDGenericDescriptor.h>
+#include <usb/common/hid/HIDDeviceDescriptor.h>
+#include <usb/common/hid/HIDInterfaceDescriptor.h>
+#include <usb/common/hid/HIDDescriptor.h>
+#include <usb/common/hid/HIDReport.h>
+#include <usb/common/hid/HIDGenericDesktop.h>
+#include <usb/common/hid/HIDLeds.h>
+#include <usb/common/hid/HIDButton.h>
+#include <usb/device/core/USBDDriverDescriptors.h>
+
+//------------------------------------------------------------------------------
+// Definitions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// \page "HID Mouse Device Descriptor IDs"
+/// ...
+///
+/// !IDs
+/// - HIDDMouseDriverDescriptors_PRODUCTID
+/// - HIDDMouseDriverDescriptors_VENDORID
+/// - HIDDMouseDriverDescriptors_RELEASE
+
+/// Device product ID.
+#define HIDDMouseDriverDescriptors_PRODUCTID 0x6200
+/// Device vendor ID.
+#define HIDDMouseDriverDescriptors_VENDORID 0x03EB
+/// Device release number.
+#define HIDDMouseDriverDescriptors_RELEASE 0x0100
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Internal types
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// List of descriptors that make up the configuration descriptors of a
+/// %device using the HID Mouse driver.
+//------------------------------------------------------------------------------
+typedef struct {
+
+ /// Configuration descriptor.
+ USBConfigurationDescriptor configuration;
+ /// Interface descriptor.
+ USBInterfaceDescriptor interface;
+ /// HID descriptor.
+ HIDDescriptor hid;
+ /// Interrupt IN endpoint descriptor.
+ USBEndpointDescriptor interruptIn;
+
+} __attribute__ ((packed)) HIDDMouseDriverConfigurationDescriptors;
+
+//------------------------------------------------------------------------------
+// Internal variables
+//------------------------------------------------------------------------------
+
+/// Device descriptor.
+static const USBDeviceDescriptor deviceDescriptor = {
+
+ sizeof(USBDeviceDescriptor),
+ USBGenericDescriptor_DEVICE,
+ USBDeviceDescriptor_USB2_00,
+ HIDDeviceDescriptor_CLASS,
+ HIDDeviceDescriptor_SUBCLASS,
+ HIDDeviceDescriptor_PROTOCOL,
+ CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0),
+ HIDDMouseDriverDescriptors_VENDORID,
+ HIDDMouseDriverDescriptors_PRODUCTID,
+ HIDDMouseDriverDescriptors_RELEASE,
+ 1, // Index of manufacturer description
+ 2, // Index of product description
+ 3, // Index of serial number description
+ 1 // One possible configuration
+};
+
+#if defined (CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS)
+/// Device qualifier descriptor (high-speed only).
+static const USBDeviceQualifierDescriptor qualifierDescriptor = {
+
+ sizeof(USBDeviceQualifierDescriptor),
+ USBGenericDescriptor_DEVICEQUALIFIER,
+ HIDDeviceDescriptor_CLASS,
+ HIDDeviceDescriptor_SUBCLASS,
+ HIDDeviceDescriptor_PROTOCOL,
+ CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0),
+ 1, // One possible configuration
+ 0 // Reserved
+};
+#endif
+
+/// Configuration descriptor.
+static const HIDDMouseDriverConfigurationDescriptors configurationDescriptors = {
+
+ // Configuration descriptor
+ {
+ sizeof(USBConfigurationDescriptor),
+ USBGenericDescriptor_CONFIGURATION,
+ sizeof(HIDDMouseDriverConfigurationDescriptors),
+ 1, // One interface in this configuration
+ 1, // This is configuration #1
+ 0, // No associated string descriptor
+ BOARD_USB_BMATTRIBUTES,
+ USBConfigurationDescriptor_POWER(100)
+ },
+ // Interface descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ 0, // This is interface #0
+ 0, // This is alternate setting #0
+ 1, // One endpoints used
+ HIDInterfaceDescriptor_CLASS,
+ HIDInterfaceDescriptor_SUBCLASS_NONE,
+ HIDInterfaceDescriptor_PROTOCOL_MOUSE,
+ 0 // No associated string descriptor
+ },
+ // HID descriptor
+ {
+ sizeof(HIDDescriptor),
+ HIDGenericDescriptor_HID,
+ HIDDescriptor_HID1_11,
+ 0, // Device is not localized, no country code
+ 1, // One HID-specific descriptor (apart from this one)
+ HIDGenericDescriptor_REPORT,
+ HIDDMouseDriverDescriptors_REPORTSIZE
+ },
+ // Interrupt IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_IN,
+ HIDDMouseDriverDescriptors_INTERRUPTIN),
+ USBEndpointDescriptor_INTERRUPT,
+ sizeof(HIDDMouseInputReport),
+ HIDDMouseDriverDescriptors_INTERRUPTIN_POLLING
+ }
+};
+
+#if defined (CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS)
+/// Other-speed configuration descriptor.
+static const HIDDMouseDriverConfigurationDescriptors otherSpeedDescriptors = {
+
+ // Configuration descriptor
+ {
+ sizeof(USBConfigurationDescriptor),
+ USBGenericDescriptor_OTHERSPEEDCONFIGURATION,
+ sizeof(HIDDMouseDriverConfigurationDescriptors),
+ 1, // One interface in this configuration
+ 1, // This is configuration #1
+ 0, // No associated string descriptor
+ BOARD_USB_BMATTRIBUTES,
+ USBConfigurationDescriptor_POWER(100)
+ },
+ // Interface descriptor
+ {
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ 0, // This is interface #0
+ 0, // This is alternate setting #0
+ 2, // Two endpoints used
+ HIDInterfaceDescriptor_CLASS,
+ HIDInterfaceDescriptor_SUBCLASS_NONE,
+ HIDInterfaceDescriptor_PROTOCOL_MOUSE,
+ 0 // No associated string descriptor
+ },
+ // HID descriptor
+ {
+ sizeof(HIDDescriptor),
+ HIDGenericDescriptor_HID,
+ HIDDescriptor_HID1_11,
+ 0, // Device is not localized, no country code
+ 1, // One HID-specific descriptor (apart from this one)
+ HIDGenericDescriptor_REPORT,
+ HIDDMouseDriverDescriptors_REPORTSIZE
+ },
+ // Interrupt IN endpoint descriptor
+ {
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_IN,
+ HIDDMouseDriverDescriptors_INTERRUPTIN),
+ USBEndpointDescriptor_INTERRUPT,
+ sizeof(HIDDMouseInputReport),
+ HIDDMouseDriverDescriptors_INTERRUPTIN_POLLING
+ }
+};
+#endif
+
+/*
+ Variables: String descriptors
+ languageIdDescriptor - Language ID string descriptor.
+ manufacturerDescriptor - Manufacturer name.
+ productDescriptor - Product name.
+ serialNumberDescriptor - Product serial number.
+ stringDescriptors - Array of pointers to string descriptors.
+*/
+static const unsigned char languageIdDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(1),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_ENGLISH_US
+};
+
+static const unsigned char manufacturerDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(5),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_UNICODE('A'),
+ USBStringDescriptor_UNICODE('T'),
+ USBStringDescriptor_UNICODE('M'),
+ USBStringDescriptor_UNICODE('E'),
+ USBStringDescriptor_UNICODE('L')
+};
+
+static const unsigned char productDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(19),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_UNICODE('A'),
+ USBStringDescriptor_UNICODE('T'),
+ USBStringDescriptor_UNICODE('M'),
+ USBStringDescriptor_UNICODE('E'),
+ USBStringDescriptor_UNICODE('L'),
+ USBStringDescriptor_UNICODE(' '),
+ USBStringDescriptor_UNICODE('A'),
+ USBStringDescriptor_UNICODE('T'),
+ USBStringDescriptor_UNICODE('9'),
+ USBStringDescriptor_UNICODE('1'),
+ USBStringDescriptor_UNICODE(' '),
+ USBStringDescriptor_UNICODE('H'),
+ USBStringDescriptor_UNICODE('I'),
+ USBStringDescriptor_UNICODE('D'),
+ USBStringDescriptor_UNICODE(' '),
+ USBStringDescriptor_UNICODE('M'),
+ USBStringDescriptor_UNICODE('O'),
+ USBStringDescriptor_UNICODE('U'),
+ USBStringDescriptor_UNICODE('S'),
+ USBStringDescriptor_UNICODE('E'),
+};
+
+static const unsigned char serialNumberDescriptor[] = {
+
+ USBStringDescriptor_LENGTH(12),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_UNICODE('0'),
+ USBStringDescriptor_UNICODE('1'),
+ USBStringDescriptor_UNICODE('2'),
+ USBStringDescriptor_UNICODE('3'),
+ USBStringDescriptor_UNICODE('4'),
+ USBStringDescriptor_UNICODE('5'),
+ USBStringDescriptor_UNICODE('6'),
+ USBStringDescriptor_UNICODE('7'),
+ USBStringDescriptor_UNICODE('8'),
+ USBStringDescriptor_UNICODE('9'),
+ USBStringDescriptor_UNICODE('A'),
+ USBStringDescriptor_UNICODE('F')
+};
+
+static const unsigned char *stringDescriptors[] = {
+
+ languageIdDescriptor,
+ manufacturerDescriptor,
+ productDescriptor,
+ serialNumberDescriptor
+};
+
+//------------------------------------------------------------------------------
+// Exported variables
+//------------------------------------------------------------------------------
+
+/// List of descriptors used by the HID keyboard driver.
+USBDDriverDescriptors hiddMouseDriverDescriptors = {
+
+ &deviceDescriptor,
+ (USBConfigurationDescriptor *) &configurationDescriptors,
+#if defined (CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS)
+ &qualifierDescriptor,
+ (USBConfigurationDescriptor *) &otherSpeedDescriptors,
+ &deviceDescriptor,
+ (USBConfigurationDescriptor *) &configurationDescriptors,
+ &qualifierDescriptor,
+ (USBConfigurationDescriptor *) &otherSpeedDescriptors,
+#else
+ 0, // No full-speed device qualifier descriptor
+ 0, // No full-speed other speed configuration
+ 0, // No high-speed device descriptor
+ 0, // No high-speed configuration descriptor
+ 0, // No high-speed device qualifier descriptor
+ 0, // No high-speed other speed configuration descriptor
+#endif
+ stringDescriptors,
+ 4 // Four string descriptors in list
+};
+
+/// Report descriptor used by the driver.
+const unsigned char hiddReportDescriptor[] = {
+
+ // Global Usage Page
+ HIDReport_GLOBAL_USAGEPAGE + 1, HIDGenericDesktop_PAGEID,
+ // Collection: Application
+ HIDReport_LOCAL_USAGE + 1, HIDGenericDesktop_MOUSE,
+ HIDReport_COLLECTION + 1, HIDReport_COLLECTION_APPLICATION,
+ // Physical collection: Pointer
+ HIDReport_LOCAL_USAGE + 1, HIDGenericDesktop_POINTER,
+ HIDReport_COLLECTION + 1, HIDReport_COLLECTION_PHYSICAL,
+
+ // Input report: buttons
+ HIDReport_GLOBAL_USAGEPAGE + 1, HIDButton_PAGEID,
+ HIDReport_GLOBAL_REPORTCOUNT + 1, 3,
+ HIDReport_GLOBAL_REPORTSIZE + 1, 1,
+ HIDReport_LOCAL_USAGEMINIMUM + 1, 1,
+ HIDReport_LOCAL_USAGEMAXIMUM + 1, 3,
+ HIDReport_GLOBAL_LOGICALMINIMUM + 1, 0,
+ HIDReport_GLOBAL_LOGICALMAXIMUM + 1, 1,
+ HIDReport_INPUT + 1, HIDReport_VARIABLE, // 3 button bits
+
+ // Input report: padding
+ HIDReport_GLOBAL_REPORTCOUNT + 1, 1,
+ HIDReport_GLOBAL_REPORTSIZE + 1, 5,
+ HIDReport_INPUT + 1, HIDReport_CONSTANT, // 5 bit padding
+
+ // Input report: pointer
+ HIDReport_GLOBAL_USAGEPAGE + 1, HIDGenericDesktop_PAGEID,
+ HIDReport_GLOBAL_REPORTSIZE + 1, 8,
+ HIDReport_GLOBAL_REPORTCOUNT + 1, 2,
+ HIDReport_LOCAL_USAGE + 1, HIDGenericDesktop_X,
+ HIDReport_LOCAL_USAGE + 1, HIDGenericDesktop_Y,
+ HIDReport_GLOBAL_LOGICALMINIMUM + 1, (unsigned char) -127,
+ HIDReport_GLOBAL_LOGICALMAXIMUM + 1, 127,
+ HIDReport_INPUT + 1, HIDReport_VARIABLE | HIDReport_RELATIVE,
+
+ HIDReport_ENDCOLLECTION,
+ HIDReport_ENDCOLLECTION
+};
+
diff --git a/usb/device/hid-mouse/HIDDMouseDriverDescriptors.h b/usb/device/hid-mouse/HIDDMouseDriverDescriptors.h
new file mode 100644
index 0000000..4f27dec
--- /dev/null
+++ b/usb/device/hid-mouse/HIDDMouseDriverDescriptors.h
@@ -0,0 +1,86 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+/**
+ \unit
+
+ !!!Purpose
+
+ Definitions of the descriptors required by the HID device keyboard
+ driver.
+
+ !!!Usage
+ -# Use the hiddMouseDriverDescriptors variable to initialize a
+ USBDDriver instance.
+ -# Send hiddReportDescriptor to the host when a GET_DESCRIPTOR request
+ for the report descriptor is received.
+*/
+
+#ifndef HIDDKEYBOARDDRIVERDESCRIPTORS_H
+#define HIDDKEYBOARDDRIVERDESCRIPTORS_H
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <usb/device/core/USBDDriverDescriptors.h>
+
+//------------------------------------------------------------------------------
+// Definitions
+//------------------------------------------------------------------------------
+/*
+ Constants: Endpoints
+ HIDDMouseDriverDescriptors_INTERRUPTIN - Interrupt IN endpoint number.
+ HIDDMouseDriverDescriptors_INTERRUPTIN_POLLING - Interrupt IN endpoint
+ polling rate (in milliseconds).
+*/
+#define HIDDMouseDriverDescriptors_INTERRUPTIN 1
+#define HIDDMouseDriverDescriptors_INTERRUPTIN_POLLING 10
+
+/*
+ Constants: Report descriptor
+ HIDDMouseDriverDescriptors_REPORTSIZE - Size of the report descriptor
+ in bytes.
+*/
+#define HIDDMouseDriverDescriptors_REPORTSIZE 50
+
+//------------------------------------------------------------------------------
+// Exported variables
+//------------------------------------------------------------------------------
+/*
+ Variables: HID keyboard driver descriptors
+ hiddMouseDriverDescriptors - List of descriptors used by the HID
+ keyboard driver.
+ hiddReportDescriptor - Report descriptor used by the driver.
+*/
+extern USBDDriverDescriptors hiddMouseDriverDescriptors;
+extern const unsigned char hiddReportDescriptor[];
+
+#endif //#ifndef HIDDKEYBOARDDRIVERDESCRIPTORS_H
+
diff --git a/usb/device/hid-mouse/HIDDMouseInputReport.c b/usb/device/hid-mouse/HIDDMouseInputReport.c
new file mode 100644
index 0000000..1c1c979
--- /dev/null
+++ b/usb/device/hid-mouse/HIDDMouseInputReport.c
@@ -0,0 +1,72 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+/*
+ Title: HIDDMouseInputReport implementation
+
+ About: Purpose
+ Implementation of the HIDDMouseInputReport class.
+*/
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include "HIDDMouseInputReport.h"
+#include "HIDDMouseDriverDescriptors.h"
+#include <utility/assert.h>
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Initializes a mouse input report instance.
+/// \param report Pointer to a HIDDMouseInputReport instance.
+//------------------------------------------------------------------------------
+void HIDDMouseInputReport_Initialize(HIDDMouseInputReport *report)
+{
+ report->bmButtons = 0;
+ report->bX = 0;
+ report->bY = 0;
+}
+
+/*
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+void HIDDMouseInputReport_UpdateButtons(HIDDMouseInputReport *report)
+{
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+void HIDDMouseInputReport_UpdateAxis(HIDDMouseInputReport *report)
+{
+}
+*/
diff --git a/usb/device/hid-mouse/HIDDMouseInputReport.h b/usb/device/hid-mouse/HIDDMouseInputReport.h
new file mode 100644
index 0000000..ca074fd
--- /dev/null
+++ b/usb/device/hid-mouse/HIDDMouseInputReport.h
@@ -0,0 +1,93 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+/**
+ \unit
+
+ !!!Purpose
+
+ Class for manipulating HID Mouse input reports.
+
+ !!!Usage
+
+ -# Initialize a newly created input report with
+ HIDDMouseInputReport_Initialize
+*/
+
+#ifndef HIDDKEYBOARDINPUTREPORT_H
+#define HIDDKEYBOARDINPUTREPORT_H
+
+//------------------------------------------------------------------------------
+// Definitions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// \page "HID Mouse Keys"
+
+/// Mouse Left Click Button
+#define HIDDMouseInputReport_LEFT_BUTTON (1 << 0)
+/// Mouse Right Click Button
+#define HIDDMouseInputReport_RIGHT_BUTTON (1 << 1)
+/// Mouse Middle Button
+#define HIDDMouseInputReport_MIDDLE_BUTTON (1 << 2)
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Types
+//------------------------------------------------------------------------------
+
+#ifdef __ICCARM__ // IAR
+#pragma pack(1) // IAR
+#define __attribute__(...) // IAR
+#endif // IAR
+
+//------------------------------------------------------------------------------
+/// HID input report structure used by the Mouse driver to notify the
+/// host of pressed keys.
+//------------------------------------------------------------------------------
+typedef struct {
+
+ unsigned char bmButtons; /// Bitmap state of three mouse buttons.
+ signed char bX; /// Pointer displacement along the X axis.
+ signed char bY; /// Pointer displacement along the Y axis.
+
+} __attribute__ ((packed)) HIDDMouseInputReport; // GCC
+
+#ifdef __ICCARM__ // IAR
+#pragma pack() // IAR
+#endif // IAR
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+extern void HIDDMouseInputReport_Initialize(HIDDMouseInputReport *report);
+
+#endif //#ifndef HIDDKEYBOARDINPUTREPORT_H
+
diff --git a/usb/device/hid-mouse/hid-mouse.dir b/usb/device/hid-mouse/hid-mouse.dir
new file mode 100644
index 0000000..9dd733b
--- /dev/null
+++ b/usb/device/hid-mouse/hid-mouse.dir
@@ -0,0 +1,544 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \dir
+///
+/// !!!Purpose
+///
+/// This directory provides definitions, structs and functions for a USB HID
+/// %device - USB HID Mouse driver, to implement an USB Mouse %device.
+///
+/// !!!Contents
+///
+/// There are three things for the implement of the USB HID Mouse driver:
+/// - Implement the USB HID driver structs and functions for the %device,
+/// to initialize, to handle HID-specific requests and dispach
+/// standard requests in USBD callbacks, to read/write through assigned USB
+/// endpoints,
+/// - Create the HID Mouse device's descriptors that should be passed to
+/// the USBDDriver instance on initialization, so that the host can
+/// recognize the %device as a USB Mouse %device.
+/// - Implement methods to update the Mouse keys status, so that host can
+/// get it through USB.
+///
+/// For more information about what a particular group contains, please refer to
+/// "USB HID Mouse".
+//------------------------------------------------------------------------------
+
+/**
+ \page "USB HID Mouse"
+ This page describes how to use the "AT91 USB device framework" to produce a USB
+ HID Mouse driver, which appears as a USB Mouse on host.
+
+ Details about the USB and the HID class can be found in the }USB specification
+ 2.0} and the }HID specification 1.11}, respectively.
+
+ !!!References
+ - "AT91 USB device framework"
+ - "USB Device Enumeration"
+ - <a href="http://www.usb.org/developers/docs/usb_20_040908.zip">
+ Universal Serial Bus Revision 2.0 specification
+ </a> (.zip file format, size 9.80 MB)
+ - <a href="http://www.usb.org/developers/devclass_docs/HID1_11.pdf">
+ Device Class Definition for HID 1.11</a>
+ - <a href="http://www.usb.org/developers/devclass_docs/Hut1_12.pdf">
+ HID Usage Tables 1.12</a>
+
+ !!!HID Basic
+ See "USB HID Basic".
+
+ !!!Architecture
+ See "USB Device Framework Architecture".
+
+ !!!Descriptors
+
+ ...
+
+ !!Device Descriptor
+ The Device descriptor of an HID %device is very basic, since the HID class
+ code is only specified at the Interface level. Thus, it only contains
+ standard values, as shown below:
+\code
+static const USBDeviceDescriptor deviceDescriptor = {
+
+ sizeof(USBDeviceDescriptor),
+ USBGenericDescriptor_DEVICE,
+ USBDeviceDescriptor_USB2_00,
+ HIDDeviceDescriptor_CLASS,
+ HIDDeviceDescriptor_SUBCLASS,
+ HIDDeviceDescriptor_PROTOCOL,
+ BOARD_USB_ENDPOINTS_MAXPACKETSIZE(0),
+ HIDDMouseDriverDescriptors_VENDORID,
+ HIDDMouseDriverDescriptors_PRODUCTID,
+ HIDDMouseDriverDescriptors_RELEASE,
+ 1, // Index of manufacturer description
+ 2, // Index of product description
+ 3, // Index of serial number description
+ 1 // One possible configuration
+};
+\endcode
+ Note that the Vendor ID is a special value attributed by the USB-IF
+ organization. The product ID can be chosen freely by the vendor.
+
+ !!Configuration Descriptor
+ Since one interface is required by the HID specification, this must be
+ specified in the Configuration descriptor. There is no other value of
+ interest to put here.
+\code
+// Configuration descriptor
+{
+ sizeof(USBConfigurationDescriptor),
+ USBGenericDescriptor_CONFIGURATION,
+ sizeof(HIDDMouseDriverConfigurationDescriptors),
+ 1, // One interface in this configuration
+ 1, // This is configuration #1
+ 0, // No associated string descriptor
+ BOARD_USB_BMATTRIBUTES,
+ USBConfigurationDescriptor_POWER(100)
+},
+\endcode
+ When the Configuration descriptor is requested by the host (by using the
+ GET_DESCRIPTOR command), the %device must also sent all the related
+ descriptors, i.e. Interface, Endpoint and Class-Specific descriptors. It is
+ convenient to create a single structure to hold all this data, for sending
+ everything in one chunk. In the example software, a
+ HIDDMouseDriverConfigurationDescriptors structure has been declared for
+ that.
+
+ !!HID Class Interface Descriptor
+ Since a Mouse %device needs to transmit as well as receive data, two
+ Interrupt (IN & OUT) endpoints are needed. This must be indicated in the
+ Interface descriptor. Conversely to the mouse example, the Boot protocol is
+ not implemented here, since there are more constraints on a Mouse %device.
+\code
+// Interface descriptor
+{
+ sizeof(USBInterfaceDescriptor),
+ USBGenericDescriptor_INTERFACE,
+ 0, // This is interface #0
+ 0, // This is alternate setting #0
+ 2, // Two endpoints used
+ HIDInterfaceDescriptor_CLASS,
+ HIDInterfaceDescriptor_SUBCLASS_NONE,
+ HIDInterfaceDescriptor_PROTOCOL_NONE,
+ 0 // No associated string descriptor
+},
+\endcode
+
+ !!HID Descriptor
+ While a HID Mouse produces two different reports, one Input and one Output,
+ only one Report descriptor can be used to describe them. Since having Physical
+ descriptors is also useless for a Mouse, there will only be one HID class
+ descriptor specified here.
+
+ For a Mouse, the }bCountryCode} field can be used to specify the language
+ of the key caps. As this is optional, it is simply set to 00h in the example:
+\code
+// HID descriptor
+{
+ sizeof(HIDDescriptor),
+ HIDGenericDescriptor_HID,
+ HIDDescriptor_HID1_11,
+ 0, // Device is not localized, no country code
+ 1, // One HID-specific descriptor (apart from this one)
+ HIDGenericDescriptor_REPORT,
+ HIDDMouseDriverDescriptors_REPORTSIZE
+},
+\endcode
+
+ !!Report Descriptor
+ Two current reports are defined in the Report descriptor. The first one is
+ used to notify the host of which keys are pressed, with both modifier keys
+ (alt, ctrl, etc.) and alphanumeric keys. The second report is necessary for
+ the host to send the LED (num lock, caps lock, etc.) states.
+
+ The Report descriptor starts with the global %device functionality, described
+ with a #Usage Page# and a #Usage# items:
+\code
+const unsigned char hiddReportDescriptor[] = {
+
+ HIDReport_GLOBAL_USAGEPAGE + 1, HIDGenericDesktop_PAGEID,
+ HIDReport_LOCAL_USAGE + 1, HIDGenericDesktop_Mouse,
+\endcode
+
+ As in the mouse example, the }Generic Desktop} page is used. This time, the
+ specific usage is the }Mouse} one. An Application collection is then
+ defined to group the reports together:
+\code
+ HIDReport_COLLECTION + 1, HIDReport_COLLECTION_APPLICATION,
+\endcode
+
+ The first report to be defined is the modifier keys. They are represented as a
+ bitmap field, indicating whether or not each key is pressed. A single byte is
+ used to map keys \#224-231 defined in the }HID Usage Tables} document:
+ LeftControl, LeftShift, LeftAlt, LeftGUI (e.g. Windows key),
+ RightControl, RightShift, RightAlt and RightGUI.
+ The }Keypad} usage page must be specified for this report, and since this is a
+ bitmap value, the data is flagged as }Variable}:
+\code
+ // Input report: modifier keys
+ HIDReport_GLOBAL_REPORTSIZE + 1, 1,
+ HIDReport_GLOBAL_REPORTCOUNT + 1, 8,
+ HIDReport_GLOBAL_USAGEPAGE + 1, HIDKeypad_PAGEID,
+ HIDReport_LOCAL_USAGEMINIMUM + 1,
+ HIDDMouseDriverDescriptors_FIRSTMODIFIERKEY,
+ HIDReport_LOCAL_USAGEMAXIMUM + 1,
+ HIDDMouseDriverDescriptors_LASTMODIFIERKEY,
+ HIDReport_GLOBAL_LOGICALMINIMUM + 1, 0,
+ HIDReport_GLOBAL_LOGICALMAXIMUM + 1, 1,
+ HIDReport_INPUT + 1, HIDReport_VARIABLE,
+\endcode
+
+ Then, the actual alphanumeric key report is described. This is done by
+ defining several bytes of data, one for each pressed key. In the example,
+ up to three keys can be pressed at the same time (and detected) by the user.
+ Once again, the usage page is set to }Keypad}. This time however, the data
+ must be specified as an }Array}, since the same control (the keypad) produces
+ several values:
+\code
+ // Input report: standard keys
+ HIDReport_GLOBAL_REPORTCOUNT + 1, 3,
+ HIDReport_GLOBAL_REPORTSIZE + 1, 8,
+ HIDReport_GLOBAL_LOGICALMINIMUM + 1,
+ HIDDMouseDriverDescriptors_FIRSTSTANDARDKEY,
+ HIDReport_GLOBAL_LOGICALMAXIMUM + 1,
+ HIDDMouseDriverDescriptors_LASTSTANDARDKEY,
+ HIDReport_GLOBAL_USAGEPAGE + 1, HIDKeypad_PAGEID,
+ HIDReport_LOCAL_USAGEMINIMUM + 1,
+ HIDDMouseDriverDescriptors_FIRSTSTANDARDKEY,
+ HIDReport_LOCAL_USAGEMAXIMUM + 1,
+ HIDDMouseDriverDescriptors_LASTSTANDARDKEY,
+ HIDReport_INPUT + 1, 0 /* Data array */,
+\endcode
+
+ The LED array is then defined, with the associated usage page. The Report
+ descriptor is formatted in this order to avoid redefining unchanged }Global}
+ items, in order to save memory. This time again, the LED status is reported as
+ a bitmap field. Three LEDs are used here: Num Lock, Caps Lock and Scroll Lock
+ (IDs 01h to 03h). It is important to note that this is an #Output# report:
+\code
+ // Output report: LEDs
+ HIDReport_GLOBAL_REPORTCOUNT + 1, 3,
+ HIDReport_GLOBAL_REPORTSIZE + 1, 1,
+ HIDReport_GLOBAL_USAGEPAGE + 1, HIDLeds_PAGEID,
+ HIDReport_GLOBAL_LOGICALMINIMUM + 1, 0,
+ HIDReport_GLOBAL_LOGICALMAXIMUM + 1, 1,
+ HIDReport_LOCAL_USAGEMINIMUM + 1, HIDLeds_NUMLOCK,
+ HIDReport_LOCAL_USAGEMAXIMUM + 1, HIDLeds_SCROLLLOCK,
+ HIDReport_OUTPUT + 1, HIDReport_VARIABLE,
+\endcode
+
+ Since the previous report only contains 3 bits, the data must be padded to a
+ multiple of one byte. This is done by using constant Output data, as follows:
+\code
+ // Output report: padding
+ HIDReport_GLOBAL_REPORTCOUNT + 1, 1,
+ HIDReport_GLOBAL_REPORTSIZE + 1, 5,
+ HIDReport_OUTPUT + 1, HIDReport_CONSTANT,
+\endcode
+
+ The last item, }End Collection}, is necessary to close the previously opened
+ }Application Collection}.
+\code
+ HIDReport_ENDCOLLECTION
+};
+\endcode
+
+ The Input and Output reports defined by this descriptor can be modeled by the
+ following structures:
+\code
+// HID Input Report
+typedef struct {
+
+ // State of modifier keys.
+ unsigned char bmModifierKeys:8;
+ // Key codes of pressed keys.
+ unsigned char pressedKeys[HIDDMouseInputReport_MAXKEYPRESSES];
+
+} __attribute__ ((packed)) HIDDMouseInputReport; // GCC
+// HID Output Report
+typedef struct {
+
+ unsigned char numLockStatus:1, // State of the num. lock LED.
+ capsLockStatus:1, // State of the caps lock LED.
+ scrollLockStatus:1, // State of the scroll lock LED.
+ padding:5; // Padding bits.
+
+} __attribute__ ((packed)) HIDDMouseOutputReport; // GCC
+\endcode
+
+ An instance of each one of the reports is stored in a HIDDMouseDriver
+ structure, which holds the standard class driver and HID Mouse-specific
+ data.
+
+ !!Physical Descriptor
+ A Physical descriptor is useless for a Mouse %device, so none are defined
+ in this example.
+
+ !!Endpoint Descriptor
+ Following the Interface and HID-specific descriptors, the two necessary
+ endpoints are defined.
+\code
+// Interrupt IN endpoint descriptor
+{
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_IN,
+ HIDDMouseDriverDescriptors_INTERRUPTIN),
+ USBEndpointDescriptor_INTERRUPT,
+ sizeof(HIDDMouseInputReport),
+ HIDDMouseDriverDescriptors_INTERRUPTIN_POLLING
+},
+// Interrupt OUT endpoint descriptor
+{
+ sizeof(USBEndpointDescriptor),
+ USBGenericDescriptor_ENDPOINT,
+ USBEndpointDescriptor_ADDRESS(
+ USBEndpointDescriptor_OUT,
+ HIDDMouseDriverDescriptors_INTERRUPTOUT),
+ USBEndpointDescriptor_INTERRUPT,
+ sizeof(HIDDMouseOutputReport),
+ HIDDMouseDriverDescriptors_INTERRUPTIN_POLLING
+}
+\endcode
+
+ !!String Descriptors
+ Please refer to "Usage: USBD VID, PID & Strings".
+
+ !!!Class-specific requests
+ A driver request handler should first differentiate between class-specific and
+ standard requests using the corresponding bits in the }bmRequestType} field.
+ In most cases, standard requests can be immediately forwarded to the standard
+ request handler method; class-specific methods must be decoded and treated by
+ the custom handler.
+
+ !!GetDescriptor
+ Three values have been added by the HID specification for the #GET_DESCRIPTOR#
+ request. The high byte of the }wValue} field contains the type of the
+ requested descriptor; in addition to the standard types, the #HID
+ specification# adds the #HID descriptor# (21h), the #Report descriptor#
+ (22h) and the #Physical descriptor# (23h) types.
+
+ There is no particular action to perform besides sending the descriptor. This
+ can be done by using the USBD_Write method, after the requested descriptor has
+ been identified:
+\code
+switch (USBGenericRequest_GetRequest(request)) {
+
+ case USBGenericRequest_GETDESCRIPTOR:
+ // Check if this is a HID descriptor,
+ // otherwise forward it to
+ // the standard driver
+ if (!HIDDMouseDriver_GetDescriptor(
+ USBGetDescriptorRequest_GetDescriptorType(request),
+ USBGenericRequest_GetLength(request))) {
+
+ USBDDriver_RequestHandler(&(hiddMouseDriver.usbdDriver),
+ request);
+ }
+ break;
+
+ default:
+ USBDDriver_RequestHandler(&(hiddMouseDriver.usbdDriver),
+ request);
+}
+\endcode
+ A slight complexity of the GET_DESCRIPTOR and SET_DESCRIPTOR requests is that
+ those are standard requests, but the standard request handler
+ (USBDDriver_RequestHandler) must not always be called to treat them (since
+ they may refer to HID descriptors). The solution is to first identify
+ GET/SET_DESCRIPTOR requests, treat the HID-specific cases and, finally,
+ forward any other request to the standard handler.
+
+ In this case, a GET_DESCRIPTOR request for the Physical descriptor is first
+ forwarded to the standard handler, and STALLed there because it is not
+ recognized. This is done because the %device does not have any Physical
+ descriptors, and thus, does not need to handle the associated request.
+
+ !!SetDescriptor
+ This request is optional and is never issued by most hosts. It is not
+ implemented in this example.
+
+ !!GetReport
+ Since the HID Mouse defines two different reports, the Report Type value
+ specified by this request (upper byte of the }wValue} field) must be examined
+ to decide which report to send. If the type value is 01h, then the Input
+ report must be returned; if it is 02h, the Output report is requested:
+\code
+case HIDGenericRequest_GETREPORT:
+//-------------------------------
+ type = HIDReportRequest_GetReportType(request);
+ length = USBGenericRequest_GetLength(request);
+ switch (type) {
+
+ case HIDReportRequest_INPUT:
+
+ // Adjust size and send report
+ if (length > sizeof(HIDDMouseInputReport)) {
+
+ length = sizeof(HIDDMouseInputReport);
+ }
+ USBD_Write(0, // Endpoint #0
+ &(hiddMouseDriver.inputReport),
+ length,
+ 0, // No callback
+ 0);
+ break;
+
+ case HIDReportRequest_OUTPUT:
+
+ // Adjust size and send report
+ if (length > sizeof(HIDDMouseOutputReport)) {
+
+ length = sizeof(HIDDMouseOutputReport);
+ }
+ USBD_Write(0, // Endpoint #0
+ &(hiddMouseDriver.outputReport),
+ length,
+ 0, // No callback
+ 0);
+ break;
+
+ default:
+ USBD_Stall(0);
+ }
+break;
+\endcode
+
+ !!SetReport
+ For an HID Mouse, the #SET_REPORT# command can be sent by the host to
+ change the state of the LEDs. Normally, the dedicated Interrupt OUT endpoint
+ will be used for this; but in some cases, using the default Control endpoint
+ can save some bandwidth on the host side.
+
+ Note that the SET_REPORT request can be directed at the Input report of the
+ Mouse; in this case, it can be safely discarded, according to the HID
+ specification. Normally, most host drivers only target the Output report. The
+ Report Type value is stored in the upper byte of the }wValue} field.
+
+ The length of the data phase to follow is stored in the }wLength} field of the
+ request. It should be equal to the total length of the Output report. If it is
+ different, the report status must still be updated with the received data as
+ best as possible.
+
+ When the reception of the new data is completed, some processing must be done
+ to enable/disable the corresponding LEDs. This is done in the callback
+ function passed as an argument to USBD_Read:
+\code
+case HIDGenericRequest_SETREPORT:
+//-------------------------------
+ type = HIDReportRequest_GetReportType(request);
+ length = USBGenericRequest_GetLength(request);
+ switch(type) {
+
+ case HIDReportRequest_INPUT:
+ // SET_REPORT requests on input reports are ignored
+ USBD_Stall(0);
+ break;
+
+ case HIDReportRequest_OUTPUT:
+ // Check report length
+ if (length != sizeof(HIDDMouseOutputReport)) {
+
+ USBD_Stall(0);
+ }
+ else {
+
+ USBD_Read(0, // Endpoint #0
+ &(hiddMouseDriver.outputReport),
+ length,
+ (TransferCallback) HIDDMouseDriver_ReportReceived,
+ 0); // No argument to the callback function
+ }
+ break;
+
+ default:
+ USBD_Stall(0);
+ }
+break;
+\endcode
+
+ !!SetIdle
+ In this case study, the #SET_IDLE# request is used to set a delay before a key
+ is repeated. This is common behavior on Mouse devices. Usually, this delay
+ is set to about 500 ms by the host.
+
+ The only action here is to store the new Idle rate. The management of this
+ setting must be done in the main function, since Interrupt IN reports are sent
+ from there.
+
+ In practice, it is not necessary to perform any action, apart from sending a
+ zero-length packet to acknowledge it. The main application however has to make
+ sure that only new reports are sent by the %device.
+\code
+case HIDGenericRequest_SETIDLE:
+//-----------------------------
+ hiddMouseDriver.inputReportIdleRate =
+ HIDIdleRequest_GetIdleRate(request);
+ USBD_Write(0, 0, 0, 0, 0);
+break;
+\endcode
+
+ !!GetIdle
+ The only necessary operation for this request is to send the previously saved
+ Idle rate. This is done by calling the USBD_Write method with the one-byte
+ variable as its parameter:
+\code
+case HIDGenericRequest_GETIDLE:
+//-----------------------------
+ USBD_Write(0, &(hiddMouseDriver.inputReportIdleRate), 1, 0, 0);
+break;
+\endcode
+
+ !!GetProtocol, SetProtocol
+ This HID Mouse example does not support the Boot protocol, so there is no
+ need to implement the SET_PROTOCOL and GET_PROTOCOL requests. This means they
+ can be safely STALLed when received.
+
+ !!!Main Application
+ Like the mouse example, the main program must perform two different
+ operations. First, it has to monitor the physical inputs used as keys. In the
+ example software, the buttons present on the evaluation boards are used to
+ produce several modifier and alphanumeric keys.
+
+ Also, the main program is in charge of sending reports as they are modified,
+ taking into account the Idle rate specified by the host. Idle rate management
+ can be carried out by firing/resetting a timer once a new report is sent; if
+ the timer expires, this means the Input report has not changed since.
+ According to the HID specification, a single instance of the report must be
+ sent in this case.
+
+ Finally, the HID specification also defines that if too many keys are pressed
+ at the same time, the %device should report an }ErrorRollOver} usage value
+ (01h) in every byte of the key array. This has to be handled by the main
+ application as well.
+
+*/ \ No newline at end of file
personal git repositories of Harald Welte. Your mileage may vary