rp2350-macropad

Public

@arkandas

Download board files

Files for version 1. Pick what you came for.

Share rp2350-macropad

Check access before sharing the link.

Who can open this board

Anyone can open this board. No sign-in is required.

This link opens the latest version. Copying it does not grant additional access.

Loading…

README

RP2350 Macropad

A 3x3 mechanical macropad built around the Raspberry Pi RP2350A. It enumerates as a standard USB HID keyboard plus a USB CDC serial port, so each of the nine keys sends a configurable HID keycode and modifier combination. The key map is programmed over the serial port from a small web app, with no need to recompile or reflash the firmware to change it.

The board also drives a 1.14 inch ST7789 LCD that shows live temperature and humidity from an AHT20 sensor, basic system info (CPU clock, static RAM, uptime) and the current 3x3 key map. Three SK6805 RGB LEDs report status: power, caps lock, and an ambient temperature gradient.

Repository layout

.
├── Kicad/              KiCad 10 schematic, PCB and project files
├── assets/             Renders, board photos, exported schematic PDF
├── datasheets/         Datasheets for the main parts on the board
├── ibom/               Interactive HTML BOM
├── production/         Gerbers and fabrication outputs
└── code/
    ├── firmware/       RP2350 firmware (C, Pico SDK 2.2)
    ├── web-programmer/ Next.js web app for editing the key map
    └── host-actions/   Optional Python daemon for host-side macros

Hardware

  • MCU: RP2350A with 4 MB (32 Mbit) external QSPI flash (W25Q32)
  • Display: 1.14 inch ST7789 240x135 SPI LCD
  • Sensor: AHT20 I2C temperature and humidity
  • LEDs: three SK6805-EC20 (WS2812 compatible) on a single PIO chain
  • Switches: nine Cherry MX switches in a 3x3 matrix (rows GP5-7, columns GP2-4). The footprint takes the 5-pin PCB mount version, not the 3-pin plate mount one
  • USB: native USB on the RP2350, exposing an HID keyboard plus a CDC serial port
  • Debug: 3-pin JST-SH SWD connector (Raspberry Pi Debug Probe) and a 2.54mm UART header

The schematic and PCB are in Kicad/. Rendered images and a PDF schematic are in assets/, and an interactive BOM is in ibom/.

Firmware (code/firmware)

Built with the Raspberry Pi Pico SDK 2.2. The recommended setup is the official "Raspberry Pi Pico" VS Code extension, which downloads the SDK, toolchain and CMake into ~/.pico-sdk/ and provides the build, debug and flash actions used by .vscode/launch.json and .vscode/tasks.json.

Building from the command line

cd code/firmware
export PICO_SDK_PATH="$HOME/.pico-sdk/sdk/2.2.0"
export PICO_TOOLCHAIN_PATH="$HOME/.pico-sdk/toolchain/14_2_Rel1"
cmake -S . -B build -G Ninja
cmake --build build

The output is build/rp2350-macropad.uf2. To flash, hold BOOTSEL while plugging the board in and copy the UF2 onto the mounted RPI-RP2 drive, or run picotool load build/rp2350-macropad.uf2 -fx. With a Debug Probe on the SWD connector, the VS Code extension can flash and debug over SWD directly.

Source files

  • main.c: main loop (USB tasks, matrix scan, sensor read, LCD draw, LED animation, the CDC command protocol, and key map persistence in the last flash sector).
  • usb_descriptors.c: composite USB descriptor (HID keyboard plus CDC).
  • st7789.c, st7789.h: minimal SPI driver and bitmap text routines for the ST7789 panel.
  • font5x7.h: 5x7 bitmap font used by the LCD text routines.
  • icons.h, tools/gen_icons.py: color macro icons, and the script that generates them.
  • ws2812.pio: PIO program driving the SK6805 LED chain.
  • tusb_config.h: TinyUSB configuration (HID and CDC enabled).
  • CMakeLists.txt, pico_sdk_import.cmake: build configuration.

Web programmer (code/web-programmer)

A Next.js app that talks to the firmware over the USB CDC serial port using the Web Serial API. It reads the current key map from the device, lets you assign a keycode and modifier combination (or a host macro) to each of the nine keys, and writes the new map back to the last sector of flash so it survives a reboot. A live tester highlights each key on an on-screen copy of the LCD as it is pressed.

Web Serial runs in Chromium browsers (Chrome, Edge and other Chromium based browsers) and in Firefox 151 and newer. Safari does not support it.

Running locally

cd code/web-programmer
npm install
npm run dev

Open http://localhost:3000, click Connect via USB, choose the "Macropad Programmer" port from the browser picker, and edit the key map.

Host actions daemon (code/host-actions)

An optional Python daemon for macros that a single keystroke cannot express, such as running a script or toggling a system setting. A cell marked as a macro in the web programmer types nothing on its own; instead the firmware emits a serial event that the daemon turns into an action on the host. See code/host-actions/README.md for details.

USB CDC command protocol

The firmware exposes a line-oriented ASCII protocol on the CDC interface (115200 baud, although the rate is irrelevant on USB CDC). Each command is a single line ending in \n; responses are also single lines.

CommandResponse
INFOINFO:{"temp":..,"hum":..,"cpu_hz":..,"heap_used":..,"heap_free":..,"static_used":..,"uptime_ms":..,"flash_used":..,"flash_total":..}
GETCONFIG:k0,k1,k2,k3,k4,k5,k6,k7,k8,m0,m1,m2,m3,m4,m5,m6,m7,m8, nine HID keycodes followed by nine modifier bytes in row-major order
SET:k0,k1,...,k8,m0,m1,...,m8OK on success, ERR on a malformed payload. The new key map is written to the last 4 KB sector of flash and takes effect immediately
NAMENAME:<current device name>, empty if the device has never been renamed
SETNAME:<name>OK on success, ERR if <name> is longer than 31 bytes or contains a non-printable-ASCII byte. The name is persisted alongside the key map

In addition to the request/response commands above, the firmware emits two asynchronous push notifications while a host is connected. These are not replies to a request; they arrive whenever a key is touched:

EventWhen
PRESS:<idx>A physical key has just gone down (idx 0-8, row-major)
RELEASE:<idx>A physical key has just gone up

Hosts that do not care about these events can ignore any line whose first token is PRESS or RELEASE. The web programmer uses them to drive the live tester, and the host actions daemon uses them to trigger macros.

Modifier bits follow the standard USB HID convention: bit 0 = Ctrl, bit 1 = Shift, bit 2 = Alt, bit 3 = GUI/Meta, with the right-side modifiers in the upper nibble.

The key map is stored in the last flash sector with the following layout:

OffsetBytesField
0..34magic = 0xCA1A1002 (little-endian)
4..129keycodes (row-major)
13..219modifiers (row-major)
221name length (0..31; 0xFF is treated as "unset")
23..5432name bytes (printable ASCII, padded with 0xFF)

If the magic is missing or wrong (a fresh chip, or a firmware update that erased the sector) the firmware falls back to digits 1-9 with no modifiers and an empty name. Configs written by older firmware that did not yet have the name field still load: byte 22 reads as 0xFF and the name is treated as unset.

License

Released under the MIT License. See LICENSE.

Comments

No comments yet. Be the first to ask about this board.

Ask about this board

Sign in to BoardRepo

New here? Signing in creates your account; there is no separate sign-up.