Getting USB to work on any microcontroller from just reading documentation and writing your own code is much more likely to drive you stark raving mad then get you to something that works. And this is regardless to what uC you use. USB is a quite complicated protocol and there are many details which all have to be dust right before anything works. From the initial startup, to "registering" your uC on the USB bus, and getting descriptors and endpoints for higher level protocols.
I have dabbed a little toe in this once. I compiled and flashed the serial demo from Satoshinm. It is a bridge that uses an STM32F103 to create 3 UART's, and the project is on github. I flashed it, saw my Linux box recognised three serial ports, and I started a few terminal emulators and echoed data back from one port to another by adding some jumpers on the breadboard with the good old Blue Pill (From back when they were still real). But that was in 2018, and after that... I got distracted.