The HID Class Driver for Sensors September 13, 2011
Abstract This paper provides information about a sample HID class-driver for sensors. It provides guidelines for IHVs who are creating sensors, or OEMs who are integrating sensors into their equipment. It assumes that the reader is familiar with the Sensor platform for Windows and the User Mode Driver Framework (UMDF). And, it assumes that the reader is familiar with the Sensor Driver Skeleton Sample that ships in the Windows Driver Kit (WDK). This information applies to the following operating systems: Windows 8
References and resources discussed here are listed at the end of this paper. The current version of this paper is maintained on the web at: The HID Class Driver for Sensors
Disclaimer Disclaimer: This document is provided “as-is”. Information and views expressed in this document, including URL and other Internet Web site references, may change without notice. You bear the risk of using it. This document does not provide you with any legal rights to any intellectual property in any Microsoft product. You may copy and use this document for your internal, reference purposes. This document is confidential and proprietary to Microsoft. It is disclosed and can be used only pursuant to a non-disclosure agreement. © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 2
Contents Introduction.................................................................................................................... 3 The HID Protocol for Sensors.......................................................................................... 3 Supporting I/O.................................................................................................................5 Defining the Sensor Objects............................................................................................9 Initializing the Sensor Object...................................................................................... 9 Setting and Retrieving the Sensor Properties.............................................................9 Reading HID Feature Reports..................................................................................... 9 Reading HID Input Reports....................................................................................... 10 Writing HID Feature Reports.................................................................................... 10 Supporting the Sensor Properties.................................................................................10 Using the Sensor Class Extension to Raise Events........................................................ 12 Supporting a Custom Sensor.........................................................................................13 Driver Installation..........................................................................................................15 Debugging a Sensor Driver with Visual Studio 2010..................................................... 15 General Visual Studio 10 Debugging Tips................................................................. 16 Tips for Debugging Sensor Driver Initialization Code............................................... 16 The Driver File List.........................................................................................................17 Resources...................................................................................................................... 23 Appendix....................................................................................................................... 23 HID Sensor Report Descriptor...................................................................................23 Consolidated Report Descriptor............................................................................... 23
September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 3
Introduction The sample HID Class driver for sensors was written to demonstrate how an OEM or IHV could write a UMDF driver to support sensors. This driver is also helpful for IHVs who must design and test firmware for a HID-based sensor. Note that this sample driver is identical to the HID class driver that will ship in-box for Windows 8. The sample driver is based on the HID protocol. It supports the Freescale Badge Board that’s produced by Freescale Semiconductor Corporation, which is headquartered in Austin, Texas. You need Rev D of the board because the earlier versions do not contain the ambient light sensor; this version is also referred to as the Sensor Development Kit board. (In addition to the three sensors on the badge board, the sample driver supports fifteen other sensors. For a complete list of supported sensors, see the list of sensor files at the end of this paper.) The badge board is built around a ColdFire™ USB Microcontroller and includes a 3-axis accelerometer, an array of capacitive touch switches, and an ambient light sensor. In addition, the badge board includes an array of LEDs as well as a 60-pin expansion slot. The board can be purchased directly from Freescale Corporation. Note that you’ll also need to update the firmware on the board with new firmware that is compatible with the HID class driver. After the sample driver is installed on your Windows 8 machine, and the Freescale badge board is connected to an available USB port, you can begin to familiarize yourself with the hardware, the driver, and the Sensor platform for Windows. The following screenshot shows accelerometer output for a very simple application that is receiving event notifications from the sensor on the badge board. (These event notifications were issued by the firmware and passed by the sample driver to the Sensor API where they were consumed by the application.)
The HID Protocol for Sensors The term HID is an abbreviation for “Human Interface Device” and originally was used to identify devices such as keyboards, mice, webcams, and joysticks. The HID protocol was intended to support these sorts of devices and originated with a working group in the USB organization. One of the unique features of the HID protocol is that it requires devices to deliver packets at initialization time that are “self describing”. As a result, HID devices are not constrained or
September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 4
limited in their reporting capabilities. This particular feature of the protocol works well with sensors because the simplest sensors may report a single Boolean value to indicate current state while more complex sensors may report a series of complex floating point numbers. A human-presence sensor is an example of a simple sensor, and an accelerometer is a more complex example. By supporting the “self describing” feature, the HID protocol enables an unlimited universe of sensors. The file internal.h, in the sample driver project, contains a HID report descriptor for the collection of sensors supported by the sample HID class driver. This report descriptor is found in comments at the end of the file. The sensors supported in this descriptor correspond to the sensors found on the Freescale badge board. The sensors are: •
3-axis accelerometer
•
Capacitive switch
•
Ambient light sensor
When the badge board is attached to a personal computer, the board sends a complete report descriptor to its host. This descriptor defines the format of the data that the sensors will send to the host (or computer) and expect to receive from the computer. (If the report descriptor contains a sensor that is not found in the driver’s INF file, the driver will be loaded only if that sensor is part of a collection. If this is the case, the driver is loaded; but the sensor is marked as unsupported.) The report descriptor is divided into two parts: feature reports and input reports. The feature reports include a sensor’s current reporting state, its status, change sensitivity, and reporting interval. The input reports contain sensor readings: True or False for a switch, G-force values for an accelerometer or LUX for an ambient light sensor. The following code snippet shows the HID feature report for the accelerometer. Note the selfdescriptive nature of this report; it includes minimum and maximum values as well as the count and size of individual fields. (The self-describing report is made human-readable by using a set of definitions found in the file internal.h) //feature reports (xmit/receive) HID_USAGE_PAGE_SENSOR, HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_SENSOR_STATUS, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_CHANGE_SENSITIVITY_ABS, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x27, 0xFF, 0xFF, 0x00, 0x00, //LOGICAL_MAXIMUM (65535) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_METERS_PER_SEC_SQRD, HID_UNIT_EXPONENT(2), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL, September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 5
0x15, 0x00, //LOGICAL_MINIMUM (0) 0x27, 0xFF, 0xFF, 0xFF, 0xFF, //LOGICAL_MAXIMUM (4294967295) HID_REPORT_SIZE(32), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_MILLISECOND, HID_UNIT_EXPONENT(0), HID_FEATURE(Data_Var_Abs),
The following code snippet shows the HID input report for the same device. Again, note the self-descriptive nature of the fields in this report. //input reports (transmit) HID_USAGE_PAGE_SENSOR, HID_USAGE_SENSOR_STATE, 0x15, 0x00, 0x26, 0xFF, 0x00, HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_EVENT, 0x15, 0x00, 0x26, 0xFF, 0x00, HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_INPUT(Data_Var_Abs),
//LOGICAL_MINIMUM (0) //LOGICAL_MAXIMUM (255)
//LOGICAL_MINIMUM (0) //LOGICAL_MAXIMUM (255)
HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_X_AXIS, 0x16, 0x01, 0x80, // LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, // LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_METERS_PER_SEC_SQRD, HID_UNIT_EXPONENT(2), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_Y_AXIS, 0x16, 0x01, 0x80, // LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, // LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_METERS_PER_SEC_SQRD, HID_UNIT_EXPONENT(2), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_Z_AXIS, 0x16, 0x01, 0x80, // LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, // LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_METERS_PER_SEC_SQRD, HID_UNIT_EXPONENT(2), HID_INPUT(Data_Var_Abs),
Supporting I/O The sample driver communicates with the Freescale badge board over a USB connection. The sensor’s firmware is programmed to send periodic readings and receive requests from the driver to update its report interval or its change sensitivity.
September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 6
The following diagram shows the data flow between the sample driver and the sensor. The sensor firmware uses the HID protocol to transmit the sensor data: •
The sensor sends either a feature report or an input report to the HID class driver. A feature report is sent in response to a request from the driver. This report contains data including the sensor’s change-sensitivity setting, its report interval, and its reporting state. An input report is sent either upon request, or asynchronously in response to an event. This report contains the actual sensor data (for example, in the case of an accelerometer, the G-forces along the x-, y-, and z-axes).
•
The HID class driver sends feature reports to the sensor. For example, when the application requests a new change sensitivity or report interval, the driver packages these values into a feature report and uses this report to send the request to the sensor’s firmware.
September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 7
The sample driver is hosted in the User Mode Driver Framework (UMDF) host process (“WUDF Host Process” in the diagram) and receives requests from a sensor application. The driver exchanges data with the kernel-mode HID driver by way of a UMDF I/O target object.
September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 8
The I/O target management and completion callback methods are implemented in the CReadWriteRequest object found in the ReadWriteRequest.cpp module. •
When the driver is initialized in CSensorDDI::InitSensorDevice CSensorDDI::InitSensorDevice, it creates the read, write, and IOCTL HID objects.
•
The sample driver uses IWDFDevice::GetDefaultIoTarget to retrieve an I/O target object. (This I/O target provides a linkage to the kernel mode HID driver that sits below the sample driver in the stack.) The IWDFDevice::GetDefaultIoTarget method is invoked in the CReadWriteRequest::InitializeRequest method.
•
After the I/O target is created, the sample driver can begin processing asynchronous read and write operations. Read operations are used to receive HID feature and input reports from the sensor. Write operations are used to send requests to the sensor to update the change sensitivity or read interval settings. These requests are sent as HID feature reports. (The file internal.h contains the HID feature and input reports for each sensor.)
HID read requests are implemented as shown in the following steps: They are generated in CReadWriteRequest::CreateAndSendReadRequest as IWDFIoRequest objects. They are initialized by using IWDFDevice::CreateRequest IWDFDevice::CreateRequest. They are forwarded by using IWDFIoRequest::Send IWDFIoRequest::Send. The CReadWriteRequest::OnCompletion callback routine processes the request data and sends the next read request. When this method processes the request data, it passes the buffer that it received from the sensor to the CSensorDDI::OnAsyncReadCallback method. This method, in turn, passes the buffer of data to a sensor-specific read method. For example, in the case of the accelerometer, the buffer is passed to the CAccelerometer::ProcessAccelerometerAsyncRead method. (The buffer contains an input report with the most recent sensor reading.) HID write requests are implemented as follows: They are generated in CReadWriteRequest::CreateAndSendWriteRequest as IWDFIoRequest objects. They are initialized by using IWDFDevice::CreateRequest IWDFDevice::CreateRequest. They are forwarded by using IWDFIoRequest::Send IWDFIoRequest::Send. In the case of write requests, the buffer may contain only feature reports. These reports correspond to requests from the application to set the change sensitivity or report interval to a new value. UMDF I/O targets provide multiple benefits that include state management and error handling, and lead to simpler and more robust driver code. For more advanced driver scenarios or stack configurations, UMDF I/O targets also natively support cancellation, request queuing, and request forwarding to the next lower driver.
September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 9
Defining the Sensor Objects The sample driver treats each sensor as an object. These objects are declared in 18 header files. The name of each file corresponds to a particular sensor; for example, the file Accelerometer.h contains the definition for the accelerometer object CAccelerometer CAccelerometer. (Refer to The Driver Filelist section for a list describing each of these files.) Each header file contains a data structure that defines the properties supported by a particular sensor. (For more information about sensor properties, see Supporting the Sensor Properties.) In addition, each header file contains the definitions of the methods that: •
Initialize the sensor object
•
Set or retrieve sensor properties
•
Read HID feature and input reports from the sensor
•
Write HID feature reports to the sensor
The definitions of the corresponding methods are found in a source file with a similar name. For example, the file Accelerometer.cpp contains the definition of the methods declared in Accelerometer.h.
Initializing the Sensor Object Each of the sensor object source files contains an Initialize method that initializes the property keys and data-field keys for a specific sensor. This method is invoked by the sensor manager at startup. If a specified sensor is available, the CSensorManager::Start method invokes the corresponding Initialize method for that sensor. In the case of the Freescale board, after the hardware is connected and the driver verifies that it contains an accelerometer device, the CAcclerometer::AddAccelerometerPropertyKeys method is called to supply the property keys for the properties supported by the accelerometer and the CAccelerometer::AddAccelerometerDataFieldKeys method is called to supply the data field keys for the supported data fields. (These methods are invoked from within CAccelerometer::InitializeAccelerometer CAccelerometer::InitializeAccelerometer.)
Setting and Retrieving the Sensor Properties When an application requests a particular property value for a sensor, a corresponding property-retrieval method is called in the sample driver. In the case of the accelerometer, this would be CAccelerometer::GetPropertyValuesForAccelerometerObject CAccelerometer::GetPropertyValuesForAccelerometerObject. The Sensor API will pass the property keys for the properties requested by the application and the driver will bundle the property values in an IPortableDeviceValues object which it returns to the API. When an application attempts to update a property on the sensor (such as change sensitivity or the report interval), a corresponding property-write method is called in the sample driver. In the case of the accelerometer, this would be CAccelerometer::UpdateAccelerometerPropertyValues CAccelerometer::UpdateAccelerometerPropertyValues. This method is declared and defined in the sensor object’s files (Accelerometer.h and Accelerometer.cpp) and is invoked in the SensorDDI.cpp module. For information about how the sensor properties are defined, see Supporting the Sensor Properties later in this paper.
Reading HID Feature Reports At startup, the driver requests a HID feature report from the sensor firmware. This report includes information such as the sensor status, the current report interval, the connection
September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 10
type, the minimum report interval, and the sensor’s friendly name. The driver, in turn, captures this data and stores it in its list of properties. In the case of the accelerometer, the method that processes the HID feature report is CAccelerometer::UpdateAccelerometerPropertyValues CAccelerometer::UpdateAccelerometerPropertyValues. (A method with a similar name in the other object files performs similar work for each sensor.) The maximum size of a HID Feature report is 64 bytes: 63 bytes for the actual report and 1 byte for the report identifier. The report identifier, the first byte in the report, will contain the value 0 if there is only one sensor. However, if there is a sensor collection, the identifier specifies the position of a given sensor in that collection. (If a collection exists, the identifier value for the first sensor is always 1.)
Reading HID Input Reports When the sensor firmware issues a new sensor reading, it sends this reading as a HID Input report to the driver. This report contains data specific to a particular sensor. For example, with the accelerometer, the input report includes the current G-force values along the x-, y-, and zaxes. The driver stores this data in its respective data fields. If an application is registered to receive the data-update event, it forwards the new fields to the Sensor API. In the case of the accelerometer, the method that processes the HID Input report is CAccelerometer::ProcessAccelerometerAsyncRead CAccelerometer::ProcessAccelerometerAsyncRead. (A method with a similar name in the other object files performs similar work for each sensor.) The maximum size of a HID Input report is 64 bytes: 63 bytes for the actual report and 1 byte for the report identifier. The report identifier, the first byte in the report, will contain the value 0 if there is only one sensor. However, if there is a sensor collection, the identifier specifies the position of a given sensor in that collection. (If a collection exists, the identifier value for the first sensor is always 1.)
Writing HID Feature Reports When a sensor application requests an update to a sensor’s report interval or change sensitivity, the Sensor class extension notifies the driver. The driver packages the request into a HID feature report and forwards it to the sensor. In the case of the accelerometer, the method that forwards the report to the sensor is CAccelerometer::UpdateAccelerometerPropertyValues CAccelerometer::UpdateAccelerometerPropertyValues. (A method with a similar name in the other object files performs similar work for each sensor.)
Supporting the Sensor Properties Each of the sensor header files contains a data structure that defines the properties supported by that sensor. A number of these properties are common to all sensors. For example, in the following definition of ACCELEROMETER_DEVICE_PROPERTIES from Accelerometer.h, the red text highlights the common properties. typedef struct _ACCELEROMETER_DEVICE_PROPERTIES { // from input report BOOL fSensorStateSupported; BOOL fEventTypeSupported; // supported datafields BOOL fAccelerometerXAxisSupported; BOOL fAccelerometerYAxisSupported; September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 11
BOOL
fAccelerometerZAxisSupported;
// from feature report BOOL fReportingStateSupported; ULONG ulReportingState; BOOL fSensorStatusSupported; ULONG ulSensorStatus; BOOL fReportIntervalSupported; ULONG ulReportInterval; // Per-datafield properties BOOL fAccelerometerSensitivitySupported; FLOAT fltAccelerometerSensitivity; BOOL fAccelerometerXSensitivitySupported; FLOAT fltAccelerometerXSensitivity; BOOL fAccelerometerYSensitivitySupported; FLOAT fltAccelerometerYSensitivity; BOOL fAccelerometerZSensitivitySupported; FLOAT fltAccelerometerZSensitivity; BOOL FLOAT BOOL FLOAT BOOL FLOAT BOOL FLOAT
fAccelerometerMaximumSupported; fltAccelerometerMaximum; fAccelerometerXMaximumSupported; fltAccelerometerXMaximum; fAccelerometerYMaximumSupported; fltAccelerometerYMaximum; fAccelerometerZMaximumSupported; fltAccelerometerZMaximum;
BOOL FLOAT BOOL FLOAT BOOL FLOAT BOOL FLOAT
fAccelerometerMinimumSupported; fltAccelerometerMinimum; fAccelerometerXMinimumSupported; fltAccelerometerXMinimum; fAccelerometerYMinimumSupported; fltAccelerometerYMinimum; fAccelerometerZMinimumSupported; fltAccelerometerZMinimum;
BOOL FLOAT BOOL FLOAT BOOL FLOAT BOOL FLOAT
fAccelerometerAccuracySupported; fltAccelerometerAccuracy; fAccelerometerXAccuracySupported; fltAccelerometerXAccuracy; fAccelerometerYAccuracySupported; fltAccelerometerYAccuracy; fAccelerometerZAccuracySupported; fltAccelerometerZAccuracy;
BOOL FLOAT BOOL FLOAT BOOL FLOAT BOOL FLOAT
fAccelerometerResolutionSupported; fltAccelerometerResolution; fAccelerometerXResolutionSupported; fltAccelerometerXResolution; fAccelerometerYResolutionSupported; fltAccelerometerYResolution; fAccelerometerZResolutionSupported; fltAccelerometerZResolution;
//Extended properties BOOL fConnectionTypeSupported; ULONG ulConnectionType; BOOL fMinimumReportIntervalSupported; ULONG ulMinimumReportInterval; BOOL fFriendlyNameSupported;
September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 12
WCHAR BOOL WCHAR BOOL WCHAR BOOL WCHAR BOOL WCHAR BOOL WCHAR
wszFriendlyName[HID_FEATURE_REPORT_STRING_MAX_LENGTH]; fPersistentUniqueIDSupported; wszPersistentUniqueID[HID_FEATURE_REPORT_STRING_MAX_LENGTH]; fManufacturerSupported; wszManufacturer[HID_FEATURE_REPORT_STRING_MAX_LENGTH]; fModelSupported; wszModel[HID_FEATURE_REPORT_STRING_MAX_LENGTH]; fSerialNumberSupported; wszSerialNumber[HID_FEATURE_REPORT_STRING_MAX_LENGTH]; fDescriptionSupported; wszDescription[HID_FEATURE_REPORT_STRING_MAX_LENGTH];
} ACCELEROMETER_DEVICE_PROPERTIES, *PACCELEROMETER_DEVICE_PROPERTIES;
The remaining properties (those not highlighted) are unique to the specific sensor. In the case of the accelerometer, these include the supported data fields and the corresponding properties for each data field.
Using the Sensor Class Extension to Raise Events Sensor applications can retrieve the current sensor data by either registering to receive event notifications from the driver or by invoking a property to retrieve the sensor’s current data field. The sample driver supports both. If an application registers for data-update events, the driver raises these events each time data arrives from the sensor. The frequency of these event notifications correspond to the current report-interval property. In addition to raising events when new data arrives from the sensor, the sample driver also raises events when the sensor is unable to send data or when the sensor is ready to begin sending data. These events are referred to as state-change events. The states supported by the sample driver correspond to two constants found in the SensorState enumeration:
Event-State Constant SENSOR_STATE_NO_DATA SENSOR_STATE_READY
Significance Indicates that the sensor is not available. Indicates that the sensor is connected and ready to send data.
The sensor class extension handles the event-linkage between a sensor driver and the Sensor API. When the driver invokes the ISensorClassExtension::PostStateChange method, the class extension forwards the notification to the API. The sample driver invokes this method within CSensorManager::SetState CSensorManager::SetState. When the driver invokes the ISensorClassExtension::PostEvent method and supplies the property key for the data-updated event, the class extension forwards the notification to the Sensor API. The sample driver invokes this method within CSensorManager::PostDataEvent CSensorManager::PostDataEvent. The two sensor manager methods ::SetState and ::PostDataEvent are invoked within the sample driver’s thread procedure for events CSensorManager::_SensorEventThreadProc CSensorManager::_SensorEventThreadProc. The event handlers are maintained within a separate thread procedure to prevent the event activity from blocking synchronous procedures in the driver (such as callback functions).
September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 13
Supporting a Custom Sensor If you have built a sensor that does not map to one of the 17 unique sensor-objects defined in the sample HID class driver, you can still use the custom sensor-object to integrate your device with the Windows Sensor platform. The one requirement of the custom object is that you to publish your sensor’s property keys to any application developer who will use the device. (This is because sensors supported by the custom object are not discoverable using the Sensor API.) The Custom feature report is similar to the feature reports for the other sensors supported by the sample driver. The primary difference is the absence of sensor-specific properties found in the HID_USAGE_SENSOR_DATA fields. //feature reports (xmit/receive) HID_USAGE_PAGE_SENSOR, HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_SENSOR_STATUS, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_CHANGE_SENSITIVITY_ABS, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x27, 0xFF, 0xFF, 0x00, 0x00, //LOGICAL_MAXIMUM (65535) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED, HID_UNIT_EXPONENT(2), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x27, 0xFF, 0xFF, 0xFF, 0xFF, //LOGICAL_MAXIMUM (4294967295) HID_REPORT_SIZE(32), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_MILLISECOND, HID_UNIT_EXPONENT(0), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_RANGE_MAXIMUM, 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED, HID_UNIT_EXPONENT(2), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_RANGE_MINIMUM, 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1),
September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 14
HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED, HID_UNIT_EXPONENT(2), HID_FEATURE(Data_Var_Abs),
The Custom input report supports an array of 16 Boolean values as well as six distinct sensor values (these values can be any type from an integer to a float). This allows you to support a wide range of sensor readings. //input reports (transmit) HID_USAGE_PAGE_SENSOR, HID_USAGE_SENSOR_STATE, 0x15, 0x00, 0x26, 0xFF, 0x00, HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_EVENT, 0x15, 0x00, 0x26, 0xFF, 0x00, HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_INPUT(Data_Var_Abs),
//LOGICAL_MINIMUM (0) //LOGICAL_MAXIMUM (255)
//LOGICAL_MINIMUM (0) //LOGICAL_MAXIMUM (255)
HID_USAGE_SENSOR_DATA_CUSTOM_USAGE, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x27, 0xFF, 0xFF, 0x00, 0x00, //LOGICAL_MAXIMUM (65535) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_CUSTOM_BOOLEAN_ARRAY, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x27, 0xFF, 0xFF, 0x00, 0x00, //LOGICAL_MAXIMUM (65535) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_1, 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED, HID_UNIT_EXPONENT(2), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_2, 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED, HID_UNIT_EXPONENT(2), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_3, 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 15
HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED, HID_UNIT_EXPONENT(2), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_4, 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED, HID_UNIT_EXPONENT(2), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_5, 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED, HID_UNIT_EXPONENT(2), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_6, 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED, HID_UNIT_EXPONENT(2), HID_INPUT(Data_Var_Abs),
Driver Installation For Windows 8, to install the driver to test the Freescale board or a sensor application, just plug the board into your Windows 8 computer. (This installs an inbox version of the HID class driver.) However, if you want to install the sample driver, you must override the default installation. To do this, follow these steps: 1.
Install the Windows Driver Kit (WDK) for Windows 8 and follow the instructions to build the sample driver (SensorsHIDClassDriver).
2.
Open the Windows Device Manager in Control Panel and disable the inbox sensor driver.
3.
Copy the DLL for the sample driver over the existing version of the inbox driver located in \Windows\System32\Drivers\UMDF.
4.
Return to Windows Device Manager and enable the sensor.
Debugging a Sensor Driver with Visual Studio 2010 Sensor drivers are based on the Windows Driver Foundation (WDF) – User-Mode Driver Framework (UMDF) platform. UMDF drivers provide greater stability and security than kernelmode drivers while providing comparable performance. And, UMDF drivers allow the use of user-mode debuggers such as Visual Studio 2010. (Debugging a driver in user mode tends to be faster than debugging in kernel-mode because an error affects only the current process instead of the entire computer.) September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 16
General Visual Studio 10 Debugging Tips After your driver is installed, you can create a debugging project in Visual Studio by following these steps: 1.
Open Visual Studio and select File > New > Project from Existing Code Code.
2. Follow the steps in the “Welcome to the Create Project from Existing Code Files Wizard” (specifying the language, the location of your driver source files, a project name, and so on). 3.
Open your newly created project.
4. Select Debug/Attach to Process Process.In the list of available processes that appears in the Attach to Process dialog box, select WudfHost.exe WudfHost.exe. After you complete these steps, you can set breakpoints in your driver’s source code and debug your driver.
Tips for Debugging Sensor Driver Initialization Code A sensor driver’s initialization code executes during the installation of your driver. If, for example, you need to set a breakpoint in CMyDevice::OnPrepareHardware CMyDevice::OnPrepareHardware, you must follow these steps: 1.
Create a debugging project in Visual Studio (as described in the previous section).
2. Open an instance of regedit.exe and specify a delay period (in seconds) for the WudfHost.exe process using the following key: \HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WUDF\Services\{193a…}\HostProcessDbgBreakOnStart 3. Force the WUDFHost.exe process to reload. This can be done in a couple of ways, depending on your device configuration: a) From Device Manager, disable and then enable your device's devnode. b) If your device has a physical connection to the computer, unplug and then reconnect your device. 4. Upon driver reload, start Visual Studio, open your debug project, and attach to the WudfHost.exe process. As a side effect, you may see Device Manager hanging when you reload the driver while WudfHost.exe is waiting for a debugger to connect. The delay that you set for the HostProcessDbgBreakOnStart value provides the necessary time to start the debugger before the installation of your driver. (For example, a value of 0x00000040 would delay the installation for 64 seconds.) This delay allows you time to attach to the process, set a breakpoint in your initialization code, and begin debugging. For more information about the HostProcessDbgBreakOnStart value, refer to this MSDN topic.
The Driver File List This section describes the contents of the files found in the driver source-file folder. There are two general categories of files. The first consists of general files that are common to a UMDF sensor driver. The second consists of sensor-specific files that are required to support a specific HID-based sensor.
September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 17
The following table describes the general files that are common to a UMDF sensor driver. Filename
Contents
Device.cpp
Contains an implementation of the CMyDevice member functions. This includes the OnPrepareHardware method which creates and initializes the sensor class extension.
Device.h
Contains a definition for the CMyDevice class.
Dllsup.cpp
Contains the driver DLL’s entry point (DLLMain).
Driver.cpp
Contains an implementation of the CMyDriver member functions. This includes the OnDeviceAdd method that creates an instance of the CMyDevice class (see description of Device.cpp).
Driver.h
Contains a definition of the CMyDriver class.
Internal.h
Contains local type definitions for the sample driver. These include sensor-specific HID definitions as well as general HID definitions.
Makefile.inc
Required to build an .INF file.
Queue.cpp
Contains an implementation of the CMyQueue member functions. This includes the CreateInstance method, which creates an instance of the I/O queue for the device. It also includes the OnDeviceIoControl method that forwards WPD I/O requests to the sensor class extension.
Queue.h
Contains a definition of the CMyQueue class.
Resource.h
Contains definitions consumed by SensorsSimpleHIDClassDriver.h.
Sensor.cpp
Contains an implementation of the CSensor member functions. This includes the methods which return lists of supported properties and data fields as well as the methods which set writeable properties and data fields.
Sensor.h
Contains a definition of the CSensor class.
SensorDDI.cpp
Contains an implementation of the ISensorDriver callback interface in the CSensorDdi class. The sensor class extension calls methods in this interface to retrieve supported data such as objects, properties, and events.
September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 18
SensorDdi.h
Contains the definition of the CSensorDdi callback class.
SensorManager.cpp
Contains an implementation of the CSensorManager class. The methods in this class, as the name implies, manage the sensor device: starting it, stopping it, retrieving the device state, and so on.
SensorManager.h
Contains the definition of the CSensorManager class.
SensorsSimpleHIDClassDriver.def
Declares the module parameters.
SensorsSimpleHIDClassDriver.htm
Contains a high-level description of the sample driver.
SensorsSimpleHIDClassDriver.idl
Contains the necessary definitions for the driver’s COM component.
SensorsSimpleHIDClassDriver.inf
Contains the information that Windows Setup requires when installing the in-box driver on x86 and amd64 machines.
SensorsSimpleHIDClassDriver.rc
Contains definitions for resources that the driver requires, such as file type, file description string, file version, and original file name.
SensorsSimpleHIDClassDriverWin8x86Manual.inf
Contains the information that is required when manually installing the driver on x86.
Sources
Contains a series of macro definitions that are recognized by the Build utility.
The following table lists the files that support the 18 categories of sensors enabled by the sample driver. Note that all of these categories return a timestamp data field. The table lists any additional data field associated with a particular class. Filename
Contents
Accelerometer.cpp
Contains an implementation of the CAccelerometer class. The methods in this class initialize the sensor, retrieve readable properties, set writeable properties, and process asynchronous data from the sensor.
The supported datafields return acceleration for 1-, 2-, and 3-axis devices. Accelerometer.h
Contains the definition of the CAccelerometer class.
AmbientLight.cpp
Contains an implementation of the CAmbientLight class. The methods in this September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 19
class initialize the sensor, retrieve readable properties, set writeable properties, and process asynchronous data from the sensor.
The supported data fields return LUX, light temperature in degrees Kelvin, and chromacity. AmbientLight.h
Contains the definition of the CAmbientLight class.
AtmosPressure.cpp
Contains an implementation of the CBarometer class. The methods in this class initialize the sensor, retrieve readable properties and process asynchronous data from the sensor.
The supported data field returns the atmospheric pressure. AtmosPressure.h
Contains the definition of the CBarometer class.
Compass.cpp
Contains an implementation of the CCompass class. The methods in this class initialize the sensor, retrieve readable properties, set writeable properties, and process asynchronous data from the sensor.
The supported data fields include the compass heading in X-, Y-, and Z-degrees as well as the compensated and uncompensated magnetic and true-north headings. Compass.h
Contains the definition of the CCompass class.
Current.cpp
Contains an implementation of the CCurrent class. The methods in this class initialize the sensor, retrieve readable properties, set writeable properties, and process asynchronous data from the sensor.
The supported data field includes the current as measured in amps. Current.h
Contains the definition of the CCurrent class.
Custom.cpp
Contains an implementation of the CCustom class. The methods in this class: initialize the September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 20
sensor, retrieve readable properties, set writeable properties, and process asynchronous data from the sensor. If you create a unique sensor that is not supported by existing classes in the driver, you can use this class to support your device. Custom.h
Contains the definition of the CCustom class.
Distance.cpp
Contains an implementation of the CDistance class. The methods in this class: initialize the sensor, retrieve readable properties, set writeable properties, and process asynchronous data from the sensor.
The supported data fields include distance measurements for 1-, 2-, and 3-axis devices. Distance.h
Contains the definition of the CDistance class.
Frequency.cpp
Contains an implementation of the CFrequency class. The methods in this class initialize the sensor, retrieve readable properties, set writeable properties, and process asynchronous data from the sensor.
The supported data field can be used to measure periodic events such as fan speed. Frequency.h
Contains the definition of the CFrequency class.
Gyrometer.cpp
Contains an implementation of the CGyrometer class. The methods in this class initialize the sensor, retrieve readable properties, set writeable properties, and process asynchronous data from the sensor.
The supported data fields measure angular acceleration and support 1-, 2-, and 3-axis sensors. Gyrometer.h
Contains the definition of the CGyrometer class.
Humidity.cpp
Contains an implementation of the CHumidity class. The methods in this class initialize the sensor, retrieve readable properties, set writeable properties, and process asynchronous data from the sensor.
September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 21
The supported data field measures relative humidity as a percentage. Humidity.h
Contains the definition of the CHumidity class.
Inclinometer.cpp
Contains an implementation of the CInclinometer class. The methods in this class initialize the sensor, retrieve readable properties, set writeable properties, and process asynchronous data from the sensor.
The supported data fields measure incline for 1-, 2-, and 3-axis sensors. Inclinometer.h
Contains the definition of the CInclinometer class.
Potentiometer.cpp
Contains an implementation of the CPotentiometer class. The methods in this class initialize the sensor, retrieve readable properties, set writeable properties, and process asynchronous data from the sensor.
The supported data field returns a percentage of the maximum range. Potentiometer.h
Contains the definition of the CPotentiometer class.
Power.cpp
Contains an implementation of the CPower class. The methods in this class initialize the sensor, retrieve readable properties, set writeable properties, and process asynchronous data from the sensor.
The supported data field measures power in watts. Power.h
Contains the definition of the CPower class.
Presence.cpp
Contains an implementation of the CPresence class. The methods in this class initialize the sensor, retrieve readable properties, set writeable properties, and process asynchronous data from the sensor.
This class supports two sets of datafields. The first returns human presence status, and the September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 22
second returns human proximity data in meters. Presence.h
Contains the definition of the CPresence class.
Switches.cpp
Contains an implementation of the CSwitch class. The methods in this class initialize the sensor, retrieve readable properties, set writeable properties, and process asynchronous data from the sensor.
This class supports multiple sets of datafields. The simplest returns a single Boolean switch state, another returns the state of an array of Boolean switches, another returns the state of a multi-value switch, and so on. Switches.h
Contains the definition of the CSwitch class.
Thermometer.cpp
Contains an implementation of the CThermometer class. The methods in this class initialize the sensor, retrieve readable properties, set writeable properties, and process asynchronous data from the sensor.
The supported datafield returns the current temperature in degrees Celsius. Thermometer.h
Contains the definition of the CThermometer class.
Unsupported.cpp
Contains an implementation of the CUnsupported class. The methods in this class initialize the sensor, retrieve readable properties, set writeable properties, and process asynchronous data from the sensor.
This class supports a single timestamp datafield. Unsupported.h
Contains the definition of the CUnsupported class.
Voltage.cpp
Contains an implementation of the CVoltage class. The methods in this class initialize the sensor, retrieve readable properties, set writeable properties, and process asynchronous data from the sensor.
The supported datafield is a voltage September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 23
measurement. Voltage.h
Contains the definition of the CVoltage class.
Resources MSDN Documentation for the Windows Driver Foundation MSDN Documentation for Sensor Drivers MSDN Documentation for Sensor Applications Sample RS232 Sensor Driver and Documentation for Windows 7 For a great book about UMDF, see “Developing Drivers with the Windows Driver Foundation Foundation”” by Orwick and Smith and published by Microsoft Press.
Appendix HID Sensor Report Descriptor The following table provides additional detail for the accelerometer, gyrometer, compass, and ambient light sensor (ALS) reports. Note that output reports are not supported by the HID sensor class driver. Also note that feature reports are generated: on initialization, client connect, client disconnect, and when properties are set.
TOP LEVEL COLLECTION Accelerometer Gyro Compass ALS
Input Report Size (bytes) 9 9 17 13
Feature Report Size (bytes) 14 14 14 14
Approximate rate at which INPUT reports are generated 60Hz 100Hz ~5Hz ~1Hz or slower
Consolidated Report Descriptor The following HID Report descriptor consolidates the report descriptors of the 5 required sensors for Slate form factors for Windows8 – accelerometer, gyrometer, compass and ambient light sensor. It is recommended that IHV and OEM partners use this descriptor when implementing sensors on Windows8 slates. This descriptor can also be used for sensor fusion when using the micro controller unit based solution for sensors. static BYTE UberHidReport[] = { HID_USAGE(0x20), 00, 0x09, 0x01, // USAGE (Collection) HID_COLLECTION(Physical), HID_REPORT_ID(1), HID_USAGE_PAGE_SENSOR, September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 24
HID_USAGE_SENSOR_TYPE_MOTION_ACCELEROMETER_3D, HID_COLLECTION(Physical), //feature reports (xmit/receive) HID_USAGE_PAGE_SENSOR, HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_SENSOR_STATUS, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_CHANGE_SENSITIVITY_ABS, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x27, 0xFF, 0xFF, 0x00, 0x00, //LOGICAL_MAXIMUM (65535) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_G, HID_UNIT_EXPONENT(2), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x27, 0xFF, 0xFF, 0xFF, 0xFF, //LOGICAL_MAXIMUM (4294967295) HID_REPORT_SIZE(32), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_MILLISECOND, HID_UNIT_EXPONENT(0), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION,HID_USAGE_SEN SOR_DATA_MOD_MAX), 0x16, 0x01, 0x80, // LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, // LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_G, HID_UNIT_EXPONENT(2), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION,HID_USAGE_SEN SOR_DATA_MOD_MIN), 0x16, 0x01, 0x80, // LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, // LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_G, HID_UNIT_EXPONENT(2), HID_FEATURE(Data_Var_Abs), //input reports (transmit) HID_USAGE_PAGE_SENSOR, HID_USAGE_SENSOR_STATE,
September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 25
0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_EVENT, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_X_AXIS, 0x16, 0x01, 0x80, // LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, // LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_G, HID_UNIT_EXPONENT(2), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_Y_AXIS, 0x16, 0x01, 0x80, // LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, // LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_G, HID_UNIT_EXPONENT(2), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_MOTION_ACCELERATION_Z_AXIS, 0x16, 0x01, 0x80, // LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, // LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_G, HID_UNIT_EXPONENT(2), HID_INPUT(Data_Var_Abs), HID_END_COLLECTION, HID_REPORT_ID(2), HID_USAGE_PAGE_SENSOR, // USAGE_PAGE (Sensor) HID_USAGE_SENSOR_TYPE_LIGHT_AMBIENTLIGHT, // USAGE (AmbientLight) HID_COLLECTION(Physical), //feature reports (xmit/receive) HID_USAGE_PAGE_SENSOR, HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_SENSOR_STATUS, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_FEATURE(Data_Var_Abs),
September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 26
HID_USAGE_SENSOR_PROPERTY_CHANGE_SENSITIVITY_REL_PCT, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x27, 0xFF, 0xFF, 0x00, 0x00, //LOGICAL_MAXIMUM (65535) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_PERCENT, HID_UNIT_EXPONENT(2), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x27, 0xFF, 0xFF, 0xFF, 0xFF, //LOGICAL_MAXIMUM (4294967295) HID_REPORT_SIZE(32), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_MILLISECOND, HID_UNIT_EXPONENT(0), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_LIGHT_ILLUMINANCE,HID_USAGE_SENSO R_DATA_MOD_MAX), 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x27, 0xFF, 0xFF, 0x00, 0x00, // LOGICAL_MAXIMUM (65535) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_LUX, HID_UNIT_EXPONENT(0xF), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_LIGHT_ILLUMINANCE,HID_USAGE_SENSO R_DATA_MOD_MIN), 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x27, 0xFF, 0xFF, 0x00, 0x00, // LOGICAL_MAXIMUM (65535) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_LUX, HID_UNIT_EXPONENT(0xF), HID_FEATURE(Data_Var_Abs), //input reports (transmit) HID_USAGE_PAGE_SENSOR, HID_USAGE_SENSOR_STATE, 0x15, 0x00, //LOGICAL_MINIMUM 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_EVENT, 0x15, 0x00, //LOGICAL_MINIMUM 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_LIGHT_ILLUMINANCE, 0x15, 0x00, //LOGICAL_MINIMUM 0x27, 0xFF, 0xFF, 0x00, 0x00, //LOGICAL_MAXIMUM HID_USAGE_SENSOR_UNITS_LUX, HID_UNIT_EXPONENT(0xF), HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_LIGHT_COLOR_TEMPERATURE, 0x15, 0x00, //LOGICAL_MINIMUM
September 13, 2011 © 2011 Microsoft. All rights reserved.
(0) (255)
(0) (255)
(0) (65535)
(0)
The HID Class Driver for Sensors - 27
0x27, 0xFF, 0xFF, 0x00, 0x00, //LOGICAL_MAXIMUM HID_USAGE_SENSOR_UNITS_KELVIN, HID_UNIT_EXPONENT(0), HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_LIGHT_CHROMATICITY_X, 0x15, 0x00, //LOGICAL_MINIMUM 0x27, 0xFF, 0xFF, 0x00, 0x00, //LOGICAL_MAXIMUM HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED, HID_UNIT_EXPONENT(4), HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_LIGHT_CHROMATICITY_Y, 0x15, 0x00, //LOGICAL_MINIMUM 0x27, 0xFF, 0xFF, 0x00, 0x00, //LOGICAL_MAXIMUM HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED, HID_UNIT_EXPONENT(4), HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_INPUT(Data_Var_Abs), HID_END_COLLECTION,
(65535)
(0) (65535)
(0) (65535)
HID_REPORT_ID(3), HID_USAGE_PAGE_SENSOR, HID_USAGE_SENSOR_TYPE_ORIENTATION_COMPASS_3D, HID_COLLECTION(Physical), //feature reports (xmit/receive) HID_USAGE_PAGE_SENSOR, HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_SENSOR_STATUS, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_CHANGE_SENSITIVITY_ABS, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x27, 0xFF, 0xFF, 0x00, 0x00, //LOGICAL_MAXIMUM (65535) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_DEGREES, HID_UNIT_EXPONENT(2), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x27, 0xFF, 0xFF, 0xFF, 0xFF, //LOGICAL_MAXIMUM (4294967295) HID_REPORT_SIZE(32), HID_REPORT_COUNT(1),
September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 28
HID_USAGE_SENSOR_UNITS_MILLISECOND, HID_UNIT_EXPONENT(0), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_HEADING,HID_USAGE_SEN SOR_DATA_MOD_MAX), 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_DEGREES, HID_UNIT_EXPONENT(1), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_ORIENTATION_HEADING,HID_USAGE_SEN SOR_DATA_MOD_MIN), 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_DEGREES, HID_UNIT_EXPONENT(1), HID_FEATURE(Data_Var_Abs), //input reports (transmit) HID_USAGE_PAGE_SENSOR, HID_USAGE_SENSOR_STATE, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_EVENT, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_ORIENTATION_HEADING_MAGNETIC_X, 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_DEGREES, HID_UNIT_EXPONENT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_ORIENTATION_HEADING_MAGNETIC_Y, 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_DEGREES, HID_UNIT_EXPONENT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_ORIENTATION_HEADING_MAGNETIC_Z, 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_DEGREES, HID_UNIT_EXPONENT(1), HID_INPUT(Data_Var_Abs),
September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 29
HID_USAGE_SENSOR_DATA_ORIENTATION_HEADING_COMPENSATED_MAGNETIC_NORTH, 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_DEGREES, HID_UNIT_EXPONENT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_ORIENTATION_HEADING_COMPENSATED_TRUE_NORTH, 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_DEGREES, HID_UNIT_EXPONENT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_ORIENTATION_HEADING_MAGNETIC_NORTH, 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_DEGREES, HID_UNIT_EXPONENT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_ORIENTATION_HEADING_TRUE_NORTH, 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_DEGREES, HID_UNIT_EXPONENT(1), HID_INPUT(Data_Var_Abs), HID_END_COLLECTION, HID_REPORT_ID(4), HID_USAGE_PAGE_SENSOR, HID_USAGE_SENSOR_TYPE_MOTION_GYROMETER_3D, HID_COLLECTION(Physical), //feature reports (xmit/receive) HID_USAGE_PAGE_SENSOR, HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_SENSOR_STATUS, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_SENSOR_CONNECTION_TYPE, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_CHANGE_SENSITIVITY_ABS, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x27, 0xFF, 0xFF, 0x00, 0x00, //LOGICAL_MAXIMUM (65535)
September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 30
HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_DEGREES_PER_SECOND, HID_UNIT_EXPONENT(2), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x27, 0xFF, 0xFF, 0xFF, 0xFF, //LOGICAL_MAXIMUM (4294967295) HID_REPORT_SIZE(32), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_MILLISECOND, HID_UNIT_EXPONENT(0), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY,HID_USAGE _SENSOR_DATA_MOD_MAX), 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_DEGREES_PER_SECOND, HID_UNIT_EXPONENT(2), HID_FEATURE(Data_Var_Abs), HID_USAGE_SENSOR_DATA(HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY,HID_USAGE _SENSOR_DATA_MOD_MIN), 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_DEGREES_PER_SECOND, HID_UNIT_EXPONENT(2), HID_FEATURE(Data_Var_Abs), //input reports (transmit) HID_USAGE_PAGE_SENSOR, HID_USAGE_SENSOR_STATE, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_EVENT, 0x15, 0x00, //LOGICAL_MINIMUM (0) 0x26, 0xFF, 0x00, //LOGICAL_MAXIMUM (255) HID_REPORT_SIZE(8), HID_REPORT_COUNT(1), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY_ROLL_AXIS, 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_DEGREES_PER_SECOND, HID_UNIT_EXPONENT(2), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY_PITCH_AXIS, 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_DEGREES_PER_SECOND,
September 13, 2011 © 2011 Microsoft. All rights reserved.
The HID Class Driver for Sensors - 31
HID_UNIT_EXPONENT(2), HID_INPUT(Data_Var_Abs), HID_USAGE_SENSOR_DATA_MOTION_ANGULAR_VELOCITY_YAW_AXIS, 0x16, 0x01, 0x80, //LOGICAL_MINIMUM (-32767) 0x26, 0xFF, 0x7F, //LOGICAL_MAXIMUM (32767) HID_REPORT_SIZE(16), HID_REPORT_COUNT(1), HID_USAGE_SENSOR_UNITS_DEGREES_PER_SECOND, HID_UNIT_EXPONENT(2), HID_INPUT(Data_Var_Abs), HID_END_COLLECTION, HID_END_COLLECTION };
September 13, 2011 © 2011 Microsoft. All rights reserved.