Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este documento se detalla la implementación del protocolo para dispositivos de entrada habilitados para háptico que se conectan a un host compatible de Windows 11. Esto no incluye instrucciones sobre restricciones mecánicas, restricciones eléctricas o selección de componentes para generar la respuesta háptica dentro del hardware del dispositivo de entrada.
Clases de dispositivo compatibles
Windows 11 admite las siguientes clases de dispositivos de entrada habilitados para háptico:
Haptic Touchpad es una extensión de la clase Touchpad Device en Windows. Esta guía de implementación se agrega a la Guía de implementación de Touchpad y se centra en la implementación de hápticos dentro del digitalizador del panel táctil, por lo que los panel táctiles hápticos deben cumplir los requisitos de la Guía de implementación del Panel táctil además de los contenidos aquí.
El mouse háptico es una extensión de la clase Mouse Device en Windows. Los ratones hápticos deben cumplir los requisitos contenidos en esta documentación.
Nota: Los dispositivos de entrada de lápiz habilitados para hápticos son una clase especial de dispositivo que no se tratará en este documento. Para obtener información sobre cómo implementar un dispositivo de lápiz con comentarios hápticos, consulte la Guía de implementación del lápiz háptico.
Implementación del protocolo háptico para dispositivos de entrada
Se necesita una buena comprensión del protocolo HID para poder comprender la información que se presenta aquí. Consulte los siguientes recursos para obtener información sobre el protocolo HID:
El firmware del dispositivo de entrada habilitado para háptico solo necesita informar los usos descritos en este tema. Windows usará el firmware y sus propios controladores HID para habilitar el dispositivo y conceder a las aplicaciones de Windows acceso al dispositivo.
Los descriptores de ejemplo para cada clase de dispositivo compatible se proporcionan en la sección Descriptores de informe de ejemplo a continuación.
Guía común
Los elementos de esta sección se aplican a todas las clases de dispositivos hápticos de entrada.
Colección HID requerida
La funcionalidad relacionada con la retroalimentación táctil debe incluirse en la colección HID SimpleHapticsController (Page 0xE, Usage 0x1).
Para los dispositivos de panel táctil háptico, esta colección debe ser un elemento secundario de la colección de nivel superior de Windows Precision Touchpad.
En el caso de los dispositivos de ratón háptico, esta colección debe ser una colección de nivel superior y un hermano de la colección de nivel superior del ratón.
Device-Initiated comentarios hápticos
Un dispositivo de entrada con soporte háptico puede opcionalmente iniciar su propio feedback háptico, por ejemplo, en respuesta a un botón presionado o soltado.
En el caso de los paneles táctiles hápticos, la sección "Guía del panel táctil háptico" siguiente describe cómo el dispositivo puede optar por admitir informes de SET_FEATURE para permitir la personalización del usuario de su comportamiento al iniciar comentarios hápticos.
Los ratones hápticos pueden desencadenar comentarios iniciados por el dispositivo, pero Windows no tiene ningún mecanismo para configurar este comportamiento.
Host-Initiated comentarios hápticos
Un dispositivo de entrada habilitado para feedback háptico puede admitir retroalimentación háptica iniciada por el host, que puede producirse en cualquier momento después de la enumeración.
Los teclados táctiles hápticos y los ratones pueden admitir opcionalmente comentarios iniciados por el host. En el caso de los paneles táctiles hápticos, si se admiten comentarios iniciados por el host, ambos informes SET_FEATURE para la personalización de comentarios iniciados por el dispositivo también deben admitirse.
La compatibilidad con la retroalimentación háptica iniciada por el host requiere dos colecciones secundarias lógicas SimpleHapticsController (Página 0x0E, Uso 0x01). Estas colecciones lógicas deben ser elementos secundarios de la colección SimpleHapticsController principal para la clase de dispositivo que se va a implementar (como se documenta en la sección "Colección HID requerida" anterior) y deben ser independientes de la colección utilizada para configurar la intensidad de los comentarios hápticos iniciados por el dispositivo para los touchpads. Una de estas colecciones secundarias lógicas debe definir un informe de GET_FEATURE usado por el host para consultar las formas de onda admitidas y sus duraciones. La otra colección hija lógica debe definir un informe de salida usado por el host para desencadenar manualmente la respuesta háptica.
El dispositivo NO debe declarar la compatibilidad con los hápticos desencadenados automáticamente y el dispositivo NO debe admitir ninguna forma de onda continua.
Onda
En la tabla siguiente se definen las formas de onda admitidas por el host para dispositivos de entrada compatibles con tecnología háptica. Las formas de onda admitidas por un dispositivo están asociadas a un ordinal. El uso y la duración de la forma de onda se proporcionan al host a través del informe de características de información de forma de onda (consulte a continuación). Al desencadenar comentarios, el host proporciona el ordinal de la forma de onda deseada como valor para el uso manual del desencadenador.
Obligatorio y opcional
| Onda | Description | Página | identificación | Obligatorio/Opcional |
|---|---|---|---|---|
| Ninguno | Sin operación. No debería afectar al estado de juego de las formas de onda en curso | 0x0E | 0x1001 | Mandatory |
| Parar | Detiene la reproducción de formas de onda en curso | 0x0E | 0x1002 | Mandatory |
| Cernerse | Un pulso de luz usado para indicar el puntero y indicar el potencial de una próxima acción | 0x0E | 0x1008 | Mandatory |
| Chocar | Pulso suave usado para indicar colisiones con límites de pantalla o los extremos de los controles deslizantes y barras de desplazamiento | 0x0E | 0x1012 | Mandatory |
| Align | Pulso nítido que confirma la alineación del objeto durante las interacciones de arrastre, escala o rotación con guías o bordes del lienzo | 0x0E | 0x1013 | Mandatory |
| Step | Un pulso firme usado para recorrer elementos en controles deslizantes, listas o limpiezas | 0x0E | 0x1014 | Mandatory |
| Grow | Pulso dinámico que transmite movimiento, transiciones o actividad inteligente del sistema | 0x0E | 0x1015 | Mandatory |
| Presione | La señal háptica desencadenada por el dispositivo cuando determina que se ha presionado el botón de superficie. Si se admite, también se debe admitir Release. | 0x0E | 0x1006 | Opcional |
| Lanzamiento | La señal háptica desencadenada por el dispositivo cuando determina que se ha liberado el botón de superficie. Si se admite, también se debe admitir Press. | 0x0E | 0x1007 | Opcional |
| Success | Señal háptica fuerte para alertar al usuario que una acción se ha realizado correctamente | 0x0E | 0x1009 | Opcional |
| Error | Señal háptica fuerte para alertar al usuario que ha producido un error o se ha producido un error. | 0x0E | 0x100A | Opcional |
Prohibido
No se deben admitir las siguientes formas de onda.
| Onda | identificación | Notas |
|---|---|---|
| Click | 0x1003 | Provocaría confusión con los comentarios hápticos existentes para las pulsaciones de botón. |
| Buzz Continuo | 0x1004 | No se deben admitir formas de onda continuas. |
| Continua de rumberos | 0x1005 | No se deben admitir formas de onda continuas. |
| Entrada de lápiz continua | 0x100B | Solo se aplica a los lápices. |
| Lápiz continuo | 0x100C | Solo se aplica a los lápices. |
| Marcador continuo | 0x100D | Solo se aplica a los lápices. |
| Marcador de chisel continuo | 0x100E | Solo se aplica a los lápices. |
| Pincel continuo | 0x100F | Solo se aplica a los lápices. |
| Borrador continuo | 0x1010 | Solo se aplica a los lápices. |
| Brillo Continuo | 0x1011 | Solo se aplica a los lápices. |
Informe de características de información de forma de onda
El host emitirá este GET_FEATURE informe al consultar el dispositivo para sus formas de onda admitidas. Este informe de características debe tener un identificador de informe dedicado.
La colección lógica debe tener dos colecciones lógicas secundarias, una para la lista de formas de onda y otra para la lista de duración. Estas colecciones deben definir un intervalo de uso en la página Ordinal (0x0A), lo que permite al host consultar la forma de onda y la duración asociadas a cada ordinal.
Usos obligatorios y opcionales
| Miembro | Description | Página | identificación | Obligatorio/Opcional |
|---|---|---|---|---|
| Lista de formas de onda | Colección lógica que contiene una lista ordenada de formas de onda hápticas admitidas por el dispositivo | 0x0E | 0x10 | Mandatory |
| Lista de duración | Colección lógica que contiene una lista ordenada de duraciones para formas de onda en la lista de formas de onda | 0x0E | 0x11 | Mandatory |
Lista de formas de onda (obligatoria)
Esta colección proporciona la asignación entre ordinales y las formas de onda correspondientes. Los ordinales 1 y 2 corresponden a WAVEFORM_NONE y WAVEFORM_STOP implícitamente y no es necesario declararlos en el descriptor. Por lo tanto, el uso mínimo del rango de uso de la colección puede ser 3 y el uso máximo debe ser lo suficientemente grande como para asignar ordinales a todas las formas de onda admitidas.
Si el máximo de uso es mayor que el número de formas de onda compatibles con el dispositivo, el dispositivo debe notificar WAVEFORM_NONE para los ordinales no admitidos.
El intervalo lógico del intervalo de uso debe incluir todos los usos de forma de onda admitidos. El intervalo físico y las unidades deben ser 0.
Lista de duración (obligatoria)
Esta colección proporciona las duraciones de las formas de onda definidas en la lista de formas de onda. El uso mínimo y máximo del intervalo de uso de la colección debe ser idéntico a los de la lista de formas de onda.
Las formas de onda discretas deben tener una duración distinta de cero. WAVEFORM_NONE y WAVEFORM_STOP, si se especifica, deben tener una duración de cero.
El mínimo lógico del intervalo de uso debe ser cero y el máximo lógico debe ser al menos tan grande como la duración de la forma de onda discreta más larga. El host tratará los valores lógicos como milisegundos. El intervalo físico debe ser cero o idéntico al intervalo lógico. Si el intervalo físico y el intervalo lógico coinciden, las unidades deben ser milisegundos.
Informe de salida manual del desencadenador
El host emitirá este informe al desencadenar comentarios hápticos discretos. Este informe de salida debe tener un identificador de informe dedicado.
Usos obligatorios y opcionales
| Miembro | Description | Página | identificación | Obligatorio/Opcional |
|---|---|---|---|---|
| Desencadenador manual | Forma de onda que se activará como comando explícito desde el host | 0x0E | 0x21 | Mandatory |
| Intensidad | Intensidad de los comentarios | 0x0E | 0x23 | Mandatory |
| Número de repeticiones | Número de veces que se repiten los comentarios después de la reproducción inicial | 0x0E | 0x24 | Opcional |
| Período de reintentos | Duración del tiempo de espera antes de volver a desencadenar los comentarios al repetir | 0x0E | 0x25 | Opcional |
| Tiempo de corte de forma de onda | Tiempo máximo que los comentarios pueden reproducirse antes de cortarse | 0x0E | 0x28 | Opcional |
Usos prohibidos
| Usage | identificación | Notas |
|---|---|---|
| Desencadenador automático | 0x20 | No es compatible con el host. |
| Control asociado de desencadenador automático | 0x22 | No es compatible con el host. |
Desencadenador manual (obligatorio)
Este uso contiene el ordinal de la forma de onda, tal como se define en el informe de características de información de forma de onda, que el host ha solicitado que lo reproduzca. Cuando un informe de salida que contiene un ordinal distinto de WAVEFORM_NONE se envía al dispositivo, debería empezar a reproducir inmediatamente la forma de onda especificada con las propiedades adicionales incluidas en el informe de salida (Intensidad, Recuento de repeticiones, Período de retrigger, Tiempo de corte, si se admite). El dispositivo solo debe respetar ordinales para formas de onda discretas, WAVEFORM_NONE y WAVEFORM_STOP. Si el ordinal corresponde a WAVEFORM_STOP, se debe detener cualquier reproducción de forma de onda discreta en curso. Si el ordinal corresponde a WAVEFORM_NONE, no se debe realizar ninguna acción y los comentarios hápticos continuos deben seguir jugando.
El intervalo lógico debe incluir todos los ordinales posibles, incluidos los ordinales implícitos 1 (WAVEFORM_NONE) y 2 (WAVEFORM_STOP). El intervalo físico y las unidades deben ser 0.
Intensidad (obligatoria)
Este uso representa el porcentaje de intensidad máxima que se aplicará a la forma de onda solicitada, con el máximo lógico que representa la intensidad máxima y el mínimo lógico que no representa ningún comentario.
El mínimo lógico debe ser cero y el máximo lógico debe seleccionarse en función de las funcionalidades del dispositivo; por ejemplo, si el dispositivo admite cuatro niveles de intensidad, el máximo lógico debe ser cuatro. Si el dispositivo admite una intensidad más granular, el máximo lógico puede ser mayor, pero no debe superar los 100. El dispositivo debe admitir al menos cuatro niveles de intensidad, por lo que el máximo lógico mínimo es cuatro. Una intensidad de cero indica que no se debe reproducir ningún comentario: el host solo usará este valor para WAVEFORM_STOP.
El intervalo físico y las unidades deben ser 0.
Recuento de repeticiones (opcional)
Este uso representa el número de veces que se repite la forma de onda después de la reproducción inicial. Un valor de cero indica que la forma de onda solo debe reproducirse una vez.
Si se admite este uso, también se deben admitir el período de reintentación y los usos de tiempo límite.
El mínimo lógico debe ser cero y el máximo lógico debe ser mayor que cero. El máximo lógico debe limitarse a un valor pequeño (por ejemplo, 10). El intervalo físico y las unidades deben ser 0.
Período de reintentado (opcional)
Este uso representa la duración entre los retriggers de la forma de onda, medida desde la hora de inicio del desencadenador anterior. Un valor de cero debe interpretarse como idéntico a la duración predeterminada de la forma de onda, por lo que el reintentado se produce inmediatamente después de que se complete el anterior. Los valores menores que la duración predeterminada de la forma de onda deben interrumpir la forma de onda y reiniciarla.
Si se admite este uso, también se deben admitir el recuento de repeticiones y los usos de tiempo límite.
El host tratará los valores lógicos como milisegundos. El mínimo lógico debe ser cero y el máximo lógico debe ser al menos 1000 (que representa un segundo). El intervalo físico debe ser cero o idéntico al intervalo lógico. Si el intervalo físico es distinto de cero, las unidades deben ser milisegundos.
Tiempo de corte de forma de onda (opcional)
Este uso representa la cantidad máxima de tiempo que un único desencadenador puede dar lugar a la reproducción, teniendo en cuenta el recuento de repeticiones y el período de reintentos.
Si se admite este uso, también se deben admitir el recuento de repeticiones y los usos de reintentos.
El host tratará los valores lógicos como milisegundos. El mínimo lógico debe ser al menos tan grande como la duración de la forma de onda discreta más larga, multiplicada por el máximo lógico del uso de recuento de repeticiones. El intervalo físico debe ser cero o idéntico al intervalo lógico. Si el intervalo físico es distinto de cero, las unidades deben ser milisegundos.
Guía del panel táctil háptico
Los elementos de esta sección solo se aplican a los paneles táctiles hápticos.
Device-Initiated comentarios hápticos
Un panel táctil háptico es responsable de desencadenar comentarios hápticos cuando determina que el botón de superficie del panel táctil se ha presionado o liberado. Puede optar por admitir SET_FEATURE informes para permitir la personalización del usuario de su comportamiento al hacerlo:
- Intensidad de los comentarios hápticos
- La fuerza necesaria para desencadenar una pulsación de botón
Ambos informes de características son obligatorios si el panel táctil también admite comentarios hápticos iniciados por el host. Cada informe debe usar un identificador de informe distinto, no se usa con ningún otro uso.
Durante la enumeración, el host evaluará el intervalo lógico y físico admitido desde el descriptor y calculará las opciones expuestas para la interfaz de usuario de configuración, incluidos los valores predeterminados. El host emitirá el SET_FEATURE para comunicar el valor especificado por el usuario al dispositivo; esta emisión puede producirse en cualquier momento, pero se producirá cada vez que se cambie la configuración, se produzca un cambio de usuario y cuando se enumera o restablezca el dispositivo.
Informe de características de intensidad háptica
Este informe SET_FEATURE especifica la preferencia del usuario por la intensidad de los comentarios hápticos para la prensa y la liberación del botón. No se aplica a la intensidad de los comentarios iniciados por el host, si el dispositivo lo admite. Para admitir esta configuración, el dispositivo debe definir una colección secundaria lógica SimpleHapticsController (Page 0x0E, Usage 0x01) en la colección de nivel superior de Windows Precision Touchpad, que contiene el uso de intensidad háptica (Page 0x0E, Usage 0x23) como informe de características con un identificador de informe dedicado. Esta colección secundaria no debe contener los usos de desencadenador automático (0x0E de página, uso 0x20) ni desencadenador manual (0x0E de página, uso 0x21).
El mínimo lógico debe ser igual a cero. La preferencia del usuario se escalará linealmente en el intervalo lógico, con cero que indica que no se debe desencadenar ningún comentario para presionar y soltar el botón.
Botón Presionar informe de características de umbral
Este SET_FEATURE informe especifica la preferencia del usuario por la cantidad de fuerza necesaria para desencadenar una pulsación de botón. Para admitir esta configuración, el dispositivo debe definir el uso del umbral de presión del botón (página 0x0D, uso 0xB0) como informe de características con un identificador de informe dedicado en la colección de nivel superior de Windows Precision Touchpad.
El intervalo lógico se asignará linealmente al intervalo físico de valores y se espaciará uniformemente y se centrará alrededor del valor predeterminado. Al adquirir el intervalo lógico, el valor predeterminado se calculará con la fórmula siguiente:
El valor mínimo lógico, el valor predeterminado y el máximo lógico corresponden a 3 niveles distintos de presión de botón expuestos a un usuario a través de la interfaz de usuario de configuración de Windows (compatible con "Bajo", "Medio" y "Alto", respectivamente).
El intervalo físico recomendado para el umbral de presión del botón es que cubra al menos el intervalo entre 110 g y 190 g, correspondientes a los valores mínimo y máximo respectivamente. Para obtener un descriptor de ejemplo que use un máximo físico de 190 g y un mínimo físico de 110 g (por lo tanto, en función de la fórmula anterior, el valor predeterminado sería 15 0g), consulte Descriptores de informe de ejemplo.
Descriptores de informe HID de ejemplo
Descriptor de ejemplo de panel táctil háptico
El descriptor siguiente admite todos los usos obligatorios y opcionales. Declara la compatibilidad con cinco formas de onda, con la mayor duración de 50 ms.
Todos los intervalos lógicos deben actualizarse en función de la compatibilidad con dispositivos. Para admitir un número diferente de formas de onda:
- El intervalo lógico del uso manual del desencadenador debe actualizarse.
- Los intervalos de uso y el recuento de informes para la lista de formas de onda y la lista de duración deben actualizarse.
Para admitir una longitud máxima de forma de onda diferente, se deben actualizar los siguientes intervalos lógicos:
- Período de reintentos (salida)
- Tiempo de corte de forma de onda (salida)
- Lista de duración (característica)
0x05, 0x0D, // UsagePage(Digitizers[0x000D])
0x09, 0x05, // UsageId(Touch Pad[0x0005])
0xA1, 0x01, // Collection(Application)
0x85, 0x40, // ReportId(64)
0x05, 0x0D, // UsagePage(Digitizers[0x000D])
0x09, 0xB0, // UsageId(Button Press Threshold[0x00B0])
0x35, 0x6E, // PhysicalMinimum(110)
0x46, 0xBE, 0x00, // PhysicalMaximum(190)
0x66, 0x01, 0x01, // Unit('gram', SiLinear, Gram:1)
0x55, 0x00, // UnitExponent(1)
0x15, 0x01, // LogicalMinimum(1)
0x25, 0x03, // LogicalMaximum(3)
0x95, 0x01, // ReportCount(1)
0x75, 0x08, // ReportSize(8)
0xB1, 0x02, // Feature(Data, Variable, Absolute)
0x85, 0x41, // ReportId(65)
0x05, 0x0E, // UsagePage(Haptics[0x000E])
0x09, 0x01, // UsageId(Simple Haptic Controller[0x0001])
0xA1, 0x02, // Collection(Logical)
0x05, 0x0E, // UsagePage(Haptics[0x000E])
0x09, 0x23, // UsageId(Intensity[0x0023])
0x35, 0x00, // PhysicalMinimum(0)
0x45, 0x00, // PhysicalMaximum(0)
0x65, 0x00, // Unit(None)
0x55, 0x00, // UnitExponent(1)
0x15, 0x00, // LogicalMinimum(0)
0x25, 0x04, // LogicalMaximum(4)
0x95, 0x01, // ReportCount(1)
0x75, 0x08, // ReportSize(8)
0xB1, 0x02, // Feature(Data, Variable, Absolute)
0xC0, // EndCollection()
0x85, 0x42, // ReportId(66)
0x05, 0x0E, // UsagePage(Haptics[0x000E])
0x09, 0x01, // UsageId(Simple Haptic Controller[0x0001])
0xA1, 0x02, // Collection(Logical)
0x05, 0x0E, // UsagePage(Haptics[0x000E])
0x09, 0x10, // UsageId(Waveform List[0x0010])
0xA1, 0x02, // Collection(Logical)
0x05, 0x0A, // UsagePage(Ordinal[0x000A])
0x19, 0x03, // UsageIdMin(Instance 3[0x0003])
0x29, 0x07, // UsageIdMax(Instance 7[0x0007])
0x35, 0x00, // PhysicalMinimum(0)
0x45, 0x00, // PhysicalMaximum(0)
0x65, 0x00, // Unit(None)
0x55, 0x00, // UnitExponent(1)
0x16, 0x03, 0x10, // LogicalMinimum(4,099)
0x26, 0xFF, 0x2F, // LogicalMaximum(12,287)
0x95, 0x05, // ReportCount(5)
0x75, 0x10, // ReportSize(16)
0xB1, 0x02, // Feature(Data, Variable, Absolute)
0xC0, // EndCollection()
0x05, 0x0E, // UsagePage(Haptics[0x000E])
0x09, 0x11, // UsageId(Duration List[0x0011])
0xA1, 0x02, // Collection(Logical)
0x05, 0x0A, // UsagePage(Ordinal[0x000A])
0x19, 0x03, // UsageIdMin(Instance 3[0x0003])
0x29, 0x07, // UsageIdMax(Instance 7[0x0007])
0x35, 0x00, // PhysicalMinimum(0)
0x45, 0x32, // PhysicalMaximum(50)
0x66, 0x01, 0x10, // Unit('millisecond', SiLinear, Seconds:1)
0x55, 0x0D, // UnitExponent(0.001)
0x15, 0x00, // LogicalMinimum(0)
0x25, 0x32, // LogicalMaximum(50)
0x95, 0x05, // ReportCount(5)
0x75, 0x08, // ReportSize(8)
0xB1, 0x02, // Feature(Data, Variable, Absolute)
0xC0, // EndCollection()
0xC0, // EndCollection()
0x85, 0x43, // ReportId(67)
0x05, 0x0E, // UsagePage(Haptics[0x000E])
0x09, 0x01, // UsageId(Simple Haptic Controller[0x0001])
0xA1, 0x02, // Collection(Logical)
0x05, 0x0E, // UsagePage(Haptics[0x000E])
0x09, 0x21, // UsageId(Manual Trigger[0x0021])
0x35, 0x00, // PhysicalMinimum(0)
0x45, 0x00, // PhysicalMaximum(0)
0x65, 0x00, // Unit(None)
0x55, 0x00, // UnitExponent(1)
0x15, 0x01, // LogicalMinimum(1)
0x25, 0x07, // LogicalMaximum(7)
0x95, 0x01, // ReportCount(1)
0x75, 0x08, // ReportSize(8)
0x91, 0x02, // Output(Data, Variable, Absolute)
0x05, 0x0E, // UsagePage(Haptics[0x000E])
0x09, 0x23, // UsageId(Intensity[0x0023])
0x35, 0x00, // PhysicalMinimum(0)
0x45, 0x00, // PhysicalMaximum(0)
0x65, 0x00, // Unit(None)
0x55, 0x00, // UnitExponent(1)
0x15, 0x00, // LogicalMinimum(0)
0x25, 0x04, // LogicalMaximum(4)
0x95, 0x01, // ReportCount(1)
0x75, 0x08, // ReportSize(8)
0x91, 0x02, // Output(Data, Variable, Absolute)
0x05, 0x0E, // UsagePage(Haptics[0x000E])
0x09, 0x24, // UsageId(Repeat Count[0x0024])
0x35, 0x00, // PhysicalMinimum(0)
0x45, 0x00, // PhysicalMaximum(0)
0x65, 0x00, // Unit(None)
0x55, 0x00, // UnitExponent(1)
0x15, 0x00, // LogicalMinimum(0)
0x25, 0x05, // LogicalMaximum(5)
0x95, 0x01, // ReportCount(1)
0x75, 0x08, // ReportSize(8)
0x91, 0x02, // Output(Data, Variable, Absolute)
0x05, 0x0E, // UsagePage(Haptics[0x000E])
0x09, 0x25, // UsageId(Retrigger Period[0x0025])
0x35, 0x00, // PhysicalMinimum(0)
0x46, 0xE8, 0x03, // PhysicalMaximum(1,000)
0x66, 0x01, 0x10, // Unit('millisecond', SiLinear, Seconds:1)
0x55, 0x0D, // UnitExponent(0.001)
0x15, 0x00, // LogicalMinimum(0)
0x26, 0xE8, 0x03, // LogicalMaximum(1,000)
0x95, 0x01, // ReportCount(1)
0x75, 0x10, // ReportSize(16)
0x91, 0x02, // Output(Data, Variable, Absolute)
0x05, 0x0E, // UsagePage(Haptics[0x000E])
0x09, 0x28, // UsageId(Waveform Cutoff Time[0x0028])
0x36, 0xE8, 0x03, // PhysicalMinimum(1,000)
0x46, 0x88, 0x13, // PhysicalMaximum(5,000)
0x66, 0x01, 0x10, // Unit('millisecond', SiLinear, Seconds:1)
0x55, 0x0D, // UnitExponent(0.001)
0x16, 0xE8, 0x03, // LogicalMinimum(1,000)
0x26, 0x88, 0x13, // LogicalMaximum(5,000)
0x95, 0x01, // ReportCount(1)
0x75, 0x10, // ReportSize(16)
0x91, 0x02, // Output(Data, Variable, Absolute)
0xC0, // EndCollection()
0xC0, // EndCollection()
El descriptor anterior se generó a través del siguiente archivo Waratah :
[[settings]]
packingInBytes = 1
optimize = false
[[unit]]
name = 'millisecond'
second = [0.001, 1.0]
[[applicationCollection]]
usage = ['Digitizers', 'Touch Pad']
# Button press threshold feature report
[[applicationCollection.featureReport]]
id = 0x40
[[applicationCollection.featureReport.variableItem]]
usage = ['Digitizers', 'Button Press Threshold']
logicalValueRange = [1, 3]
physicalValueRange = [110, 190]
unit = 'gram'
# Feedback intensity feature report
[[applicationCollection.featureReport]]
id = 0x41
[[applicationCollection.featureReport.logicalCollection]]
usage = ['Haptics', 'Simple Haptic Controller']
[[applicationCollection.featureReport.logicalCollection.variableItem]]
usage = ['Haptics', 'Intensity']
logicalValueRange = [0, 4]
# Host-initiated waveform information feature report
[[applicationCollection.featureReport]]
id = 0x42
[[applicationCollection.featureReport.logicalCollection]]
usage = ['Haptics', 'Simple Haptic Controller']
[[applicationCollection.featureReport.logicalCollection.logicalCollection]]
usage = ['Haptics', 'Waveform List']
[[applicationCollection.featureReport.logicalCollection.logicalCollection.variableItem]]
usageRange = ['Ordinal', 'Instance 3', 'Instance 7']
logicalValueRange = [0x1003, 0x2FFF]
[[applicationCollection.featureReport.logicalCollection.logicalCollection]]
usage = ['Haptics', 'Duration List']
[[applicationCollection.featureReport.logicalCollection.logicalCollection.variableItem]]
usageRange = ['Ordinal', 'Instance 3', 'Instance 7']
logicalValueRange = [0, 50]
physicalValueRange = [0, 50]
unit = 'millisecond'
# Host-initiated waveform manual trigger output report
[[applicationCollection.outputReport]]
id = 0x43
[[applicationCollection.outputReport.logicalCollection]]
usage = ['Haptics', 'Simple Haptic Controller']
[[applicationCollection.outputReport.logicalCollection.variableItem]]
usage = ['Haptics', 'Manual Trigger']
logicalValueRange = [1, 7]
[[applicationCollection.outputReport.logicalCollection.variableItem]]
usage = ['Haptics', 'Intensity']
logicalValueRange = [0, 4]
[[applicationCollection.outputReport.logicalCollection.variableItem]]
usage = ['Haptics', 'Repeat Count']
logicalValueRange = [0, 5]
[[applicationCollection.outputReport.logicalCollection.variableItem]]
usage = ['Haptics', 'Retrigger Period']
logicalValueRange = [0, 1000]
physicalValueRange = [0, 1000]
unit = 'millisecond'
[[applicationCollection.outputReport.logicalCollection.variableItem]]
usage = ['Haptics', 'Waveform Cutoff Time']
logicalValueRange = [1000, 5000]
physicalValueRange = [1000, 5000]
unit = 'millisecond'
Descriptor de ratón háptico de ejemplo
El descriptor siguiente admite todos los usos obligatorios y opcionales. Declara la compatibilidad con ocho formas de onda, con la mayor duración de 200 ms.
Todos los intervalos lógicos deben actualizarse en función de la compatibilidad con dispositivos. Para admitir un número diferente de formas de onda:
- El intervalo lógico del uso manual del desencadenador debe actualizarse.
- Los intervalos de uso y el recuento de informes para la lista de formas de onda y la lista de duración deben actualizarse.
Para admitir una longitud máxima de forma de onda diferente, se deben actualizar los siguientes intervalos lógicos:
- Período de reintentos (salida)
- Tiempo de corte de forma de onda (salida)
- Lista de duración (característica)
0x05, 0x01, // UsagePage(Generic Desktop[0x0001])
0x09, 0x02, // UsageId(Mouse[0x0002])
0xA1, 0x01, // Collection(Application)
0x85, 0x01, // ReportId(1)
0x09, 0x01, // UsageId(Pointer[0x0001])
0xA1, 0x00, // Collection(Physical)
0x09, 0x30, // UsageId(X[0x0030])
0x09, 0x31, // UsageId(Y[0x0031])
0x15, 0x80, // LogicalMinimum(-128)
0x25, 0x7F, // LogicalMaximum(127)
0x95, 0x02, // ReportCount(2)
0x75, 0x08, // ReportSize(8)
0x81, 0x06, // Input(Data, Variable, Relative)
0x05, 0x09, // UsagePage(Button[0x0009])
0x19, 0x01, // UsageIdMin(Button 1[0x0001])
0x29, 0x03, // UsageIdMax(Button 3[0x0003])
0x15, 0x00, // LogicalMinimum(0)
0x25, 0x01, // LogicalMaximum(1)
0x95, 0x03, // ReportCount(3)
0x75, 0x01, // ReportSize(1)
0x81, 0x02, // Input(Data, Variable, Absolute)
0xC0, // EndCollection()
0x95, 0x01, // ReportCount(1)
0x75, 0x05, // ReportSize(5)
0x81, 0x03, // Input(Constant, Variable, Absolute)
0xC0, // EndCollection()
0x05, 0x0E, // UsagePage(Haptics[0x000E])
0x09, 0x01, // UsageId(Simple Haptic Controller[0x0001])
0xA1, 0x01, // Collection(Application)
0x85, 0x10, // ReportId(16)
0x09, 0x10, // UsageId(Waveform List[0x0010])
0xA1, 0x02, // Collection(Logical)
0x05, 0x0A, // UsagePage(Ordinal[0x000A])
0x19, 0x03, // UsageIdMin(Instance 3[0x0003])
0x29, 0x0A, // UsageIdMax(Instance 10[0x000A])
0x16, 0x03, 0x10, // LogicalMinimum(4,099)
0x26, 0xFF, 0x2F, // LogicalMaximum(12,287)
0x95, 0x08, // ReportCount(8)
0x75, 0x0E, // ReportSize(14)
0xB1, 0x02, // Feature(Data, Variable, Absolute)
0xC0, // EndCollection()
0x05, 0x0E, // UsagePage(Haptics[0x000E])
0x09, 0x11, // UsageId(Duration List[0x0011])
0xA1, 0x02, // Collection(Logical)
0x05, 0x0A, // UsagePage(Ordinal[0x000A])
0x19, 0x03, // UsageIdMin(Instance 3[0x0003])
0x29, 0x0A, // UsageIdMax(Instance 10[0x000A])
0x46, 0xC8, 0x00, // PhysicalMaximum(200)
0x66, 0x01, 0x10, // Unit('millisecond', SiLinear, Seconds:1)
0x55, 0x0D, // UnitExponent(0.001)
0x15, 0x00, // LogicalMinimum(0)
0x26, 0xC8, 0x00, // LogicalMaximum(200)
0x75, 0x08, // ReportSize(8)
0xB1, 0x02, // Feature(Data, Variable, Absolute)
0xC0, // EndCollection()
0x85, 0x11, // ReportId(17)
0x05, 0x0E, // UsagePage(Haptics[0x000E])
0x09, 0x21, // UsageId(Manual Trigger[0x0021])
0x45, 0x00, // PhysicalMaximum(0)
0x65, 0x00, // Unit(None)
0x55, 0x00, // UnitExponent(1)
0x15, 0x01, // LogicalMinimum(1)
0x25, 0x0A, // LogicalMaximum(10)
0x95, 0x01, // ReportCount(1)
0x75, 0x04, // ReportSize(4)
0x91, 0x02, // Output(Data, Variable, Absolute)
0x09, 0x23, // UsageId(Intensity[0x0023])
0x15, 0x00, // LogicalMinimum(0)
0x25, 0x04, // LogicalMaximum(4)
0x75, 0x03, // ReportSize(3)
0x91, 0x02, // Output(Data, Variable, Absolute)
0x09, 0x24, // UsageId(Repeat Count[0x0024])
0x25, 0x05, // LogicalMaximum(5)
0x91, 0x02, // Output(Data, Variable, Absolute)
0x09, 0x25, // UsageId(Retrigger Period[0x0025])
0x46, 0xE8, 0x03, // PhysicalMaximum(1,000)
0x66, 0x01, 0x10, // Unit('millisecond', SiLinear, Seconds:1)
0x55, 0x0D, // UnitExponent(0.001)
0x26, 0xE8, 0x03, // LogicalMaximum(1,000)
0x75, 0x0A, // ReportSize(10)
0x91, 0x02, // Output(Data, Variable, Absolute)
0x09, 0x28, // UsageId(Waveform Cutoff Time[0x0028])
0x36, 0xE8, 0x03, // PhysicalMinimum(1,000)
0x46, 0x88, 0x13, // PhysicalMaximum(5,000)
0x16, 0xE8, 0x03, // LogicalMinimum(1,000)
0x26, 0x88, 0x13, // LogicalMaximum(5,000)
0x75, 0x0D, // ReportSize(13)
0x91, 0x02, // Output(Data, Variable, Absolute)
0x75, 0x07, // ReportSize(7)
0x91, 0x03, // Output(Constant, Variable, Absolute)
0xC0, // EndCollection()
El descriptor anterior se generó a través del siguiente archivo Waratah :
[[unit]]
name = 'millisecond'
second = [0.001, 1.0]
[[applicationCollection]]
usage = ['Generic Desktop', 'Mouse']
# Mouse
[[applicationCollection.inputReport]]
[[applicationCollection.inputReport.physicalCollection]]
usage = ['Generic Desktop', 'Pointer']
[[applicationCollection.inputReport.physicalCollection.variableItem]]
usage = ['Generic Desktop', 'X']
sizeInBits = 8
logicalValueRange = 'maxSignedSizeRange'
reportFlags = ['relative']
[[applicationCollection.inputReport.physicalCollection.variableItem]]
usage = ['Generic Desktop', 'Y']
sizeInBits = 8
logicalValueRange = 'maxSignedSizeRange'
reportFlags = ['relative']
[[applicationCollection.inputReport.physicalCollection.variableItem]]
usageRange = ['Button', 'Button 1', 'Button 3']
logicalValueRange = [0, 1]
[[applicationCollection]]
usage = ['Haptics', 'Simple Haptic Controller']
# Host-initiated waveform information feature report
[[applicationCollection.featureReport]]
id = 0x10
[[applicationCollection.featureReport.logicalCollection]]
usage = ['Haptics', 'Waveform List']
[[applicationCollection.featureReport.logicalCollection.variableItem]]
usageRange = ['Ordinal', 'Instance 3', 'Instance 10']
logicalValueRange = [0x1003, 0x2FFF]
[[applicationCollection.featureReport.logicalCollection]]
usage = ['Haptics', 'Duration List']
[[applicationCollection.featureReport.logicalCollection.variableItem]]
usageRange = ['Ordinal', 'Instance 3', 'Instance 10']
logicalValueRange = [0, 200]
physicalValueRange = [0, 200]
unit = 'millisecond'
# Host-initiated waveform manual trigger output report
[[applicationCollection.outputReport]]
id = 0x11
[[applicationCollection.outputReport.variableItem]]
usage = ['Haptics', 'Manual Trigger']
logicalValueRange = [1, 10]
[[applicationCollection.outputReport.variableItem]]
usage = ['Haptics', 'Intensity']
logicalValueRange = [0, 4]
[[applicationCollection.outputReport.variableItem]]
usage = ['Haptics', 'Repeat Count']
logicalValueRange = [0, 5]
[[applicationCollection.outputReport.variableItem]]
usage = ['Haptics', 'Retrigger Period']
logicalValueRange = [0, 1000]
physicalValueRange = [0, 1000]
unit = 'millisecond'
[[applicationCollection.outputReport.variableItem]]
usage = ['Haptics', 'Waveform Cutoff Time']
logicalValueRange = [1000, 5000]
physicalValueRange = [1000, 5000]
unit = 'millisecond'