Skip to content

Latest commit

 

History

History
85 lines (61 loc) · 4.01 KB

DEVELOP.md

File metadata and controls

85 lines (61 loc) · 4.01 KB

Develop with BSidesSF Badge 2024

Readme Using the Badge Playing the Game Software Development Badge Hardware

Developing for the badge

Version: CircuitPython 9.0.4; Seeeduino XIAO RP2040

Make sure you use version compatible libraries

Installing CircuitPython

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.

Installing The Attribution Game

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.

Provisioning the game data

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

  • /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

Architecture

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

Dependencies

  • core circuitpython libraries: time,board,busio,pulseio,digitalio,displayio, terminalio
  • additional adafruit libraries in /software/lib/: debouncer, ticks, displayio_ssh1106, imageload, display_text

Support modules

  • 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

Screen

Driven by: https://docs.circuitpython.org/en/latest/shared-bindings/displayio/