RP2350 Rust Button Driver

September 17, 2026 · View on GitHub

FREE Reverse Engineering Self-Study Course HERE

VIDEO PROMO HERE


RP2350 Rust Button Driver

An RP2350 button driver written in Rust w/ Embassy.


Install ARM Toolchain

NOTE: Be SURE to select Add path to environment variable on setup.

HERE


Wiring

  • Button: Connect one terminal of the button to GPIO15 and the other terminal to GND.
  • LED: Connect LED anode (long leg) to GPIO16 through a 330Ω resistor, and cathode (short leg) to GND.

Build

cargo run

Clean

cargo clean

Test

make test

main.rs Code

/*
 * @file main.rs
 * @brief Microcontroller entry point
 * @author Kevin Thomas
 * @date 2025
 *
 * MIT License
 *
 * Copyright (c) 2025 Kevin Thomas
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

//! FILE: main.rs
//!
//! DESCRIPTION:
//! RP2350 Embedded Rust Embassy Button Driver Application.
//!
//! BRIEF:
//! Main application entry point for RP2350 GPIO button driver using Embassy.
//! Implements button input on GPIO 15 controlling LED on GPIO 16.
//! Button is active-low (tied to GND when pressed).
//!
//! AUTHOR: Kevin Thomas
//! CREATION DATE: November 28, 2025
//! UPDATE DATE: December 5, 2025

#![no_std]
#![no_main]

mod button;
mod config;
mod led;

use button::ButtonController;
use config::DEBOUNCE_DELAY_MS;
use embassy_executor::Spawner;
use embassy_rp::gpio::{Input, Level, Output, Pull};
use embassy_time::Timer;
use led::{led_state_to_level, LedState};
use panic_halt as _;

/// Main application entry point.
///
/// # Details
/// Initializes Embassy runtime and runs the main button polling loop.
/// Uses ButtonController for state management with debouncing.
/// Button on GPIO15 (active-low) controls LED on GPIO16.
///
/// # Arguments
/// * `_spawner` - Embassy task spawner (reserved for future async tasks).
///
/// # Returns
/// * `()` - Never returns (infinite loop).
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
    let p = embassy_rp::init(Default::default());
    let button = Input::new(p.PIN_15, Pull::Up);
    let mut led = Output::new(p.PIN_16, Level::Low);
    let mut controller = ButtonController::new();
    loop {
        controller.update(button.is_high());
        let state = if controller.is_pressed() {
            LedState::On
        } else {
            LedState::Off
        };
        if led_state_to_level(state) {
            led.set_high();
        } else {
            led.set_low();
        }
        Timer::after_millis(DEBOUNCE_DELAY_MS).await;
    }
}

License

MIT