Blackpill STM32F401CC USB with libopencm3

I’m struggling to get a Blackpill board with an STM32F401CC talking over USB CDC.
My code is a copy of this example, with one change:


is replaced with


due to the clock speed limit of the STM32F401 (and the crystal being 25MHz instead of 8).

Other than that, my code is the same as the one in the example.

Still, I can’t get the USB device to show up (using lsusb under Linux or in the Windows device manager).

What I think could be the cause:

  • some clocking issue (some peripheral clock not being the same due to the different rcc config)
  • differences in the USB peripheral (it looks like STM has two versions of a USB-FS peripheral, a USB-FS-OTG peripheral, and a USB-HS peripheral, as well as all the USB C PD stuff)
  • example got broken by changes in libopencm3 (I tried compiling with a version of libopencm3 that was committed when the example was made, but that didn’t help)

Stepping through the init process didn’t reveal anything suspicious. Any ideas how to narrow this down?

Thanks for your help

Found the solution after a few hours of searching: the board I am using does not have the VBUS pin connected. I therefore needed to set the OTG_GCCFG_NOVBUSSENS bit in the OTG_FS_GCCFG register (Reference Manual RM0368 Rev 5 p.718f).
These few lines need to be added to the program after the defines:

#define USB_OTG_FS_BASE			(PERIPH_BASE_AHB2 + 0x00000)
#define OTG_GCCFG			0x038

#define OTG_GCCFG_NOVBUSSENS	(1 << 21)

and this after the peripheral clock is enabled before the USB device is initialized:


This is likely an issue with lots of other boards as well.

Is this fix / configurability already in libopencm3 upstream?

Well, it’s not really a fix, but a more missing config option (maybe it even exists somewhere).
But I agree it should be added and there should be a remark in the examples.