March 1, 2025

Black Pill boards - F411 USB -- initialization

My routine usb_init() makes this call:
USB_OTG_CORE_HANDLE  USB_OTG_dev;

USBD_Init ( &USB_OTG_dev,
            USB_OTG_FS_CORE_ID,
            &USR_desc,
            &USBD_CDC_cb,
            &USR_cb);
The first argument is an uninitialized device structure that will get initialized, and that we will use for other calls.

The second argument, USB_OTG_FS_CORE_ID, is a enum with one of two values -- ether FS as it is here, or HS if we want high speed. Asking for high speed will be useless for our hardware, but other chips can work either way.

USR_desc comes from the header file vcp/usbd_desc.h and holds all the stuff that will be returned to the host during enumeration. Note that it is specific to the VCP identity that we will be setting up.

USBD_CDC_cb holds a bunch of callbacks (function pointers) that are set up in library/usbd_cdc_core.c. The reference to the struct comes from the include file library/usbd_cdc_core.h CDC stands for "Communication Device Class" and is a standard class within USB. There are a bunch of other define USB classes like HID for "human interface device", mass storage device, and so on.

USR_cb holds a bunch of callbacks that are set up in vcp/usbd_usr.c. The reference to the struct comes from the include file library/usbd_usr.h

The routine USBD_Init() is in library/usbd_core.c and is quite short. I begins intializing the dev structure and makes calls to:

  /* set USB OTG core params */
  DCD_Init(pdev , coreID);

  /* Upon Init call usr callback */
  pdev->dev.usr_cb->Init();

What about all those callbacks?

The thing to do would be to look at all of those callback structures, find out exactly what routines are set up in those for our use case (the VCP) and examine what each of them does and in what situations it is called. Notice that this code is partitioned into 3 major sections: This structure allows either the driver or the vcp component to be swapped for another. For example if we want to support the F103 chip with its different USB, we ought to be able to just swap the driver component -- and we might someday. In fact, I am willing to bet that it is already there to be taken in the Arduino-STM32 source tree

For the F4, I found the USB code at STM32F4/cores/maple/libmaple/usbF4/STM32_USB_Device_Library
For the F1, I see code at STM32F1/cores/maple/libmaple/usb (and it is much simpler than the F4)


Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org