Bluepad32 firmware for AirLift¶
What is AirLift¶
AirLift is an ESP32 module. This module is a "co-processor", usually used to bring WiFi or BLE to the main processor.
AirLift modules are present in some Adafruit boards, like in:
Or it can be a standalone board:
AirLift modules come pre-installed with Adafruit's NINA firmware.
NOTE: Adafruit's NINA firmware is a fork of Arduino's NINA firmware. They are pretty similar, but they are not compatible since they use different SPI pins.
To have gamepad support, the original AirLift firmware must be replaced with Bluepad32 firmware. This is a simple step that needs to be done just once and can be "undone" at any time.
This is how it works:
- Gamepad (A) talks to AirLift module (B)
- AirLift module (B) talks to the main processor (C)
Bluepad32 firmware is "compatible-enough" with the original firmware:
- Uses SPI, and the same GPIOs to talk to the main processor
- Uses the same protocol that runs on top of SPI
- But not all messages are implemented. Only the ones that are needed to have gamepad support working.
Flashing Bluepad32 firmware¶
To flash Bluepad32 firmware, you have to:
- Put the Adafruit board in "pass-through" mode
- Flash pre-compiled version
- Or compile it yourself and flash it.
1. Put Adafruit board in "passthrough" mode¶
It might slightly vary from board to board, but basically what you have to do is:
- Put the board in "boot" mode, usually by double pressing the "reset" button.
- Flash the right "Passthrough" firmware for your board.
- Details here: Adafruit's Upgrade AirLift firmware
2. Flash pre-compiled version¶
Download the latest pre-compiled version from here:
Unzip it, and follow the instructions described in the README.md
file.
3. Or compile it yourself¶
Install the requirements described here: README.md.
Chose airlift
as the target platform:
cd {BLUEPAD32}/src/
# Select AirLift platform:
# Components config -> Bluepad32 -> Target Platform -> AirLift
idf.py menuconfig
# And then compile it!
idf.py build
4. Flash it using esptool¶
To flash it, you have to use the --before no_reset
option:
# Flash it!
# Port might be different
export ESPPORT=/dev/ttyACM0
esptool.py --port ${ESPPORT} --baud 115200 --before no_reset write_flash 0x1000 ./build/bootloader/bootloader.bin 0x10000 ./build/bluepad32-airlift.bin 0x8000 ./build/partitions_singleapp.bin
5. (OPTIONAL) Flash it using CircuitPython code¶
If step 4a) failed, you can try by using this CircuitPython code.
Copy & paste this file in your CIRCUITPYTHON
folder with the name code.py
.
And also copy the bluepad32-airlift-full-xxx.bin
to the CIRCUITPYTHON
folder.
import time
import board
import busio
from digitalio import DigitalInOut, Direction
import adafruit_miniesptool
print("ESP32 Bluepad32-FW")
# Override these if you are manually wiring. Otherwise, this will use ESP pins from board.
tx = getattr(board, "ESP_TX", board.TX)
rx = getattr(board, "ESP_RX", board.RX)
resetpin = getattr(board, "ESP_RESET", board.D12)
gpio0pin = getattr(board, "ESP_GPIO0", board.D10)
uart = busio.UART(rx, tx, baudrate=115200, timeout=1)
esptool = adafruit_miniesptool.miniesptool(
uart, DigitalInOut(gpio0pin), DigitalInOut(resetpin), flashsize=4 * 1024 * 1024
)
esptool.sync()
print("Synced")
print("Found:", esptool.chip_name)
if esptool.chip_name != "ESP32":
raise RuntimeError("This example is for ESP32 only")
esptool.baudrate = 115200 * 4 # speed up so we can wrap it in under 2 minutes
# Test connection again by asking for the MAC address
print("MAC ADDR: ", [hex(i) for i in esptool.mac_addr])
# Note: Make sure to use the LATEST nina-fw binary release! update the md5sum as well
# esptool.flash_file("NINA_W102-1.7.4.bin", 0x0, "80c2dfd8ad2e97b2c32899382860acb1")
esptool.flash_file("bluepad32-airlift-full-v3.7.1.bin", 0x0, "a8ae34c6d7cc7f08e0cafc468e66e0af")
esptool.reset()
time.sleep(0.5)
CircuitPython example¶
The Bluepad32 library for CircuitPython, including a working example, is available here:
How to debug Bluepad32 for AirLift¶
ADVANCED: Normally you wouldn't need this.
Assuming that the ESP32 UART pins are not exposed (true for all AirLift modules), the recommended way to debug the Bluepad32 firmware is:
- Get any ESP32 breakout module. It could be an Adafruit HUZZAH32
or any other ESP32 breakout.
- JUST DON'T GET A ESP32-S2 (doesn't have Bluetooth!). JUST "ESP32"
- Get a SAMD51 module, like the Adafruit Feather M4 Express
- Wire it like this:
ESP32 | SAMD51 | |
---|---|---|
MOSI | 14 | MOSI |
MISO | 23 | MISO |
SCK | 18 | SCK |
CS | 5 | D10 |
READY | 33 | D9 |
RESET | EN | D6 |
Something like this (left: Feather M4 express, right: HUZZAH32)
NOTE: If you use a HUZZAH32, pay attention to the GPIO labels. The MOSI/MISO/SCK lables that are in the front of board are not the ones that you should use. See the back of the board for the correct GPIO numbers.
In real life, it might look more messy:
The benefits of using two separate modules (SAMD51 + ESP32) are:
- You can see the console of both the ESP32 and SAM51 at the same time
- Faster flashing: it is > 2x faster to flash Bluepad32 directly to the ESP32 than to flash it with "PassThrough" method required for AirLift modules.
- If needed, you can inspect the SPI protocol with a logic analyzer