libopencm3-examples
libopencm3-examples copied to clipboard
Composite USB device example
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.