Skip to content

Instantly share code, notes, and snippets.

@dglaude
Last active March 13, 2025 00:40
Show Gist options
  • Save dglaude/b3ca959990736b18e9908633dd812c29 to your computer and use it in GitHub Desktop.
Save dglaude/b3ca959990736b18e9908633dd812c29 to your computer and use it in GitHub Desktop.
MacroPad (CircuitPython) that implement Zaparoo protocol to select game on the MisterFPGA
import storage, usb_cdc
import board, digitalio
import usb_hid, usb_midi
# On the Macropad, pressing a key grounds it. You need to set a pull-up.
# If not pressed, the key will be at +V (due to the pull-up).
button = digitalio.DigitalInOut(board.KEY12)
button.pull = digitalio.Pull.UP
if button.value: # Disable devices only if button is not pressed.
storage.disable_usb_drive() #
usb_cdc.disable() #
usb_midi.disable() #
usb_hid.disable() #
usb_cdc.enable(console=False, data=True) # Enable just data
print("End of boot.py")
# Based on Macropad demo from Kattni Rembor
# MIT Licence
# Copyright David Glaude
"""
Implement the Zaparoo "simple_serial" protocol to select a game from a MacroPad
Features:
1) Boot by default without access to CIRCUITPY drive and with only serial over CDC.
2) To access CIRCUITPY drive and REPL, press the lower left button while reseting.
3) Send on serial over USB a text string pre-defined for each key.
4) The first 12 entry in the shortcut table are map to physical key
5) All the entries are accessible via the rotary encoder, view on the screen and click to select.
On your MiSTer install Zaparoo and edit the config.toml file to add this driver:
[[readers.connect]]
driver = 'simple_serial'
path = '/dev/ttyACM0'
"""
import supervisor
from adafruit_macropad import MacroPad
import usb_cdc
import time
# Does not need to be exactly 12 entries, can be more or less
shortcut = [
"Nintendo64/mister-boot.z64",
"C64/Empty.g64",
"MacPlus/Disk605.dsk",
"Vectrex/Mine Storm (1982).vec",
"ao486/media/star trek 25th anniversary/star trek 25th anniversary.vhd",
"Gameboy/fake_tetris.gb",
"GBA/mister-boot.gba",
]
macropad = MacroPad()
# Select if we are in DEBUG mode writing to the REPL console or to USB_CDC Data
if usb_cdc.data==None:
text_lines = macropad.display_text(title="DEBUG")
serial=usb_cdc.console
else:
text_lines = macropad.display_text(title="MiSTer MacroPad")
serial=usb_cdc.data
old_rotary=-1
old_switch=False
while True:
key_event = macropad.keys.events.get()
# 12 physical keys
if key_event and key_event.pressed:
#print(key_event.key_number)
text_lines[0].text = "Key {} pressed!".format(key_event.key_number)
if key_event.key_number<len(shortcut):
text_lines[1].text = shortcut[key_event.key_number]
text = "SCAN\tremovable=yes\tuid={}\ttext=".format(key_event.key_number)
serial.write(text+shortcut[key_event.key_number]+"\n")
else:
text_lines[1].text = "No mapping".format(key_event.key_number)
# Rotary encoder
rotary=macropad.encoder
if rotary != old_rotary:
index=rotary%len(shortcut)
text_lines[0].text = "Rotary {} {}".format(macropad.encoder,macropad.encoder_switch)
text_lines[1].text = shortcut[index]
old_rotary=rotary
# Click with the rotary encoder
switch=macropad.encoder_switch
if switch and not old_switch:
index=rotary%len(shortcut)
text_lines[0].text = "Rotary {} {}".format(macropad.encoder,macropad.encoder_switch)
text_lines[1].text = shortcut[index]
text = "SCAN\tremovable=yes\tuid={}\ttext=".format(index)
serial.write(text+shortcut[index]+"\n")
time.sleep(0.2)
old_switch=switch
text_lines.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment