Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este documento detalha a implementação do protocolo para dispositivos de entrada com capacidade háptica que se ligam a um host Windows 11 compatível. Isto não inclui orientações sobre restrições mecânicas, restrições elétricas ou seleção de componentes para gerar a resposta háptica dentro do hardware do dispositivo de entrada.
Classes de dispositivo suportadas
O Windows 11 suporta as seguintes classes de dispositivos de entrada com capacidade háptica:
Haptic Touchpad é uma extensão da classe Touchpad Device no Windows. Este guia de implementação adiciona ao Guia de Implementação do Touchpad e se concentra na implementação de hápticas dentro do digitalizador de touchpad, portanto, os touchpads hápticos devem atender aos requisitos do Guia de Implementação do Touchpad , além dos contidos aqui.
Haptic Mouse é uma extensão da classe Mouse Device no Windows. Os ratos hápticos devem cumprir os requisitos contidos nesta documentação.
Observação
Os dispositivos de entrada de caneta com capacidade háptica são uma classe especial de dispositivo que não será abordada neste documento. Para informações sobre como implementar um dispositivo de caneta com feedback háptico, consulte o Guia de Implementação da Caneta Háptica.
Implementação do Protocolo de Háptica para Dispositivos de Entrada
É necessária uma boa compreensão do protocolo HID para poder compreender as informações aqui apresentadas. Consulte os seguintes recursos para obter informações sobre o protocolo HID:
O firmware do dispositivo de entrada com capacidade háptica só precisa de reportar os usos descritos neste tópico. O Windows usará o firmware e os seus próprios drivers HID para ativar o dispositivo e dar acesso às aplicações Windows ao dispositivo.
Descritores de exemplo para cada classe de dispositivo suportada são fornecidos na secção de Descritores de Relatório de Exemplo abaixo.
Feedback háptico Iniciado pelo Host
Um dispositivo de entrada equipado com tecnologia háptica pode suportar feedback háptico iniciado pelo sistema anfitrião, que pode ser acionado a qualquer momento após a enumeração. Funcionalidades relacionadas com háptica devem ser incluídas numa coleção HID SimpleHapticsController (Página 0x0E, Uso 0x01).
- No caso dos touchpads, esta coleção deve ser filha da coleção de nível superior do Windows Precision Touchpad.
- Para ratos, esta coleção deve ser uma coleção de topo e estar ao mesmo nível da coleção de topo do Rato.
O suporte para feedback háptico iniciado pelo host requer relatórios HID:
- Um relatório GET_FEATURE usado pelo anfitrião para consultar as formas de onda suportadas e as suas durações. Consulte a secção "Relatório de Funcionalidades de Informação sobre Formas de Onda" abaixo.
- Um relatório OUTPUT usado pelo anfitrião para ativar manualmente os hápticos. Consulte a secção "Relatório de Saída de Disparo Manual" abaixo.
Para touchpads, estes relatórios devem ser definidos em duas coleções filhas lógicas SimpleHapticsController associadas à coleção principal de coleções filhas SimpleHapticsController. Para ratos, estes relatórios podem ser definidos diretamente dentro da coleção de nível superior.
Formas de onda
A tabela seguinte define as formas de onda suportadas pelo host para dispositivos de entrada com capacidade háptica. As formas de onda suportadas por um dispositivo estão associadas a um ordinal. O uso e a duração da forma de onda são fornecidos ao host através do relatório da funcionalidade de informações da forma de onda (veja abaixo). Ao acionar o feedback, o host fornece o ordinal da forma de onda desejada como o valor para a utilização manual do gatilho.
Obrigatório e Opcional
| Forma de onda | Description | Página | ID | Obrigatório/Opcional |
|---|---|---|---|---|
| Nenhum | Não-op. Não deve afetar o estado de jogo das formas de onda em curso | 0x0E | 0x1001 | Mandatory |
| Parar | Interrompe a reprodução de formas de onda em curso | 0x0E | 0x1002 | Mandatory |
| Passe o cursor | Um pulso de luz que indica estados de hover, sinalizando o potencial para uma ação futura | 0x0E | 0x1008 | Mandatory |
| Colisão | Um pulso suave para indicar que se atingiu uma fronteira ou limite | 0x0E | 0x1012 | Mandatory |
| Align | Um impulso agudo quando um objeto se encaixa num guia de alinhamento | 0x0E | 0x1013 | Mandatory |
| Step | Um pulso firme para alterações discretas, como passar por passos ou valores | 0x0E | 0x1014 | Mandatory |
| Crescer | Um pulso dinâmico que transmite movimento, transições ou atividade inteligente do sistema | 0x0E | 0x1015 | Mandatory |
| Pressionar | Um pulso que representa o pressionar de um botão | 0x0E | 0x1006 | Ver abaixo |
| Release | Um pulso que representa um botão de libertação | 0x0E | 0x1007 | Ver abaixo |
| Sucesso | Um padrão ascendente que confirma uma ação concluída | 0x0E | 0x1009 | Ver abaixo |
| Erro | Um padrão descendente que indica uma ação falhada | 0x0E | 0x100A | Ver abaixo |
As formas de onda Press and Release são opcionais, mas se uma for suportada, a outra também deve ser. Para touchpads, as formas de onda devem corresponder ao feedback de pressão e libertação iniciado pelo dispositivo.
As formas Success e Error são obrigatórias para ratos e opcionais para touchpads. Se um é apoiado, o outro também tem de ser.
Proibido
As seguintes formas de onda NÃO DEVEM ser suportadas.
| Forma de onda | ID | Observações |
|---|---|---|
| Clique em | 0x1003 | Causaria confusão com o feedback háptico existente para pressionar botões. |
| Buzz Contínuo | 0x1004 | Formas de onda contínuas não devem ser suportadas. |
| Vibração Contínua | 0x1005 | Formas de onda contínuas não devem ser suportadas. |
| Tinta Contínua | 0x100B | Aplicável apenas a canetas. |
| Lápis Contínuo | 0x100C | Aplicável apenas a canetas. |
| Marcador Contínuo | 0x100D | Aplicável apenas a canetas. |
| Marcador de cinzel contínuo | 0x100E | Aplicável apenas a canetas. |
| Escova Contínua | 0x100F | Aplicável apenas a canetas. |
| Borracha Contínua | 0x1010 | Aplicável apenas a canetas. |
| Brilho Contínuo | 0x1011 | Aplicável apenas a canetas. |
Relatório de características de dados de forma de onda
O host emitirá esse relatório de GET_FEATURE ao consultar o dispositivo para suas formas de onda suportadas. Este relatório de característica deve ter um ID dedicado para o relatório.
O relatório deve conter duas coleções lógicas subordinadas, uma para a lista de formas de onda e outra para a lista de durações. Estas coleções devem definir um intervalo de utilização na página Ordinal (0x0A), que permite ao host consultar 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 formas de onda | Coleção lógica contendo uma lista ordenada de formas de onda háptica suportadas pelo dispositivo | 0x0E | 0x10 | Mandatory |
| 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 | Mandatory |
Lista de Formas de Onda (Obrigatório)
Esta coleção fornece o mapeamento entre ordinais e as formas de onda correspondentes. Os ordinais 1 e 2 correspondem implicitamente a None e Stop e não precisam de ser declarados no descriptor. Portanto, o mínimo de utilização da gama de utilização da coleção pode ser 3, e o máximo de utilização deve ser suficientemente grande para atribuir ordinais a todas as formas de onda suportadas. Não existe uma ordem obrigatória para atribuir formas de onda aos ordinais 3 e superiores – apenas os ordinais 1 e 2 têm definições fixas.
Se o máximo de utilização for superior ao número de formas de onda suportadas pelo dispositivo, o dispositivo deve reportar Nenhuma para os ordinais não suportados.
O intervalo lógico do intervalo de utilização deve incluir todas as utilizações das formas de onda suportadas. A gama física e as unidades devem ser 0.
Lista de Duração (Obrigatório)
Esta coleção fornece as durações das formas de onda definidas na lista de formas 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.
As 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 alcance físico e o alcance lógico coincidirem, as unidades devem ser milissegundos.
Relatório de saída de gatilho manual
O anfitrião emitirá este relatório quando acionar um feedback háptico discreto. Este relatório de saída deve ter um ID de relatório dedicado.
Usos Obrigatórios e Opcionais
| Membro | Description | Página | ID | Obrigatório/Opcional |
|---|---|---|---|---|
| Gatilho manual | Waveform para executar como um comando explícito do host | 0x0E | 0x21 | Mandatory |
| Intensidade | Intensidade do feedback | 0x0E | 0x23 | Mandatory |
| Número de repetições | Número de vezes para repetir o feedback após o jogo inicial | 0x0E | 0x24 | Ver abaixo |
| Período de Retrigger | Duração do tempo de espera antes de acionar novamente o feedback ao repetir | 0x0E | 0x25 | Ver abaixo |
| Tempo de corte da forma de onda | Tempo máximo em que o feedback pode ser reproduzido antes de ser cortado | 0x0E | 0x28 | Ver abaixo |
Contagem de Repetições, Período de Reativação e Tempo de Corte da Forma de Onda são opcionais, mas se um deles for suportado, os outros dois também o devem ser.
Usos Proibidos
| Usage | ID | Observações |
|---|---|---|
| Gatilho automático | 0x20 | Não suportado pelo host. |
| Controlo Associado ao Disparo Automático | 0x22 | Não suportado pelo host. |
Gatilho Manual (Obrigatório)
Este uso contém o ordinal da forma de onda, conforme definido a partir do relatório de caraterísticas da forma de onda, que foi pedido para ser reproduzido pelo host. Quando um relatório de saída contendo um ordinal diferente de Nenhum é enviado para o dispositivo, deverá começar imediatamente a executar a forma de onda especificada, com as propriedades adicionais incluídas no relatório de saída (Intensidade, Contagem de Repetições, Período de Reativação, Tempo de Corte, se suportadas). O dispositivo deve apenas honrar ordinais para formas de onda discretas, Nenhuma e Stop. Se o ordinal corresponder a Stop, qualquer reprodução de forma de onda discreta em curso deve ser interrompida. Se o ordinal corresponder a Nenhum, nenhuma ação deve ser tomada, e o feedback háptico contínuo deve continuar a ocorrer.
O intervalo lógico deve incluir todos os ordinais possíveis, incluindo os ordinais implícitos 1 (Nenhum) e 2 (Stop). A gama física e as unidades devem ser 0.
Intensidade (Obrigatório)
Este uso representa a percentagem de intensidade máxima a aplicar à forma de onda solicitada, com o máximo lógico a representar a intensidade máxima e o mínimo lógico a representar nenhum feedback.
O mínimo lógico deve ser zero, e o máximo lógico deve ser selecionado com base nas capacidades do dispositivo – por exemplo, se o dispositivo suporta quatro níveis de intensidade, o máximo lógico deve ser quatro. Se o dispositivo suportar uma intensidade mais granular, o máximo lógico pode ser maior, mas não deve exceder 100. O dispositivo deve suportar pelo menos quatro níveis de intensidade, de modo que o máximo lógico mínimo é quatro. Uma intensidade de zero indica que não deve ser emitido qualquer feedback – o sistema apenas usará este valor para Parar.
A gama física e as unidades devem ser 0.
Contagem de repetições (opcional)
Este 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 tocada uma vez.
Se este uso for suportado, o período de reatrigger e o tempo de encerramento também devem ser suportados.
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). A gama física e as unidades devem ser 0.
Período de reacionamento (opcional)
Este uso representa a duração entre os retigres da onda, medida a partir do momento de início do gatilho anterior. Um valor de zero deve ser interpretado como idêntico à duração padrão para a forma de onda, de modo que o retrigger ocorre imediatamente após a conclusão da anterior. Valores inferiores à duração padrão para a forma de onda devem interromper a forma de onda e reiniciá-la.
Se esse uso for suportado, a contagem de repetições e o uso do tempo limite também devem ser suportados.
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 for diferente de zero, as unidades devem ser milissegundos.
Tempo de limite da 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 reacionamento.
Se este uso for suportado, também devem ser suportados a contagem de repetições e o período de reativação.
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 da forma de onda discreta mais longa, multiplicado pelo máximo lógico do uso da contagem de repetições mais um. Este mínimo lógico representa a duração da activação da forma de onda mais longa, com o número máximo suportado de activações repetidas e sem atraso entre as reativações. O máximo lógico pode ser limitado para evitar uma duração excessiva de feedback háptico para um único pedido, a critério do dispositivo. O intervalo físico deve ser zero ou idêntico ao intervalo lógico. Se o intervalo físico for diferente de zero, as unidades devem ser milissegundos.
Orientação com Touchpad Háptico
Os itens desta secção aplicam-se apenas a touchpads táteis.
Feedback Háptico Iniciado pelo Dispositivo
Um touchpad háptico é responsável por acionar o feedback háptico quando determina que o botão de superfície do touchpad foi pressionado ou liberado. Ele pode optar por oferecer suporte a relatórios SET_FEATURE para permitir a personalização do usuário de seu comportamento ao fazer isso:
- A intensidade do feedback háptico
- A força necessária para acionar um botão pressionado
Ambos os relatórios de funcionalidades são obrigatórios se o touchpad também suportar feedback háptico iniciado pelo host. Cada relatório deve usar um ID de relatório distinto, não usado com qualquer outro uso.
Durante a enumeração, o host avaliará o intervalo lógico e físico suportado a partir 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 utilizador ao dispositivo; Esta emissão pode ocorrer a qualquer momento, mas deve ocorrer sempre que a configuração for alterada, ocorrer uma troca de utilizador e quando o dispositivo for enumerado ou reiniciado. Antes de o relatório SET_FEATURE ser emitido, o dispositivo deve usar um padrão razoável à sua escolha (por exemplo, o meio do seu intervalo lógico).
Relatório de recursos de intensidade háptica
Este relatório de SET_FEATURE especifica a preferência do usuário pela intensidade do feedback háptico para pressionar e soltar botões. Ele NÃO se aplica à intensidade de qualquer feedback iniciado pelo host, se suportado pelo dispositivo. Para suportar esta configuração, o dispositivo deve definir uma coleção lógica de filhos do SimpleHapticsController (Página 0x0E, Uso 0x01) na coleção de topo do Windows Precision Touchpad, contendo o uso de Intensidade Háptica (Página 0x0E, Uso 0x23) como um relatório de características com um ID de relatório dedicado. Esta coleção filha não deve conter os usos de Gatilho Automático (Página 0x0E, Uso 0x20) ou Gatilho Manual (Página 0x0E, Uso 0x21). Deve ser independente da coleção filha SimpleHapticsController usada para feedback háptico iniciado pelo host (se suportado).
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 para pressionar e soltar botões.
Relatório de recursos de limite de pressionamento de botão
Este relatório SET_FEATURE especifica a preferência do usuário pela quantidade de força necessária para acionar um botão pressionado. Para suportar esta configuração, o dispositivo deve definir a utilização do Limiar de Pressão de Botão (Página 0x0D, Utilização 0xB0) como um relatório de funcionalidades com um ID de relatório dedicado na coleção de topo do Windows Precision Touchpad. Não deve estar dentro de uma coleção lógica do SimpleHapticsController.
O intervalo lógico deve ser mapeado linearmente para o intervalo físico de valores e ser uniformemente espaçado e centrado em torno do valor padrão. Após adquirir o intervalo lógico, o valor padrão será calculado usando a seguinte fórmula:
O Mínimo Lógico, o Padrão e o Máximo Lógico corresponderão a 3 níveis distintos de força de pressão de botões expostos ao utilizador através das definições do Windows (suportando "Baixo", "Médio" e "Alto", respetivamente).
O intervalo físico recomendado para o Button Press Threshold é cobrir, pelo menos, o intervalo entre 110g e 190g, correspondendo aos valores mínimo e máximo, respectivamente. Para um descritor de exemplo utilizando um Máximo Físico de 190g e Mínimo Físico de 110g (assim, com base na fórmula acima, o padrão seria 150g), consulte Descritores de Relatório de Amostra.
Exemplos de Descritores de Relatório HID
Exemplo de Descritor do Touchpad Háptico
O descritor a seguir suporta 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 suportar 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 Formas de Onda e Lista de Duração devem ser atualizados
Para suportar um comprimento máximo de forma de onda diferente, os seguintes intervalos lógicos devem ser atualizados:
- Período de Rearme (Saída)
- Tempo de corte da forma de onda (saída)
- Lista de Duração (Funcionalidade)
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 através 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'
Exemplo de Descrição de Rato Háptico
O descritor a seguir suporta todos os usos obrigatórios e opcionais. Declara suporte para oito formas de onda, sendo a mais longa com uma duração de 200ms.
Todos os intervalos lógicos devem ser atualizados com base no suporte ao dispositivo. Para suportar 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 Formas de Onda e Lista de Duração devem ser atualizados
Para suportar um comprimento máximo de forma de onda diferente, os seguintes intervalos lógicos devem ser atualizados:
- Período de Rearme (Saída)
- Tempo de corte da forma de onda (saída)
- Lista de Duração (Funcionalidade)
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 através 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'