MCPcopy Index your code
hub / github.com/ATOVproject/faderpunk

github.com/ATOVproject/faderpunk @configurator-v1.7.1

Chat with this repo
repository ↗ · DeepWiki ↗ · release configurator-v1.7.1 ↗ · + Follow
741 symbols 2,162 edges 126 files 55 documented · 7%

Browse by type

Functions 535 Types & classes 206
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Faderpunk

A powerful, modular eurorack and MIDI synthesizer controller built on the RP2350B microcontroller. Faderpunk provides 16 channels of flexible, programmable control with faders, buttons, CV jacks, and full MIDI integration, all configured through an intuitive web interface.

Overview

Faderpunk is an embedded Rust project that uses an RP2350B to create a feature-rich eurorack and MIDI controller. Each of the 16 channels can run a different "app" - from LFOs and sequencers to MIDI converters and Turing machines - creating a highly versatile control surface for modular synthesis.

Key Features

  • 16 Independent Channels: Each channel features a fader, button, RGB LED, and configurable CV jack
  • Modular App Architecture: Run different apps on different channels simultaneously
  • Dual-Core Performance: Hardware tasks on Core 0, application logic on Core 1
  • WebUSB Configuration: Browser-based configurator with drag-and-drop layout management
  • FRAM Storage: Persistent scene storage with fast save/recall
  • Full MIDI Support: USB MIDI device capabilities
  • I2C Integration: Compatible with 16n faderbank protocol
  • Real-time Control: Async architecture ensures responsive performance

Hardware Platform

Microcontroller

  • RP2350B (Raspberry Pi Pico 2)
  • Dual Cortex-M33 cores @ 150 MHz (overclocked to 250MHz)
  • 520 KB SRAM

I/O Components

  • MAX11300: 20-port programmable mixed-signal I/O (ADC/DAC)
  • FM24V10: 1 Mbit FRAM for persistent storage
  • WS2812B: RGB LED chains for visual feedback
  • 16 faders, 16 buttons, configurable CV jacks per channel

Architecture

Faderpunk uses a sophisticated dual-core architecture to maximize performance:

Core 0: Hardware Management

Runs dedicated Embassy async tasks for hardware interfaces: - MAX11300 ADC/DAC communication - Button scanning and debouncing - LED control (WS2812B) - MIDI input/output - FRAM storage operations - I2C communication - WebUSB protocol handling

Core 1: Application Logic

Executes user-facing apps: - Each app runs as an independent Embassy task - Apps receive hardware events via PubSub channels - Apps send commands to hardware via async channels - Clean abstraction through the App<N> API

Communication

  • Event PubSub: Broadcasts input events (button presses, fader changes, MIDI) to all apps
  • Command Channel: Apps send hardware commands (set LED color, configure CV, send MIDI)
  • Watch Channels: Global configuration and clock synchronization
  • Serialization: Postcard format for efficient no_std data exchange

Getting Started

Prerequisites

Hardware

  • Raspberry Pi Pico 2 (RP2350B)
  • Faderpunk PCB with supporting components
  • USB cable for programming and power

Software

  • Rust toolchain (nightly recommended)
  • picotool for UF2 conversion
  • Chromium-based browser for WebUSB configurator

Development Environment

You will need: - rustup - Rust (1.89 or newer) with thumbv8m.main-none-eabihf target (rustup target add thumbv8m.main-none-eabihf) - picotool

Building and Flashing

Build Firmware

cd faderpunk # important, not in root
cargo build --release

Create UF2 File

Use the provided script to build and convert to UF2 format:

# this needs to be done in the repository root
./build-uf2.sh

This creates target/thumbv8m.main-none-eabihf/release/faderpunk.uf2

Flash to Device

  1. Hold the SHIFT button (the one on the very bottom right, the yellow one) while connecting Faderpunk to your computer via USB.
  2. Device appears as a mass storage device
  3. Copy faderpunk.uf2 to the device
  4. Device automatically reboots with new firmware

Development Workflow

For rapid development with debug output:

cd faderpunk
cargo build
# Use probe-rs or similar tool for flashing with RTT debug output

Web Configurator

The Faderpunk Configurator is a React/TypeScript web application that communicates with the device via WebUSB.

Features

  • Drag-and-drop layout management
  • Real-time parameter configuration
  • Global settings (MIDI, I2C, clock, quantizer)
  • Scene management
  • Live visual feedback

Running the Configurator

You will need: - NodeJS v22.x or higher - pnpm

Before building the configurator you'll need to run

# in the root
./gen-bindings.sh

This will create the Postcard bindings for the configurator (from libfp).

cd configurator
pnpm install
pnpm dev

Access at http://localhost:5173

NOTE: When changes to libfp happen, the bindings will need to be regenerated. Delete the node_modules folder in configurator and do the following steps in that case.

Browser Requirements

WebUSB requires: - Chrome/Chromium - Edge - Opera - Brave - Vivaldi or any Chromium-based browser

Firefox and Safari do not support WebUSB.

For more details, see configurator/README.md

Development

Project Structure

faderpunk/
├── faderpunk/           # Main firmware crate
│   ├── src/
│   │   ├── main.rs      # System initialization, core orchestration
│   │   ├── app.rs       # App API and abstractions
│   │   ├── apps/        # App implementations
│   │   ├── tasks/       # Hardware driver tasks
│   │   ├── events.rs    # Event types
│   │   ├── storage.rs   # FRAM persistence
│   │   └── layout.rs    # Channel layout management
│   └── Cargo.toml
├── libfp/               # Shared library
│   ├── src/             # Common types and utilities
│   └── Cargo.toml
├── configurator/        # Web configurator
│   ├── src/
│   └── package.json
├── gen-bindings/        # TypeScript binding generator
└── Cargo.toml           # Workspace configuration

Creating a New App

  1. Create a new file in faderpunk/src/apps/my_app.rs:
use embassy_futures::select::select;
use embassy_sync::{blocking_mutex::raw::NoopRawMutex, signal::Signal};
use libfp::{AppIcon, Brightness, Color, Config, Range};
use crate::app::{App, Led};

pub const CHANNELS: usize = 1;

// App configuration visible to the configurator
pub static CONFIG: Config<0> = Config::new(
    "My App",
    "Description of what this app does",
    Color::Blue,
    AppIcon::Fader,
);

// Wrapper task - required for all apps
#[embassy_executor::task(pool_size = 16/CHANNELS)]
pub async fn wrapper(app: App<CHANNELS>, exit_signal: &'static Signal<NoopRawMutex, bool>) {
    // Exit handler allows clean shutdown when app is removed from layout
    select(run(&app), app.exit_handler(exit_signal)).await;
}

// Main app logic
pub async fn run(app: &App<CHANNELS>) {
    let output = app.make_out_jack(0, Range::_0_10V).await;
    let fader = app.use_faders();
    let buttons = app.use_buttons();
    let leds = app.use_leds();

    leds.set(0, Led::Button, Color::Blue, Brightness::Mid);

    loop {
        buttons.wait_for_down(0).await;
        let value = fader.get_value();
        output.set_value(value);
        leds.set(0, Led::Top, Color::Blue, Brightness::Custom((value / 16) as u8));
    }
}
  1. Register in faderpunk/src/apps/mod.rs
    42 => my_app,
  1. Build the firmware and see if you can find your app in the configurator

Code Quality

# Check compilation
cargo check

# Run Clippy linter
cargo clippy

# Format code
cargo fmt

Debugging

The project uses defmt for structured logging:

defmt::info!("Button pressed on channel {}", channel);

View logs using probe-rs or similar RTT-capable debugger.

Storage and Scenes

Faderpunk uses a 1 Mbit FRAM (FM24V10) for persistent storage:

  • Fast writes (no wear leveling needed)
  • Scene-based storage system
  • Apps can save/load state via serialization
  • Global configuration persistence

Apps implement scene save/load by serializing their state with postcard.

Communication Protocols

MIDI

  • USB MIDI device (shows as MIDI interface to host)
  • Configurable channel routing
  • Full MIDI message support via midly crate

I2C

  • 16n faderbank protocol support
  • Eurorack module integration
  • Configurable addressing

WebUSB

  • COBS framing for reliable packet transmission
  • Postcard serialization for compact binary protocol
  • Type-safe message definitions shared between firmware and configurator
  • Real-time bidirectional communication

Build Configuration

Release Profile

The workspace Cargo.toml configures aggressive optimization:

[profile.release]
lto = true
incremental = false
codegen-units = 1
debug = 2

This maximizes performance while retaining debug symbols for profiling.

Contributing

Contributions are welcome! Please follow the Rust Code of Conduct.

Development Guidelines

  • Use cargo fmt and cargo clippy before committing
  • Test on hardware when possible
  • Document new apps and features
  • Update TypeScript bindings when changing protocol types

Pull Request Process

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes with clear commit messages
  4. Ensure code passes clippy and builds successfully (warnings are, for the most part ok and expected at this point)
  5. Test on hardware if applicable
  6. Submit a pull request with a clear description

Release Process

Faderpunk uses a dual-track release system managed by release-please: - Beta releases: Published from the develop branch (e.g., 1.6.0-beta.5) - Stable releases: Published from the main branch (e.g., 1.5.0)

Both workflows are automated via GitHub Actions, but version management requires manual steps to keep the tracks synchronized.

Making a Beta Release

Beta releases happen automatically when commits are merged to the develop branch:

  1. Merge changes to develop: bash git checkout develop git merge feature-branch git push origin develop

  2. Release-please creates a PR:

  3. Workflow runs automatically on push
  4. Creates/updates a release PR with changelog
  5. Review the PR to verify version bumps and changelog

  6. Merge the release PR:

  7. Merge the release-please PR on GitHub
  8. This triggers the build and publish workflow
  9. Beta releases are published with prerelease: true flag
  10. Configurator deploys to GitHub Pages at /beta path

Making a Stable Release

Stable releases happen when develop is ready for production:

  1. Create PR from develop to main: bash git checkout develop git push origin develop # Ensure develop is up to date Then create a PR on GitHub from developmain

  2. Review and merge to main:

  3. Review the PR carefully
  4. Merge to main when ready for stable release

  5. Release-please creates a release PR on main:

  6. Workflow runs automatically
  7. Creates/updates a release PR with changelog
  8. Version numbers will match what was in develop

  9. Merge the release PR:

  10. Merge the release-please PR on GitHub
  11. This triggers the build and publish workflow
  12. Stable releases are published as full releases (not prereleases)
  13. Configurator deploys to GitHub Pages root path
  14. libfp is published to crates.io (if version changed)

Making a Patch Release (Hotfix)

Patch releases allow you to fix critical bugs in stable releases without pulling in new features from develop.

For example, to release 1.5.1 while develop is working on 1.6.0-beta.x:

  1. Create a hotfix branch from main: bash git checkout main git pull origin main git checkout -b hotfix/critical-bug

  2. Make your fix and push: bash # Make your changes git add . git commit -m "fix: critical bug in X" git push origin hotfix/critical-bug

  3. Create PR to main and merge:

  4. Create a PR from your hotfix branch → main
  5. Review and merge the PR

  6. Release-please creates a patch release PR:

  7. Workflow runs automatically
  8. Creates/updates a release PR (e.g., 1.5.01.5.1)
  9. Review and merge the release PR
  10. This triggers the build and publish workflow

  11. Sync the fix back to develop: bash git checkout develop git pull origin develop git merge main --no-edit git push origin develop

This ensures the fix is included in future beta and stable releases.

Important: You don't need to bump beta versions after a patch release, since beta is already ahead on the minor version (e.g., 1.6.0-beta.x is ahead of 1.5.1).

Critical: Sync Branches After Stable Release

IMPORTANT: After a stable release is published, you must sync the release history back to develop and bump beta versions ahead of stable.

  1. Merge main back into develop: bash git checkout develop git pull origin develop git merge main --no-edit git push origin develop

This ensures release-please on develop sees the stable release commits and doesn't get confused about what's been released.

  1. Bump beta versions ahead of stable using Release-As:

Use release-please's Release-As: footer to manually set the next beta version. You need to create separate commits for each package, touching a file in each package directory so release-please correctly assigns the version.

For example, if stable just released faderpunk-1.5.0 and configurator-1.6.1, beta should jump to 1.6.0-beta.0 and 1.7.0-beta.0:

```bash # Bump faderpunk to next beta version touch faderpunk/.release-as git add faderpunk/.release-as git commit -m "chore(faderpunk): bump to next beta version" -m "Release-As: 1.6.0-beta.0"

# Bump configurator to next beta version touch configurator/.release-as git add configurator/.release-as git commit -m "chore(configurator): bump to next beta version" -m "Release-As: 1.7.0-beta.0"

# Push to trigger release-please git

Extension points exported contracts — how you extend this code

Core symbols most depended-on inside this repo

Shape

Function 313
Method 222
Class 98
Interface 62
Enum 46

Languages

Rust74%
TypeScript26%

Modules by API surface

faderpunk/src/app.rs75 symbols
libfp/src/lib.rs58 symbols
faderpunk/src/storage.rs41 symbols
libfp/src/latch.rs25 symbols
libfp/src/quantizer.rs21 symbols
faderpunk/src/tasks/fram.rs20 symbols
faderpunk/src/tasks/midi.rs15 symbols
faderpunk/src/tasks/leds.rs15 symbols
configurator/src/utils/config.ts15 symbols
faderpunk/src/tasks/web_usb.rs14 symbols
faderpunk/src/tasks/clock.rs13 symbols
configurator/src/utils/usb-protocol.ts13 symbols

For agents

$ claude mcp add faderpunk \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page