Skip to content

donRaphaco/usbd-midi

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

55 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

usbd-midi

A simple usb midi device class for usb-device.

Currently this aims to be a very simple implementation, that allows the micro controller to send MIDI information to the PC and also receive MIDI information.

This crate requires the use of a hardware driver, that implements the usb-device traits.

Example

Receive MIDI

Turn on the integrated LED of a STM32 BluePill board as long as C2 is pressed

fn main() -> ! {
    let dp = pac::Peripherals::take().unwrap();

    let mut rcc = dp.RCC.constrain();

    let mut gpioa = dp.GPIOA.split(&mut rcc.apb2);
    let mut gpioc = dp.GPIOC.split(&mut rcc.apb2);

    let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
    led.set_high().unwrap();

    let mut usb_dp = gpioa.pa12.into_push_pull_output(&mut gpioa.crh);

    let usb = Peripheral {
        usb: dp.USB,
        pin_dm: gpioa.pa11,
        pin_dp: usb_dp.into_floating_input(&mut gpioa.crh),
    };

    let usb_bus = UsbBus::new(usb);

    let mut midi = MidiClass::new(&usb_bus, 1, 1);

    let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x5e4))
        .product("MIDI Test")
        .device_class(USB_AUDIO_CLASS)
        .device_sub_class(USB_MIDISTREAMING_SUBCLASS)
        .build();

    const CHANNEL1: Channel = Channel::new(0);

    loop {
        if !usb_dev.poll(&mut [&mut midi]) {
            continue;
        }

        let mut buffer = [0; 64];

        if let Ok(size) = midi.read(&mut buffer) {
            let buffer_reader = MidiPacketBufferReader::new(&buffer, size);
            for packet in buffer_reader.into_iter() {
                if let Ok(packet) = packet {
                    match packet.message {
                        MidiMessage::NoteOn(CHANNEL1, Note::C2, ..) => {
                            led.set_low().unwrap();
                        },
                        MidiMessage::NoteOff(CHANNEL1, Note::C2, ..) => {
                            led.set_high().unwrap();
                        },
                        _ => {}
                    }
                }
            }
        }
    }
}

Using more than one MIDI port

Calling MidiClass::new(&usb_bus, N, M); with N, M >= 1 to provide more than one input or output port requires the control-buffer-256 feature of the usb-device crate:

Cargo.toml:

usb-device = { version = ">=0.2.1", features = ["control-buffer-256"] }

Up to 5 in/out pairs can be used this way until we again run out of buffer space. Note that exceeding the available buffer space will silently fail to send the descriptors correctly, no obvious panic! will hint the actual problem.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Rust 100.0%