February 27, 2025

Black Pill boards - USB experiments with Hydra, circa 2021

My notes tell me that I began by writing usb411.c and usb_console.c. These are not used in the current build and can be ignored with respect the code I am currently running.

Using these (usb411 and usb_console) I was able to get an interrupt from USB, but I concluded that the device mode documentation in the TRM was confusing and that I would be well served to look at some operational source code.

I decided (for no reason that I clearly remember) to work with code from the Arduino_STM32 project, namely:

Arduino_STM32/STM32F4/cores/maple/libmaple/usbF4.
This has several components: I did a lot of work reorganizing this. I'll mention again how valuable ctags is in conjunction with some configuring of the vim editor to work with ctags. This is the only way to cope with a large unfamiliar code base. I've never understood why some people feel compelled to sequester all of their header files (*.h) in a separate diretory. It makes sense for system library header files, but not for something like a device driver.

I got to the point where I could see the host attempting enumeration and sending setup packets (over and over after a timeout since we are not responding).

How does this all start up

In locore_411,s there is a call to stm_init(), which is in init.c. This calls several things of interest before it calls startup() in main.c. In particular:
rcc_init()
usb_init()
The call to rcc_init() enables the USB clocks. usb_init() is in usbF4/usb.c and is critical.

It enables USB interrupts, calls a gpio routine to configure the pins that are used for USB, and then makes a call:

USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_CDC_cb, &USR_cb);
This initializes the driver layer in the Arduino_STM32 code. This routine is in usbF4/library/usbd_core.c
Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org