Aula — 31 de Outubro (Sexta feira) - theedwilk/JoystickRaspberry-HandsOn-DevTitans GitHub Wiki
Resumo: documento técnico do firmware atual do transmissor (ESP32) e do comportamento antigo. Descreve o protocolo síncrono por GPIO usado para enviar uma palavra de 16 bits com o estado do joystick, mapeamentos de pinos, rotina de transmissão (
write_2_bytes) e orientações para integração com o driver kernel (driver/joy_driver_module.c).
-
02/11 (atual) — Firmware ESP32 transmite palavra síncrona de 16 bits via GPIO (TX, CLK, SYNC). Driver kernel lê via IRQ no clock e transforma em eventos
input. -
24/09 (antigo) — Firmware simples que enviava atualizações por Serial textual (CSV ou linhas
CHAVE:VALOR) / leituras viaSerial.println().
| Sinal | Pino (ESP32) | Direção | Observação |
|---|---|---|---|
| TX_PIN | 5 | OUT | Dados bit a bit |
| CLK_PIN | 4 | OUT | Clock (pulso) |
| SYNC_PIN | 2 | IN | Lê sincronização gerada pelo driver Linux |
| PIN_UP | 36 | IN | Botão UP |
| PIN_RIGHT | 39 | IN | Botão RIGHT |
| PIN_DOWN | 34 | IN | Botão DOWN |
| PIN_LEFT | 35 | IN | Botão LEFT |
| PIN_START | 32 | IN | Botão START |
| PIN_SELECT | 33 | IN | Botão SELECT |
| PIN_ANALOGB | 25 | IN | Botão ANALOG (presente no firmware) |
| PIN_AXIS_X | 26 | ADC | Leitura analógica X |
| PIN_AXIS_Y | 27 | ADC | Leitura analógica Y |
Driver kernel espera os 3 sinais em GPIOs mapeados no driver (
DATA_GPIO = 229,CLK_GPIO = 230,SYNC_GPIO = 228).
O firmware agrupa 11 estados (7 botões + 4 D-Pad derivados dos eixos) em um uint16_t dataToWrite. A sua implementação atual define os bits 0..10; bits superiores ficam reservados.
| Bit | Função |
|---|---|
| 0 | botão 0 — (ex. UP ou conforme ordem do array) |
| 1 | botão 1 — DOWN |
| 2 | botão 2 — LEFT |
| 3 | botão 3 — RIGHT |
| 4 | START |
| 5 | SELECT |
| 6 | ANALOG |
| 7 | DPAD_UP |
| 8 | DPAD_DOWN |
| 9 | DPAD_LEFT |
| 10 | DPAD_RIGHT |
| 11–15 | reservado |
Nota: a ordem exata dos bits corresponde à forma como
sendJoystickData()montadataToWrite(o código colocaallStates[i]em1 << iparai = 0..10). Ao integrar com o driver, alinhe o mapeamento de botões entre firmware e driver.
Fluxo simplificado por frame (16 bits):
-
Driver (Linux) alterna
SYNC_GPIOperiodicamente (estadolastSync) para indicar ao ESP32 quando começar o próximo bit/frame. - ESP32 no
write_2_bytes()monitoraSYNC_PIN; quando detecta alternância, envia o próximo bit:- espera mudança de
SYNC_PIN(sincronização), - coloca
TX_PINcom o valor do bit atual, - faz
CLK_PINLOW → HIGH (pulso) comBIT_TIME_USentre transições, - repete para os 16 bits (i = 0..15).
- espera mudança de
- Driver detecta IRQ no
CLK_GPIO(subida) e, a cada IRQ, lêDATA_GPIOe acumula bit emreceived_data. - Após 16 bits completos, driver processa
received_datae dispara eventosinput_report_key().
Tempos:
-
BAUD_RATEdo firmware = 9600 (definido para calcularBIT_TIME_US). -
BIT_TIME_US = 1000000 / BAUD_RATE ≈ 104 µs(usado porets_delay_usno ESP32 eudelayno kernel).
Trecho importante (resumido):
// no firmware (ESP32)
#define bit_delay() ets_delay_us(BIT_TIME_US)
void IRAM_ATTR write_2_bytes(uint16_t data) {
static int lastSync = 0;
int syncBit = digitalRead(SYNC_PIN);
for (int i = 0; i < 16; i++) {
// espera mudança de sync
while (syncBit == lastSync) {
bit_delay();
syncBit = digitalRead(SYNC_PIN);
}
lastSync = syncBit;
bit_delay();
digitalWrite(CLK_PIN, LOW);
if (data & (1 << i)) digitalWrite(TX_PIN, HIGH);
else digitalWrite(TX_PIN, LOW);
bit_delay();
digitalWrite(CLK_PIN, HIGH);
}
}O firmware mais antigo (24/09) era simples e baseado em Serial textual:
-
Lê analógicos e botões com analogRead() e digitalRead().
-
Aplica threshold/anti-ruído a analógicos e debounce simples nos botões.
-
Envia apenas quando há mudança: linhas X:\n, Y:\n, A:0/1\n, etc.
-
Iteração por delay(10) (~100 Hz).
| Data | Alteração |
|---|---|
| 24/09 | Versão base: Serial textual (CSV / CHAVE:VALOR). |
| 29/09 | Adição de D-Pad analógico e debounce. |
| 15/10 | Driver kernel inicial (joy_driver_module.c) — leitura via /dev/uinput no userspace e primeiros testes. |
| 02/11 | Firmware atual: transmissão síncrona de 16 bits via GPIO (TX/CLK/SYNC). Início de integração com kernel AOSP/RPi. |