Skip to content

atmel-samd: enable picogame on PyBadge - #11430

Merged
dhalbert merged 3 commits into
adafruit:mainfrom
MakerClassCZ:picogame-samd-dma
Sep 20, 2026
Merged

dhalbert merged 3 commits into
adafruit:mainfrom
MakerClassCZ:picogame-samd-dma

Conversation

@lynt-smitka

Copy link
Copy Markdown

Turns on picogame for the PyBadge, with a SAMD DMA display backend and RGB444.

  1. picogame: Canvas.text raises NotImplementedError without fontio - the ja/ko/ru builds of this board turn off terminalio (and with it fontio); Canvas.text did not link there.
  2. atmel-samd: picogame fast Display backend on the SERCOM SPI DMA - third implementation of the port contract next to raspberrypi and espressif. The engine composes the next strip while the DMA sends the previous one. +1604 B text together with RGB444.
  3. atmel-samd: enable picogame on pybadge.

Measured on PyBadge (160x128 ST7735 at 24 MHz), picowing-class load, uncapped:

path fps
portable bus.send 55.2
DMA backend 65.3
DMA backend + RGB444 82.3

Flash: picogame with the backend and RGB444 is 28356 B; the stock PyBadge has 5436 B free. The commit turns off following - they all are reachable through the Feather header only:

  • bleio (18344 B)
  • sdcardio (2956)
  • i2ctarget (2248)
  • ps2io (1664)
  • pulseio (1812)
  • frequencyio (1776)

Free after: 7716 B (en_US), 4840 B (fr), 10900 B (ja). If more room is needed later there are possible candidates:

  • stage (10952 B, the frozen bundle included) - picogame has a compatibility layer with stage
  • ulab (89416 B) - in my opinion it is less related on gaming board than picogame

fontio is off when terminalio is off (the ja/ko/ru builds of boards that
drop the terminal font), and picogame_canvas_text then fails to link.
Same shape as the raspberrypi backend: the first strip of a frame goes
through the portable bus.send path (which sets the window), later
strips are handed to shared_dma_transfer_start() on the display's
SERCOM and the engine renders the next strip while the DMA drains the
previous one. Strips over 65535 bytes (the DMAC transfer count) fall
back to a blocking send.

shared_dma_transfer_* carries the SAMD51 DMAC details a hand-rolled
descriptor got wrong the first time: the "transfer never starts"
errata kick, and draining the RX overflow left behind by a TX-only
job (without that the next bus.send saw a stale SPI state and the
board froze after a few frames).

Measured on a PyBadge (SAMD51, 160x128 ST7735 at 24 MHz) with the
picowing game: portable 55.2 fps, this backend 65.3 fps, +RGB444
82.3 fps. Cost +1604 B text with RGB444.
picogame with the DMA backend and RGB444 is 28356 B; the stock build
has 5436 B free. Turn off bleio, frequencyio, i2ctarget, ps2io,
pulseio and sdcardio, which are only reachable through the Feather
header. Free after: 7716 B (en_US), 4840 B (fr), 10900 B (ja).

@dhalbert dhalbert left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The newly turned-off modules look appropriate to me. I checked https://github.com/adafruit/Adafruit_Learning_System_Guides and don't see uses of those in existing projects.

@dhalbert
dhalbert requested a review from tannewt September 19, 2026 22:46
@dhalbert
dhalbert merged commit 8808ab7 into adafruit:main Sep 20, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants