Configuring user project with STM32CubeMX code generator to use MIDI Device Class Middleware

In STM32CubeMX / STM32CubeIDE:
  • At USB → enable Device FS
  • At USB_DEVICE → choose Human Interface Device Class (HID)
  • Generate code

To use MIDI Device Class middleware, project requires few modifications in generated code:

  • Copy usbd_midi.c and usbd_midi.h to Middlewares/ST/STM32_USB_Device_Library/Class/MIDI/ Src and Inc folders respectively.
  • In your IDE add those folders to C/C++ compiler include path, and files to corresponding group.
  • Modify USB_DEVICE/App/usb_device.c:
#include "usbd_hid.h"  // replace this line
#include "usbd_midi.h" // with this line
if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_HID) != USBD_OK)  // replace this line
if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_MIDI) != USBD_OK) // with this line 
  • Modify USB_DEVICE/Target/usbd_conf.c:
#include "usbd_hid.h"  // replace this line
#include "usbd_midi.h" // with this line
/* USER CODE BEGIN EndPoint_Configuration_HID */ // You may replace HID with MIDI for more convenience, but code generator will not keep it on next code generate
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x01 , PCD_SNG_BUF, 0xC0); // add this line
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x81 , PCD_SNG_BUF, 0x100); // leave this line as is
/* USER CODE END EndPoint_Configuration_HID */
static uint32_t mem[(sizeof(USBD_HID_HandleTypeDef)/4)+1]; // replace this line
static uint32_t mem[(sizeof(USBD_MIDI_HandleTypeDef)/4)+1]; // with this line
  • Modify Core/Inc/main.h:
#define MIDI_IN_PORTS_NUM   0x01 // Specify input ports number of your device
#define MIDI_OUT_PORTS_NUM  0x03 // Specify output ports number of your device

Send midi messages packet to host device:

  • Ensure that MIDI driver status is IDLE by:
    USBD_MIDI_GetState(&hUsbDeviceFS) == MIDI_IDLE
  • Send midi messages packet with:
    USBD_MIDI_SendReport(&hUsbDeviceFS, messagesBuffer, MIDI_EPIN_SIZE); 

Receive midi messages packet from host device:

  • Implement this weak function with something like this:
    void USBD_MIDI_DataInHandler(uint8_t *usb_rx_buffer, uint8_t usb_rx_buffer_length)
      while (usb_rx_buffer_length && *usb_rx_buffer != 0x00)
        wire = usb_rx_buffer[0] >> 4;
        message = usb_rx_buffer[1] >> 4;
        channel = usb_rx_buffer[1] & 0x0F;
        messageByte1 = usb_rx_buffer[2];
        messageByte2 = usb_rx_buffer[3];
        usb_rx_buffer += 4;
        usb_rx_buffer_length -= 4;