I don’t need to tell you what USB is, because the U stands for Universal. You know what it is because it’s everywhere. Has been, for over two decades. There are now so many variants and applications for USB that I couldn’t list them all before hitting retirement age… even though I don’t plan on retiring ever.

So it’s no surprise that many microcontrollers, including STM32, feature at least one USB controller. Some even have several. Now the obvious question is : since I have this nice universal interface on my chip, how do I use it ?

The short answer ? With great pains.

My personal view of USB is that it’s a poorly-designed interface that tries to do everything and therefore isn’t particularly good at anything except keeping non-technical people from getting a headache when they want to connect something to some other thing. And maybe that’s the entire point of USB. But just like a swan seems graceful on the surface while it paddles furiously underwater, the apparent simplicity of USB comes at the price of complexity under the hood.

Unfortunately for you, dear programmer, programming USB is as “under the hood” as it gets. Fortunately for you, I’m here to lend a hand.

This section is dedicated to the USB libraries provided by ST as part of its HAL (Hardware Abstraction Layer) libraries. Those can be added to a project very easily using the STM32CubeIDE development tool. Much like USB, those libraries aim to be as universal as possible, meaning : application-agnostic. As a result, they are not easy to use… and that’s why I found it necessary to write about it.