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 unter 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 unter Windows. Haptische Mäuse müssen die in dieser Dokumentation enthaltenen Anforderungen erfüllen.

Hinweis: Haptisch-fähige 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 verwendet die Firmware und seine 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".

Allgemeine Anleitungen

Die Elemente in diesem Abschnitt gelten für alle Klassen von Eingabe haptischen Geräten.

Erforderliche HID-Sammlung

Funktionen im Zusammenhang mit Haptik müssen in einer HID SimpleHapticsController-Auflistung (Page 0xE, Usage 0x1) enthalten sein.

Bei Geräten mit Haptic Touchpad muss diese Sammlung ein untergeordnetes Element der Windows Precision Touchpad-Sammlung auf höherer Ebene sein.

Bei Haptic Mouse-Geräten muss diese Sammlung eine Top-Level-Sammlung sein und parallel zur Top-Level-Sammlung der Maus sein.

Device-Initiated haptisches Feedback

Ein haptisches Eingabegerät kann optional das Initiieren eines eigenen haptischen Feedbacks unterstützen, z. B. als Reaktion auf eine Taste, die gedrückt oder losgelassen wird.

Für haptische Touchpads beschreibt der Abschnitt "Haptische Touchpad-Anleitungen" unten, wie das Gerät auswählen kann, SET_FEATURE Berichte zu unterstützen, um die Benutzeranpassung seines Verhaltens beim Initiieren von haptischem Feedback zu ermöglichen.

Haptische Mäuse dürfen vom Gerät initiiertes Feedback auslösen, windows hat jedoch keinen Mechanismus zum Konfigurieren dieses Verhaltens.

Host-Initiated haptisches Feedback

Ein haptisch aktiviertes Eingabegerät kann das vom Host initiierte haptische Feedback unterstützen, das jederzeit nach der Aufzählung auftreten kann.

Haptische Touchpads und Mäuse können optional vom Host initiiertes Feedback unterstützen. Bei haptischen Touchpads müssen sowohl SET_FEATURE Berichte für geräteinitiierte Feedbackanpassungen unterstützt werden, wenn hostinitiiertes Feedback unterstützt wird.

Unterstützung für vom Host initiiertes haptisches Feedback erfordert zwei logische untergeordnete SimpleHapticsController-Sammlungen (Page 0x0E, Usage 0x01). Diese logischen Auflistungen müssen untergeordnete Elemente der SimpleHapticsController-Hauptauflistung für die implementierte Geräteklasse sein (wie im Abschnitt "Erforderliche HID-Auflistung" oben dokumentiert) und müssen von der Sammlung getrennt sein, die zum Konfigurieren der Intensität von vom Gerät initiierten haptischen Feedbacks für Touchpads verwendet wird. Eine dieser logischen untergeordneten Sammlungen muss einen GET_FEATURE-Report definieren, den der Host verwendet, um die unterstützten Wellenformen sowie ihre jeweiligen Dauern abzufragen. Die andere logische untergeordnete Sammlung muss einen Ausgabebericht definieren, der vom Host verwendet wird, um Haptik manuell auszulösen.

Das Gerät darf keine Unterstützung für automatisch ausgelöste Haptik deklarieren, und das Gerät darf keine fortlaufenden Wellenformen unterstützen.

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 No-op. Sollte sich nicht auf den Spielzustand laufender Wellenformen auswirken 0x0E 0x1001 Obligatorisch.
Stopp! Beendet die Wiedergabe fortlaufender Wellenformen. 0x0E 0x1002 Obligatorisch.
Hover Ein Lichtpuls, der verwendet wird, um darauf hinzuweisen und das Potenzial für eine bevorstehende Aktion zu signalisieren 0x0E 0x1008 Obligatorisch.
Kollidieren Ein weicher Impuls, der verwendet wird, um Kollisionen mit Bildschirmgrenzen oder den Enden von Schiebereglern und Bildlaufleisten anzuzeigen 0x0E 0x1012 Obligatorisch.
Align Ein scharfer Impuls, der die Objektausrichtung beim Ziehen, Skalieren oder Drehen von Interaktionen mit Führungslinien oder Zeichenbereichsrändern bestätigt 0x0E 0x1013 Obligatorisch.
Schritt Ein fester Impuls zum Durchlaufen von Elementen in Schiebereglern, Listen oder Scrubbern 0x0E 0x1014 Obligatorisch.
Wachsen Ein dynamischer Impuls, der Bewegung, Übergänge oder intelligente Systemaktivität vermittelt 0x0E 0x1015 Obligatorisch.
Presse Das haptische Signal, das vom Gerät ausgelöst wird, wenn festgestellt wird, dass die Schaltfläche der Oberfläche gedrückt wurde. Falls unterstützt, muss release ebenfalls unterstützt werden. 0x0E 0x1006 Wahlfrei
Freigabe Das haptische Signal, das vom Gerät ausgelöst wird, wenn es bestimmt, dass die Oberflächenschaltfläche losgelassen wurde. Wenn dies unterstützt wird, muss auch die Presse unterstützt werden. 0x0E 0x1007 Wahlfrei
Success Starkes haptisches Signal, um den Benutzer zu benachrichtigen, dass eine Aktion erfolgreich war 0x0E 0x1009 Wahlfrei
Fehler Starkes haptisches Signal, um den Benutzer zu benachrichtigen, dass eine Aktion fehlgeschlagen ist oder ein Fehler aufgetreten ist. 0x0E 0x100A Wahlfrei
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 sollten nicht unterstützt werden.
Rumble fortlaufend 0x1005 Kontinuierliche Wellenformen sollten nicht unterstützt werden.
Freihand fortlaufend 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.

Die logische Auflistung muss über zwei logische Auflistungen mit untergeordneten Elementen verfügen, eine für die Wellenformliste und eine für die Dauerliste. Diese Auflistungen müssen einen Verwendungsbereich auf der Ordinalseite (0x0A) definieren, mit dem 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 Auflistung, die eine sortierte Liste der Daueren für Wellenformen in der Waveform-Liste enthält 0x0E 0x11 Obligatorisch.
Waveform-Liste (verpflichtend)

Diese Auflistung stellt die Zuordnung zwischen Ordnungszahlen und den entsprechenden Wellenformen bereit. Ordnungszahlen 1 und 2 entsprechen WAVEFORM_NONE und WAVEFORM_STOP implizit und müssen nicht im Deskriptor deklariert werden. Daher kann der Mindesteinsatzbereich der Sammlung 3 sein, und die maximale Nutzung sollte groß genug sein, um allen unterstützten Wellenformen Ordinale zuzuweisen.

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

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

Dauerliste (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. WAVEFORM_NONE und WAVEFORM_STOP( sofern angegeben) muss 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 Wahrheitswerte als Millisekunden. Der physische Bereich muss entweder null oder identisch mit dem logischen Bereich sein. Wenn der physische Bereich und der logische Bereich übereinstimmen, sollten 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 Trigger 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 der ersten Wiedergabe 0x0E 0x24 Wahlfrei
Wiederholungszeitraum Dauer der Wartezeit, bevor das Feedback beim Wiederholen erneut ausgelöst wird 0x0E 0x25 Wahlfrei
Wellenform-Abschneidzeit Max. Zeit, zu der das Feedback wiedergegeben werden kann, bevor es abgeschnitten wird 0x0E 0x28 Wahlfrei
Verbotene Verwendungen
Usage ID Hinweise
Automatischer Trigger 0x20 Vom Host nicht unterstützt.
Zugeordnetes Steuerelement automatisch auslösen 0x22 Vom Host nicht unterstützt.
Manueller Trigger (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 WAVEFORM_NONE an das Gerät gesendet wird, sollte es sofort mit der Wiedergabe der angegebenen Wellenform mit den zusätzlichen Eigenschaften beginnen, die im Ausgabebericht enthalten sind (Intensität, Wiederholungsanzahl, Wiederholungsperiode, Ausschneidezeit, falls unterstützt). Das Gerät sollte nur Ordnungszahlen für diskrete Wellenformen, WAVEFORM_NONE und WAVEFORM_STOP berücksichtigen. Wenn das Ordinal WAVEFORM_STOP entspricht, sollte jede fortlaufende diskrete Wellenformwiedergabe beendet werden. Wenn das Ordinal WAVEFORM_NONE entspricht, sollte keine Aktion ausgeführt werden, und laufende haptisches Feedback sollte weiterhin wiedergegeben werden.

Der logische Bereich muss alle möglichen Ordnungszahlen enthalten, einschließlich der impliziten Ordnungszahlen 1 (WAVEFORM_NONE) und 2 (WAVEFORM_STOP). 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 genauere Intensität unterstützt, kann das logische Maximum größer sein, darf aber nicht mehr als 100 sein. 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 WAVEFORM_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 kleinen Wert (z. B. 10) begrenzt werden. Der physische Bereich und die Einheiten müssen 0 sein.

Wiederholungszeitraum (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 Wahrheitswerte 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, sollten 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 Wiederholungs- und Wiederholungsverwendungen unterstützt werden.

Der Host behandelt die Wahrheitswerte als Millisekunden. Das logische Minimum muss mindestens so groß sein wie die Dauer der längsten diskreten Wellenform, multipliziert mit dem logischen Maximum der Wiederholungsanzahlnutzung. Der physische Bereich muss entweder null oder identisch mit dem logischen Bereich sein. Wenn der physische Bereich ungleich Null ist, sollten 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 Surface-Taste des Touchpads gedrückt oder losgelassen wurde. Es kann sich entscheiden, SET_FEATURE Berichte zu unterstützen, um benutzerspezifische Anpassungen des Verhaltens zu ermöglichen, wenn dies geschieht:

  • 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.

Haptische Intensitätsfunktionsbericht

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 SimpleHapticsController-Sammlung (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 Auslöser (Page 0x0E, Usage 0x20) noch den manuellen Trigger (Page 0x0E, Usage 0x21) enthalten.

Das logische Minimum muss gleich Null sein. Die Benutzereinstellung wird linear in den logischen Bereich skaliert, wobei null angibt, dass kein Feedback für Das Drücken und Loslassen der Schaltfläche 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 Verwendung des Tastendruckschwellenwerts (Seite 0x0D, Verwendung 0xB0) als Featurebericht mit einer dedizierten Berichts-ID in der Windows Precision Touchpad-Sammlung auf oberster Ebene definieren.

Der logische Bereich muss linear dem physischen Wertebereich zugeordnet werden und gleichmäßig um den Standardwert zentriert sein. Beim Abrufen 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, "Standard" und "Logisches Maximum" entsprechen 3 unterschiedlichen Ebenen der Tastendruckkraft, die einem Benutzer über die 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. Er deklariert Die Unterstützung für fünf Wellenformen mit der längsten Dauer von 50 ms.

Alle logischen Bereiche sollten basierend auf der Geräteunterstützung aktualisiert werden. So unterstützen Sie eine andere 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:

  • Wiederholungszeitraum (Ausgabe)
  • Wellenform-Abschneidzeit (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, 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()

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 = [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'

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. So unterstützen Sie eine andere 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:

  • Wiederholungszeitraum (Ausgabe)
  • Wellenform-Abschneidzeit (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, 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()

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 = [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'