Skip to content

pimoroni/badgeware-cpp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PicoVector on Badgeware 2350 boards - bare Pico SDK / C++

A standalone Pico SDK C++ project that drives the PicoVector vector renderer on the Pimoroni RP2350 Badgeware boards, from one codebase:

Board Display Notes
Tufty 2350 320x240 colour parallel ST7789 LORES 160x120 (pixel-doubled) or HIRES 320x240
Blinky 2350 39x26 mono LED matrix PIO+DMA BCD driver; brightness-mapped from RGB
Badger 2350 264x176 mono SSD1680 e-ink slow static refresh; present sparingly

It provides a small badge runtime - mirroring the Badgeware MicroPython screen / badge API - on top of a thin per-board hardware layer, plus C++ ports of the Badgeware PicoVector demos.

Boards

The runtime is written against a uniform board:: interface. Each board lives in board/<name>/ and supplies its Pico board header, its display driver, and the board:: glue (init / framebuffer / present / width / height and the COLOR / EPAPER capability constants). Everything shared between boards (PSRAM, power/RTC, buttons, panic) is header-driven and lives in lib/.

Select the target at configure time with -DBADGE_BOARD=<tufty|blinky|badger> (default tufty).

Getting it

PicoVector is a git submodule, so clone recursively:

git clone --recursive https://github.com/pimoroni/badgeware-cpp
# or, in an existing checkout:
git submodule update --init

Layout

.
├── assets/                fonts + images, embedded at build time
├── cmake/                 bin2c + badge_embed_asset (asset embedding)
├── lib/                   board-agnostic runtime + shared support
│   ├── picovector/        the PicoVector renderer (git submodule, no-bindings)
│   ├── badge.*            the screen/badge/shape runtime (uses board::)
│   ├── psram.*            APS6404 PSRAM bring-up over the RP2350 QMI
│   ├── buttons.*          debounced A/B/C/Up/Down/Home input
│   ├── powman.*           power button long-press -> sleep, and the RTC
│   └── panic.c            a panic hook to print out errors
├── board/                 one directory per target board
│   ├── tufty/             pimoroni_tufty2350.h, st7789.*, board.*
│   ├── blinky/            pimoroni_blinky2350.h, blinky.*, board.*
│   └── badger/            pimoroni_badger2350.h, ssd1680.*, board.*
└── demos/                 one executable per directory

Each board/<name>/board.cmake defines the board target for that target; the top-level CMakeLists.txt picks the board header before the SDK is pulled in.

Build

Needs the Arm GCC toolchain and CMake. The Pico SDK is located from PICO_SDK_PATH, or fetched from git automatically if that is unset. Use a separate build directory per board.

export PICO_SDK_PATH=/path/to/pico-sdk         # optional; omit to fetch the SDK

cmake -S . -B build/tufty  -DBADGE_BOARD=tufty
cmake --build build/tufty -j4                  # build every demo for Tufty

cmake -S . -B build/blinky -DBADGE_BOARD=blinky
cmake --build build/blinky --target text       # ...or just one demo

Each demo produces its own UF2 under build/<board>/demos/<name>/. Flash by drag-and-drop in BOOTSEL mode, or picotool load -x <path>.uf2.

-DPICOVECTOR_DUAL_CORE=ON rasterises on core1 as well as core0 (~2x faster).

Demos

C++ ports of the Badgeware PicoVector demos, written against the badge runtime. Demos marked * scale their layout by k = min(width,height)/120 (so Tufty at 160x120 is k=1 and unchanged) and also build for Blinky's 39x26 matrix; the rest assume Tufty's colour framebuffer and are Tufty-only:

primitives circles* lines* triangles* shape vector_shapes*
brushes gradient* pattern* pixelate blur_brush lighten_darken
filters blur* dither
strokes stroke joins_caps
fill rules / clipping fill_rules intersect line_clip
images sprites* transform_sprite* image_brush
other raycast · vector_text · buttons (input viz)

text and clock go further: they use badge::epaper() to pick a cadence and also target Badger's e-ink. text builds on all three boards; clock targets Tufty + Badger only (a clock face is meaningless on Blinky's 39x26 matrix). Use them as the template when porting more.

Which demo targets which board is declared in one place - BOARDS_<demo> in demos/CMakeLists.txt (default: Tufty only). A demo not listed for the current board has no build target at all. To see the whole map for a configured build:

cmake --build build/blinky --target list-demos   # or: make list-demos

which prints every demo and its supported boards, marking (*) the ones built for the board you configured.

Writing a demo

Own your loop (mirrors the Python while True: ...; badge.update() style):

#include "badge.hpp"
using namespace badge;

int main() {
  badge::init();
  while (true) {
    clear();
    /* draw on `screen` */
    present();          // gate on badge::epaper() for static e-ink
    poll();
  }
}

badge::run(update) is also available as a convenience loop (clear -> update -> present -> poll, with Home rebooting to BOOTSEL by default).

Query the target with badge::width / badge::height, badge::color() (false on the mono panels) and badge::epaper() (true on Badger).

Assets

Fonts and images live in assets/ and are embedded as C arrays at build time (badge_embed_asset() -> cmake/bin2c.cmake); nothing is read from a filesystem at runtime. The runtime embeds its fonts - the Sins .ppf pixel font (text()) and DynaPuff .af vector font (text_v()). Demos embed their own assets, e.g. the sprite demos decode skull.png via load_png() (PNGDEC).

Hardware

The framebuffer is RGBA8888 in SRAM (PicoVector's native format); each board's present() converts it to what the panel needs (RGB565 for the ST7789, a brightness map for the mono LED matrix / e-ink).

  • Displays - Tufty: 8-bit parallel (8080) ST7789 via PIO+DMA, landscape framebuffer transposed into the panel's portrait GRAM. Blinky: 39x26 LED matrix refreshed continuously by a PIO+DMA BCD bitstream. Badger: 264x176 SSD1680 e-ink over SPI, full-refresh (blocking, ~1s).
  • Power rail - the peripherals sit on a switched rail enabled via BW_SW_POWER_EN, brought up in board::init().
  • PSRAM - psram_init() maps the APS6404 at 0x11000000 (available for large/static data); the rendered framebuffer stays in SRAM for bandwidth.
  • Buttons - A/B/C/Up/Down/Home, debounced, with pressed/held/released.
  • RTC - PCF85063 on I2C; rtc_get_datetime() / rtc_set_datetime().
  • Power off - the power button is wired to RESET; powman_boot_check() (run at startup) detects a held button and powers the badge down (sleep, or shipping mode with Up+Down held). powman_sleep() and friends are also callable directly.

badge runtime API (summary)

screen (the image_t framebuffer) · width / height · color() / epaper() · ticks() · pen(colour|brush) · text / text_v · custom() and the PicoVector shape helpers (circle, star, rounded_rectangle, ...) · rnd / frnd · load_png · buttons::* · rtc_* / powman_*.

About

A C++ framework and demos for Badgeware's Tufty, Blinky and Badger boards.

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors