USB MIDI, am I headed down the right path?

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
Rick Burnett
Posts: 150
Joined: Tue Jan 08, 2013 2:20 pm

USB MIDI, am I headed down the right path?

Post by Rick Burnett »

I took all the SerialIUSB code out of the example, modified by board.h for using the pins I am using, used the define to tell it not to look for sense (using A9 for something else) and was able to successfully see the Serial device and usbmodem.

Second step was I found a device configuration example that defines and audio/midi interface. Used that instead and sure enough, shows up as a class compliant MIDI device.

HOWEVER,

After looking through the MIDI spec on USB, it looks like I have to arrange my messages into 32-bit packets whereas I think the SerialUSB system might be sending it as 8-bits at a time?

It would seem to me that I need to abandon the SerialUSB code and work on the regular USB driver. Does this sound correct? Also, any pointers on example code to get me going down this path?

As in the subject, I am trying to use the STM32 to send and receive MIDI data over USB as a class compliant device.

Thanks!
Rick
Rick Burnett
Posts: 150
Joined: Tue Jan 08, 2013 2:20 pm

Re: USB MIDI, am I headed down the right path?

Post by Rick Burnett »

So far, I am fairly certain that my configuration description is correct. This is a combination of code that was shared online by others and a COMPLETE review of all settings with the example information at the end of the USB-MIDI SPEC:

Code: Select all

static const uint8_t midi_descriptor[]=
{
  0x09, 0x02, 0x65, 0x00, 0x02, 0x01, 0x00, 0x00, 0x32, // Config                   CONFIG DESC    (bLength bDescType wTotalLength(2bytes) bNumInterfaces bConfigValue iConfig bmAttributes bMaxPower
  0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, // Interface 0              INTERFACE DESC (bLength bDescType bInterfaceNumber bAltSetting bNumEndpoints bInterfaceClass bInterfaceSubClass bInterfaceProtocol iInterface)
  0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, // CS Interface (audio)     CLASS SPECIFIC AC INTERFACE DESC
  0x09, 0x04, 0x01, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, // Interface 1              INTERFACE DESC (bLength bDescType bInterfaceNumber bAltSetting bNumEndpoints bInterfaceClass bInterfaceSubClass bInterfaceProtocol iInterface)
  0x07, 0x24, 0x01, 0x00, 0x01, 0x41, 0x00,             // CS Interface (midi)      CLASS SPECIFIC MS INTERFACE DESC
  0x06, 0x24, 0x02, 0x01, 0x01, 0x00,                   //   IN  Jack 1 (emb)       MIDI IN JACK DESC (bLength bDescType bDescSubType bJackType bJackID iJack)
  0x06, 0x24, 0x02, 0x02, 0x02, 0x00,                   //   IN  Jack 2 (ext)       MIDI IN JACK DESC (bLength bDescType bDescSubType bJackType bJackID iJack)
  0x09, 0x24, 0x03, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, //   OUT Jack 3 (emb)       MIDI OUT JACK DESC (bLength bDescType bDescSubType bJackType bJackID bNrInputPins baSourceID(1) baSourceID(1) iJack)
  0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x01, 0x01, 0x00, //   OUT Jack 4 (ext)       MIDI OUT JACK DESC (bLength bDescType bDescSubType bJackType bJackID bNrInputPins baSourceID(1) baSourceID(1) iJack)
  0x09, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, // Endpoint OUT             ENDPOINT DESC  (bLength bDescType bEndpointAddr bmAttr wMaxPacketSize(2 bytes)  bInterval bRefresh bSyncAddress)
  0x05, 0x25, 0x01, 0x01, 0x01,                         //   CS EP IN  Jack         CLASS SPECIFIC MS BULK DATA EP DESC
  0x09, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, // Endpoint IN              ENDPOINT DESC  (bLength bDescType bEndpointAddr bmAttr wMaxPacketSize(2 bytes)  bInterval bRefresh bSyncAddress)
  0x05, 0x25, 0x01, 0x01, 0x03                         //   CS EP OUT Jack          CLASS SPECIFIC MS BULK DATA EP DESC
};


I added comments to help identify what each of the positions mean. Even though I am not using any audio, the audio description IS REQUIRED to be in there as stated in the USB-MIDI docs.

I am not sure I fully understand embedded vs external in terms of the jacks, I am still digging into that in terms with what that means. Also decoding the two endpoint lines to understand if that is adding 2 more endpoints after the EP0 that exists always for control.

I also understand that they are using bulk transfer mode (which probably explains why MIDI should NOT be on a bus with other things if this what people use?!? given that bulk is lowest on the priority list).

How I move away from the serial driver and or if I can use that I still don't understand yet, but I'm absorbing pieces bit by bit. I hope what I post here will help others in using ChibiOS with USB for MIDI as I just cannot find anyone who is doing that (or they just aren't sharing what they've done.)
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: USB MIDI, am I headed down the right path?

Post by Giovanni »

Hi,

The serial-usb driver sends data using packets large up to the defined size, the size of the packet is determined by the queue fill level.

Giovanni
Rick Burnett
Posts: 150
Joined: Tue Jan 08, 2013 2:20 pm

Re: USB MIDI, am I headed down the right path?

Post by Rick Burnett »

Understood. I am trying to understand how the HOST deals with all the endpoints/ports described in the description and how that related to handling things in ChibiOS. It would seem that it must send that information and I must need to decode it somehow in a message handler?

The whole embeded verses external concept I read, I believe it's all in handling how virtual ports are concerned with inside your application. There is a link between them that you establish with the description, so that it kind of explains what one side sees (host) an the other side(peripheral) and what to do with it. The External ports are optional.

I'm thinking it might be good to see if I can examine with some sort of USB sniffer what the host is sending to me, maybe it will help make more sense.

Right now, this is a lot to absorb. haha.
Rick Burnett
Posts: 150
Joined: Tue Jan 08, 2013 2:20 pm

Re: USB MIDI, am I headed down the right path?

Post by Rick Burnett »

So for those going down this path who do not want to buy a USB Port Analyzer (because they are VERY expensive) find an old PC or load up Ubuntu into Parallels, VM-Ware or VirtualBox(free). I've tested this with parallels, but I've read it works with all of them once you figure out how to pass the USB through (on Parallels it just asks you when you plug in a device if you want it to go to your Parallels session). Be sure to load a NEW VERISON of Ubuntu so you have all the right libraries and kernel extensions installed.

1) I installed wireshark using the ubuntu software installer gui

2) I installed tshark with 'apt-get install tshark' This is like a text based version of wireshark if you want to use it (nice for testing out if devices are seen)

3) To get the usb monitoring stuff running you have to do this (i did 'sudo bash' and did everything as root so no permission problems which I had if I didn't do this AND was using sudo, for various problems:

(as root or use sudo)

Code: Select all

   modprobe usbmon   
   mount -t debugfs /sys/kernel/debug


I think the second line complained that it was already mounted but I left it in and ran it anyways just in case. Now go look in this dir:

Code: Select all

   /sys/kernel/debug/usb/usbmon


If you see a lot of 1u 1s etc, then congrats, your system sees the usb stuff. You can use this command to enumerate everything connected (very detailed):

Code: Select all

   lsusb -v (verbose mode)
   lsusb (very short summary mode)


Now, the problem is, this new method in Ubuntu doesn't work with wireshark/tshark which appears to be using some depricated linux locations that the ubuntu release doesn't use, so we have to fool the system. These next command can probably break something if left in place so it's better to just execute them in a session when you need them and NOT make this permanent in your fstab or anything.


(as root or use sudo)

Code: Select all

   mount --bind /dev/bus /proc/bus
   ln -s /sys/kernel/debug/usb/devices /proc/bus/usb/devices


Now, if you installed tshark, with root permissions do this:

Code: Select all

   tshark -D


And you should see a list of everything that is monitorable. usbmon1-usbmon# is basically the busses you can see. If you start wireshark as root (with 'wireshark') and scan the interfaces, you will see these show up. You can use lsusb to figure out what port you are attached to.

I have not fully figured out how to use wireshark, but this is probably a lot of detail to help.

Also, if you cat the files in /sys/kernel/debug/usb/usbmon (ie cat 0u) then you can watch as you plug things in and out the raw data converted to text. If you look online you can find out what each of the letters after the number mean. Also, '0' indicates a catch all of ALL traffic on ALL buses.

So far, I can watch as my STM32F4 device enumerates all the descriptor information. I do not see my other traffic coming through, so at least I have something to start looking at. Hope anyone else looking at this, finds this helpful!

Rick
Rick Burnett
Posts: 150
Joined: Tue Jan 08, 2013 2:20 pm

Re: USB MIDI, am I headed down the right path?

Post by Rick Burnett »

Stay tuned, me and two other people got the MIDI code working over USB so we want to share the ChibiOS code for doing this. Cleaning up the code to get rid of the unnecessary stuff for the example.
Post Reply