Multiple USB CDC?

Hi there,

Is there a way to have more than one VCP with libDaisy’s USB CDC implementation? I feel this would be a very neat feature.

Thank you,
Adrian

I thought there was a github issue discussing this, but I can’t find it.
I remember someone sharing some code of this being supported in a different stm32-based opensource project, and it would certainly be a cool feature.

Maybe it was an older forum post, or something that has vanished from the histories of slack… :confused:

All that said, there’s no way of doing it with libDaisy as-is, but it would be a welcome feature addition for sure!

Thank you for your reply, @shensley!

I ended up ditching libDaisy’s USB handling and introducing tinyUSB in the mix. I managed to get audio class and 2xCDC serials. Perhaps it would not be a bad idea to officially support tinyUSB.

4 Likes

woah, awesome that you were able to get it up and running quickly!

tinyUSB has been on my list of stuff to check out for well over a year, and I just haven’t found the time to try it out.
Knowing it can (quickly) do composite device handling, and has such an extensive list of supported device classes is really promising.

I think it would make a great fit with libDaisy, especially still being an MIT licensed project.

Would you be willing to share any steps you took, or some example code to try out on Daisy?

1 Like

Hi @benishor, I was taking a look at tinyUSB and noticed the daisyseed bsp checkins had your name on them - cool!

I’m trying to build the dfu examples and nothing’s working as expected, I can’t get the led to blink, even after commenting out the majority of the usb specific init/task code. I was poking around and noticed the board_stm32h7_clock_init() looks quite different libDaisy’s System::ConfigureClocks(). Any particular reason for that?

Have you got any working examples you’d be willing to share?

Cheers

Hi @shensley , @jaradical

Yes, I contributed the BSP for daisy seed and it works on my machine ™. I am using daisy seed 1.1 though I don’t think that ought to be a problem. Can you specify what hardware version are you using and what problems you encountered?

@shensley I will share an example laterish. The problem is I strayed from the regular dev path and I employed CMake and CLion for dev so I need to extract things.

Following steps must be followed thougfh:

  • add tinyUSB to the project
  • add your device configuration in tusb_config.h
  • initialize USB hardware (hw.usb_handle.Init(daisy::UsbHandle::FS_INTERNAL); suffices)
  • initialize tinyUSB device (tud_init(BOARD_TUD_RHPORT);)
  • call tud_task(); as often as possible

Also make sure to modify OTG_FS_IRQHandler() from libDaisy/src/hid/usb.cpp to serve tinyUSB as follows:

void OTG_FS_IRQHandler(void) {
    tud_int_handler(BOARD_TUD_RHPORT);
}

This should get you going provided you have the proper configuration in-place. I am using a composite device with audio in/out stream and 2 x CDC serial devices.

All the best,
benishor

4 Likes

Nice work and thanks for the details @benishor.

I’ve got a Rev4 seed, but I’m not sure that would make much of a difference.

My troubles were when trying to run the tinyusb dfu device example using BOARD=daisyseed and the tinyusb makefiles. I uploaded via the ST rom bootloader in DFU mode, but wasn’t seeing the LED blinking. In board.h I replaced the contents board_stm32h7_clock_init with something very similar to the libDaisy System::ConfigureClocks() and that seemed to work okay, I got the expected LED blinking and the device was presenting itself when running dfu-util -l.

I’ll keep your other tips in mind as I try and incorporate that into the daisy framework. My goals here are two-fold, one is to have a way of storing some waveforms in QSPI for some kind of wavetable synth, the other is to put blocks of code compiled for running from SRAM there, and then being able to switch them in and out on the fly.

Cheers

I’ve been trying unsuccessfully all morning to get this working.

I’ve followed these steps as closely as possible and everything is compiling successfully. I’m using one of the CDC example configuration/descriptions almost verbatim, just adding the necessary MCU config (OPT_MCU_STM32H7).

The problem is, when I attempt to initialize USB hardware on the Seed using hw.usb_handle.Init(daisy::UsbHandle::FS_INTERNAL); with the Seed attached to my computer via the internal USB port, I immediately hit hard fault with IMPRECISERR. My computer freaks out and locks up all USB for a moment, and that repeats several times.

What appears to be happening from a stack trace is the USB FS IRQ handler is called as soon as the Seed starts USB within the USBHandle (immediately after USBD_LL_Start() is called). The IRQ handler calls tud_int_handler, so on so forth down the stack… then boom.

Any ideas what I might be doing wrong? I haven’t tried the tinyusb examples directly yet, but I am a little confused by the board support code for the seed in that it never seems to interact with the STM USBD library at all (which is what libDaisy is using to set everything up when initializing the USB hardware). It seems like there’s some kind of mismatch happening but it’s a little above me to understand at this point.

Figured it out. We actually don’t want to start the default STM USB driver nor register any descriptors or device classes, but rather just initialize the USBD handle (USBD_LL_Init) Modifying libDaisy’s default USBHandle initializer to this fixes it:

static void InitFS()
{
    rx_callback = DummyRxCallback;
    if(USBD_Init(&hUsbDeviceFS, NULL, DEVICE_FS) != USBD_OK)
    {
        UsbErrorHandler();
    }
}

After that change I can see two USB Serial devices show up when I plug in the Seed.

Very cool to get it actually up and running! Now to figure out how to use the device classes :slight_smile:

2 Likes