From 0489e7c8f80bcb37cd99e91078dc76c679580e87 Mon Sep 17 00:00:00 2001 From: dogeystamp Date: Mon, 15 Apr 2024 20:09:53 -0400 Subject: [PATCH] restructure --- README.md | 8 +++- src/{main.rs => bin/pin_test.rs} | 65 +++++++------------------------- src/blinky.rs | 17 +++++++++ src/lib.rs | 27 +++++++++++++ src/pins.rs | 4 +- src/usb.rs | 3 +- 6 files changed, 69 insertions(+), 55 deletions(-) rename src/{main.rs => bin/pin_test.rs} (53%) create mode 100644 src/blinky.rs create mode 100644 src/lib.rs diff --git a/README.md b/README.md index 33dfc50..56070b1 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,13 @@ This project only attempts to expose the keyboard as a MIDI device. - Clone project. - Go into project directory. - Install `elf2uf2-rs`. -- `cargo run --bin --release geode-piano` +- Follow the materials and wiring sections below. +- Set the Pico into BOOTSEL mode: + - Hold down the BOOTSEL button on the Pico. Keep holding it during the following steps. + - Reset the Pico: either replug the power, or short Pin 30 (RUN) to GND through a button or wire. +- Mount the Pico's storage on your device. +- `cargo run --release --bin [binary]` + - `[binary]` can be any binary under `src/bin/`. Run `cargo run --bin` to list them. ## materials diff --git a/src/main.rs b/src/bin/pin_test.rs similarity index 53% rename from src/main.rs rename to src/bin/pin_test.rs index 2dcf476..e5f217c 100644 --- a/src/main.rs +++ b/src/bin/pin_test.rs @@ -1,3 +1,7 @@ +//! Tester for `geode_piano::pins::TransparentPins`. +//! +//! This is quickly hacked together. + #![no_std] #![no_main] #![deny(rust_2018_idioms)] @@ -9,46 +13,8 @@ use embassy_rp::i2c; use embassy_rp::peripherals::USB; use embassy_rp::usb::{Driver, InterruptHandler}; use embassy_time::Timer; -use gpio::{Level, Output}; -use usb::usb_task; -use {defmt_rtt as _, panic_probe as _}; - -mod midi; -mod pins; -mod usb; - -bind_interrupts!(struct Irqs { - USBCTRL_IRQ => InterruptHandler; -}); - -/// Unwrap, but log before panic -/// -/// Waits a bit to give time for the logger to flush before halting. -/// This exists because I do not own a debug probe 😎 -async fn unwrap(res: Result) -> T { - match res { - Ok(v) => v, - Err(e) => { - log::error!("[FATAL] {:?}", e); - log::error!("HALTING DUE TO PANIC."); - Timer::after_millis(10).await; - panic!(); - } - } -} - -#[embassy_executor::task] -async fn blink_task(pin: embassy_rp::gpio::AnyPin) { - let mut led = Output::new(pin, Level::Low); - - loop { - led.set_high(); - Timer::after_millis(100).await; - - led.set_low(); - Timer::after_millis(900).await; - } -} +use geode_piano::usb::usb_task; +use geode_piano::{blinky, pin_array, pins, unwrap}; #[embassy_executor::task] async fn read_task(mut pin_driver: pins::TransparentPins) { @@ -58,14 +24,17 @@ async fn read_task(mut pin_driver: pins::TransparentPins) { } } +bind_interrupts!(struct Irqs { + USBCTRL_IRQ => InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_rp::init(Default::default()); let driver = Driver::new(p.USB, Irqs); - _spawner.spawn(usb_task(driver)).unwrap(); - - _spawner.spawn(blink_task(p.PIN_25.into())).unwrap(); + unwrap(_spawner.spawn(usb_task(driver, log::LevelFilter::Debug))).await; + unwrap(_spawner.spawn(blinky::blink_task(p.PIN_25.into()))).await; Timer::after_secs(2).await; @@ -82,7 +51,7 @@ async fn main(_spawner: Spawner) { let mut pin_driver = pins::TransparentPins::new( i2c, [0x20, 0x27], - pins::pin_array!(p.PIN_15, p.PIN_14, p.PIN_13, p.PIN_12, p.PIN_11, p.PIN_10, p.PIN_18, p.PIN_19), + pin_array!(p.PIN_15, p.PIN_14, p.PIN_13, p.PIN_12, p.PIN_11, p.PIN_10, p.PIN_18, p.PIN_19), ); log::info!("main: setting pins as input"); @@ -92,13 +61,7 @@ async fn main(_spawner: Spawner) { } log::debug!("main: setting pin 0 as output, active low"); unwrap(pin_driver.set_output(0)).await; - unwrap(pin_driver.write_all(((1 << 40 - 1)) & 0)).await; - - // these pins are faulty as inputs - // unwrap(pin_driver.set_output(7)).await; - // unwrap(pin_driver.set_output(8 + 7)).await; - // unwrap(pin_driver.set_output(16 + 7)).await; - // unwrap(pin_driver.set_output(16 + 8 + 7)).await; + unwrap(pin_driver.write_all((1 << 40 - 1) & 0)).await; log::debug!("main: starting read task"); _spawner.spawn(read_task(pin_driver)).unwrap(); diff --git a/src/blinky.rs b/src/blinky.rs new file mode 100644 index 0000000..72d4cfc --- /dev/null +++ b/src/blinky.rs @@ -0,0 +1,17 @@ +//! blinky task + +use embassy_rp::gpio::{Level, Output}; +use embassy_time::Timer; + +#[embassy_executor::task] +pub async fn blink_task(pin: embassy_rp::gpio::AnyPin) { + let mut led = Output::new(pin, Level::Low); + + loop { + led.set_high(); + Timer::after_millis(100).await; + + led.set_low(); + Timer::after_millis(900).await; + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..d8f1148 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,27 @@ +#![no_std] +#![no_main] +#![deny(rust_2018_idioms)] + +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +pub mod blinky; +pub mod midi; +pub mod pins; +pub mod usb; + +/// Unwrap, but log before panic +/// +/// Waits a bit to give time for the logger to flush before halting. +/// This exists because I do not own a debug probe 😎 +pub async fn unwrap(res: Result) -> T { + match res { + Ok(v) => v, + Err(e) => { + log::error!("[FATAL] {:?}", e); + log::error!("HALTING DUE TO PANIC."); + Timer::after_millis(10).await; + panic!(); + } + } +} diff --git a/src/pins.rs b/src/pins.rs index f46aa78..6e72d3e 100644 --- a/src/pins.rs +++ b/src/pins.rs @@ -85,12 +85,12 @@ pub struct TransparentPins { } /// Helper to define the onboard pins in TransparentPins +#[macro_export] macro_rules! pin_array { ($($pin: expr),*) => { [$($pin.into(),)*] } } -pub(crate) use pin_array; /// Create a new short-lived MCP23017 struct. /// @@ -133,7 +133,7 @@ impl TransparentPins { log::trace!("write_all: called with val {}", val); for i in 0..N_PIN_EXTENDERS { // value for this extender - let ext_val = (val >> (i*PINS_PER_EXTENDER)) & ((1 << PINS_PER_EXTENDER) - 1); + let ext_val = (val >> (i * PINS_PER_EXTENDER)) & ((1 << PINS_PER_EXTENDER) - 1); extender!(self, i)?.write_gpioab(ext_val as u16)?; } for pin in 0..N_REGULAR_PINS { diff --git a/src/usb.rs b/src/usb.rs index af71fbc..5d814d0 100644 --- a/src/usb.rs +++ b/src/usb.rs @@ -43,6 +43,7 @@ use embassy_usb::{Builder, Config}; pub async fn usb_task( // remember this is the Driver struct not the trait driver: Driver<'static, USB>, + log_level: log::LevelFilter, ) { // Create embassy-usb Config let mut config = Config::new(0xc0de, 0xcafe); @@ -81,7 +82,7 @@ pub async fn usb_task( // Create classes on the builder. let mut midi_class = MidiClass::new(&mut builder, 1, 1, 64); let logger_class = CdcAcmClass::new(&mut builder, &mut logger_state, 64); - let log_fut = embassy_usb_logger::with_class!(1024, log::LevelFilter::Trace, logger_class); + let log_fut = embassy_usb_logger::with_class!(1024, log_level, logger_class); // The `MidiClass` can be split into `Sender` and `Receiver`, to be used in separate tasks. // let (sender, receiver) = class.split();