¶PyBadge notes
I want to install the Uxn emulator for the Adafruit PyBadge. The default instructions have you install the graphical IDE. I'd rather do things through the command line.
¶Initial setup
The Arduino CLI is available in Pacman.
$ sudo pacman -S arduino-cli
Per the IDE instructions, we have to make sure to add the Adafruit URL as an additional board manager URL.
$ arduino-cli config init [edit ~/.arduino15/arduino-cli.yaml] $ head -n 2 ~/.arduino15/arduino-cli.yaml board_manager: additional_urls: ["https://adafruit.github.io/arduino-board-index/package_adafruit_index.json"]
Install the PyBadge board and Arcada libraries.
$ arduino-cli core download arduino:samd $ arduino-cli core install adafruit:samd $ arduino-cli board attach -b adafruit:samd:adafruit_pybadge_m4
Plug in the PyBadge and update its bootloader. (Follow the recommendation to double-check which cable you're using, to make sure it's not power only!)
Updating the PyBadge bootloader
[double-press reset button] $ sudo mount /dev/sda /mnt $ sudo cp ~/Downloads/update-bootloader-arcade_pybadge-v3.15.0.uf2 /mnt [wait for bootloader to update and PyBadge to restart] $ sudo umount /mnt
Compile the Uxn emulator.
$ arduino-cli compile uxn-pybadge.ino
Upload the emulator.
$ arduino-cli upload -p /dev/ttyACM0 uxn-pybadge.ino
It's not currently working! The filesystem doesn't exist, and so I can't follow the emulator README's instructions for uploading a Uxn ROM.
To debug and see the serial console output:
$ arduino-cli monitor -p /dev/ttyACM0
[Note that I think you have to time things carefully so that /dev/ttyACM0 exists for the command to succeed. But that device file doesn't exist until you plug in the PyBadge. So if you time things poorly you might miss the first couple of serial port output lines.]
¶Flash filesystem
I was able to get the flash filesystem to work in the Arduino IDE. It required adding the Adafruit TinyUSB and Adafruit SPIFlash libraries in the sketch. (This just adds the relevant include directives to the sketch's .ino file — it seems that the compile step uses the include directives to determine which libraries to compile and link into the final executable.)
#include <Adafruit_TinyUSB.h> #include <Adafruit_FlashCache.h> #include <Adafruit_SPIFlash.h> #include <Adafruit_SPIFlashBase.h> #include <Adafruit_FlashTransport.h> #include <flash_devices.h>
I also had to choose “Tools › USB Stack › TinyUSB” to activate the TinyUSB implementation.
Next step is to figure out how to reproduce all of the above with arduino-cli. The library inclusion step should be persistent, since that updated the actual .ino file.
Having read through the source of the Adafruit libraries, my hunch is that the TinyUSB menu option just adds -DUSE_TINYUSB to the compilation flags. I was eventually able to find this description of how those custom menu options work:
To confirm, I found the following lines in the Adafruit boards.txt file:
$ less ~/.arduino15/packages/adafruit/hardware/samd/1.7.13 [snip] # Menu: USB Stack adafruit_pybadge_m4.menu.usbstack.arduino=Arduino adafruit_pybadge_m4.menu.usbstack.tinyusb=TinyUSB adafruit_pybadge_m4.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB
The documentation says that we can for the CLI, we can add the option value to the fqbn while compiling:
$ arduino-cli board attach -b adafruit:samd:adafruit_pybadge_m4:usbstack=tinyusb $ arduino-cli compile uxn-pybadge.ino
And this worked! I can now upload the (fixed) emulator to the PyBadge.
$ arduino-cli upload -p /dev/ttyACM0 uxn-pybadge.ino
If you hold down the ‹start› button while the PyBadge starts up, the emulator will start in MSD (mass storage device) mode. The PyBadge will appear as a new block device (/dev/sda etc). Mount that and copy a Uxn rom as start.rom. The emulator will run that ROM when it boots.
sudo mount /dev/sda /mnt sudo cp ~/roms/catclock.rom /mnt/start.rom sudo umount /mnt
¶Fixing the interpreter loop
This “worked”, in the sense that the emulator would start and load the rom, but most of the roms I tried wouldn't actually work as they do in uxnemu on the desktop. The serial console shows a lot of “uxn halt” messages. I added some additional debug messages to print out the PC and the instruction byte for every instruction that is executed, both in the PyBadge interpreter and in uxnemu. At some point, some of the traces would start to diverge. This suggested to me that the interpreter loop in the PyBadge emulator isn't correct, though I didn't take the time to figure out precisely how. Instead, I just copied the interpreter loop from uxnemu over to the Arduino project.
[PATCH] Use latest uxnemu emulation loop
And with this patch, roms started to actually work!
...except that the apple in that snake game always shows up in the upper left corner.
...and none of the clocks show anything.
¶Fixing the ‘datetime’ device
Turns out that there's a recent patch to use an attached RTC board to provide “real” data when accessing the datetime device. And snake uses the current hour and minute as a poor man's random number generator. So the last change was to partially revert the RTC patch. If it's available, go ahead and use it. If not, fall back on the previous datetime implementation that assumes that the PyBadge was turned on at 2022-02-19 00:00:00, and counts up from there.