restructure
This commit is contained in:
parent
4b851614c0
commit
0489e7c8f8
@ -8,7 +8,13 @@ This project only attempts to expose the keyboard as a MIDI device.
|
|||||||
- Clone project.
|
- Clone project.
|
||||||
- Go into project directory.
|
- Go into project directory.
|
||||||
- Install `elf2uf2-rs`.
|
- 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
|
## materials
|
||||||
|
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
//! Tester for `geode_piano::pins::TransparentPins`.
|
||||||
|
//!
|
||||||
|
//! This is quickly hacked together.
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![deny(rust_2018_idioms)]
|
#![deny(rust_2018_idioms)]
|
||||||
@ -9,46 +13,8 @@ use embassy_rp::i2c;
|
|||||||
use embassy_rp::peripherals::USB;
|
use embassy_rp::peripherals::USB;
|
||||||
use embassy_rp::usb::{Driver, InterruptHandler};
|
use embassy_rp::usb::{Driver, InterruptHandler};
|
||||||
use embassy_time::Timer;
|
use embassy_time::Timer;
|
||||||
use gpio::{Level, Output};
|
use geode_piano::usb::usb_task;
|
||||||
use usb::usb_task;
|
use geode_piano::{blinky, pin_array, pins, unwrap};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
|
||||||
|
|
||||||
mod midi;
|
|
||||||
mod pins;
|
|
||||||
mod usb;
|
|
||||||
|
|
||||||
bind_interrupts!(struct Irqs {
|
|
||||||
USBCTRL_IRQ => InterruptHandler<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 😎
|
|
||||||
async fn unwrap<T, E: core::fmt::Debug>(res: Result<T, E>) -> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn read_task(mut pin_driver: pins::TransparentPins) {
|
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<USB>;
|
||||||
|
});
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let p = embassy_rp::init(Default::default());
|
let p = embassy_rp::init(Default::default());
|
||||||
|
|
||||||
let driver = Driver::new(p.USB, Irqs);
|
let driver = Driver::new(p.USB, Irqs);
|
||||||
_spawner.spawn(usb_task(driver)).unwrap();
|
unwrap(_spawner.spawn(usb_task(driver, log::LevelFilter::Debug))).await;
|
||||||
|
unwrap(_spawner.spawn(blinky::blink_task(p.PIN_25.into()))).await;
|
||||||
_spawner.spawn(blink_task(p.PIN_25.into())).unwrap();
|
|
||||||
|
|
||||||
Timer::after_secs(2).await;
|
Timer::after_secs(2).await;
|
||||||
|
|
||||||
@ -82,7 +51,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
let mut pin_driver = pins::TransparentPins::new(
|
let mut pin_driver = pins::TransparentPins::new(
|
||||||
i2c,
|
i2c,
|
||||||
[0x20, 0x27],
|
[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");
|
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");
|
log::debug!("main: setting pin 0 as output, active low");
|
||||||
unwrap(pin_driver.set_output(0)).await;
|
unwrap(pin_driver.set_output(0)).await;
|
||||||
unwrap(pin_driver.write_all(((1 << 40 - 1)) & 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;
|
|
||||||
|
|
||||||
log::debug!("main: starting read task");
|
log::debug!("main: starting read task");
|
||||||
_spawner.spawn(read_task(pin_driver)).unwrap();
|
_spawner.spawn(read_task(pin_driver)).unwrap();
|
17
src/blinky.rs
Normal file
17
src/blinky.rs
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
27
src/lib.rs
Normal file
27
src/lib.rs
Normal file
@ -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<T, E: core::fmt::Debug>(res: Result<T, E>) -> T {
|
||||||
|
match res {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("[FATAL] {:?}", e);
|
||||||
|
log::error!("HALTING DUE TO PANIC.");
|
||||||
|
Timer::after_millis(10).await;
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -85,12 +85,12 @@ pub struct TransparentPins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Helper to define the onboard pins in TransparentPins
|
/// Helper to define the onboard pins in TransparentPins
|
||||||
|
#[macro_export]
|
||||||
macro_rules! pin_array {
|
macro_rules! pin_array {
|
||||||
($($pin: expr),*) => {
|
($($pin: expr),*) => {
|
||||||
[$($pin.into(),)*]
|
[$($pin.into(),)*]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) use pin_array;
|
|
||||||
|
|
||||||
/// Create a new short-lived MCP23017 struct.
|
/// Create a new short-lived MCP23017 struct.
|
||||||
///
|
///
|
||||||
@ -133,7 +133,7 @@ impl TransparentPins {
|
|||||||
log::trace!("write_all: called with val {}", val);
|
log::trace!("write_all: called with val {}", val);
|
||||||
for i in 0..N_PIN_EXTENDERS {
|
for i in 0..N_PIN_EXTENDERS {
|
||||||
// value for this extender
|
// 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)?;
|
extender!(self, i)?.write_gpioab(ext_val as u16)?;
|
||||||
}
|
}
|
||||||
for pin in 0..N_REGULAR_PINS {
|
for pin in 0..N_REGULAR_PINS {
|
||||||
|
@ -43,6 +43,7 @@ use embassy_usb::{Builder, Config};
|
|||||||
pub async fn usb_task(
|
pub async fn usb_task(
|
||||||
// remember this is the Driver struct not the trait
|
// remember this is the Driver struct not the trait
|
||||||
driver: Driver<'static, USB>,
|
driver: Driver<'static, USB>,
|
||||||
|
log_level: log::LevelFilter,
|
||||||
) {
|
) {
|
||||||
// Create embassy-usb Config
|
// Create embassy-usb Config
|
||||||
let mut config = Config::new(0xc0de, 0xcafe);
|
let mut config = Config::new(0xc0de, 0xcafe);
|
||||||
@ -81,7 +82,7 @@ pub async fn usb_task(
|
|||||||
// Create classes on the builder.
|
// Create classes on the builder.
|
||||||
let mut midi_class = MidiClass::new(&mut builder, 1, 1, 64);
|
let mut midi_class = MidiClass::new(&mut builder, 1, 1, 64);
|
||||||
let logger_class = CdcAcmClass::new(&mut builder, &mut logger_state, 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.
|
// The `MidiClass` can be split into `Sender` and `Receiver`, to be used in separate tasks.
|
||||||
// let (sender, receiver) = class.split();
|
// let (sender, receiver) = class.split();
|
||||||
|
Loading…
Reference in New Issue
Block a user