Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
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:
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'