Implementatiehandleiding voor haptische invoerapparaten

Dit document bevat informatie over de protocol-implementatie voor invoerapparaten met haptische functionaliteit die verbinding maken met een compatibele Windows 11 host. Dit omvat geen richtlijnen voor mechanische beperkingen, elektrische beperkingen of selectie van onderdelen voor het genereren van de haptische reactie binnen de hardware van het invoerapparaat.

Ondersteunde apparaatklassen

Windows 11 ondersteunt de volgende klassen invoerapparaten met haptische functionaliteit:

  • Haptic Touchpad is een uitbreiding van de touchpad-apparaatklasse op Windows. Deze implementatiehandleiding voegt toe aan de Implementatiehandleiding voor touchpad en richt zich op het implementeren van haptiek in de touchpad-digitalisatiefunctie, dus haptische touchpads moeten voldoen aan de vereisten in de implementatiehandleiding voor touchpads , naast de vereisten die hier zijn opgenomen.

  • Haptic Mouse is een uitbreiding van de klasse Mouse Device op Windows. Haptic mice moeten voldoen aan de vereisten in deze documentatie.

Opmerking

Haptic-compatibele peninvoerapparaten zijn een speciale apparaatklasse die niet wordt behandeld in dit document. Zie de Haptic Pen Implementation Guide (Implementatiehandleiding voor Haptic Pen) voor informatie over het implementeren van een penapparaat met haptische feedback.

Implementatie van het Haptics-protocol voor invoerapparaten

Een goed begrip van het HID-protocol is nodig om inzicht te krijgen in de informatie die hier wordt gepresenteerd. Zie de volgende bronnen voor informatie over het HID-protocol:

De firmware van haptic-invoerapparaten hoeft alleen de gebruiksgegevens te rapporteren die in dit onderwerp worden beschreven. Windows gebruikt de firmware en de eigen HID-stuurprogramma's om het apparaat in te schakelen en Windows toepassingen toegang te geven tot het apparaat.

Voorbeelddescriptors voor elke ondersteunde apparaatklasse vindt u in de sectie Voorbeeldrapportdescriptors hieronder.

Door Host Geïnitieerde Haptische Terugkoppeling

Een haptisch ondersteund invoerapparaat kan ondersteuning bieden voor door de host geïnitieerde haptische feedback, die op elk gewenst moment na enumeratie kan worden geactiveerd. Functionaliteit met betrekking tot haptiek moet worden opgenomen in een HID SimpleHapticsController-verzameling (Page 0x0E, Usage 0x01).

  • Voor touchpads moet deze verzameling een onderdeel zijn van de Windows Precision Touchpad topniveau-verzameling.
  • Voor muizen moet deze verzameling een verzameling op het hoogste niveau zijn en een broertje van de verzameling Muis op het hoogste niveau.

Ondersteuning voor door de host geïnitieerde haptische feedback vereist HID-rapporten:

  • Een GET_FEATURE rapport dat door de host wordt gebruikt om een query uit te voeren op ondersteunde golfvormen en de duur ervan. Zie de sectie Waveform Information Feature Report hieronder.
  • Een UITVOERrapport dat door de host wordt gebruikt om haptiek handmatig te activeren. Zie de sectie "Handmatige triggeruitvoerrapport" hieronder.

Voor touchpads moeten deze rapporten worden gedefinieerd in twee logische onderliggende verzamelingen van SimpleHapticsController die gekoppeld zijn aan de hoofdverzameling van SimpleHapticsController. Voor muizen kunnen deze rapporten rechtstreeks binnen de verzameling op het hoogste niveau worden gedefinieerd.

Golfvormen

In de volgende tabel worden de golfvormen gedefinieerd die door de host worden ondersteund voor invoerapparaten met haptische functionaliteit. De golfvormen die door een apparaat worden ondersteund, zijn gekoppeld aan een ordinaal. Het gebruik en de duur van de golfvorm worden aan de host verstrekt via het rapport van de waveform-informatiefunctie (zie hieronder). Bij het activeren van feedback geeft de host het rangtelwoord van de gewenste golfvorm op als de waarde voor het handmatige triggergebruik.

Verplicht en optioneel
Golfvorm Description Page ID-kaart Verplicht/optioneel
Geen Geen operatie. Mag geen invloed hebben op de weergavestatus van actieve golfvormen 0x0E 0x1001 Mandatory
Stoppen Stopt het afspelen van lopende golfvormen 0x0E 0x1002 Mandatory
Zweven Een lichte puls die zweefstatussen aangeeft en het potentieel voor een aankomende actie signaleert. 0x0E 0x1008 Mandatory
Botsen Een zachte puls om aan te geven dat een grens of limiet bereikt wordt 0x0E 0x1012 Mandatory
Align Een scherpe impuls wanneer een object vastklikt op een uitlijningshulplijn 0x0E 0x1013 Mandatory
Step Een stevige puls voor discrete wijzigingen, zoals het doorlopen van stappen of waarden 0x0E 0x1014 Mandatory
Groei Een dynamische puls die beweging, overgangen of intelligente systeemactiviteit overbrengt 0x0E 0x1015 Mandatory
Druk Een puls die een knopdruk vertegenwoordigt 0x0E 0x1006 Zie hieronder
Vrijgeven Een puls die een knoprelease vertegenwoordigt 0x0E 0x1007 Zie hieronder
Success Een oplopend patroon dat een voltooide actie bevestigt 0x0E 0x1009 Zie hieronder
Fout Een aflopend patroon dat een mislukte actie aangeeft 0x0E 0x100A Zie hieronder

De druk en release-golfvormen zijn optioneel, maar als de ene wordt ondersteund, moet de andere ook ondersteund zijn. Voor touchpads moeten de golfvormen overeenkomen met de door het apparaat geïnitieerde pers- en releasefeedback.

De succes- en foutgolfvormen zijn verplicht voor muizen en optioneel voor touchpads. Als de ene wordt ondersteund, moet de andere dat ook zijn.

Verboden

De volgende golfvormen moeten niet worden ondersteund.

Golfvorm ID-kaart Opmerkingen
Klik 0x1003 Zou verwarring veroorzaken met de bestaande haptische feedback voor knopdrukken.
Doorlopende buzz 0x1004 Doorlopende golfvormen moeten niet worden ondersteund.
Doorlopende Trilling 0x1005 Doorlopende golfvormen moeten niet worden ondersteund.
Inkt doorlopend 0x100B Alleen van toepassing op pennen.
Potlood doorlopend 0x100C Alleen van toepassing op pennen.
Doorlopende markering 0x100D Alleen van toepassing op pennen.
Beitelmarkering doorlopend 0x100E Alleen van toepassing op pennen.
Borstel doorlopend 0x100F Alleen van toepassing op pennen.
Gum doorlopend 0x1010 Alleen van toepassing op pennen.
Sparkle Doorlopend 0x1011 Alleen van toepassing op pennen.

Waveform Informatie Eigenschapsrapport

De host zal dit GET_FEATURE-rapport verstrekken wanneer het apparaat wordt geraadpleegd voor zijn ondersteunde golfvormen. Dit functierapport moet een toegewezen rapport-id hebben.

Het rapport moet twee onderliggende logische verzamelingen hebben, één voor de lijst met golfvormen en één voor de lijst met duur. Deze verzamelingen moeten een gebruiksbereik definiëren op de Ordinal-pagina (0x0A), waarmee de host de golfvorm en de duur kan opvragen die aan elke ordinaal is gekoppeld.

Verplicht en optioneel gebruik
Lid Description Page ID-kaart Verplicht/optioneel
Lijst met golfvormen Logische verzameling met een geordende lijst haptische golfvormen die door het apparaat worden ondersteund 0x0E 0x10 Mandatory
Duurlijst Logische verzameling met een geordende lijst van duur voor golfvormen in de Golfvormlijst 0x0E 0x11 Mandatory
Lijst van golfvormen (verplicht)

Deze verzameling biedt de koppeling tussen rangnummers en de bijbehorende golfvormen. De rangtelwoorden 1 en 2 komen impliciet overeen met Geen en Stop en hoeven niet in de descriptor te worden opgenomen. Daarom kan het gebruiksminimum van het gebruiksbereik van de verzameling 3 zijn en moet het gebruikslimiet groot genoeg zijn om ordinalen toe te wijzen aan alle ondersteunde golfvormen. Er is geen vereiste volgorde voor het toewijzen van golfvormen aan rangtelwoorden 3 en hoger. Alleen de rangtelwoorden 1 en 2 hebben vaste definities.

Als het gebruikslimiet groter is dan het aantal golfvormen dat door het apparaat wordt ondersteund, moet het apparaat Geen rapporteren voor de niet-ondersteunde ordinalen.

Het logische bereik van het toepassingsbereik moet alle ondersteunde golfvormgebruiken bevatten. Het fysieke bereik en de eenheden moeten 0 zijn.

Duurlijst (verplicht)

Deze verzameling bevat de duur van de golfvormen die zijn gedefinieerd in de lijst met golfvormen. Het gebruiksminimum en maximum van het gebruiksbereik van de verzameling moeten identiek zijn aan die van de golfvormlijst.

Discrete golfvormen moeten een niet-nulduur hebben. Geen en Stop, indien opgegeven, moeten een duur van nul hebben.

Het logische minimum van het gebruiksbereik moet nul zijn en het logische maximum moet minstens zo groot zijn als de duur van de langste discrete golfvorm. De host behandelt de logische waarden als milliseconden. Het fysieke bereik moet nul of identiek zijn aan het logische bereik. Als het fysieke bereik en het logische bereik overeenkomen, moeten de eenheden milliseconden zijn.

Rapport voor handmatige triggergegevensuitvoer

De host geeft dit rapport uit bij het activeren van discrete haptische feedback. Dit uitvoerrapport moet een toegewezen rapport-id hebben.

Verplicht en optioneel gebruik
Lid Description Page ID-kaart Verplicht/optioneel
Handmatige trigger Golfvorm aansturen door een expliciet commando van de host 0x0E 0x21 Mandatory
Intensiteit Intensiteit van de feedback 0x0E 0x23 Mandatory
Aantal herhalingen Aantal keren om de feedback te herhalen na het eerste afspelen 0x0E 0x24 Zie hieronder
Herstartperiode De tijdsduur die moet worden gewacht voordat de feedback opnieuw wordt geactiveerd bij het herhalen 0x0E 0x25 Zie hieronder
Uitschakeltijd voor golfvorm Maximale tijd dat de feedback kan worden afgespeeld voordat deze wordt afgekapt 0x0E 0x28 Zie hieronder

Repeat Count, Retrigger Period en Waveform Cutoff Time zijn optioneel, maar als de ene wordt ondersteund, moeten de andere twee ook zijn.

Verboden gebruik
Usage ID-kaart Opmerkingen
Trigger voor Automatisch Activeren 0x20 Niet ondersteund door de host.
Automatische activering geassocieerde bediening 0x22 Niet ondersteund door de host.
Handmatige Trigger (Verplicht)

Dit gebruik bevat het rangtelwoord van de golfvorm, zoals gedefinieerd in het rapport met informatie over golfvormen, dat is aangevraagd om door de host te worden afgespeeld. Wanneer een uitvoerrapport met een andere rangtel dan Geen naar het apparaat wordt verzonden, moet het onmiddellijk beginnen met het afspelen van de opgegeven golfvorm met de aanvullende eigenschappen die zijn opgenomen in het uitvoerrapport (Intensiteit, Aantal herhalingen, Retriggerperiode, Cutoff-tijd, indien ondersteund). Het apparaat dient alleen ordeningen voor discrete golfvormen, Geen en Stop, te respecteren. Als het rangtelwoord overeenkomt met Stoppen, moet het afspelen van doorlopende discrete golfvormen worden gestopt. Als het rangtelwoord overeenkomt met Geen, moet er geen actie worden uitgevoerd en moet doorlopende haptische feedback blijven spelen.

Het logische bereik moet alle mogelijke rangtelwoorden bevatten, inclusief de impliciete rangtelwoorden 1 (Geen) en 2 (Stop). Het fysieke bereik en de eenheden moeten 0 zijn.

Intensiteit (verplicht)

Dit gebruik vertegenwoordigt het percentage van de maximale intensiteit dat moet worden toegepast op de aangevraagde golfvorm, met het logische maximum dat de maximale intensiteit vertegenwoordigt en het logische minimum dat helemaal geen feedback vertegenwoordigt.

Het logische minimum moet nul zijn en het logische maximum moet worden geselecteerd op basis van de mogelijkheden van het apparaat, bijvoorbeeld als het apparaat vier intensiteitsniveaus ondersteunt, moet het logische maximum vier zijn. Als het apparaat meer gedetailleerde intensiteit ondersteunt, kan het logische maximum groter zijn, maar mag het niet groter zijn dan 100. Het apparaat moet ten minste vier intensiteitsniveaus ondersteunen, dus het minimale logische maximum is vier. Een intensiteit van nul geeft aan dat er geen feedback moet worden afgespeeld. De host gebruikt deze waarde alleen voor Stop.

Het fysieke bereik en de eenheden moeten 0 zijn.

Aantal herhalingen (optioneel)

Dit gebruik geeft het aantal keren aan dat de golfvorm na het eerste afspelen moet worden herhaald. Een waarde van nul geeft aan dat de golfvorm slechts één keer moet worden afgespeeld.

Als dit gebruik wordt ondersteund, moeten de retriggerperiode en de cutofftijd-gebruiken ook worden ondersteund.

Het logische minimum moet nul zijn en het logische maximum moet groter zijn dan nul. Het logische maximum moet worden beperkt tot een redelijke waarde (bijvoorbeeld 10). Het fysieke bereik en de eenheden moeten 0 zijn.

Periode opnieuw inrigger (optioneel)

Dit gebruik vertegenwoordigt de duur tussen retriggers van de golfvorm, gemeten vanaf de begintijd van de vorige trigger. Een waarde van nul moet worden geïnterpreteerd als identiek aan de standaardduur voor de golfvorm, dus de retrigger vindt plaats zodra de vorige is voltooid. Waarden die kleiner zijn dan de standaardduur voor de golfvorm, moeten de golfvorm onderbreken en opnieuw opstarten.

Als dit gebruik wordt ondersteund, moeten het aantal herhalingen en het gebruik van afkaptijd ook worden ondersteund.

De host behandelt de logische waarden als milliseconden. Het logische minimum moet nul zijn en het logische maximum moet ten minste 1000 zijn (één seconde). Het fysieke bereik moet nul of identiek zijn aan het logische bereik. Als het fysieke bereik niet nul is, moeten de eenheden milliseconden zijn.

Afkaptijd voor golfvormen (optioneel)

Dit gebruik vertegenwoordigt de maximale tijdsduur dat een enkele trigger kan leiden tot het afspelen, rekening houdend met het aantal herhalingen en de periode voor opnieuw activeren.

Als dit gebruik wordt ondersteund, moeten ook het herhalingsaantal en de opnieuw-triggerperiode worden ondersteund.

De host behandelt de logische waarden als milliseconden. Het logische minimum moet minstens zo groot zijn als de duur van de langste discrete golfvorm, vermenigvuldigd met het logische maximum van het gebruik van het aantal herhalingen plus één. Dit logische minimum vertegenwoordigt de tijdsduur waarin de langste golfvorm wordt geactiveerd met het maximaal ondersteunde aantal herhaalde triggers en zonder vertraging tussen de retriggers. Het logische maximum kan worden beperkt om overmatige haptische feedbackduur voor één aanvraag te voorkomen, naar eigen goeddunken van het apparaat. Het fysieke bereik moet nul of identiek zijn aan het logische bereik. Als het fysieke bereik niet nul is, moeten de eenheden milliseconden zijn.

Richtlijnen voor Haptic Touchpad

De items in deze sectie zijn alleen van toepassing op haptische touchpads.

Apparaat-geïnitieerde Haptische Feedback

Een haptisch aanraakvlak is verantwoordelijk voor het activeren van haptische feedback wanneer wordt vastgesteld dat de knop op het aanraakvlak is ingedrukt of losgelaten. Het kan ervoor kiezen om SET_FEATURE rapporten te ondersteunen zodat gebruikers het gedrag ervan kunnen aanpassen wanneer u dit doet:

  • De intensiteit van de haptische feedback
  • De kracht die nodig is om een knop in te drukken

Beide functierapporten zijn verplicht als de touchpad ook ondersteuning biedt voor door de host geïnitieerde haptische feedback. Elk rapport moet een unieke rapport-id gebruiken, die niet voor een ander doel is gebruikt.

Tijdens de inventarisatie beoordeelt de host het ondersteunde logische en fysieke bereik van de descriptor en berekent de beschikbare opties voor de gebruikersinterface met instellingen, inclusief de standaardinstellingen. De host geeft de SET_FEATURE uit om de door de gebruiker opgegeven waarde aan het apparaat te communiceren; deze uitgifte kan zich op elk gewenst moment voordoen, maar gebeurt wanneer de instelling wordt gewijzigd, een gebruikersswitch plaatsvindt en wanneer het apparaat wordt geïnventariseerd of opnieuw wordt ingesteld. Voordat het SET_FEATURE rapport is uitgegeven, moet het apparaat een redelijke standaardinstelling van eigen keuze gebruiken (bijvoorbeeld het midden van het logische bereik).

Functierapport haptische intensiteit

Dit SET_FEATURE rapport geeft de voorkeur van de gebruiker op voor de intensiteit van de haptische feedback voor knopdrukken en vrijgeven. Deze is niet van toepassing op de intensiteit van door de host geïnitieerde feedback, indien ondersteund door het apparaat. Ter ondersteuning van deze configuratie moet het apparaat een logische verzameling logische onderliggende objecten van SimpleHapticsController (Pagina 0x0E, Gebruik 0x01) definiëren in de verzameling Windows Precision Touchpad op het hoogste niveau, met daarin het gebruik van haptische intensiteit (Pagina 0x0E, Gebruik 0x23) als een functierapport met een toegewezen rapport-id. Deze subverzameling mag het gebruik van de automatische trigger (pagina 0x0E, gebruik 0x20) of de handmatige trigger (pagina 0x0E, gebruik 0x21) niet bevatten. Deze moet gescheiden zijn van de onderliggende verzameling SimpleHapticsController die wordt gebruikt voor door de host geïnitieerde haptische feedback (indien ondersteund).

Het logische minimum moet gelijk zijn aan nul en het logische maximum moet groter zijn dan of gelijk zijn aan vier. De voorkeur van de gebruiker wordt lineair geschaald naar het logische bereik, waarbij nul aangeeft dat er geen feedback moet worden geactiveerd voor knopdrukken en vrijgeven.

Knopdruk drempelwaarde functie rapport

Dit SET_FEATURE rapport geeft de voorkeur van de gebruiker op voor de hoeveelheid kracht die nodig is om een knop te activeren. Ter ondersteuning van deze configuratie moet het apparaat het gebruik van Button Press Threshold (pagina 0x0D, gebruik 0xB0) definiëren als een functierapport met een speciale rapport-ID in de toplevelcollectie van Windows Precision Touchpad. Deze mag zich niet in een logische verzameling SimpleHapticsController bevinden.

Het logische bereik moet lineair worden toegewezen aan het fysieke waardenbereik en gelijkmatig worden gespomd en gecentreerd rond de standaardwaarde. Bij het verkrijgen van het logische bereik wordt de standaardwaarde berekend met behulp van de volgende formule:

Diagram met de formule voor het berekenen van de standaardknopdrukdrempel in logische eenheden

Het logische minimum, de standaardwaarde en het logische maximum komen overeen met drie verschillende niveaus van knopdrukken die door de gebruikersinterface van Windows instellingen worden weergegeven (ondersteuning voor respectievelijk 'Laag', 'Gemiddeld' en 'Hoog').

Het aanbevolen fysieke bereik voor knopdrukdrempel is om ten minste het bereik tussen 110g en 190g te dekken, dat overeenkomt met respectievelijk de minimum- en maximumwaarden. Zie Voorbeeldrapportdescriptors voor een voorbeelddescriptor die gebruikmaakt van een fysiek maximum van 190g en fysieke minimum van 110g (dus op basis van de bovenstaande formule is de standaardwaarde 150g).

Voorbeelden van HID-rapportdescriptors

Voorbeeld van Haptic Touchpad Descriptor

De volgende descriptor ondersteunt alle verplichte en optionele gebruiksgegevens. Het declareert ondersteuning voor vijf golfvormen, met de langste duur van 50 ms.

Alle logische bereiken moeten worden bijgewerkt op basis van de ondersteuning door apparaten. Ter ondersteuning van een ander aantal golfvormen:

  • Het logische bereik van het handmatige triggergebruik moet worden bijgewerkt
  • De gebruiksbereiken en het aantal rapporten voor Waveform List en Duration List moeten worden bijgewerkt

Als u een andere maximale golfvormlengte wilt instellen, moet het volgende logische bereik worden bijgewerkt:

  • Retriggerperiode (uitvoer)
  • Cutoff-tijd voor golfvormen (uitvoer)
  • Duuuroverzicht (functie)
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()

De bovenstaande descriptor is gegenereerd via het volgende Waratah-bestand :

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

Voorbeeld van Haptic Mouse Descriptor

De volgende descriptor ondersteunt alle verplichte en optionele gebruiksgegevens. Het declareert ondersteuning voor acht golfvormen, met de langste duur van 200 ms.

Alle logische bereiken moeten worden bijgewerkt op basis van de ondersteuning door apparaten. Ter ondersteuning van een ander aantal golfvormen:

  • Het logische bereik van het handmatige triggergebruik moet worden bijgewerkt
  • De gebruiksbereiken en het aantal rapporten voor Waveform List en Duration List moeten worden bijgewerkt

Als u een andere maximale golfvormlengte wilt instellen, moet het volgende logische bereik worden bijgewerkt:

  • Retriggerperiode (uitvoer)
  • Cutoff-tijd voor golfvormen (uitvoer)
  • Duuuroverzicht (functie)
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()

De bovenstaande descriptor is gegenereerd via het volgende Waratah-bestand :

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