Skip to content

Composite USB device example #242

@PocketPi

Description

@PocketPi

Hey

I am trying to make a composite usb device consisting of cdcacm and msc profiles.

I am using a STM32F411CEU

I have tried to merge the cdcacm and msc example but when i connect my device to the pc i get the following error:

Mar 07 13:47:02 thickpad kernel: usb 3-6.1.4: new full-speed USB device number 36 using xhci_hcd
Mar 07 13:47:02 thickpad kernel: usb 3-6.1.4: New USB device found, idVendor=aabb, idProduct=ccdd, bcdDevice= 2.00
Mar 07 13:47:02 thickpad kernel: usb 3-6.1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Mar 07 13:47:02 thickpad kernel: usb 3-6.1.4: Product: wqer
Mar 07 13:47:02 thickpad kernel: usb 3-6.1.4: Manufacturer: asdf
Mar 07 13:47:02 thickpad kernel: usb 3-6.1.4: SerialNumber: 62908886
Mar 07 13:47:02 thickpad kernel: usb-storage 3-6.1.4:1.1: USB Mass Storage device detected
Mar 07 13:47:02 thickpad kernel: scsi host0: usb-storage 3-6.1.4:1.1
Mar 07 13:47:34 thickpad kernel: usb 3-6.1.4: reset full-speed USB device number 36 using xhci_hcd
Mar 07 13:47:49 thickpad kernel: usb 3-6.1.4: device descriptor read/64, error -110
Mar 07 13:48:05 thickpad kernel: usb 3-6.1.4: device descriptor read/64, error -110
Mar 07 13:48:05 thickpad kernel: usb 3-6.1.4: reset full-speed USB device number 36 using xhci_hcd

This is most of the code i am running:

#include "usb.h"
#include "buffered_printf.h"
#include "ramdisk.h"
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/usb/cdc.h>
// clang-format off
#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/msc.h>
// clang-format on
#include <stddef.h>

#define DEVICE_ID_ADDR 0x1FFF7A10

static char serialno[9] = {0};

static usbd_device *usb_device;

static const struct usb_device_descriptor dev_descr = {
    .bLength = USB_DT_DEVICE_SIZE,
    .bDescriptorType = USB_DT_DEVICE,
    .bcdUSB = 0x0200,
    .bDeviceClass = 0,
    .bDeviceSubClass = 0,
    .bDeviceProtocol = 0,
    .bMaxPacketSize0 = 64,
    .idVendor = 0xaabb,
    .idProduct = 0xccdd,
    .bcdDevice = 0x0200,
    .iManufacturer = 1,
    .iProduct = 2,
    .iSerialNumber = 3,
    .bNumConfigurations = 1,
};

static const struct usb_endpoint_descriptor data_endp[] = {{
                                                               .bLength = USB_DT_ENDPOINT_SIZE,
                                                               .bDescriptorType = USB_DT_ENDPOINT,
                                                               .bEndpointAddress = 0x01,
                                                               .bmAttributes = USB_ENDPOINT_ATTR_BULK,
                                                               .wMaxPacketSize = 64,
                                                               .bInterval = 1,
                                                           },
                                                           {
                                                               .bLength = USB_DT_ENDPOINT_SIZE,
                                                               .bDescriptorType = USB_DT_ENDPOINT,
                                                               .bEndpointAddress = 0x81,
                                                               .bmAttributes = USB_ENDPOINT_ATTR_BULK,
                                                               .wMaxPacketSize = 64,
                                                               .bInterval = 1,
                                                           }};

static const struct usb_endpoint_descriptor msc_endp[] = {{
                                                              .bLength = USB_DT_ENDPOINT_SIZE,
                                                              .bDescriptorType = USB_DT_ENDPOINT,
                                                              .bEndpointAddress = 0x03,
                                                              .bmAttributes = USB_ENDPOINT_ATTR_BULK,
                                                              .wMaxPacketSize = 64,
                                                              .bInterval = 1,
                                                          },
                                                          {
                                                              .bLength = USB_DT_ENDPOINT_SIZE,
                                                              .bDescriptorType = USB_DT_ENDPOINT,
                                                              .bEndpointAddress = 0x83,
                                                              .bmAttributes = USB_ENDPOINT_ATTR_BULK,
                                                              .wMaxPacketSize = 64,
                                                              .bInterval = 1,
                                                          }};

static const struct usb_interface_descriptor data_iface[] = {{
    .bLength = USB_DT_INTERFACE_SIZE,
    .bDescriptorType = USB_DT_INTERFACE,
    .bInterfaceNumber = 0,
    .bAlternateSetting = 0,
    .bNumEndpoints = 2,
    .bInterfaceClass = USB_CLASS_DATA,
    .bInterfaceSubClass = 0,
    .bInterfaceProtocol = 0,
    .iInterface = 0,

    .endpoint = data_endp,
}};

static const struct usb_interface_descriptor msc_iface[] = {{
    .bLength = USB_DT_INTERFACE_SIZE,
    .bDescriptorType = USB_DT_INTERFACE,
    .bInterfaceNumber = 1,
    .bAlternateSetting = 0,
    .bNumEndpoints = 2,
    .bInterfaceClass = USB_CLASS_MSC,
    .bInterfaceSubClass = USB_MSC_SUBCLASS_SCSI,
    .bInterfaceProtocol = USB_MSC_PROTOCOL_BBB,
    .iInterface = 0,

    .endpoint = msc_endp,
}};

static const struct usb_interface ifaces[] = {{
                                                  .num_altsetting = 1,
                                                  .altsetting = data_iface,
                                              },
                                              {
                                                  .num_altsetting = 1,
                                                  .altsetting = msc_iface,
                                              }};

static const struct usb_config_descriptor config_descr = {
    .bLength = USB_DT_CONFIGURATION_SIZE,
    .bDescriptorType = USB_DT_CONFIGURATION,
    .wTotalLength = 0,
    .bNumInterfaces = 2,
    .bConfigurationValue = 1,
    .iConfiguration = 0,
    .bmAttributes = 0x80,
    .bMaxPower = 0x32,

    .interface = ifaces,
};

static const char *usb_strings[] = {
    "asdf",
    "wqer",
    serialno,
};

/* Buffer to be used for control requests. */
uint8_t usbd_control_buffer[128];

static void cdcacm_sof_callback(void) {
    char buf[64];
    uint16_t i = 0;
    while (!usb_fifo_is_empty() && i < 64) {
        usb_fifo_get(&buf[i++]);
    }

    if (i && usb_device) {
        while (usbd_ep_write_packet(usb_device, 0x82, buf, i) == 0) {
        };
    }
}

static void cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep) {
    (void)ep;

    char buf[64];
    uint16_t len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64);
}

static void cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue) {
    (void)wValue;

    usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb);
    usbd_ep_setup(usbd_dev, 0x81, USB_ENDPOINT_ATTR_BULK, 64, NULL);

    usbd_register_sof_callback(usbd_dev, cdcacm_sof_callback);
}

static void serialno_read(char *buf) {
    volatile uint32_t *DEVICE_ID = (volatile uint32_t *)DEVICE_ID_ADDR;
    const uint32_t uid = *DEVICE_ID + *(DEVICE_ID + 1) + *(DEVICE_ID + 2);

    /* Fetch serial number from chip's unique ID. */
    for (int i = 0; i < 8; i++)
        buf[7 - i] = ((uid >> (4 * i)) & 0xF) + '0';

    for (int i = 0; i < 8; i++)
        if (buf[i] > '9')
            buf[i] += 'A' - '9' - 1;
    buf[8] = 0;
}

void usb_setup(void) {
    serialno_read(serialno);

    usb_device = usbd_init(
        &otgfs_usb_driver, &dev_descr, &config_descr, usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer));

    usbd_register_set_config_callback(usb_device, cdcacm_set_config);

    ramdisk_init();
    usb_msc_init(
        usb_device, 0x83, 64, 0x03, 64, "VendorID", "ProductID", "0.00", ramdisk_blocks(), ramdisk_read, ramdisk_write);

    /* NVIC setup. */
    nvic_enable_irq(NVIC_OTG_FS_IRQ);
    nvic_set_priority(NVIC_OTG_FS_IRQ, 1);
}

void otg_fs_isr(void) {
    if (usb_device) {
        usbd_poll(usb_device);
    }
}

Can you guys help me find out how to progress either with concrete changes to the code or how to debug the problem.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions