Readme | Using the Badge | Playing the Game | Software Development | Badge Hardware |
---|
Version: CircuitPython 9.0.4; Seeeduino XIAO RP2040
Make sure you use version compatible libraries
When the RP2040 boots, it checks for valid data in the spi flash. If it doesn't, it boots into USB boot-loader mode and shows up as a drive labeled RPI-RP2. Download and copy the .UF2 file to the drive and it will reboot into CircuitPython. If you need to reinstall for any reason, short the 'BOOT' test pads while resetting the RP2040 and it will go back to the boot-loader mode.
Once CircuitPython is installed, when the badge is plugged in it will show
both a serial port and a drive labeled CIRCUITPY. Copy the entire contents
of /software/
in this repository to that drive. the badge will reboot and run the code.
The /config/
directory contains some text files with data specific to
the game. These will be copied along with the rest of the code:
- genfiles generates a pair of keys, and creates 50 variations of game*.csv files
- game*.csv has all the possible clues for each game, and is provisioned with one signed clue per game
- seed.txt needs to be filled with a seed for the random choice of solutions
- priv.json and pub.json are generated by genfiles and contain the game keys which can be used to authenticate the signed clues you receive. This is generated by the controller, the public key is copied to all badges
Details about the hardware can be found in HARDWARE
/software/
contains the code on the badge/flash/
contains files and tools for automatically flashing badges/config/
contains tools to generate all of the encrypted badge configurations
Most functions are wrapped inside classes with the priority to make the top level code more clean and readable versus sticking to a clean object model.
All functions should be non-blocking and quick to make sure the UI doesn't get frozen and button presses don't get missed. This means stuff like checking for enough UART valid data before reading it, and scheduling timed actions based on timestamps instead of sleep() calls
- core circuitpython libraries: time,board,busio,pulseio,digitalio,displayio, terminalio
- additional adafruit libraries in
/software/lib/
: debouncer, ticks, displayio_ssh1106, imageload, display_text
- Fake_IRDA.py wraps the UART interface, handles enabling/disabling the IRDA enable pin, and stuffing/unstuffing the bytes that are transmitted to work with the IRDA phy in the nonstandard way we use it
- Five_Way_Dpad.py wraps the dpad with the Adafruit Debouncer including all setup and a few helper functions for checking all buttons at once. The non-blocking update() function needs to be run periodically to capture all button presses.
- sh1106_ui.py/ssd1306.py wraps the I2C display interface, handles the overall display view, and creates a separate group for each of the navigation pages. The non-blocking show() function should be called periodically to make sure the correct view is displayed and to manage the transition animations
- disp.py wraps the functionality of the pages. The class handles initialization, managing the display view, underlying data and operations. Most of this is handled in a non-blocking update() function that returns the next state
- https://www.arduino.cc/reference/en/libraries/oled-ssd1306-sh1106/
- https://docs.circuitpython.org/projects/displayio_sh1106/en/latest/api.html
Driven by: https://docs.circuitpython.org/en/latest/shared-bindings/displayio/