-
Notifications
You must be signed in to change notification settings - Fork 19
basic midi example #21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
x37v
wants to merge
2
commits into
mtthw-meyer:master
Choose a base branch
from
x37v:feature/midi
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
//! examples/midi.rs | ||
#![no_main] | ||
#![no_std] | ||
use log::info; | ||
|
||
use embedded_midi::{MidiMessage, MidiOut}; | ||
|
||
use libdaisy::{gpio, prelude::*, system::System}; | ||
use stm32h7xx_hal::{ | ||
stm32, | ||
timer::{Event, Timer}, | ||
}; | ||
|
||
#[derive(Copy, Clone)] | ||
enum NoteState { | ||
On, | ||
Off, | ||
Idle, | ||
} | ||
|
||
impl NoteState { | ||
pub fn next(&self) -> Self { | ||
match self { | ||
Self::On => Self::Off, | ||
Self::Off => Self::Idle, | ||
Self::Idle => Self::On, | ||
} | ||
} | ||
} | ||
|
||
#[rtic::app( | ||
device = stm32h7xx_hal::stm32, | ||
peripherals = true, | ||
monotonic = rtic::cyccnt::CYCCNT, | ||
)] | ||
const APP: () = { | ||
struct Resources { | ||
seed_led: gpio::SeedLed, | ||
timer2: Timer<stm32::TIM2>, | ||
midi_out: MidiOut<stm32h7xx_hal::serial::Tx<stm32h7xx_hal::stm32::USART1>>, | ||
} | ||
|
||
#[init] | ||
fn init(ctx: init::Context) -> init::LateResources { | ||
libdaisy::logger::init(); | ||
|
||
let device = ctx.device; | ||
let mut ccdr = System::init_clocks(device.PWR, device.RCC, &device.SYSCFG); | ||
let mut timer2 = device | ||
.TIM2 | ||
.timer(100.ms(), ccdr.peripheral.TIM2, &mut ccdr.clocks); | ||
timer2.listen(Event::TimeOut); | ||
|
||
info!("Startup done!"); | ||
|
||
timer2.set_freq(100.ms()); | ||
|
||
let gpioa = device.GPIOA.split(ccdr.peripheral.GPIOA); | ||
let gpiob = device.GPIOB.split(ccdr.peripheral.GPIOB); | ||
let gpioc = device.GPIOC.split(ccdr.peripheral.GPIOC); | ||
let gpiod = device.GPIOD.split(ccdr.peripheral.GPIOD); | ||
let gpiog = device.GPIOG.split(ccdr.peripheral.GPIOG); | ||
|
||
let mut gpio = crate::gpio::GPIO::init( | ||
gpioc.pc7, | ||
gpiob.pb11, | ||
Some(gpiob.pb12), | ||
Some(gpioc.pc11), | ||
Some(gpioc.pc10), | ||
Some(gpioc.pc9), | ||
Some(gpioc.pc8), | ||
Some(gpiod.pd2), | ||
Some(gpioc.pc12), | ||
Some(gpiog.pg10), | ||
Some(gpiog.pg11), | ||
Some(gpiob.pb4), | ||
Some(gpiob.pb5), | ||
Some(gpiob.pb8), | ||
Some(gpiob.pb9), | ||
Some(gpiob.pb6), | ||
Some(gpiob.pb7), | ||
Some(gpioc.pc0), | ||
Some(gpioa.pa3), | ||
Some(gpiob.pb1), | ||
Some(gpioa.pa7), | ||
Some(gpioa.pa6), | ||
Some(gpioc.pc1), | ||
Some(gpioc.pc4), | ||
Some(gpioa.pa5), | ||
Some(gpioa.pa4), | ||
Some(gpioa.pa1), | ||
Some(gpioa.pa0), | ||
Some(gpiod.pd11), | ||
Some(gpiog.pg9), | ||
Some(gpioa.pa2), | ||
Some(gpiob.pb14), | ||
Some(gpiob.pb15), | ||
); | ||
|
||
let (serial_tx, _) = libdaisy::serial::midi( | ||
gpio.daisy13.take().unwrap(), | ||
gpio.daisy14.take().unwrap(), | ||
device.USART1, | ||
ccdr.peripheral.USART1, | ||
&ccdr.clocks, | ||
) | ||
.unwrap() | ||
.split(); | ||
|
||
init::LateResources { | ||
seed_led: gpio.led, | ||
timer2, | ||
midi_out: MidiOut::new(serial_tx), | ||
} | ||
} | ||
|
||
#[task(binds = TIM2, resources = [timer2, seed_led, midi_out] )] | ||
fn send(ctx: send::Context) { | ||
static mut NOTE: NoteState = NoteState::Idle; | ||
static mut NOTE_NUM: u8 = 0; | ||
|
||
ctx.resources.timer2.clear_irq(); | ||
|
||
*NOTE = NOTE.next(); | ||
|
||
let note = *NOTE_NUM; | ||
|
||
match NOTE { | ||
NoteState::On => { | ||
ctx.resources.seed_led.set_high().unwrap(); | ||
ctx.resources | ||
.midi_out | ||
.write(&MidiMessage::NoteOn(0u8.into(), note.into(), 0x40u8.into())) | ||
.unwrap(); | ||
} | ||
NoteState::Off => { | ||
ctx.resources.seed_led.set_low().unwrap(); | ||
ctx.resources | ||
.midi_out | ||
.write(&MidiMessage::NoteOff( | ||
0u8.into(), | ||
note.into(), | ||
0x40u8.into(), | ||
)) | ||
.unwrap(); | ||
} | ||
NoteState::Idle => { | ||
*NOTE_NUM = (note + 1) & 0x7F; | ||
} | ||
}; | ||
} | ||
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
use stm32h7xx_hal::{ | ||
gpio::Analog, | ||
prelude::*, | ||
rcc, | ||
serial::{config::InvalidConfig, Serial, SerialExt}, | ||
stm32::USART1, | ||
}; | ||
|
||
/// Get a configured serial MIDI device | ||
pub fn midi( | ||
daisy13: crate::gpio::Daisy13<Analog>, | ||
daisy14: crate::gpio::Daisy14<Analog>, | ||
usart1_d: USART1, | ||
usart1_p: rcc::rec::Usart1, | ||
clocks: &rcc::CoreClocks, | ||
) -> Result<Serial<stm32h7xx_hal::stm32::USART1>, InvalidConfig> { | ||
let (tx, rx) = (daisy13.into_alternate_af7(), daisy14.into_alternate_af7()); | ||
usart1_d.serial( | ||
(tx, rx), | ||
stm32h7xx_hal::serial::config::Config::default() | ||
.baudrate(31_250.bps()) | ||
.parity_none(), | ||
usart1_p, | ||
&clocks, | ||
) | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This implementation is very specific with hard coded pins and serial settings. Unless the h/w or protocol restricts it these should be configurable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah.. this is specific to the serial midi that these 2 devices support, but i could make it more general and then make a specific call if we end up with a
Field
and orPatch
classThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, midi does have a specific serial setting that it needs, but this could be configurable to different pin for non
Field
orPatch
devices.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As long as it's clear that the specific pins are for field/patch h/w I'm fine with either a specific or general implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds good. i'll make some changes to either make that more clear or make it more general or both