Freigeben über


Implementierungshandbuch für Eingabegeräte-Haptik

In diesem Dokument wird die Protokollimplementierung für haptische Eingabegeräte erläutert, die eine Verbindung mit einem kompatiblen Windows 11 Host herstellen. Dies schließt keine Anleitungen zu mechanischen Einschränkungen, elektrischen Einschränkungen oder Komponentenauswahl zum Generieren der haptischen Reaktion innerhalb der Hardware des Eingabegeräts ein.

Unterstützte Geräteklassen

Windows 11 unterstützt die folgenden Klassen haptischer Eingabegeräte:

  • Haptic Touchpad ist eine Erweiterung der Touchpad-Geräteklasse auf Windows. Dieser Implementierungsleitfaden fügt zum Implementierungshandbuch für Touchpads hinzu und konzentriert sich auf die Implementierung von Haptik innerhalb des Touchpad-Digitalisierungsreglers, sodass haptische Touchpads zusätzlich zu den hier enthaltenen Anforderungen auch die Anforderungen im Implementierungshandbuch für Touchpads erfüllen müssen.

  • Haptische Maus ist eine Erweiterung der Mouse Device-Klasse auf Windows. Haptische Mäuse müssen die in dieser Dokumentation enthaltenen Anforderungen erfüllen.

Hinweis

Haptische Stifteingabegeräte sind eine spezielle Geräteklasse, die in diesem Dokument nicht behandelt wird. Informationen zum Implementieren eines Stiftgeräts mit haptischem Feedback finden Sie im Implementierungshandbuch für haptische Stifte.

Implementierung des Haptikprotokolls für Eingabegeräte

Ein gutes Verständnis des HID-Protokolls ist erforderlich, um die hier dargestellten Informationen verstehen zu können. Informationen zum HID-Protokoll finden Sie in den folgenden Ressourcen:

Haptisch-fähige Eingabegerätefirmware muss nur die in diesem Thema beschriebenen Verwendungen melden. Windows verwenden die Firmware und ihre eigenen HID-Treiber, um das Gerät zu aktivieren und Windows Anwendungen Zugriff auf das Gerät zu gewähren.

Beispieldeskriptoren für jede unterstützte Geräteklasse finden Sie unten im Abschnitt "Beispielberichtdeskriptoren".

Host-initiiertes haptisches Feedback

Ein haptisch aktiviertes Eingabegerät kann das vom Host initiierte haptische Feedback unterstützen, das jederzeit nach der Enumeration ausgelöst werden kann. Funktionen im Zusammenhang mit Haptik müssen in einer HID SimpleHapticsController-Auflistung (Page 0x0E, Usage 0x01) enthalten sein.

  • Bei Touchpads muss diese Sammlung ein untergeordnetes Element der Windows Precision Touchpad-Sammlung auf oberster Ebene sein.
  • Bei Mäusen muss diese Sammlung eine Sammlung der obersten Ebene und ein gleichgeordnetes Element der Sammlung der obersten Ebene der Maus sein.

Unterstützung für vom Host initiiertes haptisches Feedback erfordert HID-Berichte:

  • Ein GET_FEATURE Bericht, der vom Host zum Abfragen nach unterstützten Wellenformen und deren Dauer verwendet wird. Weitere Informationen finden Sie im Abschnitt "Waveform Information Feature Report" weiter unten.
  • Ein AUSGABEbericht, der vom Host verwendet wird, um haptische Effekte manuell auszulösen. Weitere Informationen finden Sie im Abschnitt "Manueller Trigger-Ausgabereport" weiter unten.

Für Touchpads müssen diese Berichte in zwei logischen untergeordneten Sammlungen von SimpleHapticsController definiert werden, die der Hauptunterkollektion "SimpleHapticsController" zugeordnet sind. Bei Mäusen können diese Berichte direkt innerhalb der Sammlung der obersten Ebene definiert werden.

Wellenformen

In der folgenden Tabelle werden die vom Host unterstützten Wellenformen für haptische Eingabegeräte definiert. Die von einem Gerät unterstützten Wellenformen sind einem Ordinal zugeordnet. Die Waveform-Nutzung und -Dauer werden dem Host über den Waveform Information Feature Report (siehe unten) bereitgestellt. Beim Auslösen des Feedbacks stellt der Host die Ordnungszahl der gewünschten Wellenform als Wert für die manuelle Triggerverwendung bereit.

Obligatorisch und optional
Wellenform Description Seite ID Obligatorisch/Optional
Nichts Keine Operation. Sollte sich nicht auf den Spielzustand laufender Wellenformen auswirken 0x0E 0x1001 Obligatorisch.
Stopp! Beendet die Wiedergabe fortlaufender Wellenformen. 0x0E 0x1002 Obligatorisch.
Hover Ein Lichtimpuls, der Hoverzustände angibt und das Potenzial für eine bevorstehende Aktion signalisiert 0x0E 0x1008 Obligatorisch.
Kollidieren Ein sanfter Impuls, der anzeigt, dass eine Grenze oder ein Limit erreicht wird. 0x0E 0x1012 Obligatorisch.
Align Ein scharfer Impuls, wenn ein Objekt an einer Ausrichtungslinie einrast 0x0E 0x1013 Obligatorisch.
Schritt Ein fester Impuls für diskrete Veränderungen, z. B. das Durchlaufen von Schritten oder Werten 0x0E 0x1014 Obligatorisch.
Wachsen Ein dynamischer Impuls, der Bewegung, Übergänge oder intelligente Systemaktivität vermittelt 0x0E 0x1015 Obligatorisch.
Presse Ein Impuls, der einen Tastendruck repräsentiert 0x0E 0x1006 Siehe unten
Freigabe Ein Impuls, der das Loslassen einer Taste darstellt 0x0E 0x1007 Siehe unten
Success Ein aufsteigendes Muster, das eine abgeschlossene Aktion bestätigt 0x0E 0x1009 Siehe unten
Fehler Ein absteigendes Muster, das eine fehlgeschlagene Aktion angibt 0x0E 0x100A Siehe unten

Die Press- und Release-Wellenformen sind optional, aber wenn eine unterstützt wird, muss auch die andere unterstützt werden. Bei Touchpads sollten die Wellenformen mit dem vom Gerät initiierten Drücken- und Freigabe-Feedback übereinstimmen.

Die Erfolgs - und Fehlerwellenforms sind für Mäuse und optional für Touchpads obligatorisch. Wenn einer unterstützt wird, muss auch der andere unterstützt werden.

Verboten

Die folgenden Wellenformen DÜRFEN NICHT unterstützt werden.

Wellenform ID Hinweise
Click 0x1003 Würde Verwirrung mit dem vorhandenen haptischen Feedback für Tastendrücke verursachen.
Fortlaufender Buzz 0x1004 Kontinuierliche Wellenformen dürfen nicht unterstützt werden.
Rumble Kontinuierlich 0x1005 Kontinuierliche Wellenformen dürfen nicht unterstützt werden.
Tinte kontinuierlich 0x100B Gilt nur für Stifte.
Bleistift fortlaufend 0x100C Gilt nur für Stifte.
Markierung fortlaufend 0x100D Gilt nur für Stifte.
Chiselmarker fortlaufend 0x100E Gilt nur für Stifte.
Pinsel fortlaufend 0x100F Gilt nur für Stifte.
Radierer fortlaufend 0x1010 Gilt nur für Stifte.
Funkeln fortlaufend 0x1011 Gilt nur für Stifte.

Waveform Information Feature Report (Wellenform-Informationsfunktionsbericht)

Der Host gibt diesen GET_FEATURE Bericht aus, wenn das Gerät nach den unterstützten Wellenformen abgefragt wird. Dieser Featurebericht muss über eine dedizierte Berichts-ID verfügen.

Der Bericht muss über zwei untergeordnete logische Auflistungen verfügen, eine für die Wellenformliste und eine für die Dauerliste. Diese Auflistungen müssen einen Verwendungsbereich auf der Ordinalseite (0x0A) definieren, sodass der Host die Wellenform und die Dauer abfragen kann, die jedem Ordinal zugeordnet ist.

Obligatorische und optionale Verwendungen
Mitglied Description Seite ID Obligatorisch/Optional
Wellenformliste Logische Sammlung mit einer sortierten Liste von haptischen Wellenformen, die vom Gerät unterstützt werden 0x0E 0x10 Obligatorisch.
Dauerliste Logische Sammlung, die eine geordnete Liste der Dauern für Wellenformen in der Wellenform-Liste enthält 0x0E 0x11 Obligatorisch.
Waveform-Liste (obligatorisch)

Diese Auflistung stellt die Zuordnung zwischen Ordnungszahlen und den entsprechenden Wellenformen bereit. Ordnungszahlen 1 und 2 entsprechen implizit "None " und "Stop " und müssen nicht im Deskriptor deklariert werden. Daher kann der Mindestwert des Nutzungsbereichs der Sammlung auf 3 festgelegt werden, und der maximale Verbrauch muss groß genug sein, um allen unterstützten Wellenformen Ordinalzahlen zuordnen zu können. Es gibt keine erforderliche Reihenfolge zum Zuweisen von Wellenformen zu Ordnungszahlen 3 und höher - nur Ordnungszahlen 1 und 2 haben feste Definitionen.

Wenn die maximale Nutzung größer als die Anzahl der vom Gerät unterstützten Wellenformen ist, sollte das Gerät "Keine " für die nicht unterstützten Ordnungszahlen melden.

Der logische Bereich des Verwendungsbereichs muss alle unterstützten Wellenformverwendungen enthalten. Der physische Bereich und die Einheiten müssen 0 sein.

Laufzeitliste (verpflichtend)

Diese Auflistung stellt die Dauer der in der Wellenformliste definierten Wellenformen bereit. Der Mindest- und Maximalwert des Nutzungsbereichs der Sammlung muss mit denen der Wellenformliste identisch sein.

Diskrete Wellenformen müssen eine Nicht-Null-Dauer aufweisen. Wenn angegeben, muss "None" und "Stop" eine Dauer von Null aufweisen.

Das logische Minimum des Verwendungsbereichs muss null sein, und das logische Maximum muss mindestens so groß sein wie die Dauer der längsten diskreten Wellenform. Der Host behandelt die logischen Werte als Millisekunden. Der physische Bereich muss entweder null oder identisch mit dem logischen Bereich sein. Wenn der physische Bereich und der logische Bereich übereinstimmen, müssen die Einheiten Millisekunden sein.

Manueller Triggerausgabebericht

Der Host gibt diesen Bericht aus, wenn diskretes haptisches Feedback ausgelöst wird. Dieser Ausgabebericht muss über eine dedizierte Berichts-ID verfügen.

Obligatorische und optionale Verwendungen
Mitglied Description Seite ID Obligatorisch/Optional
Manueller Auslöser Waveform zum Auslösen als expliziter Befehl vom Host 0x0E 0x21 Obligatorisch.
Intensität Intensität des Feedbacks 0x0E 0x23 Obligatorisch.
Zahl der Wiederholungen Anzahl der Wiederholungen des Feedbacks nach dem ersten Abspielen 0x0E 0x24 Siehe unten
Neuauslösezeitraum Dauer der Wartezeit, bevor das Feedback beim Wiederholen erneut ausgelöst wird 0x0E 0x25 Siehe unten
Wellenform-Abschneidzeit Max. Zeit, zu der das Feedback wiedergegeben werden kann, bevor es abgeschnitten wird 0x0E 0x28 Siehe unten

Wiederholungsanzahl, Wiederholungszeitraum und Wellenform-Abschaltzeit sind optional, aber wenn eine unterstützt wird, müssen die anderen beiden ebenfalls unterstützt werden.

Verbotene Verwendungen
Usage ID Hinweise
Automatischer Trigger 0x20 Vom Host nicht unterstützt.
Automatisches Auslösen des zugeordneten Steuerelements 0x22 Vom Host nicht unterstützt.
Manueller Auslöser (verpflichtend)

Diese Verwendung enthält die Ordnungszahl der Wellenform, wie aus dem Bericht der Waveform-Informationsfunktion definiert, der vom Host wiedergegeben werden soll. Wenn ein Ausgabebericht mit einem anderen Ordinal als "None " an das Gerät gesendet wird, sollte er sofort mit der Wiedergabe der angegebenen Wellenform beginnen, wobei die zusätzlichen Eigenschaften im Ausgabebericht enthalten sind (Intensität, Wiederholungsanzahl, Wiederholungsperiode, Abgrenzungszeit, falls unterstützt). Das Gerät sollte nur Ordnungszahlen für diskrete Wellenformen, Keine und Stopp berücksichtigen. Wenn das Ordinal "Stop" entspricht, sollte jede fortlaufende diskrete Wellenformwiedergabe angehalten werden. Wenn die Ordnungszahl None entspricht, sollte keine Aktion ausgeführt werden, und laufendes haptisches Feedback sollte weiterhin wiedergegeben werden.

Der logische Bereich muss alle möglichen Ordnungszahlen enthalten, einschließlich der impliziten Ordnungszahlen 1 (Keine) und 2 (Stopp). Der physische Bereich und die Einheiten müssen 0 sein.

Intensität (verpflichtend)

Diese Verwendung stellt den Prozentsatz der maximalen Intensität dar, der auf die angeforderte Wellenform angewendet werden soll, wobei das logische Maximum die maximale Intensität und das logische Minimum, das überhaupt kein Feedback darstellt, darstellt.

Das logische Minimum muss null sein, und das logische Maximum sollte basierend auf den Funktionen des Geräts ausgewählt werden, z. B. wenn das Gerät vier Intensitätsstufen unterstützt, sollte das logische Maximum vier sein. Wenn das Gerät eine differenziertere Intensität unterstützt, kann das logische Maximum größer sein, darf aber 100 nicht überschreiten. Das Gerät muss mindestens vier Intensitätsstufen unterstützen, sodass das minimale logische Maximum vier beträgt. Eine Intensität von Null gibt an, dass kein Feedback wiedergegeben werden soll – der Host verwendet diesen Wert nur für Stop.

Der physische Bereich und die Einheiten müssen 0 sein.

Wiederholungsanzahl (optional)

Diese Verwendung stellt die Anzahl der Wiederholungen der Wellenform nach der ersten Wiedergabe dar. Ein Wert von Null gibt an, dass die Wellenform nur einmal wiedergegeben werden soll.

Wenn diese Verwendung unterstützt wird, müssen auch die Wiederholungs- und Ablaufzeitnutzungen unterstützt werden.

Das logische Minimum muss null sein, und das logische Maximum muss größer als Null sein. Das logische Maximum sollte mit einem angemessenen Wert (z. B. 10) begrenzt werden. Der physische Bereich und die Einheiten müssen 0 sein.

Neuauslösezeitraum (optional)

Diese Verwendung stellt die Dauer zwischen Wiederholungen der Wellenform dar, gemessen von der Startzeit des vorherigen Triggers. Ein Wert von Null sollte mit der Standarddauer für die Wellenform identisch interpretiert werden, sodass der Wiederholungsversuch unmittelbar nach Abschluss der vorherigen erfolgt. Werte kleiner als die Standarddauer für die Wellenform sollten die Wellenform unterbrechen und neu starten.

Wenn diese Verwendung unterstützt wird, müssen auch die Wiederholungs- und Abschneidzeitnutzungen unterstützt werden.

Der Host behandelt die logischen Werte als Millisekunden. Das logische Minimum muss null sein, und das logische Maximum muss mindestens 1000 (eine Sekunde) sein. Der physische Bereich muss entweder null oder identisch mit dem logischen Bereich sein. Wenn der physische Bereich ungleich Null ist, müssen die Einheiten Millisekunden sein.

Wellenform-Abschneidzeit (optional)

Diese Verwendung stellt die maximale Zeitspanne dar, die ein einzelner Trigger zur Wiedergabe führen kann, wobei die Wiederholungsanzahl und der Wiederholungszeitraum berücksichtigt werden.

Wenn diese Verwendung unterstützt wird, müssen auch die Wiederholungsanzahl und der Wiederholungszeitraum unterstützt werden.

Der Host behandelt die logischen Werte als Millisekunden. Das logische Minimum muss mindestens so groß sein wie die Dauer der längsten diskreten Wellenform, multipliziert mit dem logischen Maximum der Wiederholungsanzahl plus 1. Dieses logische Minimum stellt die Dauer des Auslösens der längsten Wellenform mit der maximal unterstützten Anzahl an erneuten Auslösern und ohne Verzögerung zwischen diesen dar. Das logische Maximum kann begrenzt werden, um eine übermäßige haptische Feedbackdauer für eine einzelne Anforderung im Ermessen des Geräts zu verhindern. Der physische Bereich muss entweder null oder identisch mit dem logischen Bereich sein. Wenn der physische Bereich ungleich Null ist, müssen die Einheiten Millisekunden sein.

Haptische Touchpad-Anleitung

Die Elemente in diesem Abschnitt gelten nur für haptische Touchpads.

Device-Initiated Haptisches Feedback

Ein haptisches Touchpad ist dafür verantwortlich, haptisches Feedback auszulösen, wenn festgestellt wird, dass die Oberfläche-Taste des Touchpads gedrückt oder losgelassen wurde. Es kann sich entscheiden, Berichte zu SET_FEATURE zu unterstützen, um benutzerspezifische Anpassungen seines Verhaltens zu ermöglichen, wenn es dies tut:

  • Die Intensität des haptischen Feedbacks
  • Die zum Auslösen eines Tastendrucks erforderliche Kraft

Beide Featureberichte sind obligatorisch, wenn das Touchpad auch vom Host initiiertes haptisches Feedback unterstützt. Jeder Bericht muss eine eindeutige Berichts-ID verwenden, die nicht mit einer anderen Verwendung verwendet wird.

Während der Enumeration bewertet der Host den unterstützten logischen und physischen Bereich vom Deskriptor und berechnet die verfügbar gemachten Optionen für die Einstellungsbenutzeroberfläche einschließlich der Standardwerte. Der Host stellt die SET_FEATURE aus, um dem Gerät den vom Benutzer angegebenen Wert mitzuteilen; Diese Veröffentlichung kann jederzeit erfolgen, tritt jedoch immer dann auf, wenn die Einstellung geändert wird, tritt ein Benutzerwechsel auf und wenn das Gerät aufgezählt oder zurückgesetzt wird. Bevor der SET_FEATURE-Bericht ausgestellt wurde, sollte das Gerät eine angemessene Standardeinstellung verwenden (z. B. die Mitte des logischen Bereichs).

Haptischer Intensitätsattribute-Bericht

Dieser SET_FEATURE Bericht gibt die Vorliebe des Benutzers für die Intensität des haptischen Feedbacks für Das Drücken und Loslassen der Schaltfläche an. Es gilt NICHT für die Intensität von vom Host initiierten Feedbacks, wenn es vom Gerät unterstützt wird. Um diese Konfiguration zu unterstützen, muss das Gerät eine logische untergeordnete Sammlung von SimpleHapticsController (Page 0x0E, Usage 0x01) in der Windows Precision Touchpad-Sammlung auf oberster Ebene definieren, die die Haptische Intensitätsnutzung (Page 0x0E, Usage 0x23) als Featurebericht mit einer dedizierten Berichts-ID enthält. Diese untergeordnete Auflistung darf weder den automatischen Trigger (Seite 0x0E, Verwendung 0x20) noch den manuellen Trigger (Seite 0x0E, Verwendung 0x21) enthalten. Sie muss von der untergeordneten Sammlung "SimpleHapticsController" getrennt sein, die für vom Host initiiertes haptisches Feedback (sofern unterstützt) verwendet wird.

Das logische Minimum muss gleich Null sein, und das logische Maximum muss größer oder gleich vier sein. Die Benutzereinstellung wird linear in den logischen Bereich skaliert, wobei null angibt, dass kein Feedback für das Drücken und Loslassen des Buttons ausgelöst werden soll.

Schwellenwert-Funktionsbericht für Tastendruck

Dieser SET_FEATURE Bericht gibt die Einstellung des Benutzers für die Zum Auslösen eines Tastendrucks erforderliche Kraftmenge an. Um diese Konfiguration zu unterstützen, muss das Gerät die Nutzung der Tastendruckschwelle (Seite 0x0D, Nutzung 0xB0) als Feature-Bericht mit einer dedizierten Berichts-ID in der Windows Precision Touchpad-Oberkollektion definieren. Sie darf nicht innerhalb einer logischen Sammlung von SimpleHapticsController enthalten sein.

Der logische Bereich muss linear dem physischen Wertebereich zugeordnet werden und gleichmäßig um den Standardwert zentriert sein. Beim Ermitteln des logischen Bereichs wird der Standardwert mit der folgenden Formel berechnet:

Diagramm, das die Formel zum Berechnen des Standardschaltflächendruckschwellenwerts in logischen Einheiten anzeigt

Das logische Minimum, Der Standardwert und das logische Maximum entsprechen 3 unterschiedlichen Ebenen der Tastendruckkraft, die einem Benutzer über Windows Einstellungs-UI verfügbar gemacht wird (unterstützt "Niedrig", "Mittel" bzw. "Hoch").

Der empfohlene physische Bereich für den Tastendruckschwellenwert besteht darin, mindestens den Bereich zwischen 110g und 190g abzudecken, der den Minimal- bzw. Höchstwerten entspricht. Für einen Beispieldeskriptor, der ein physisches Maximum von 190g verwendet, und physisches Minimum von 110g (also basierend auf der obigen Formel wäre der Standardwert 150g) siehe Beispielberichtdeskriptoren.

HID-Beispiel-Berichtdeskriptoren

Beispiele für haptische Touchpad-Beschreibungen

Der folgende Deskriptor unterstützt alle obligatorischen und optionalen Verwendungen. Es unterstützt fünf Signalformen, wobei die längste eine Dauer von 50 ms hat.

Alle logischen Bereiche sollten basierend auf der Geräteunterstützung aktualisiert werden. Zur Unterstützung einer anderen Anzahl von Wellenformen:

  • Der logische Bereich der Manuellen Triggerverwendung muss aktualisiert werden.
  • Die Nutzungsbereiche und die Berichtsanzahl für Waveform-Liste und Dauerliste müssen aktualisiert werden.

Um eine andere maximale Wellenformlänge zu unterstützen, müssen die folgenden logischen Bereiche aktualisiert werden:

  • Rückstellperiode (Ausgang)
  • Wellenform-Schnittzeit (Ausgabe)
  • Dauerliste (Feature)
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, 0x01, 0x10, //    LogicalMinimum(4,097)
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()

Der obige Deskriptor wurde über die folgende Waratah-Datei generiert:

[[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 = [0x1001, 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'

Haptische Mausdeskriptorbeispiel

Der folgende Deskriptor unterstützt alle obligatorischen und optionalen Verwendungen. Er deklariert Unterstützung für acht Wellenformen, wobei die längste Dauer von 200 ms aufweist.

Alle logischen Bereiche sollten basierend auf der Geräteunterstützung aktualisiert werden. Zur Unterstützung einer anderen Anzahl von Wellenformen:

  • Der logische Bereich der Manuellen Triggerverwendung muss aktualisiert werden.
  • Die Nutzungsbereiche und die Berichtsanzahl für Waveform-Liste und Dauerliste müssen aktualisiert werden.

Um eine andere maximale Wellenformlänge zu unterstützen, müssen die folgenden logischen Bereiche aktualisiert werden:

  • Rückstellperiode (Ausgang)
  • Wellenform-Schnittzeit (Ausgabe)
  • Dauerliste (Feature)
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, 0x01, 0x10, //   LogicalMinimum(4,097)
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()

Der obige Deskriptor wurde über die folgende Waratah-Datei generiert:

[[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 = [0x1001, 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'