Condividi tramite


Guida all'implementazione degli haptics per dispositivi di input

Questo documento illustra in dettaglio l'implementazione del protocollo per i dispositivi di input abilitati per l'aptico che si connettono a un host Windows 11 compatibile. Ciò non include indicazioni su vincoli meccanici, vincoli elettrici o selezione dei componenti per generare la risposta aptica all'interno dell'hardware del dispositivo di input.

Classi di dispositivi supportate

Windows 11 supporta le classi seguenti di dispositivi di input abilitati per l'aptico:

  • Touchpad aptico è un'estensione della classe Touchpad Device in Windows. Questa guida all'implementazione aggiunge alla Guida all'implementazione del Touchpad e si concentra sull'implementazione di aptici all'interno del digitalizzatore touchpad, quindi i touchpad aptici devono soddisfare i requisiti nella Guida all'implementazione del Touchpad oltre a quelli contenuti qui.

  • Mouse aptico è un'estensione della classe Mouse Device in Windows. I topi aptici devono soddisfare i requisiti contenuti in questa documentazione.

Annotazioni

I dispositivi di input penna abilitati per l'aptico sono una classe di dispositivi speciale che non verrà trattata in questo documento. Per informazioni su come implementare un dispositivo penna con feedback aptico, vedere la Guida all'implementazione della penna aptica.

Implementazione del protocollo Aptica del dispositivo di ingresso

Per comprendere le informazioni presentate qui, è necessaria una buona comprensione del protocollo HID. Per informazioni sul protocollo HID, vedere le risorse seguenti:

Il firmware del dispositivo di input abilitato alla risposta aptica deve segnalare solo gli utilizzi descritti in questo argomento. Windows userà il firmware e i relativi driver HID per abilitare il dispositivo e concedere alle applicazioni Windows l'accesso al dispositivo.

I descrittori di esempio per ogni classe di dispositivo supportata sono disponibili nella sezione Descrittori di report di esempio seguente.

Feedback aptico avviato dall'host

Un dispositivo di input abilitato apticamente può supportare il feedback aptico avviato dal sistema ospite, che può essere innescato in qualsiasi momento dopo l'enumerazione. Le funzionalità aptiche devono essere incluse in una raccolta HID SimpleHapticsController (Page 0x0E, Usage 0x01).

  • Per i touchpad, questa raccolta deve essere un elemento figlio della raccolta di primo livello Windows Precision Touchpad.
  • Per i topi, questa raccolta deve essere una raccolta di primo livello e un elemento di pari livello della raccolta top-level Mouse.

Il supporto per il feedback aptico avviato dall'host richiede report HID:

  • Report GET_FEATURE utilizzato dall'host per eseguire una query sulle forme d'onda supportate e sulle relative durate. Vedere la sezione "Waveform Information Feature Report" di seguito.
  • Report OUTPUT usato dall'host per manualmente attivare le interazioni aptiche. Vedere la sezione "Report output trigger manuale" di seguito.

Per i touchpad, questi report devono essere definiti su due collezioni figlie logiche SimpleHapticsController, che fanno parte della collezione figlia principale SimpleHapticsController. Per i topi, questi report possono essere definiti direttamente all'interno della raccolta di primo livello.

Forme d' onda

La tabella seguente definisce le forme d'onda supportate dall'host per i dispositivi di input abilitati per l'aptico. Le forme d'onda supportate da un dispositivo sono associate a un ordinale. L'utilizzo e la durata delle forme d'onda vengono forniti all'host tramite il report delle informazioni sulle forme d'onda (vedere di seguito). Quando si attiva il feedback, l'host fornisce l'ordinale della forma d'onda desiderata come valore per l'utilizzo manuale del trigger.

Obbligatorio e facoltativo
Forma d' onda Description Pagina Documento d'identità Obbligatorio/Facoltativo
None Nessuna operazione Non dovrebbe influire sullo stato di riproduzione delle forme d'onda in corso 0x0E 0x1001 Obbligatorio
Fermati Arresta la riproduzione delle forme d'onda in corso 0x0E 0x1002 Obbligatorio
Hover Un impulso di luce che indica gli stati di hover, segnalando il potenziale per azioni future. 0x0E 0x1008 Obbligatorio
Collidere Un impulso delicato per indicare di aver raggiunto un limite o confine 0x0E 0x1012 Obbligatorio
Align Un impulso acuto quando un oggetto si aggancia a una guida di allineamento 0x0E 0x1013 Obbligatorio
Step Un impulso fisso per cambiamenti discreti, ad esempio lo spostamento attraverso passaggi o valori 0x0E 0x1014 Obbligatorio
Crescere Un impulso dinamico che trasmette il movimento, le transizioni o l'attività intelligente del sistema 0x0E 0x1015 Obbligatorio
Passeggiata Un impulso che rappresenta una pressione di un pulsante 0x0E 0x1006 Vedere di seguito
Rilascio Un impulso che rappresenta un rilascio di un pulsante 0x0E 0x1007 Vedere di seguito
Success Modello crescente che conferma un'azione completata 0x0E 0x1009 Vedere di seguito
Errore Modello decrescente che indica un'azione non riuscita 0x0E 0x100A Vedere di seguito

Le forme d'onda Press e Release sono facoltative, ma se una è supportata, anche l'altra deve esserlo. Per i touchpad, le forme d'onda devono corrispondere al feedback della pressione e del rilascio avviato dal dispositivo.

Le forme d'onda Success e Error sono obbligatorie per i mouse e facoltative per i touchpad. Se uno è supportato, anche l'altro deve esserlo.

Vietato

Le forme d'onda seguenti NON DEVONO essere supportate.

Forma d' onda Documento d'identità Note
Click 0x1003 Causerebbe confusione con il feedback aptico esistente per le presse dei pulsanti.
Continuo ronzio 0x1004 Le forme d'onda continue non devono essere supportate.
Vibrazione Continua 0x1005 Le forme d'onda continue non devono essere supportate.
Inchiostro continuo 0x100B Applicabile solo alle penne.
Matita continua 0x100C Applicabile solo alle penne.
Marcatore continuo 0x100D Applicabile solo alle penne.
Marcatore di chisele continuo 0x100E Applicabile solo alle penne.
Pennello continuo 0x100F Applicabile solo alle penne.
Gomma continuo 0x1010 Applicabile solo alle penne.
Sparkle Continuous 0x1011 Applicabile solo alle penne.

Report sulle informazioni sulle forme d'onda

L'host emetterà questo report GET_FEATURE quando si eseguono query sul dispositivo per individuare le forme d'onda supportate. Questo report di funzionalità deve avere un ID report dedicato.

Il report deve avere due raccolte logiche secondarie, una per l'elenco delle forme d'onda e una per l'elenco delle durate. Queste raccolte devono definire un intervallo di utilizzo nella pagina Ordinale (0x0A), che consente all'host di eseguire query sulla forma d'onda e sulla durata associata a ogni ordinale.

Utilizzi obbligatori e facoltativi
Membro Description Pagina Documento d'identità Obbligatorio/Facoltativo
Elenco delle forme d'onda Raccolta logica contenente un elenco ordinato di forme d'onda aptice supportate dal dispositivo 0x0E 0x10 Obbligatorio
Elenco delle durate Raccolta logica contenente un elenco ordinato di durate per le forme d'onda nell'elenco Waveform 0x0E 0x11 Obbligatorio
Elenco waveform (obbligatorio)

Questa raccolta fornisce la mappatura tra ordinali e alle forme d'onda corrispondenti. Gli ordinali 1 e 2 corrispondono in modo implicito a Nessuno e Stop e non devono essere dichiarati nel descrittore. Pertanto, il limite minimo dell'intervallo di utilizzo della raccolta può essere 3, mentre il limite massimo deve essere sufficientemente ampio da consentire l'assegnazione degli ordinali a tutte le forme d'onda supportate. Non esiste alcun ordine necessario per l'assegnazione di forme d'onda ai ordinali 3 e versioni successive. Solo gli ordinali 1 e 2 hanno definizioni fisse.

Se il valore massimo di utilizzo è maggiore del numero di forme d'onda supportate dal dispositivo, il dispositivo deve segnalare Nessuno per gli ordinali non supportati.

L'intervallo logico dell'intervallo di utilizzo deve includere tutti gli utilizzi delle forme d'onda supportate. L'intervallo fisico e le unità devono essere 0.

Elenco delle durate (obbligatorio)

Questa raccolta fornisce le durate delle forme d'onda definite nell'elenco delle forme d'onda. L'utilizzo minimo e massimo dell'intervallo di utilizzo della raccolta deve essere identico a quello dell'elenco delle forme d'onda.

Le forme d'onda discrete devono avere una durata diversa da zero. Nessuno e Stop, se specificato, deve avere una durata pari a zero.

Il minimo logico dell'intervallo di utilizzo deve essere zero e il valore massimo logico deve essere pari almeno alla durata della forma d'onda discreta più lunga. L'host considererà i valori logici come millisecondi. L'intervallo fisico deve essere zero o identico all'intervallo logico. Se l'intervallo fisico e l'intervallo logico corrispondono, le unità devono essere millisecondi.

Report di output di attivazione manuale

L'host emetterà questo report quando si attiva un feedback aptico discreto. Questo report di output deve avere un ID report dedicato.

Utilizzi obbligatori e facoltativi
Membro Description Pagina Documento d'identità Obbligatorio/Facoltativo
Attivazione manuale Forma d'onda da attivare come comando esplicito dall'host 0x0E 0x21 Obbligatorio
Intensità Intensità del feedback 0x0E 0x23 Obbligatorio
Ripeti conteggio Numero di volte in cui ripetere il feedback dopo la riproduzione iniziale 0x0E 0x24 Vedere di seguito
Periodo di riattivazione Durata dell'attesa prima di riattivare il feedback durante la ripetizione 0x0E 0x25 Vedere di seguito
Tempo di Interruzione della Forma d'Onda Tempo massimo di riproduzione del feedback prima di essere tagliato 0x0E 0x28 Vedere di seguito

Repeat Count, Retrigger Period e Waveform Cutoff Time sono facoltativi, ma se ne è supportato uno, gli altri due devono anche essere.

Utilizzi non consentiti
Usage Documento d'identità Note
Attivazione automatica 0x20 Non supportato dall'host.
Controllo associato al trigger automatico 0x22 Non supportato dall'host.
Trigger manuale (obbligatorio)

Questo utilizzo contiene l'ordine della forma d'onda, come definito dal report delle informazioni sulla forma d'onda, che l'host ha richiesto di riprodurre. Quando un report di output contenente un ordinale diverso da Nessuno viene inviato al dispositivo, deve iniziare immediatamente a riprodurre la forma d'onda specificata con le proprietà aggiuntive incluse nel report di output (intensità, conteggio delle ripetizioni, periodo di riattivazione, tempo di interruzione, se supportato). Il dispositivo deve rispettare solo i ordinali per forme d'onda discrete, None e Stop. Se l'ordinale corrisponde a Stop, è necessario arrestare qualsiasi riproduzione di forme d'onda discrete in corso. Se l'ordinale corrisponde a Nessuno, nessuna azione deve essere eseguita e il feedback aptico continuo deve continuare a funzionare.

L'intervallo logico deve includere tutti i possibili ordinali, inclusi i ordinali impliciti 1 (None) e 2 (Stop). L'intervallo fisico e le unità devono essere 0.

Intensità (obbligatorio)

Questo utilizzo rappresenta la percentuale di intensità massima da applicare alla forma d'onda richiesta, con il massimo logico che rappresenta l'intensità massima e il minimo logico che non rappresenta alcun feedback.

Il minimo logico deve essere zero e il massimo logico deve essere selezionato in base alle funzionalità del dispositivo, ad esempio se il dispositivo supporta quattro livelli di intensità, il massimo logico deve essere quattro. Se il dispositivo supporta un'intensità più granulare, il massimo logico può essere maggiore, ma non deve superare 100. Il dispositivo deve supportare almeno quattro livelli di intensità, quindi il massimo logico minimo è quattro. Un'intensità pari a zero indica che non deve essere riprodotto alcun feedback. L'host userà solo questo valore per Stop.

L'intervallo fisico e le unità devono essere 0.

Conteggio ripetizioni (facoltativo)

Questo utilizzo rappresenta il numero di volte in cui ripetere la forma d'onda dopo la riproduzione iniziale. Un valore pari a zero indica che la forma d'onda deve essere riprodotta una sola volta.

Se questo utilizzo è supportato, devono essere supportati anche il periodo di riattivazione e il tempo di interruzione.

Il valore minimo logico deve essere zero e il valore massimo logico deve essere maggiore di zero. Il valore massimo logico deve essere limitato a un valore ragionevole ,ad esempio 10. L'intervallo fisico e le unità devono essere 0.

Periodo di ripetizione del tentativo (facoltativo)

Questo utilizzo rappresenta la durata tra i ritrigger della forma d'onda, misurata dall'ora di inizio del trigger precedente. Un valore pari a zero deve essere interpretato come identico alla durata predefinita per la forma d'onda, quindi il retrigger si verifica immediatamente dopo il completamento di quello precedente. I valori inferiori alla durata predefinita per la forma d'onda devono interrompere la forma d'onda e riavviarla.

Se questo utilizzo è supportato, è necessario supportare anche il conteggio delle ripetizioni e il tempo di interruzione.

L'host considererà i valori logici come millisecondi. Il minimo logico deve essere zero e il valore massimo logico deve essere almeno 1000 (che rappresenta un secondo). L'intervallo fisico deve essere zero o identico all'intervallo logico. Se l'intervallo fisico è diverso da zero, le unità devono essere millisecondi.

Tempo di Interruzione dell'Onda (facoltativo)

Questo utilizzo rappresenta la durata massima per cui un singolo trigger può comportare la riproduzione, tenendo conto del numero di ripetizioni e del periodo di riattivazione.

Se questo utilizzo è supportato, anche il conteggio delle ripetizioni e il periodo di riattivazione devono essere supportati.

L'host considererà i valori logici come millisecondi. Il minimo logico deve essere pari almeno alla durata della forma d'onda discreta più lunga, moltiplicata per il massimo logico dell'utilizzo del numero di ripetizioni più uno. Questo minimo logico rappresenta la durata degli inneschi della forma d'onda più lunga con il numero massimo supportato di inneschi ripetuti e senza ritardo tra i riattivazioni. Il valore massimo logico può essere limitato per evitare una durata eccessiva del feedback aptico per una singola richiesta, a discrezione del dispositivo. L'intervallo fisico deve essere zero o identico all'intervallo logico. Se l'intervallo fisico è diverso da zero, le unità devono essere millisecondi.

Linee guida per il touchpad aptico

Gli elementi in questa sezione si applicano solo ai touchpad aptici.

Feedback aptico del dispositivo

Un touchpad aptico è responsabile dell'attivazione del feedback aptico quando determina che il pulsante della superficie del touchpad è stato premuto o rilasciato. Può scegliere di supportare i report SET_FEATURE per consentire la personalizzazione del comportamento dell'utente in questo modo:

  • L'intensità del feedback aptico
  • Forza necessaria per attivare una pressione di un pulsante

Entrambi i report delle funzionalità sono obbligatori se il touchpad supporta anche il feedback aptico avviato dall'host. Ogni report deve usare un ID report distinto, non usato con altri utilizzi.

Durante l'enumerazione, l'host valuterà l'intervallo logico e fisico supportato dal descrittore e calcola le opzioni esposte per l'interfaccia utente delle impostazioni, incluse le impostazioni predefinite. L'host rilascia il SET_FEATURE per comunicare il valore specificato dall'utente al dispositivo; questo rilascio può verificarsi in qualsiasi momento, ma deve verificarsi ogni volta che l'impostazione viene modificata, si verifica un cambio utente e quando il dispositivo viene enumerato o reimpostato. Prima che il report SET_FEATURE sia stato rilasciato, il dispositivo deve usare un valore predefinito ragionevole di propria scelta (ad esempio, il centro dell'intervallo logico).

Rapporto delle funzionalità di intensità aptica

Questo report SET_FEATURE specifica la preferenza dell'utente per l'intensità del feedback aptico per la pressione e il rilascio dei pulsanti. Non si applica all'intensità di qualsiasi feedback avviato dall'host, se supportato dal dispositivo. Per supportare questa configurazione, il dispositivo deve definire una raccolta figlio logica SimpleHapticsController (Page 0x0E, Usage 0x01) nella raccolta principale Windows Precision Touchpad che contenga l'uso dell'intensità aptica (Page 0x0E, Usage 0x23) come report delle caratteristiche con un ID report dedicato. Questa raccolta di figlio non deve contenere le voci Attivazione automatica (Pagina 0x0E, utilizzo 0x20) o Attivazione manuale (Pagina 0x0E, utilizzo 0x21). Deve essere separato dalla raccolta figlio SimpleHapticsController usata per il feedback aptico avviato dall'host (se supportato).

Il valore minimo logico deve essere uguale a zero e il valore massimo logico deve essere maggiore o uguale a quattro. La preferenza dell'utente verrà ridimensionata in modo lineare nell'intervallo logico, con zero che indica che non deve essere attivato alcun feedback per la pressione e il rilascio del pulsante.

Report sulla soglia di pressione del pulsante

Questo report SET_FEATURE specifica la preferenza dell'utente per la quantità di forza necessaria per attivare la pressione di un pulsante. Per supportare questa configurazione, il dispositivo deve definire l'utilizzo di Button Press Threshold (Page 0x0D, Usage 0xB0) come report delle funzionalità con un ID report dedicato nella raccolta Windows Precision Touchpad di primo livello. Non deve trovarsi all'interno di una raccolta logica SimpleHapticsController.

L'intervallo logico deve essere mappato in modo lineare all'intervallo fisico di valori ed essere distanziato e centrato uniformemente intorno al valore predefinito. Dopo l'acquisizione dell'intervallo logico, il valore predefinito verrà calcolato usando la formula seguente:

Diagramma che mostra la formula per il calcolo della soglia di pressione del pulsante predefinita nelle unità logiche

Il valore Di minimo logico, Predefinito e Massimo logico corrisponderà a 3 livelli distinti di pressione del pulsante esposti a un utente tramite l'interfaccia utente delle impostazioni di Windows (supportando rispettivamente "Basso", "Medio" e "Alto").

L'intervallo fisico consigliato per Button Press Threshold è quello di coprire almeno l'intervallo compreso tra 110g e 190g, corrispondente rispettivamente ai valori minimo e massimo. Per un descrittore di esempio che usa un valore fisico massimo di 190g e Physical Minimum of 110g (in questo modo, in base alla formula precedente, il valore predefinito è 150g) vedere Descrittori di report di esempio.

Descrittori di report HID di esempio

Descrittore del Touchpad haptico di esempio

Il descrittore seguente supporta tutti gli utilizzi obbligatori e facoltativi. Dichiara il supporto per cinque forme d'onda, con la durata massima di 50 ms.

Tutti gli intervalli logici devono essere aggiornati in base al supporto dei dispositivi. Per supportare un numero diverso di forme d'onda:

  • L'intervallo logico dell'utilizzo del trigger manuale deve essere aggiornato
  • Gli intervalli di utilizzo e il conteggio dei report per l'elenco delle forme d'onda e l'elenco delle durate devono essere aggiornati.

Per supportare una lunghezza massima diversa della forma d'onda, è necessario aggiornare gli intervalli logici seguenti:

  • Periodo di ripetizione del tentativo (output)
  • Tempo di interruzione forma d'onda (output)
  • Elenco durata (funzionalità)
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()

Il descrittore precedente è stato generato tramite il file Waratah seguente:

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

Descrittore mouse aptico di esempio

Il descrittore seguente supporta tutti gli utilizzi obbligatori e facoltativi. Dichiara il supporto per otto forme d'onda, con una durata massima di 200 ms.

Tutti gli intervalli logici devono essere aggiornati in base al supporto dei dispositivi. Per supportare un numero diverso di forme d'onda:

  • L'intervallo logico dell'utilizzo del trigger manuale deve essere aggiornato
  • Gli intervalli di utilizzo e il conteggio dei report per l'elenco delle forme d'onda e l'elenco delle durate devono essere aggiornati.

Per supportare una lunghezza massima diversa della forma d'onda, è necessario aggiornare gli intervalli logici seguenti:

  • Periodo di ripetizione del tentativo (output)
  • Tempo di interruzione forma d'onda (output)
  • Elenco durata (funzionalità)
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()

Il descrittore precedente è stato generato tramite il file Waratah seguente:

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