cancel
Showing results for 
Search instead for 
Did you mean: 

USB CDC not being initialized

ym21
Associate III
I have an STM32L4R on a custom PCB. I am able to flash firmware using CubeProgrammer/CubeIDE to it via an ST-LINK SWD connection as well as a DFU Bootloader via a USB D connector. I have a makeshift connection between the USB D connector to a USB C cable to my laptop in order to flash it using USB_DM, USB_DP, and VBUS wires between the D and C connectors. When the PCB is powered, the ST-LINK is connected to my target MCU and my laptop, and my PCB is connected to my device, my laptop is able to recognize the ST-LINK as a VCP and my target MCU as an "STM32 BOOTLOADER", which allows it to be flashed. The ST-LINK connection is critical in the target MCU being recognized by my laptop. I have written CDC initialization code in order to enumerate my target MCU as a VCP and transmit data to my laptop, however, I am having trouble with that...
My code works on the NUCLEO that I have for the STM32L4R. I am also able to step through initialization all the way to the CDC_Transmit() function inside of my while() loop which just sends simple printf() statements to a terminal. Although my target MCU has been flashed with CDC code and I am able to step through it using the Debug session, my laptop is still not able to recognize it.
I added a dynamic printf() statement right at the line where I want to print data to a terminal. This breakpoint tells me the device state of the USB is 1

/* Device Status */

#define USBD_STATE_DEFAULT 0x01U

#define USBD_STATE_ADDRESSED 0x02U

#define USBD_STATE_CONFIGURED 0x03U

#define USBD_STATE_SUSPENDED 0x04U

Which, judging from the code files, means that the USBD state is at its default. 

I am not sure how to approach this problem, I am not sure if it is a hardware, software, or connection issue. Any advice will help. Thank you.

 
7 REPLIES 7
Pavel A.
Super User

Debugging USB device is tricky because you can't set breakpoints and step. The USB host requires real-time response. If the target does not respond, host can try to reset it. Slow debug prints can cause the communication timeout as well.

 

Are you suggesting that I must debug the USB code in real time? How would I reset it using the host? Can you provide a bit more clarification?

gtrking
Associate II

It sounds like your STM32 isn’t enumerating properly as a USB CDC device because the host only sees it in the default state (USBD_STATE_DEFAULT)—meaning enumeration never completes.
This is often caused by an unstable or mismatched USB interface connection between your MCU and the laptop.

Since you’re using a makeshift D-to-C cable, I’d recommend switching to a proper USB-to-TTL bridge, such as a CP2102/CP2104 USB to TTL/UART Module. It provides stable USB data lines (D+ and D−), proper 5V/3.3V logic selection, and ESD protection—preventing voltage mismatches that can cause incomplete enumeration.

Once connected, confirm the D+ and D− routing matches your STM32 pins, verify the pull-up resistor on D+, and ensure USBD_Init() is called before CDC_Transmit().
With a reliable bridge module, your CDC VCP should appear correctly in the device manager without needing the ST-LINK as a pass-through.

gbm
Principal

First, check if your code works on a good, working board (like Nucleo with its onboard target USB connector). Then verify your USB connection - I am not sure what you mean by "makeshift cable" but USB rarely works with jumper wires, so you need to have a properly routed USB connector on the PCB. If it is USB-C, then for powering the board via USB you need two 5k1 resistors between CCx lines and GND.

Check the clock settings for USB. The easiest solution is to use HSI48 WITH CRS SYNC to USB SOF. USB will not work with other HSI or MSI.

Also, calling Transmit from the main loop will sooner or later hang the USB stack. Try to do simple USB echo first, calling Transmit from receive callback.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice

I'm only saying that the host expects responses from device with tight timing. Debug the USB code so that it does not cause timeouts.

I noticed these TTL to UART adapters have headers for TX and RX, not DM and DP. Does this pose an issue or can my USB DM and DP pins be connected to the TX and RX ports in the TTL to UART adapters? 

Huh? Your initial question was about USB device in STM32. This has nothing to do with USB-UART module which could be used to connect your MCU UART to a PC.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice