Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este documento detalha a implementação do protocolo para dispositivos de entrada habilitados para háptico que se conectam a um host Windows 11 compatível. Isso não inclui diretrizes sobre restrições mecânicas, restrições elétricas ou seleção de componente para gerar a resposta háptica no hardware do dispositivo de entrada.
Classes de dispositivo com suporte
Windows 11 dá suporte às seguintes classes de dispositivos de entrada habilitados para háptico:
O Touchpad háptico é uma extensão da classe Touchpad Device no Windows. Este guia de implementação complementa o Guia de Implementação do Touchpad e se concentra na implementação de hápticos no digitalizador do touchpad, logo, os touchpads hápticos devem atender aos requisitos do Guia de Implementação do Touchpad, além dos contidos aqui.
O Mouse Háptico é uma extensão da classe Dispositivo do Mouse no Windows. Os camundongos hápticos devem atender aos requisitos contidos nesta documentação.
Observação
Os dispositivos de entrada de caneta compatíveis com feedback tátil são uma classe especial de dispositivos que não será abordada neste documento. Para obter informações sobre como implementar um dispositivo de caneta com comentários hápticos, consulte o Guia de Implementação de Caneta Háptica.
Implementação do Protocolo de Háptica para Dispositivo de Entrada
Uma boa compreensão do protocolo HID é necessária para entender as informações apresentadas aqui. Consulte os seguintes recursos para obter informações sobre o protocolo HID:
O firmware de dispositivo de entrada habilitado para haptic só precisa relatar os usos descritos neste tópico. Windows usará o firmware e seus próprios drivers HID para habilitar o dispositivo e conceder acesso aos aplicativos do Windows ao dispositivo.
Os descritores de exemplo para cada classe de dispositivo com suporte são fornecidos na seção Descritores de Relatório de Exemplo abaixo.
Feedback Háptico Iniciado pelo Host
Um dispositivo de entrada com suporte háptico pode dar suporte a feedback háptico iniciado pelo host, que pode ser acionado a qualquer momento após a enumeração. A funcionalidade relacionada aos hápticos deve ser incluída em uma coleção HID SimpleHapticsController (Página 0x0E, Uso 0x01).
- Para touchpads, essa coleção deve ser um filho da coleção de nível superior Windows Precision Touchpad.
- Para camundongos, essa coleção deve ser uma coleção de nível superior e um irmão da coleção de nível superior do Mouse.
O suporte para comentários hápticos iniciados pelo host requer relatórios HID:
- Um relatório GET_FEATURE usado pelo host para consultar formas de onda com suporte e suas durações. Consulte a seção "Relatório de Funcionalidades da Forma de Onda" abaixo.
- Um relatório de OUTPUT usado pelo host para acionar hápticos manualmente. Consulte a seção "Relatório de Saída do Disparo Manual" abaixo.
Para os touchpads, esses relatórios devem ser definidos em duas coleções filhas lógicas SimpleHapticsController relacionadas à coleção filha principal SimpleHapticsController. Para camundongos, esses relatórios podem ser definidos diretamente na coleção de nível superior.
Formas de onda
A tabela a seguir define os formatos de onda compatíveis com o host para dispositivos de entrada habilitados para háptico. As formas de onda compatíveis com um dispositivo são associadas a um ordinal. O uso e a duração da forma de onda são fornecidos ao host por meio do relatório de informações da forma de onda (veja abaixo). Ao acionar feedback, o host fornece o ordinal da forma de onda desejada como o valor para o uso manual do acionamento.
Obrigatório e opcional
| Forma de onda | Description | Página | ID | Obrigatório/opcional |
|---|---|---|---|---|
| None | Nenhuma operação. Não deve afetar o estado de reprodução de formas de onda contínuas | 0x0E | 0x1001 | Obrigatório |
| Parar | Interrompe a reprodução de formas de onda contínuas | 0x0E | 0x1002 | Obrigatório |
| Passar o cursor | Um pulso de luz que indica estados de foco, sinalizando o potencial para uma ação futura | 0x0E | 0x1008 | Obrigatório |
| Colidir | Um pulso suave para indicar alcançar uma fronteira ou limite | 0x0E | 0x1012 | Obrigatório |
| Align | Um pulso rápido quando um objeto é encaixado em um guia de alinhamento | 0x0E | 0x1013 | Obrigatório |
| Passo | Um sinal firme para alterações discretas, como percorrer etapas ou valores | 0x0E | 0x1014 | Obrigatório |
| Crescer | Um pulso dinâmico que transmite movimento, transições ou atividade inteligente do sistema | 0x0E | 0x1015 | Obrigatório |
| Imprensa | Um pulso que representa um botão pressionado | 0x0E | 0x1006 | Veja abaixo |
| Liberação | Um pulso que representa uma liberação de botão | 0x0E | 0x1007 | Veja abaixo |
| Êxito | Um padrão crescente que confirma uma ação concluída | 0x0E | 0x1009 | Veja abaixo |
| Erro | Um padrão decrescente que indica uma ação com falha | 0x0E | 0x100A | Veja abaixo |
As formas de onda de Pressionar e Liberar são opcionais, mas, se houver suporte para uma, deve haver suporte para a outra também. Para touchpads, as formas de onda devem corresponder ao feedback de pressão e liberação iniciados pelo dispositivo.
As formas de onda de êxito e erro são obrigatórias para mouses e opcionais para touchpads. Se houver suporte para um, o outro também deverá ser.
Proibido
As formas de onda a seguir não devem ter suporte.
| Forma de onda | ID | Anotações |
|---|---|---|
| Click | 0x1003 | Causaria confusão com o feedback háptico existente para pressionamento de botões. |
| Buzz Contínuo | 0x1004 | Não é necessário dar suporte a formas de onda contínuas. |
| Vibração Contínua | 0x1005 | Não é necessário dar suporte a formas de onda contínuas. |
| Tinta Contínua | 0x100B | Aplicável somente a canetas. |
| Lápis Contínuo | 0x100C | Aplicável somente a canetas. |
| Marcador contínuo | 0x100D | Aplicável somente a canetas. |
| Marcador de cinzel contínuo | 0x100E | Aplicável somente a canetas. |
| Pincel Contínuo | 0x100F | Aplicável somente a canetas. |
| Borracha Contínua | 0x1010 | Aplicável somente a canetas. |
| Brilho Contínuo | 0x1011 | Aplicável somente a canetas. |
Relatório de Informações da Forma de Onda
O host emitirá esse relatório GET_FEATURE ao consultar o dispositivo em busca de suas formas de onda com suporte. Este relatório de funcionalidade deve ter um identificador de relatório exclusivo.
O relatório deve ter duas coleções lógicas filhas, uma para a lista de formas de onda e outra para a lista de duração. Essas coleções devem definir um intervalo de uso na página Ordinal (0x0A), que permite que o host consulte a forma de onda e a duração associadas a cada ordinal.
Usos obrigatórios e opcionais
| Membro | Description | Página | ID | Obrigatório/opcional |
|---|---|---|---|---|
| Lista de forma de onda | Coleção lógica que contém uma lista ordenada de formatos de onda hápticos compatíveis com o dispositivo | 0x0E | 0x10 | Obrigatório |
| Lista de Duração | Coleção lógica contendo uma lista ordenada de durações para formas de onda na Lista de Formas de Onda | 0x0E | 0x11 | Obrigatório |
Lista de forma de onda (obrigatória)
Essa coleção fornece o mapeamento entre ordinais e as formas de onda correspondentes. Os ordinais 1 e 2 correspondem a None e Stop implicitamente e não precisam ser declarados no descritor. Portanto, o mínimo de uso do intervalo de uso da coleção pode ser 3 e o máximo de uso deve ser grande o suficiente para atribuir ordinais a todas as formas de onda com suporte. Não há nenhuma ordem necessária para atribuir formas de onda aos ordinais 3 e superiores – somente ordinais 1 e 2 têm definições fixas.
Se o máximo de uso for maior do que o número de formas de onda compatíveis com o dispositivo, o dispositivo deverá relatar Nenhum para ordinais sem suporte.
O alcance lógico de uso deve incluir todas as configurações de forma de onda compatíveis. O intervalo físico e as unidades devem ser 0.
Lista de duração (obrigatória)
Essa coleção fornece as durações das formas de onda definidas na lista de forma de onda. O mínimo e o máximo de uso do intervalo de uso da coleção devem ser idênticos aos da lista de formas de onda.
Formas de onda discretas devem ter uma duração diferente de zero. Nenhum e Parar, se especificado, devem ter uma duração de zero.
O mínimo lógico do intervalo de uso deve ser zero e o máximo lógico deve ser pelo menos tão grande quanto a duração da forma de onda discreta mais longa. O host tratará os valores lógicos como milissegundos. O intervalo físico deve ser zero ou idêntico ao intervalo lógico. Se o intervalo físico e o intervalo lógico corresponderem, as unidades deverão ser milissegundos.
Relatório de saída do gatilho manual
O host emitirá este relatório ao disparar feedback háptico discreto. Este relatório de saída deve ter uma ID de relatório dedicada.
Usos obrigatórios e opcionais
| Membro | Description | Página | ID | Obrigatório/opcional |
|---|---|---|---|---|
| Gatilho Manual | Forma de onda para disparar por comando explícito do host | 0x0E | 0x21 | Obrigatório |
| Intensidade | Intensidade dos comentários | 0x0E | 0x23 | Obrigatório |
| Contagem repetida | Número de vezes para repetir o feedback após a execução inicial | 0x0E | 0x24 | Veja abaixo |
| Período de Retorno de Acionamento | Tempo para aguardar antes de acionar novamente o feedback quando repetir | 0x0E | 0x25 | Veja abaixo |
| Tempo de Corte de Onda | Tempo máximo que o feedback pode ser reproduzido antes de ser cortado. | 0x0E | 0x28 | Veja abaixo |
Contagem de Repetição, Período de Retrigger e Tempo de Corte da Forma de Onda são opcionais, mas se houver suporte para um, os outros dois também deverão ser.
Usos proibidos
| Usage | ID | Anotações |
|---|---|---|
| Gatilho Automático | 0x20 | Não é suportado pelo host. |
| Controle associado do gatilho automático | 0x22 | Não é suportado pelo host. |
Gatilho Manual (Obrigatório)
Este uso contém o ordinal da forma de onda, conforme definido no relatório de informações da forma de onda, que o host solicitou para reprodução. Quando um relatório de saída que contém um ordinal diferente de None é enviado para o dispositivo, ele deve começar imediatamente a reproduzir a forma de onda especificada com as propriedades adicionais incluídas no relatório de saída (Intensidade, Contagem de Repetição, Período de Repetição, Tempo de Corte, se houver suporte). O dispositivo deve apenas respeitar ordinais para formas de onda discretas, "None" e "Stop". Se o ordinal corresponder a Parar, qualquer reprodução de forma de onda discreta contínua deverá ser interrompida. Se o ordinal corresponder a Nenhum, nenhuma ação deverá ser executada e o feedback háptico contínuo deve permanecer em execução.
O intervalo lógico deve incluir todos os ordinais possíveis, incluindo os ordinais implícitos 1 (Nenhum) e 2 (Parar). O intervalo físico e as unidades devem ser 0.
Intensidade (obrigatório)
Esse uso representa a porcentagem de intensidade máxima a ser aplicada à forma de onda solicitada, com o máximo lógico representando a intensidade máxima e o mínimo lógico representando nenhuma intensidade.
O mínimo lógico deve ser zero e o máximo lógico deve ser selecionado com base nos recursos do dispositivo, por exemplo, se o dispositivo der suporte a quatro níveis de intensidade, o máximo lógico deverá ser quatro. Se o dispositivo der suporte a uma intensidade mais granular, o máximo lógico poderá ser maior, mas não deverá exceder 100. O dispositivo deve dar suporte a pelo menos quatro níveis de intensidade, portanto, o máximo lógico mínimo é quatro. Uma intensidade de zero indica que nenhum comentário deve ser reproduzido. O host usará apenas esse valor para Parar.
O intervalo físico e as unidades devem ser 0.
Contagem de repetição (opcional)
Esse uso representa o número de vezes para repetir a forma de onda após a reprodução inicial. Um valor zero indica que a forma de onda só deve ser reproduzida uma vez.
Se esse uso tiver suporte, o período de reativação e os usos de tempo limite também deverão ter suporte.
O mínimo lógico deve ser zero e o máximo lógico deve ser maior que zero. O máximo lógico deve ser limitado a um valor razoável (por exemplo, 10). O intervalo físico e as unidades devem ser 0.
** Período de reativação (opcional)
Esse uso representa a duração entre os reativamentos da forma de onda, medida a partir do horário de início do gatilho anterior. Um valor zero deve ser interpretado como idêntico à duração padrão da forma de onda, de modo que o retrigger ocorra imediatamente após a conclusão da anterior. Valores menores que a duração padrão do formato de onda devem interromper a forma de onda e reiniciá-la.
Se esse uso tiver suporte, a contagem de repetições e o tempo limite também deverão ter suporte.
O host tratará os valores lógicos como milissegundos. O mínimo lógico deve ser zero e o máximo lógico deve ser pelo menos 1000 (representando um segundo). O intervalo físico deve ser zero ou idêntico ao intervalo lógico. Se o intervalo físico não for zero, as unidades deverão ser milissegundos.
Tempo de corte de onda (opcional)
Esse uso representa a quantidade máxima de tempo que um único gatilho pode resultar em reprodução, levando em conta a contagem de repetições e o período de repetição.
Se esse uso tiver suporte, os usos de contagem de repetição e período de reativação também devem ter suporte.
O host tratará os valores lógicos como milissegundos. O mínimo lógico deve ser pelo menos tão grande quanto a duração do formato de onda discreto mais longo, multiplicado pelo máximo lógico do uso de contagem de repetição mais um. Esse mínimo lógico representa a duração de acionar a forma de onda mais longa com o número máximo suportado de acionamentos repetidos e sem atraso entre os reacionamentos. O máximo lógico pode ser limitado para evitar uma duração excessiva do feedback háptico para uma única solicitação, conforme a configuração do dispositivo. O intervalo físico deve ser zero ou idêntico ao intervalo lógico. Se o intervalo físico não for zero, as unidades deverão ser milissegundos.
Diretrizes de touchpad tátil
Os itens nesta seção se aplicam somente a touchpads hápticos.
Realimentação Háptica Iniciada pelo Dispositivo
Um touchpad háptico é responsável por disparar feedback tátil quando determina que o botão de superfície foi pressionado ou solto. Ele pode optar por dar suporte a relatórios SET_FEATURE para permitir a personalização do comportamento do usuário ao fazer isso:
- A intensidade do feedback háptico
- A força necessária para acionar o pressionamento de um botão.
Ambos os relatórios de recursos serão obrigatórios se o touchpad também oferecer suporte a comentários hápticos iniciados pelo host. Cada relatório deve usar uma ID de relatório distinta, não usada com qualquer outro uso.
Durante a enumeração, o host avaliará o intervalo lógico e físico com suporte do descritor e calculará as opções expostas para a interface do usuário de configurações, incluindo os padrões. O host deve emitir o SET_FEATURE para comunicar o valor especificado pelo usuário ao dispositivo; essa emissão pode ocorrer a qualquer momento, mas ocorrerá sempre que a configuração for alterada, ocorrer uma opção de usuário e quando o dispositivo for enumerado ou redefinido. Antes que o relatório SET_FEATURE tenha sido emitido, o dispositivo deve usar um padrão razoável de sua própria escolha (por exemplo, o meio de seu intervalo lógico).
Relatório de características de intensidade háptica
Este relatório SET_FEATURE especifica a preferência do usuário pela intensidade do feedback háptico ao pressionar e soltar o botão. Ele não se aplica à intensidade de qualquer comentário iniciado pelo host, se houver suporte do dispositivo. Para dar suporte a essa configuração, o dispositivo deve definir uma coleção lógica de filhos SimpleHapticsController (Página 0x0E, Uso 0x01) na coleção de nível superior Windows Precision Touchpad, contendo o uso de intensidade háptica (Página 0x0E, Uso 0x23) como um relatório de características com uma ID de relatório dedicada. Essa coleção filha não deve conter os usos Auto Trigger (Página 0x0E, Uso 0x20) ou Manual Trigger (Página 0x0E, Uso 0x21). Deve ser separado da coleção filha SimpleHapticsController usada para feedback háptico iniciado pelo host (se houver suporte).
O mínimo lógico deve ser igual a zero e o máximo lógico deve ser maior ou igual a quatro. A preferência do usuário será dimensionada linearmente para o intervalo lógico, com zero indicando que nenhum feedback deve ser acionado ao pressionar e soltar o botão.
Relatório do Limiar de Pressão do Botão
Este relatório SET_FEATURE especifica a preferência do usuário pela quantidade de força necessária para disparar uma tecla. Para dar suporte a essa configuração, o dispositivo deve definir o uso do "Limite de Pressão do Botão" (Página 0x0D, Uso 0xB0) como um relatório de recursos com uma ID de relatório dedicada na coleção de nível superior do Windows Precision Touchpad. Ele não deve estar dentro de uma coleção lógica SimpleHapticsController.
O intervalo lógico deve ser mapeado linearmente para o intervalo físico de valores e ser espaçado uniformemente e centralizado em torno do valor padrão. Após adquirir o intervalo lógico, o padrão será calculado usando a seguinte fórmula:
O Mínimo Lógico, Padrão e Máximo Lógico corresponderão a 3 níveis distintos de força de pressionamento de botão expostos a um usuário através da interface de configurações do Windows (com suporte para "Baixo", "Médio" e "Alto", respectivamente).
O intervalo físico recomendado para o Limite de Pressionamento de Botão é abranger pelo menos o intervalo entre 110g e 190g, correspondente aos valores mínimo e máximo, respectivamente. Para um descritor de exemplo que utiliza um máximo físico de 190g e mínimo físico de 110g (portanto, com base na fórmula acima, o padrão seria 150g) consulte Descritores de Relatório de Exemplo.
Descritores de relatório HID de exemplo
Descritor de touchpad haptic de exemplo
O descritor a seguir dá suporte a todos os usos obrigatórios e opcionais. Ele declara suporte para cinco formas de onda, com a mais longa tendo uma duração de 50ms.
Todos os intervalos lógicos devem ser atualizados com base no suporte ao dispositivo. Para dar suporte a um número diferente de formas de onda:
- O intervalo lógico do uso do Gatilho Manual deve ser atualizado
- Os intervalos de uso e a contagem de relatórios para Lista de Forma de Onda e Lista de Duração devem ser atualizados
Para dar suporte a um comprimento de forma de onda máximo diferente, os seguintes intervalos lógicos devem ser atualizados:
- Período de repetição (saída)
- Tempo de corte de forma de onda (saída)
- Lista de Duração (Recurso)
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()
O descritor acima foi gerado por meio do seguinte arquivo 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 = [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'
Descritor de exemplo de mouse háptico
O descritor a seguir dá suporte a todos os usos obrigatórios e opcionais. Ele declara suporte para oito formas de onda, sendo que a mais longa tem uma duração de 200ms.
Todos os intervalos lógicos devem ser atualizados com base no suporte ao dispositivo. Para dar suporte a um número diferente de formas de onda:
- O intervalo lógico do uso do Gatilho Manual deve ser atualizado
- Os intervalos de uso e a contagem de relatórios para Lista de Forma de Onda e Lista de Duração devem ser atualizados
Para dar suporte a um comprimento de forma de onda máximo diferente, os seguintes intervalos lógicos devem ser atualizados:
- Período de repetição (saída)
- Tempo de corte de forma de onda (saída)
- Lista de Duração (Recurso)
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()
O descritor acima foi gerado por meio do seguinte arquivo 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 = [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'