This is a tentative to reverse engineer/develop alternative firmwares for the Paintaudio Midi Captain.
This is based on reverse engineering, and is make available to the public hoping it will be useful, but I offer
no warranty whatsoever on anything (if you break it YOU ARE ON YOUR OWN!!!!).
This infomation is similar to other Paintaudio products:
- Midi Captain STD Version Black (Same with no wireless module)
- Midi Captain Mini 6
- Midi Captain Nano 4
- Midi Captain Duo
- Midi Captain One
that seems to be based on the same microcontroller (RP2040) and CircuitPython. But not having them I cannot verify the information.
The board is based on a Raspberry Pi Core Microcontroller (RP2040 Datasheet) and is programmed using CircuitPython.
The CircuitPython Version on the board as per firmware 4.0 is 7.3.1 (see boot_out.txt)
Links:
- RP2040 Datasheet
- CircuitPython
- Paintaudio Recover uf2 file
- CircuitPython 7.x Library Bundle
- Paintaudio Midi Captain 3in1 Firmware 4.0
As described in the main product page here, to modify the CircuitPython code you have to enter the Update Mode
On the MIDI Captain this is done pressing switch0 (top left switch) when powering up while being connected via usb to a computer. This will show you the MIDICAPTAIN drive where you can load new firmware and modify the code.
On the board there's a 2 pin header that if you short it and reboot you'll go into circuitpython recovery mode.
Don't mess with it if you don't know what you are doing.
- Install the [mu editor][https://learn.adafruit.com/welcome-to-circuitpython/installing-mu-editor]
- Start the midi captain in fw update mode (switch 0 pressed at boot)
- with the mu editor, open the boot.py file and the serial consol
- comment the following lines to enable autoreload
# import supervisor # supervisor.disable_autoreload()
- Restart in fw update mode. You will see:
Adafruit CircuitPython 7.3.1 on 2022-06-22; Raspberry Pi Pico with rp2040 >>>
- if you modify the boot.py or the code.py files you will see
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable. code.py output:
- You can stop the boot pressing
Enter
at the prompt, or soft reboot withCtrl+D
based on the normal+geek_super 3in1 FW4.0
.
├── boot.py # Raspbe
├── boot_out.txt
├── code.py # Main Python Code
├── lib
│ ├── adafruit_bitmap_font # Display Libraries
│ ├── adafruit_display_notification
│ ├── adafruit_display_shapes
│ ├── adafruit_display_text
│ ├── adafruit_displayio_layout
│ ├── adafruit_imageload
│ ├── adafruit_progressbar
│ ├── adafruit_st7789.mpy
│ ├── adafruit_framebuf.mpy
│ ├── adafruit_midi # Midi Library
│ ├── adafruit_bus_device #
│ ├── adafruit_hid # USB Keyboard
│ ├── adafruit_io #
│ ├── adafruit_minimqtt # MQTT library?
│ ├── asyncio/ #
│ ├── adafruit_ticks.mpy #
│ ├── neopixel.mpy
│ ├── midicaptain.mpy # MIDI Captain
│ ├── midicaptain10s.mpy # MIDI Captain
│ ├── midicaptain_ledon.mpy # MIDI Captain
│ ├── midigeek.mpy # MIDI Captain Geek Mode
│ └── midigeek_C.mpy # MIDI Captain
Adafruit CircuitPython 7.3.1 on 2022-06-22; Raspberry Pi Pico with rp2040
Board ID:raspberry_pi_pico
import storage
import board
import digitalio
import time
# remove this two lines to auto reload the code when is modified
import supervisor
supervisor.disable_autoreload()
switch = digitalio.DigitalInOut(board.GP1)
switch.direction = digitalio.Direction.INPUT
switch.pull = digitalio.Pull.UP
time.sleep(0.05)
if switch.value is True:
storage.disable_usb_drive()
storage.remount("/", readonly=False)
else:
storage.remount("/", readonly=False)
m = storage.getmount("/")
m.label = "MIDICAPTAIN"
storage.enable_usb_drive()
storage.remount("/", readonly=True)
A lot of code to select the firmware mode.
The board is based on a Raspberry Pi Core Microcontroller (Datasheet), with the following peripherals:
- 10 footswitches
- 30 RGB led, separately addressables
- Midi In/Out
- 2 expression pedal Input
- Battery
- wireless module
GPIO | PERIPERAL | board lib pin / notes? |
---|---|---|
GP0 | encoder switch | |
GP1 | switch1 | |
GP2 | encoder A | |
GP3 | encoder B | |
GP4 | ||
GP5 | ||
GP6 | ||
GP7 | neopixel GPIO | |
GP8 | tft_pwm | |
GP9 | switchA | |
GP10 | switchB | |
GP11 | switchC | |
GP12 | tft_dc | (debug_port??) |
GP13 | tft_cs | (debug_port??) |
GP14 | tft_spi_clk | |
GP15 | tft_spi_mosi | |
GP16 | uart_midi_tx | |
GP17 | uart_midi_rx | |
GP18 | switchD | |
GP19 | switchDown | |
GP20 | switchUp | |
GP21 | ||
GP22 | ||
GP23 | switch4 | SMPS_MODE |
GP24 | switch3 | VBUS_SENSE |
GP25 | switch2 | LED |
GP26 | GP26_A0 | |
GP27 | ExpPdl1 | GP27_A1 |
GP28 | ExpPdl2 | GP28_A2 |
GP29 | VOLTAGE_MONITOR |
UART pins can be assigned to any GPIO.
- set a midi cable between midi in and out
- run the following
30 RGB led on the board.
Adafruit 1.54" 240x240 Wide Angle TFT LCD Display with MicroSD | ST7789 with EYESPI Connector
-
https://www.adafruit.com/product/3787
1.54" 240x240 Color IPS TFT Display
tft_pwm = board.GP8
tft_dc = board.GP12
tft_cs = board.GP13
spi_clk = board.GP14
spi_mosi = board.GP15
spi = busio.SPI(spi_clk, spi_mosi)
display_bus = displayio.FourWire(spi, command=tft_dc, chip_select=tft_cs)
display = ST7789(
display_bus, width=240, height=240,
rowstart=80,
# colstart=53,
rotation=180,
)
The wireless module is a "wireless mouse" serial RF IC