Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Ten dokument zawiera szczegółowe informacje na temat implementacji protokołu dla haptycznych urządzeń wejściowych łączących się z zgodnym hostem systemu Windows 11. Nie obejmuje to wskazówek dotyczących ograniczeń mechanicznych, ograniczeń elektrycznych lub wyboru składników do generowania odpowiedzi haptycznej w sprzęcie urządzenia wejściowego.
Obsługiwane klasy urządzeń
System Windows 11 obsługuje następujące klasy urządzeń wejściowych z haptyczną obsługą.
Haptic Touchpad to rozszerzenie klasy urządzenia Touchpad w systemie Windows. Ten przewodnik implementacji dodaje do przewodnika implementacji touchpad i koncentruje się na implementowaniu haptyki w cyferyzatorze touchpad, więc dotykowe tablety dotykowe muszą spełniać wymagania w Przewodniku implementacji touchpad oprócz tych zawartych w tym miejscu.
Haptic Mouse to rozszerzenie klasy Urządzenia myszy w systemie Windows. Myszy haptyczne muszą spełniać wymagania zawarte w tej dokumentacji.
Uwaga: urządzenia wejściowe pióra z obsługą haptycznej są specjalną klasą urządzeń, która nie zostanie omówiona w tym dokumencie. Aby uzyskać informacje na temat implementacji urządzenia pióra z haptycznym sprzężeniem zwrotnym, zobacz w Przewodniku po implementacji haptycznego pióra.
Implementacja protokołu urządzenia wejściowego Haptics
Aby zrozumieć przedstawione tutaj informacje, należy dobrze zrozumieć protokół HID. Aby uzyskać informacje o protokole HID, zobacz następujące zasoby:
Oprogramowanie układowe urządzenia wejściowego z obsługą haptyczną musi zgłaszać tylko użycia opisane w tym temacie. System Windows będzie używać oprogramowania układowego i własnych sterowników HID, aby włączyć urządzenie i zapewnić aplikacjom systemu Windows dostęp do urządzenia.
Przykładowe deskryptory dla każdej obsługiwanej klasy urządzeń znajdują się w poniższej sekcji Przykładowe deskryptory raportów.
Typowe wskazówki
Elementy w tej sekcji dotyczą wszystkich klas haptycznych urządzeń wejściowych.
Wymagana kolekcja HID
Funkcje związane z haptyki muszą być zawarte w kolekcji HID SimpleHapticsController (Page 0xE, Usage 0x1).
W przypadku urządzeń Haptic Touchpad kolekcja ta musi być elementem podrzędnym najwyższego poziomu kolekcji Windows Precision Touchpad.
W przypadku urządzeń myszy haptycznej ta kolekcja musi być główną kolekcją i elementem równorzędnym do głównej kolekcji myszy.
Device-Initiated haptic feedback
Urządzenie wejściowe z obsługą haptycznych może opcjonalnie obsługiwać inicjowanie własnych opinii haptycznych, np. w odpowiedzi na naciśnięcie lub zwolnienie przycisku.
W przypadku dotykowych gładzików, w sekcji "Wskazówki dotyczące haptycznego gładzika" poniżej opisano sposób, w jaki urządzenie może wybrać obsługę raportów SET_FEATURE, aby umożliwić użytkownikowi dostosowanie jego zachowania podczas inicjowania informacji zwrotnej haptycznej.
Myszy haptyczne mogą wyzwalać sprzężenie zwrotne inicjowane przez urządzenie, ale system Windows nie ma mechanizmu do konfigurowania tego zachowania.
Host-Initiated haptic feedback
Urządzenie wejściowe z obsługą haptyczną może obsługiwać informacje zwrotne haptyczne inicjowane przez hosta, które mogą wystąpić w dowolnej chwili po wyliczeniu.
Haptic touchpady i myszy mogą opcjonalnie wspierać informację zwrotną inicjowaną przez hosta. W przypadku gładzików dotykowych, jeśli obsługiwana jest informacja zwrotna inicjowana przez hosta, muszą być również obsługiwane oba raporty SET_FEATURE dotyczące dostosowywania informacji zwrotnej inicjowanej przez urządzenie.
Obsługa haptycznych opinii inicjowanych przez hosta wymaga dwóch kolekcji logicznych elementów podrzędnych SimpleHapticsController (page 0x0E, Usage 0x01). Te kolekcje logiczne muszą być elementami podrzędnymi głównej kolekcji SimpleHapticsController dla implementowanych klas urządzeń (zgodnie z opisem w powyższej sekcji "Wymagana kolekcja HID") i muszą być oddzielone od kolekcji używanej do konfigurowania intensywności sprzężenia zwrotnego haptycznego inicjowanego przez urządzenie dla płytek dotykowych. Jedna z tych logicznych kolekcji podrzędnych musi zdefiniować raport GET_FEATURE używany przez hosta do wykonywania zapytań dotyczących obsługiwanych kształtów falowych i ich czasów trwania. Drugi podrzędny zbiór logiczny musi zdefiniować raport wyjściowy używany przez hosta do ręcznego uruchamiania funkcji haptycznych.
Urządzenie nie może zadeklarować obsługi automatycznie wyzwalanych haptyki, a urządzenie nie może obsługiwać żadnych ciągłych kształtów fal.
Przebiegów
W poniższej tabeli zdefiniowano kształty fal sygnału obsługiwane przez hosta dla urządzeń wejściowych z funkcją haptyczną. Kształty fali obsługiwane przez urządzenie są skojarzone z porządkowymi. Użycie i czas trwania kształtów falowych są udostępniane hostowi za pośrednictwem raportu funkcji informacji o formach falowych (patrz poniżej). Podczas wyzwalania opinii host udostępnia porządkowy żądany kształt fali jako wartość użycia wyzwalacza ręcznego.
Obowiązkowe i opcjonalne
| Przebiegu | Description | Strona | identyfikator | Obowiązkowe/opcjonalne |
|---|---|---|---|---|
| Żaden | Brak operacji. Nie należy wpływać na stan odtwarzania bieżących kształtów fali | 0x0E | 0x1001 | Mandatory |
| Zatrzymaj | Zatrzymuje odtwarzanie trwających kształtów fal | 0x0E | 0x1002 | Mandatory |
| Hover | Impuls światła używany do wskazywania aktywowania i sygnalizowania potencjału nadchodzącej akcji | 0x0E | 0x1008 | Mandatory |
| Zderzają się | Impuls miękki używany do wskazywania kolizji z granicami ekranu lub końcami suwaków i pasków przewijania | 0x0E | 0x1012 | Mandatory |
| Align | Ostry impuls, który potwierdza wyrównanie obiektu podczas przeciągania, skalowania lub obracania interakcji z prowadnicami lub krawędziami kanwy | 0x0E | 0x1013 | Mandatory |
| Step | Mocny impuls używany do przechodzenia przez elementy w suwakach, listach lub szorach | 0x0E | 0x1014 | Mandatory |
| Rosnąć | Impuls dynamiczny, który przekazuje ruch, przejścia lub inteligentną aktywność systemu | 0x0E | 0x1015 | Mandatory |
| Prasa | Sygnał haptyczny wyzwalany przez urządzenie, gdy określa, że przycisk powierzchni został naciśnięty. Jeśli jest obsługiwana, wersja musi być również obsługiwana. | 0x0E | 0x1006 | Opcjonalnie |
| Uwolnij | Sygnał haptyczny wyzwalany przez urządzenie, gdy określa, że przycisk powierzchni został zwolniony. Jeśli jest obsługiwana, naciśnięcie musi być również obsługiwane. | 0x0E | 0x1007 | Opcjonalnie |
| Powodzenie | Silny sygnał haptyczny ostrzegawczego użytkownika, że akcja powiodła się | 0x0E | 0x1009 | Opcjonalnie |
| Error | Silny sygnał haptyczny ostrzegawcy użytkownika, że akcja nie powiodła się lub wystąpił błąd | 0x0E | 0x100A | Opcjonalnie |
Zakazany
Następujące kształty fali NIE MOGĄ być obsługiwane.
| Przebiegu | identyfikator | Notatki |
|---|---|---|
| Kliknij | 0x1003 | Spowodowałoby to zamieszanie z istniejącymi haptycznymi opiniami dotyczącymi naciśnięcia przycisków. |
| Buzz Continuous | 0x1004 | Ciągłe kształty fal nie powinny być obsługiwane. |
| Ciągłe rumble | 0x1005 | Ciągłe kształty fal nie powinny być obsługiwane. |
| Ciągłe pisma odwłocznego | 0x100B | Dotyczy tylko długopisów. |
| Ołówek ciągły | 0x100C | Dotyczy tylko długopisów. |
| Znacznik ciągły | 0x100D | Dotyczy tylko długopisów. |
| Znacznik szselowy ciągły | 0x100E | Dotyczy tylko długopisów. |
| Szczotka ciągła | 0x100F | Dotyczy tylko długopisów. |
| Gumka ciągła | 0x1010 | Dotyczy tylko długopisów. |
| Sparkle Ciągły | 0x1011 | Dotyczy tylko długopisów. |
Raport funkcji informacji o kształtach falowych
Host wyda ten raport GET_FEATURE podczas wykonywania zapytań dotyczących urządzenia pod kątem obsługiwanych kształtów fali. Ten raport funkcji musi mieć dedykowany identyfikator raportu.
Kolekcja logiczna musi mieć dwie podrzędne kolekcje logiczne, jedną dla listy kształtów falowych i jedną dla listy czasu trwania. Te kolekcje muszą definiować zakres użycia na stronie porządkowej (0x0A), która umożliwia hostowi wykonywanie zapytań o kształt fali i czas trwania skojarzony z każdą porządkową.
Obowiązkowe i opcjonalne użycie
| Członek | Description | Strona | identyfikator | Obowiązkowe/opcjonalne |
|---|---|---|---|---|
| Lista kształtów falowych | Kolekcja logiczna zawierająca uporządkowaną listę haptycznych kształtów fali obsługiwanych przez urządzenie | 0x0E | 0x10 | Mandatory |
| Lista czasu trwania | Kolekcja logiczna zawierająca uporządkowaną listę czasów trwania kształtów falowych na liście kształtów fali | 0x0E | 0x11 | Mandatory |
Lista kształtów falowych (obowiązkowe)
Ta kolekcja zawiera mapowanie między regułami i odpowiednimi kształtami fal. Reguły 1 i 2 odpowiadają WAVEFORM_NONE i WAVEFORM_STOP niejawnie i nie muszą być deklarowane w deskryptorze. W związku z tym minimalna wartość użycia zakresu użycia kolekcji może wynosić 3, a maksymalny rozmiar użycia powinien być wystarczająco duży, aby przypisać reguły do wszystkich obsługiwanych kształtów falowych.
Jeśli wartość maksymalna użycia jest większa niż liczba kształtów fal obsługiwanych przez urządzenie, urządzenie powinno zgłosić WAVEFORM_NONE dla nieobsługiwanych wartości zwykłych.
Zakres logiczny zakresu użycia powinien obejmować wszystkie obsługiwane użycie kształtów falowych. Zakres fizyczny i jednostki muszą mieć wartość 0.
Lista czasu trwania (obowiązkowe)
Ta kolekcja zawiera czasy trwania kształtów fal zdefiniowanych na liście kształtów falowych. Minimalne i maksymalne użycie zakresu użycia kolekcji muszą być identyczne z wartościami listy kształtów falowych.
Dyskretne kształty fali muszą mieć niezerowy czas trwania. WAVEFORM_NONE i WAVEFORM_STOP, jeśli określono, muszą mieć czas trwania zero.
Logiczne minimum zakresu użycia musi wynosić zero, a wartość logiczna musi być co najmniej tak duża, jak czas trwania najdłuższego dyskretnego kształt fali. Host będzie traktować wartości logiczne jako milisekundy. Zakres fizyczny musi być zerowy lub identyczny z zakresem logicznym. Jeśli zakres fizyczny i zakres logiczny są zgodne, jednostki powinny być milisekundami.
Raport wyjściowy wyzwalacza ręcznego
Host wyda ten raport podczas wyzwalania dyskretnych opinii haptycznych. Ten raport wyjściowy musi mieć dedykowany identyfikator raportu.
Obowiązkowe i opcjonalne użycie
| Członek | Description | Strona | identyfikator | Obowiązkowe/opcjonalne |
|---|---|---|---|---|
| Wyzwalacz ręczny | Kształt fali do wyzwolenia jako jawne polecenie z hosta | 0x0E | 0x21 | Mandatory |
| Intensywność | Intensywność opinii | 0x0E | 0x23 | Mandatory |
| Liczba powtórzeń | Liczba powtórzeń opinii po początkowym odtwarzaniu | 0x0E | 0x24 | Opcjonalnie |
| Okres ponownego pobierania | Czas oczekiwania przed ponownym wyzwoleniem opinii podczas powtarzania | 0x0E | 0x25 | Opcjonalnie |
| Czas odcięcia kształtów falowych | Maksymalny czas odtwarzania opinii przed odcięciem | 0x0E | 0x28 | Opcjonalnie |
Zabronione użycie
| Usage | identyfikator | Notatki |
|---|---|---|
| Wyzwalacz automatyczny | 0x20 | Nieobsługiwane przez hosta. |
| Kontrolka skojarzona z automatycznym wyzwalaczem | 0x22 | Nieobsługiwane przez hosta. |
Wyzwalacz ręczny (obowiązkowy)
To użycie zawiera porządkowość kształtów fali, zgodnie z definicją w raporcie funkcji informacji o formach falowych, który został poproszony o odtworzenie przez hosta. Gdy raport wyjściowy zawierający porządkowy inny niż WAVEFORM_NONE jest wysyłany do urządzenia, powinien natychmiast rozpocząć odtwarzanie określonego kształta fali z dodatkowymi właściwościami zawartymi w raporcie wyjściowym (intensywność, liczba powtórzeń, okres pobierania, czas odcięcia, jeśli jest obsługiwany). Urządzenie powinno uwzględniać tylko reguły dyskretnych kształtów fal, WAVEFORM_NONE i WAVEFORM_STOP. Jeśli porządkowy odpowiada WAVEFORM_STOP, wszelkie trwające dyskretne odtwarzanie kształtów falowych powinno zostać zatrzymane. Jeśli porządkowy odpowiada WAVEFORM_NONE, nie należy wykonywać żadnych działań, a ciągłe opinie zwrotne powinny nadal działać.
Zakres logiczny musi zawierać wszystkie możliwe reguły, w tym niejawne reguły 1 (WAVEFORM_NONE) i 2 (WAVEFORM_STOP). Zakres fizyczny i jednostki muszą mieć wartość 0.
Intensywność (obowiązkowe)
To użycie reprezentuje wartość procentową maksymalnej intensywności, która ma być stosowana do żądanego kształtów falowych, z wartością logiczną maksymalną reprezentującą maksymalną intensywność i wartość logiczną reprezentującą w ogóle brak opinii.
Minimum logiczne musi wynosić zero, a wartość logiczna powinna być wybierana na podstawie możliwości urządzenia — na przykład jeśli urządzenie obsługuje cztery poziomy intensywności, wartość logiczna powinna wynosić cztery. Jeśli urządzenie obsługuje bardziej szczegółową intensywność, wartość logiczna może być większa, ale nie powinna przekraczać 100. Urządzenie musi obsługiwać co najmniej cztery poziomy intensywności, więc minimalna wartość logiczna wynosi cztery. Intensywność zerowa wskazuje, że nie należy odtwarzać żadnych opinii — host będzie używać tej wartości tylko dla WAVEFORM_STOP.
Zakres fizyczny i jednostki muszą mieć wartość 0.
Liczba powtórzeń (opcjonalnie)
To użycie reprezentuje liczbę powtórzeń kształt fali po początkowym odtwarzaniu. Wartość zero wskazuje, że kształt fali powinien być odtwarzany tylko raz.
Jeśli to użycie jest obsługiwane, okres ponownego pobierania i użycie czasu redukcji również musi być obsługiwane.
Wartość minimalna logiczna musi być równa zero, a wartość logiczna musi być większa niż zero. Maksymalna wartość logiczna powinna być ograniczona do małej wartości (na przykład 10). Zakres fizyczny i jednostki muszą mieć wartość 0.
Okres ponownego pobierania (opcjonalnie)
To użycie reprezentuje czas trwania między ponawianiami kształtów fal, mierzony od czasu rozpoczęcia poprzedniego wyzwalacza. Wartość zero powinna być interpretowana jako identyczna z domyślnym czasem trwania dla kształtów fali, więc ponowne pobieranie następuje natychmiast po zakończeniu poprzedniego. Wartości mniejsze niż domyślny czas trwania kształt fali powinny przerwać kształt fali i ponownie go uruchomić.
Jeśli to użycie jest obsługiwane, należy również obsługiwać użycie liczby powtórzeń i czasu redukcji.
Host będzie traktować wartości logiczne jako milisekundy. Wartość logiczna musi wynosić zero, a wartość logiczna musi wynosić co najmniej 1000 (reprezentując jedną sekundę). Zakres fizyczny musi być zerowy lub identyczny z zakresem logicznym. Jeśli zakres fizyczny jest inny niż zero, jednostki powinny być milisekundami.
Czas odcięcia kształtów falowych (opcjonalnie)
To użycie reprezentuje maksymalny czas, przez jaki pojedynczy wyzwalacz może spowodować odtwarzanie, biorąc pod uwagę liczbę powtórzeń i okres ponownego pobierania.
Jeśli to użycie jest obsługiwane, liczba powtórzeń i ponowne pobieranie użycia muszą być również obsługiwane.
Host będzie traktować wartości logiczne jako milisekundy. Minimum logiczne musi być co najmniej tak duże, jak czas trwania najdłuższego dyskretnego kształt fali, pomnożony przez logiczne maksymalne użycie liczby powtórzeń. Zakres fizyczny musi być zerowy lub identyczny z zakresem logicznym. Jeśli zakres fizyczny jest inny niż zero, jednostki powinny być milisekundami.
Wskazówki dotyczące haptycznego panelu dotykowego
Elementy w tej sekcji dotyczą tylko dotykowych tabletów dotykowych.
Device-Initiated haptic feedback
Haptic touchpad jest odpowiedzialny za wyzwalanie haptycznych opinii, gdy określa, że przycisk powierzchni touchpad został naciśnięty lub zwolniony. Może on obsługiwać raporty SET_FEATURE, aby umożliwić użytkownikom dostosowywanie jego zachowania podczas wykonywania tych czynności:
- Intensywność haptycznych opinii
- Siła wymagana do wyzwolenia naciśnięcia przycisku
Oba te raporty funkcji są obowiązkowe, jeśli touchpad obsługuje również opinie haptyczne inicjowane przez hosta. Każdy raport musi używać odrębnego identyfikatora raportu, który nie jest używany z żadnym innym użyciem.
Podczas wyliczania host oceni obsługiwany zakres logiczny i fizyczny z deskryptora i obliczy uwidocznione opcje interfejsu użytkownika ustawień, w tym wartości domyślne. Host wydaje SET_FEATURE, aby przekazać użytkownikowi określoną wartość do urządzenia; wystawianie może wystąpić w dowolnym momencie, ale występuje za każdym razem, gdy ustawienie zostanie zmienione, nastąpi przełączenie użytkownika i gdy urządzenie zostanie wyliczone lub zresetowane.
Raport funkcji intensywności haptycznej
Ten raport SET_FEATURE określa preferencje użytkownika dotyczące intensywności haptycznej opinii na temat naciśnięcia i wydania przycisku. Nie ma zastosowania do intensywności jakiejkolwiek opinii zainicjowanej przez hosta, jeśli jest obsługiwana przez urządzenie. Aby obsługiwać tę konfigurację, urządzenie musi zdefiniować logiczną kolekcję podrzędną SimpleHapticsController (page 0x0E, Usage 0x01) w kolekcji najwyższego poziomu windows Precision Touchpad zawierającą użycie intensywności haptic (Page 0x0E, Usage 0x23) jako raport funkcji z dedykowanym identyfikatorem raportu. Ta kolekcja podrzędna nie może zawierać użycia wyzwalacza automatycznego (0x0E strony, 0x20 użycia) ani wyzwalacza ręcznego (0x0E strony, 0x21 użycia).
Minimum logiczne musi być równe zero. Preferencja użytkownika będzie liniowo skalowana do zakresu logicznego z zerowym wskazującym, że żadne opinie nie powinny być wyzwalane dla naciśnięcia i zwolnienia przycisku.
Raport funkcji naciśnięcia przycisku— próg
Ten raport SET_FEATURE określa preferencje użytkownika dotyczące ilości siły wymaganej do wyzwolenia naciśnięcia przycisku. Aby obsługiwać tę konfigurację, urządzenie musi zdefiniować użycie przycisku Naciśnij próg (strona 0x0D, użycie 0xB0) jako raport funkcji z dedykowanym identyfikatorem raportu w kolekcji najwyższego poziomu windows Precision Touchpad.
Zakres logiczny jest liniowo mapowany na fizyczny zakres wartości i równomiernie rozmieszczony i wyśrodkowany wokół wartości domyślnej. Po uzyskaniu zakresu logicznego wartość domyślna zostanie obliczona przy użyciu następującej formuły:
Wartość Minimum logiczne, Wartość domyślna i Wartość logiczna odpowiada 3 odrębnym poziomom naciśnięcia przycisku uwidocznionemu użytkownikowi za pośrednictwem interfejsu użytkownika ustawień systemu Windows (obsługującego odpowiednio "Niski", "Średni" i "Wysoki").
Zalecany zakres fizyczny dla progu naciśnięcia przycisku jest co najmniej pokrycie zakresu od 110g do 190g, co odpowiada odpowiednio minimalnym i maksymalnym wartościom. W przypadku deskryptora próbki korzystającego z wartości Fizycznej maksymalnej 190g i fizycznej minimalnej 110g (w związku z tym na podstawie powyższej formuły domyślna wartość domyślna to 150g), zobacz Przykładowe deskryptory raportów.
Przykładowe deskryptory raportów HID
Przykładowy deskryptor haptycznego touchpada
Poniższy deskryptor obsługuje wszystkie obowiązkowe i opcjonalne użycie. Deklaruje wsparcie dla pięciu kształtów fal, z najdłuższym okresem trwania 50 ms.
Wszystkie zakresy logiczne powinny być aktualizowane na podstawie obsługi urządzeń. Aby obsługiwać inną liczbę kształtów fal:
- Należy zaktualizować zakres logiczny użycia wyzwalacza ręcznego
- Należy zaktualizować zakresy użycia i liczbę raportów dla listy kształtów falowych i listy czasu trwania
Aby obsługiwać inną maksymalną długość kształtów fali, należy zaktualizować następujące zakresy logiczne:
- Okres pobierania (dane wyjściowe)
- Czas odcięcia kształtów falowych (dane wyjściowe)
- Lista czasu trwania (funkcja)
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()
Powyższy deskryptor został wygenerowany za pośrednictwem następującego pliku Waratah :
[[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'
Przykładowy opis myszy haptycznej
Poniższy deskryptor obsługuje wszystkie obowiązkowe i opcjonalne użycie. Deklaruje wsparcie dla ośmiu kształtów fali, z najdłuższym okresem trwania 200 ms.
Wszystkie zakresy logiczne powinny być aktualizowane na podstawie obsługi urządzeń. Aby obsługiwać inną liczbę kształtów fal:
- Należy zaktualizować zakres logiczny użycia wyzwalacza ręcznego
- Należy zaktualizować zakresy użycia i liczbę raportów dla listy kształtów falowych i listy czasu trwania
Aby obsługiwać inną maksymalną długość kształtów fali, należy zaktualizować następujące zakresy logiczne:
- Okres pobierania (dane wyjściowe)
- Czas odcięcia kształtów falowych (dane wyjściowe)
- Lista czasu trwania (funkcja)
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()
Powyższy deskryptor został wygenerowany za pośrednictwem następującego pliku Waratah :
[[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'