Firmware Overview
Firmware Overview
The ESP32 firmware handles input capture, debouncing, and BLE communication for each child module.
Architecture
┌──────────────────────────────────────────────────────────────────────────────────────────┐│ ESP32 CONTROLLER FIRMWARE ││ ││ ┌───────────────────────────────────────────────────────────────────────────────────┐ ││ │ FreeRTOS Tasks │ ││ │ │ ││ │ ┌─────────────────────────────────────────────────────────────┐ │ ││ │ │ Controller Task (Priority 5, 10ms loop) │ │ ││ │ │ │ │ ││ │ │ GPIO Read ──► Debounce ──► Aggregate ──► BLE Notify │ │ ││ │ └─────────────────────────────────────────────────────────────┘ │ ││ │ │ ││ │ ┌─────────────────────┐ ┌─────────────────────┐ │ ││ │ │ NimBLE Host (P6) │ │ Battery Task (P4) │ │ ││ │ │ BLE stack │ │ ADC read (2s) │ │ ││ │ └─────────────────────┘ └─────────────────────┘ │ ││ └───────────────────────────────────────────────────────────────────────────────────┘ ││ ││ ┌───────────────────────────────────────────────────────────────────────────────────┐ ││ │ Hardware Layer │ ││ │ │ ││ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ ││ │ │ 8 Action │ │ 4-Way │ │ System │ │ OLED │ │ Battery │ │ ││ │ │ Buttons │ │ Joystick │ │ Buttons │ │ Display │ │ ADC │ │ ││ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ ││ └───────────────────────────────────────────────────────────────────────────────────┘ │└──────────────────────────────────────────────────────────────────────────────────────────┘Project Structure
Directoryfirmware/esp32/
Directorymain/
- main.c Entry point, task creation
Directorysrc/
- controller_input.c GPIO config, state aggregation
- debounce.c Button debounce state machine
- gatt_svc.c BLE GATT service
- gap.c BLE advertising, connection
- display.c SSD1306 OLED driver
- battery.c ADC battery monitoring
Directoryinclude/ Header files
- …
- CMakeLists.txt
- sdkconfig.defaults
Components
Controller Input
Handles GPIO configuration and state aggregation:
| GPIO | Function |
|---|---|
| 15, 4, 16, 17, 5, 18, 19, 23 | Action buttons (1-8) |
| 25, 32, 33, 26 | Joystick (L, R, U, D) |
| 27, 14, 12 | Select, Start, Pair |
| 21, 22 | I2C (Display) |
| 34 | Battery ADC |
Debounce Module
Software debouncing with configurable timing:
- Debounce delay: 20-50ms
- Algorithm: State machine with counter
- Purpose: Filter electrical noise and bounce
GATT Service
BLE GATT server for input state notifications:
Service UUID: 666f7065-6e41-7263-6164-65000000000├── Characteristic: Input State│ ├── UUID: 666f7065-6e41-7263-6164-65000000001│ ├── Properties: Read, Notify│ └── Value: 4-byte state packetGAP (Generic Access Profile)
Handles BLE advertising and connection management:
- Device name: “NimBLE_GATT” (or configured name)
- Advertising interval: 20-40ms
- Connection parameters: 7.5-15ms interval for low latency
Button State Packet
4-byte packet sent via BLE notification:
Byte 0: [b1][b2][b3][b4][b5][b6][b7][b8] Action buttonsByte 1: [jL][jR][jU][jD][--][--][--][--] JoystickByte 2: [SE][ST][PA][--][--][--][--][--] System buttonsByte 3: [reserved]Building and Flashing
cd firmware/esp32idf.py set-target esp32idf.py buildidf.py -p /dev/ttyUSB0 flash monitorConfiguration
Key settings in sdkconfig.defaults:
# BLE ConfigurationCONFIG_BT_ENABLED=yCONFIG_BT_NIMBLE_ENABLED=yCONFIG_BT_NIMBLE_MAX_CONNECTIONS=1
# FreeRTOSCONFIG_FREERTOS_HZ=1000Next Steps
- BLE Protocol – Detailed BLE specification
- Server Overview – How the parent hub connects