dmitrystu / libusb_stm32

Lightweight USB device Stack for STM32 microcontrollers
Apache License 2.0
721 stars 165 forks source link

Add MIDI device class #11

Open kisielk opened 6 years ago

kisielk commented 6 years ago

I'm mostly doing USB-MIDI on STM32 devices and would like to switch to this library. Unless someone else is already working on it or has a functional implementation I will contribute mine when I have it ready.

Spec is here: http://www.usb.org/developers/docs/devclass_docs/midi10.pdf

xcvista commented 6 years ago

Another common class I would suggest is mass storage.

dmitrystu commented 6 years ago

The MSC class definitions are partially done.

kisielk commented 6 years ago

That should probably be tracked in a separate issue ;)

kisielk commented 6 years ago

I already have a functional MIDI implementation using ST's Device Library for the F072, F373 and F746, so I should be able to port it over to this lib when I have some time..

WojtaCZ commented 4 years ago

I know this is a old one, but has anyone made any progress on the MIDI class?

dmitrystu commented 4 years ago

No one but me. :) But it's yet not completed nor tested. See this branch.

GrantMTG commented 2 years ago

We need to add another struct to usb_midi.h (there might be other things I discover as I go through this as well):

// Class-Specific AC (Audio Control) Interface Descriptor
struct usb_midi_ac_interface_desc {
   uint8_t  bLength;              /**<\brief Size of this descriptor in bytes. */
   uint8_t  bDescriptorType;      /**<\brief CS_INTERFACE descriptor type.     */
   uint8_t  bDescriptorSubType;   /**<\brief MIDI_HEADER descriptor subtype.  */
   uint16_t bcdADC;               /**<\brief AC SubClass Specification Release Number. */
   uint16_t wTotalLength;         /**<\brief Total size of class specific descriptors. */
   uint8_t  bInCollection;        /**<\brief Number of streaming interfaces.   */
   uint8_t  bInterfaceNumber;     /**<\brief Index of the current interface.   */
} __attribute__ ((packed));
GrantMTG commented 2 years ago

The only other things that I think are missing from usb_midi.h are,

(a) adding the definition for USB_MIDI_SUBCLASS_STREAM

#define USB_CLASS_MIDI              0x01U   /**<\brief MIDI Device class */
#define USB_MIDI_SUBCLASS_CONTROL   0x01U   /**<\brief Data Interface class */
#define USB_MIDI_SUBCLASS_STREAM    0x03U   /**<\brief MIDI Streaming */

(b) Preferred spelling of USB_MIDI_JACK_EXTERNAL

//#define USB_MIDI_JACK_EXTERNL       0x02U   /**<\brief Declares external Jack */ 
#define USB_MIDI_JACK_EXTERNAL      0x02U   /**<\brief Declares external Jack */ 

(c) Correction of baAssocJackID in usb_midi_class_ep_descriptor

struct usb_midi_class_ep_descriptor {
    uint8_t     bLength;                /**<\brief Size of the descriptor, in bytes.*/
    uint8_t     bDescriptorType;        /**<\brief CS_ENDPOINT descriptor.*/
    uint8_t     bDescriptorSubType;     /**<\brief USB_DTYPE_MIDI_EP_GENERAL subtype.*/
    uint8_t     bNumEmbMIDIJack;        /**<\brief Number of Embedded MIDI Jacks.*/
//    uint8_t     baAssocJackID[];        /**<\brief Embedded jacks ID's */ 
    uint8_t     baAssocJackID;          /**<\brief Embedded jacks ID's */ 
} __attribute__((packed));

(d) and finally, if it is not elsewhere (I didn't see it), the 9-byte version of the bulk endpoints. This one I am not 100% sure of yet since I have not run the USB Compliance Suite and both endpoint versions for USB MIDI.

struct usb_bulk_endpoint_desc {
    uint8_t  bLength;             /**<\brief Size of the descriptor, in bytes. */
    uint8_t  bDescriptorType;     /**<\brief Endpoint descriptor.*/
    uint8_t  bEndpointAddress;    /**<\brief Logical address of the endpoint within the device for
                                   * the current configuration, including direction mask. */
    uint8_t  bmAttributes;        /**<\brief Endpoint attributes, \ref USB_ENDPOINT_DEF.  */
    uint16_t wMaxPacketSize;      /**<\brief Size of the endpoint bank, in bytes. This indicates the
                                   * maximum packet size that the endpoint can receive at a time. */
    uint8_t  bInterval;           /**<\brief Ignored for bulk.   */
    uint8_t  bRefresh;            /**<\brief               */
    uint8_t  bSynchAddress;       /**<\brief               */
} __attribute__((packed));

See: Example: https://github.com/kshoji/USB-MIDI-Link/blob/master/firmware/main.c Discussion elsewhere: https://github.com/libopencm3/libopencm3/issues/1130