Aula — 19 de Novembro (Quarta feira) - theedwilk/JoystickRaspberry-HandsOn-DevTitans GitHub Wiki
Comunicação ESP32 ↔ Raspberry Pi e Integração com Android (.kl / .idc)
Nesta aula documentamos como funciona a comunicação elétrica entre o ESP32 e o Raspberry Pi, e como o Android traduz os eventos do driver para eventos de controle de jogo usando arquivos .kl e .idc.
Fonte:
- Waldomiro Seabra
Como funciona a comunicação ESP32 ↔ Raspberry Pi
1. SPI com linha "Ready" ou "Busy"
Durante o desenvolvimento foi tentada a implementaçãodo protocolo SPI onde se us dois pinos, um de dados e um de clock. O dispositivo Iniciador emite um pulso de clock por meio do pino, o pulso é capturado por uma interrupção pelo dispositivo alvo e começa a leitura do bit enviado pelo pino de dados. Esse processo se repete por toda a leitura dos 2 bytes de dados
O protocolo padrão SPI não tem mecanismo de "espera". O Iniciador joga o clock e o Alvo tem que acompanhar. Se o Alvo precisar processar dados, ele perde o sincronismo. Para resolver isso, adiciona-se um terceiro fio:
-
Fio 1 (Clock): SCLK (Gerado pelo Iniciador).
-
Fio 2 (Dados): MOSI ("Master" Out "Slave" In).
-
Fio 3 (Notificação): Geralmente chamado de BUSY, DRDY (Data Ready) ou INT.
Como funciona na prática (Exemplo de Driver):
1. O Iniciador quer enviar dados.
* Antes de ativar o Clock, o driver verifica o estado do pino BUSY (o 3º fio).
* Se o pino estiver em nível lógico alto, significa "Estou ocupado, espere".
2. O Iniciador fica em loop esperando o pino ser liberado.
* Assim que o Alvo libera o pino, o Iniciador inicia o Clock e o envio de dados.
Interpretação técnica aplicada ao nosso projeto
-
A ESP32 atua como Iniciador
-
A Raspberry Pi / Kernel atua como Alvo
-
A linha SYNC funciona como DRDY / BUSY
-
O Clock (CLK) só é ativado quando a Raspberry sinaliza estar pronta
-
Isso garante transmissão de bits sincronizada e confiável
Integração com Android — .kl e .idc
1. Arquivo Key Layout (.kl)
Função: É o tradutor entre o Kernel e o Android. Ele mapeia os ScanCodes (valores numéricos brutos emitidos pelo seu driver Linux) para os KeyCodes (constantes lógicas usadas pela API do Android).
Exemplo Crítico: Converte o evento 304 BTN_SOUTH/0x130) para BUTTON_A, garantindo que o botão "A" do controle seja entendido semanticamente como um botão de confirmação de jogo, e não uma tecla genérica.
2. Arquivo Input Device Configuration (.idc)
Função: Define o comportamento e a classificação do dispositivo.
Configurações Chave:
-
keyboard.layout: Vincula explicitamente este dispositivo ao arquivo
.klacima. -
device.internal = 0: Informa que é um periférico externo.
-
keyboard.orientationAware = 0: Impede que os eixos do controle mudem se a tela do Android girar.
3. Estratégia de Deploy (/data vs /system)
Devido ao bloqueio do bootloader (Verity enabled), não foi possível escrever na partição padrão /system. A solução foi utilizar a partição de dados do usuário, que o Android também escaneia:
Caminhos Utilizados:
- .kl enviado para:
/data/system/devices/keylayout/Vendor_1234_Product_5678.kl - .idc enviado para:
/data/system/devices/idc/Vendor_1234_Product_5678.idc
Permissões: Foi aplicado o comando chmod 644 em ambos os arquivos. Isso é obrigatório, pois o processo do sistema (InputManagerService) roda com um usuário diferente e precisa de permissão de leitura (Read) nesses arquivos para carregar as configurações do seu driver.
Essa configuração garante que, ao reiniciar o framework ou o dispositivo, o Android reconheça seu driver GPIO como um Gamepad Xbox funcional.
Interpretação técnica aplicada ao projeto
-
O Driver interpreta os bits do controle e emites eventos ao kernel
-
O Android não usa esses eventos diretamente
-
O Android precisa saber:
- “Esse evento significa BOTÃO A”
- “Esse evento significa ANALÓGICO ESQUERDO CIMA”
-
Isso é feito pelo
.kl
Depois:
-
O Android precisa saber o tipo do dispositivo
- controle? teclado? mouse? sensor?
-
Isso é feito pelo
.idc
Finalmente:
-
Como não podemos editar
/systempor causa do Android Verified Boot -
Instalamos os arquivos em
/data/system/devices/