Dela via


Implementeringsguide för haptik i indataenheter

Det här dokumentet beskriver protokollimplementeringen för haptiska indataenheter som ansluter till en kompatibel Windows 11-värd. Detta omfattar inte vägledning om mekaniska begränsningar, elektriska begränsningar eller komponentval för att generera haptiska svar i indataenhetens maskinvara.

Enhetsklasser som stöds

Windows 11 stöder följande klasser av haptiska indataenheter:

  • Haptic Touchpad är ett tillägg till klassen Touchpad Device i Windows. Den här implementeringsguiden lägger till i implementeringsguiden för pekplatta och fokuserar på att implementera haptics i digitaliseraren för pekplattor, så haptiska pekplattor måste uppfylla kraven i Pekplatta-implementeringsguiden utöver de som finns här.

  • Haptic Mouse är ett tillägg till klassen Musenhet i Windows. Haptiska möss måste uppfylla kraven i den här dokumentationen.

Obs! Haptic-aktiverade penninmatningsenheter är en särskild enhetsklass som inte kommer att omfattas av det här dokumentet. Information om hur du implementerar en pennenhet med haptisk feedback finns i implementeringsguiden för Haptic Pen.

Implementering av haptikprotokollet för indataenheter

Det krävs en god förståelse för HID-protokollet för att kunna förstå den information som presenteras här. Se följande resurser för information om HID-protokollet:

Den haptiska indataenhetens inbyggda programvara behöver bara rapportera de användningar som beskrivs i det här avsnittet. Windows använder den inbyggda programvaran och sina egna HID-drivrutiner för att aktivera enheten och ge Windows-program åtkomst till enheten.

Exempelbeskrivningar för varje enhetsklass som stöds finns i avsnittet Exempelrapportbeskrivningar nedan.

Vanliga riktlinjer

Objekten i det här avsnittet gäller för alla klasser av haptiska indataenheter.

Obligatorisk HID-samling

Funktioner relaterade till haptics måste ingå i en HID SimpleHapticsController-samling (page 0xE, usage 0x1).

För Haptic Touchpad-enheter måste den här samlingen vara underordnad Windows Precision Touchpad-samlingen på högsta nivån.

För Haptic Mouse-enheter måste den här samlingen vara en toppnivåsamling och ett syskon till mussamlingen på den översta nivån.

Enhetsinitierad haptisk återkoppling

En haptisk-aktiverad indataenhet kan eventuellt ha stöd för att initiera sin egen haptiska feedback, t.ex. som svar på en knapp som trycks eller släpps.

För haptiska pekplattor beskriver avsnittet "Haptic Touchpad Guidance" nedan hur enheten kan välja att stödja SET_FEATURE rapporter för att tillåta användaranpassning av dess beteende när haptisk feedback initieras.

Haptiska möss kan utlösa enhetsinitierad feedback, men Windows har ingen mekanism för att konfigurera det här beteendet.

Värdinitierad haptisk feedback

En haptikaktiverad indataenhet kan stödja värdinitierad haptisk feedback, som kan inträffa när som helst efter enumerering.

Haptiska pekplattor och möss kan eventuellt stödja värdinitierad feedback. Om värdinitierad feedback stöds för haptiska pekplattor måste både SET_FEATURE rapporter för enhetsinitierad feedbackanpassning också stödjas.

Stöd för värdinitierad haptisk feedback kräver två logiska SimpleHapticsController-samlingar (page 0x0E, Usage 0x01). Dessa logiska samlingar måste vara underordnade till huvudsamlingen SimpleHapticsController för enhetsklassen som implementeras (enligt beskrivningen i avsnittet "Obligatorisk HID-samling" ovan) och måste vara åtskilda från samlingen som används för att konfigurera intensiteten av enhetsinitierad haptisk feedback för pekplattor. En av dessa logiska underordnade samlingar måste definiera en GET_FEATURE rapport som används av värden för att fråga efter vågformer som stöds och deras varaktighet. Den andra logiska underordnade samlingen måste definiera en utdatarapport som används av värden för att manuellt utlösa haptisk feedback.

Enheten får INTE deklarera stöd för automatiskt utlösta haptics och enheten får INTE ha stöd för kontinuerliga vågformer.

Vågformer

Följande tabell definierar de vågformer som stöds av hosten för haptik-aktiverade indataenheter. Vågformerna som stöds av en enhet är associerade med en ordningstal. Vågformens användning och varaktighet tillhandahålls till värden via funktionsrapporten för vågformsinformation (se nedan). När du utlöser feedback tillhandahåller värden ordningstalet för önskad vågform som värde för den manuella utlösaranvändningen.

Obligatoriskt och valfritt
Vågform Description Sida ID-nummer Obligatoriskt/valfritt
None No-op. Bör inte påverka uppspelningstillståndet för pågående vågformer 0x0E 0x1001 Mandatory
Stoppa Stoppar uppspelningen av pågående vågformer 0x0E 0x1002 Mandatory
Sväva En ljuspuls som används för att indikera hovring och signalera potentialen för en kommande åtgärd 0x0E 0x1008 Mandatory
Kollidera En mjuk puls som används för att indikera kollisioner med skärmgränser eller ändarna på skjutreglage och rullningslister 0x0E 0x1012 Mandatory
Align En skarp puls som bekräftar objektjustering under dra, skala eller rotera interaktioner med stödlinjer eller arbetsytekanter 0x0E 0x1013 Mandatory
Step En fast puls som används för att stega igenom objekt i skjutreglage, listor eller scrubbers 0x0E 0x1014 Mandatory
Växa En dynamisk puls som förmedlar rörelse, övergångar eller intelligent systemaktivitet 0x0E 0x1015 Mandatory
Tryck Den haptiska signal som utlöses av enheten när den fastställer att ytknappen har tryckts in. Om det stöds måste release också stödjas. 0x0E 0x1006 Valfritt
Lansering Den haptiska signal som utlöses av enheten när den fastställer att ytknappen har släppts. Tryck måste också stödjas om det stöds. 0x0E 0x1007 Valfritt
Success Stark haptisk signal för att varna användaren om att en åtgärd har slutförts 0x0E 0x1009 Valfritt
Error Stark haptisk signal för att varna användaren om att en åtgärd har misslyckats, eller så har ett fel inträffat 0x0E 0x100A Valfritt
Ej tillåtet

Följande vågformer får inte stödjas.

Vågform ID-nummer Noteringar
Klicka 0x1003 Skulle orsaka förvirring med den befintliga haptiska feedbacken för knapptryckningar.
Buzz Kontinuerlig 0x1004 Kontinuerliga vågformer bör inte stödjas.
Muller kontinuerlig 0x1005 Kontinuerliga vågformer bör inte stödjas.
Kontinuerlig pennanteckning 0x100B Gäller endast pennor.
Löpande penna 0x100C Gäller endast pennor.
Kontinuerlig markör 0x100D Gäller endast pennor.
Markör för mejseln kontinuerlig 0x100E Gäller endast pennor.
Pensla kontinuerligt 0x100F Gäller endast pennor.
Radera kontinuerligt 0x1010 Gäller endast pennor.
Sparkle Kontinuerlig 0x1011 Gäller endast pennor.

Funktionsrapport för vågformsinformation

Värden utfärdar den här GET_FEATURE rapporten när den frågar enheten om dess vågformer som stöds. Den här funktionsrapporten måste ha ett dedikerat rapport-ID.

Den logiska samlingen måste ha två underordnade logiska samlingar, en för vågformslistan och en för varaktighetslistan. Dessa samlingar måste definiera ett användningsintervall på sidan Ordning (0x0A) som gör att värden kan fråga efter vågformen och varaktigheten som är associerad med varje ordningstal.

Obligatoriska och valfria användningar
Medlem Description Sida ID-nummer Obligatoriskt/valfritt
Vågformslista Logisk samling som innehåller en ordnad lista över haptiska vågformer som stöds av enheten 0x0E 0x10 Mandatory
Varaktighetslista Logisk samling som innehåller en ordnad lista över varaktigheter för vågformer i vågformslistan 0x0E 0x11 Mandatory
Vågformslista (obligatorisk)

Den här samlingen innehåller mappningen mellan ordningstal och motsvarande vågformer. Ordningstalen 1 och 2 motsvarar WAVEFORM_NONE och WAVEFORM_STOP implicit och behöver inte deklareras i beskrivningen. Därför kan användningsminimum för samlingens användningsintervall vara 3, och användningsgränsen bör vara tillräckligt stor för att tilldela ordningstal till alla vågformer som stöds.

Om maxanvändningen är större än antalet vågformer som stöds av enheten bör enheten rapportera WAVEFORM_NONE för ordningstal som inte stöds.

Det logiska intervallet för användningsintervallet bör innehålla alla vågformsanvändningar som stöds. Det fysiska intervallet och enheterna måste vara 0.

Varaktighetslista (obligatorisk)

Den här samlingen innehåller varaktigheterna för vågformerna som definierats i vågformslistan. Användningsminimum och maximum för samlingens användningsintervall måste vara identiska med dem i vågformslistan.

Diskreta vågformer måste ha en varaktighet som inte är noll. WAVEFORM_NONE och WAVEFORM_STOP, om de anges, måste ha en varaktighet på noll.

Det logiska minimivärdet för användningsintervallet måste vara noll och det logiska maxvärdet måste vara minst lika stort som varaktigheten för den längsta diskreta vågformen. Värden behandlar de logiska värdena som millisekunder. Det fysiska intervallet måste antingen vara noll eller identiskt med det logiska intervallet. Om det fysiska intervallet och det logiska intervallet matchar ska enheterna vara millisekunder.

Utdatarapport för manuell utlösare

Värden utfärdar den här rapporten när diskret haptisk feedback utlöses. Den här utdatarapporten måste ha ett dedikerat rapport-ID.

Obligatoriska och valfria användningar
Medlem Description Sida ID-nummer Obligatoriskt/valfritt
Manuell utlösare Waveform som utlöses som explicit kommando från värden 0x0E 0x21 Mandatory
Intensitet Feedbackens intensitet 0x0E 0x23 Mandatory
Antal upprepningar Antal gånger som feedbacken ska upprepas efter inledande uppspelning 0x0E 0x24 Valfritt
Retrigger-period Hur lång tid det tar att vänta innan feedbacken återutlöses vid upprepande 0x0E 0x25 Valfritt
Tid för vågformsavstängning Maximal tid som feedbacken kan spelas upp innan den stängs av 0x0E 0x28 Valfritt
Förbjuden användning
Usage ID-nummer Noteringar
Automatisk utlösare 0x20 Stöds inte av värden.
Automatisk utlösare associerad kontroll 0x22 Stöds inte av värden.
Manuell utlösare (obligatorisk)

Den här användningen innehåller ordningstalet för vågformen, enligt definitionen i funktionsrapporten för vågformsinformation, som har begärts att spelas upp av värden. När en utdatarapport som innehåller en annan ordning än WAVEFORM_NONE skickas till enheten bör den omedelbart börja spela upp den angivna vågformen med de ytterligare egenskaper som ingår i utdatarapporten (Intensitet, Upprepa antal, Retriggerperiod, Bryttid, om det stöds). Enheten bör endast respektera ordningstal för diskreta vågformer, WAVEFORM_NONE och WAVEFORM_STOP. Om ordningstalet motsvarar WAVEFORM_STOP ska all pågående diskret vågformsuppspelning stoppas. Om ordningstalet motsvarar WAVEFORM_NONE ska ingen åtgärd utföras, och pågående haptisk feedback bör fortsätta att spelas upp.

Det logiska intervallet måste innehålla alla möjliga ordningstal, inklusive implicita ordningstal 1 (WAVEFORM_NONE) och 2 (WAVEFORM_STOP). Det fysiska intervallet och enheterna måste vara 0.

Intensitet (obligatoriskt)

Den här användningen representerar procentandelen av maximal intensitet som ska tillämpas på den begärda vågformen, där det logiska maxvärdet representerar maximal intensitet och det logiska minimum som inte representerar någon feedback alls.

Det logiska minimumet måste vara noll och det logiska maxvärdet ska väljas baserat på enhetens funktioner – om enheten till exempel stöder fyra nivåer av intensitet bör det logiska maxvärdet vara fyra. Om enheten stöder mer detaljerad intensitet kan det logiska maxvärdet vara större, men det får inte överstiga 100. Enheten måste ha stöd för minst fyra nivåer av intensitet, så det minsta logiska maxvärdet är fyra. En intensitet på noll anger att ingen feedback ska spelas upp – värden använder bara det här värdet för WAVEFORM_STOP.

Det fysiska intervallet och enheterna måste vara 0.

Upprepa antal (valfritt)

Den här användningen representerar antalet gånger som vågformen ska upprepas efter den första uppspelningen. Värdet noll anger att vågformen bara ska spelas upp en gång.

Om den här användningen stöds måste användningen av retrigger-perioden och tidsgränsen också stödjas.

Det logiska minimumet måste vara noll och det logiska maxvärdet måste vara större än noll. Det logiska maxvärdet bör begränsas till ett litet värde (till exempel 10). Det fysiska intervallet och enheterna måste vara 0.

Retrigger-period (valfritt)

Den här användningen representerar varaktigheten mellan vågformens retriggers, mätt från starttiden för den föregående utlösaren. Värdet noll ska tolkas som identiskt med standardvaraktigheten för vågformen, så retriggern inträffar omedelbart efter att den föregående har slutförts. Värden som är mindre än standardvaraktigheten för vågformen bör avbryta vågformen och starta om den.

Om den här användningen stöds måste användning av antal upprepningar och tidsgränser också stödjas.

Värden behandlar de logiska värdena som millisekunder. Det logiska minimumet måste vara noll och det logiska maxvärdet måste vara minst 1 000 (representerar en sekund). Det fysiska intervallet måste antingen vara noll eller identiskt med det logiska intervallet. Om det fysiska intervallet inte är noll ska enheterna vara millisekunder.

Bryttid för vågform (valfritt)

Den här användningen representerar den maximala tid som en enskild utlösare kan leda till uppspelning, med hänsyn till antalet upprepningar och retriggerperioden.

Om den här användningen stöds måste även antalet upprepningar och retrigger-användningar stödjas.

Värden behandlar de logiska värdena som millisekunder. Det logiska minimumet måste vara minst lika stort som varaktigheten för den längsta diskreta vågformen multiplicerat med det logiska maxvärdet för användningen av upprepat antal. Det fysiska intervallet måste antingen vara noll eller identiskt med det logiska intervallet. Om det fysiska intervallet inte är noll ska enheterna vara millisekunder.

Haptic Touchpad-vägledning

Objekten i det här avsnittet gäller endast för haptiska pekplattor.

Enhetsinitierad haptisk återkoppling

En haptisk pekplatta ansvarar för att utlösa haptisk feedback när den fastställer att pekplattans yta knapp har tryckts eller släppts. Den kan välja att stödja SET_FEATURE rapporter för att tillåta användaranpassning av dess beteende när du gör det:

  • Intensiteten i den haptiska feedbacken
  • Den kraft som krävs för att utlösa en knapptryckning

Båda dessa funktionsrapporter är obligatoriska om pekplattan också stöder värdinitierad haptisk feedback. Varje rapport måste använda ett distinkt rapport-ID, som inte används med någon annan användning.

Under uppräkningen utvärderar värden det logiska och fysiska intervall som stöds från beskrivningen och beräknar de tillgängliga alternativen för inställningsgränssnittet, inklusive standardvärdena. Värden ska utfärda SET_FEATURE för att förmedla användarens angivna värde till enheten. Denna utfärdande kan inträffa när som helst, men ska inträffa när inställningen ändras, en användarväxel inträffar och när enheten räknas upp eller återställs.

Rapport om haptisk intensitet och funktioner

Den här SET_FEATURE rapporten anger användarens inställning för intensiteten i haptisk feedback för knapptryckning och -släpp. Den gäller INTE för intensiteten i någon värdinitierad feedback, om den stöds av enheten. För att stödja den här konfigurationen måste enheten definiera en logisk underordnad SimpleHapticsController-samling (sida 0x0E, användning 0x01) i samlingen Windows Precision Touchpad på den översta nivån som innehåller haptisk intensitetsanvändning (sida 0x0E, användning 0x23) som en funktionsrapport med ett dedikerat rapport-ID. Den här underordnade samlingen får inte innehålla användning av automatisk utlösare (0x0E, användning 0x20) eller manuell utlösare (0x0E, användning 0x21).

Det logiska minimumet måste vara lika med noll. Användarens inställning skalas linjärt in i det logiska intervallet, med noll som anger att ingen feedback ska utlösas för knapptryckning och släpp.

Knapp Tryck på tröskelfunktionsrapport

Den här SET_FEATURE rapporten anger användarens inställning för hur mycket kraft som krävs för att utlösa en knapptryckning. För att stödja den här konfigurationen måste enheten definiera knapptryckningströskelanvändningen (page 0x0D, usage 0xB0) som en funktionsrapport med ett dedikerat rapport-ID i samlingen Windows Precision Touchpad på översta nivån.

Det logiska intervallet ska linjärt mappas till det fysiska intervallet med värden och vara jämnt fördelat och centrerat kring standardvärdet. När du hämtar det logiska intervallet beräknas standardvärdet med hjälp av följande formel:

Diagram som visar formeln för att beräkna standardknappens trycktröskel i logiska enheter

Det logiska minimivärdet, standardvärdet och det logiska maxvärdet motsvarar tre olika nivåer av knapptryckning som exponeras för en användare via Användargränssnittet för Windows-inställningar (stöd för "Låg", "Medel" respektive "Hög").

Det rekommenderade fysiska intervallet för knapptryckningströskel är att åtminstone täcka intervallet mellan 110g och 190g, vilket motsvarar de lägsta respektive högsta värdena. En exempelbeskrivning som använder ett fysiskt maxvärde på 190g och ett fysiskt minimum på 110 g (baserat på formeln ovan är standardvärdet 150 g) finns i Exempelrapportbeskrivningar.

Exempel på HID-rapportbeskrivningar

Haptic Touchpad-exempelbeskrivning

Följande beskrivning stöder alla obligatoriska och valfria användningar. Den deklarerar stöd för fem vågformer, med den längsta varaktigheten på 50 ms.

Alla logiska intervall bör uppdateras baserat på enhetsstöd. Så här stöder du ett annat antal vågformer:

  • Det logiska intervallet för användningen av manuell utlösare måste uppdateras
  • Användningsintervallen och rapportantalet för Vågformslista och Varaktighetslista måste uppdateras

För att stödja en annan maximal vågformslängd måste följande logiska intervall uppdateras:

  • Retrigger-period (utdata)
  • Bryttid för vågform (utdata)
  • Varaktighetslista (funktion)
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()

Ovanstående beskrivning genererades via följande Waratah-fil :

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

Exempel på haptisk musbeskrivning

Följande beskrivning stöder alla obligatoriska och valfria användningar. Det deklarerar stöd för åtta vågformer, med den längsta varaktigheten på 200 ms.

Alla logiska intervall bör uppdateras baserat på enhetsstöd. Så här stöder du ett annat antal vågformer:

  • Det logiska intervallet för användningen av manuell utlösare måste uppdateras
  • Användningsintervallen och rapportantalet för Vågformslista och Varaktighetslista måste uppdateras

För att stödja en annan maximal vågformslängd måste följande logiska intervall uppdateras:

  • Retrigger-period (utdata)
  • Bryttid för vågform (utdata)
  • Varaktighetslista (funktion)
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()

Ovanstående beskrivning genererades via följande Waratah-fil :

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