Showing results for 
Search instead for 
Did you mean: 

(SOLVED) USB Device CDC middleware : unable to even understand how to use it.

Associate III

(I'm still working on this, I'll edit this as I progress, keep reading)

Well, the title of this question should be clear enough. I wanted to add virtual COM port functionality to a project. Using STM32CubeIDE, I enabled the USB device on an SMT32F103 and then I enabled the USB CDC middleware. After generating the project, I get 20 new source files, none of which seem to contain anything even remotely comparable to the USART HAL functions, either in name or in purpose.

The code does compile. But when I connect the USB to my PC my board isn't even enumerated. The generated code calls an MX_USB_DEVICE_Init function which executes without error but then again, so would a bunch of NOP's.

The offical documentation at seems like it's talking about an entirely different middleware. It mentions files that appear nowhere in the code I generated. The "how to use" section might as well be fiction.

Trying to be as thorough as possible, I look at the example projects that shipped with the HAL installed on my PC (version 1.8.0) and find a couple of CDC example which do contain the files mentioned in the documentation (usbd_cdc_interface.c and .h)

So I read those files, trying to find what they could be doing and how it matches what the code generator barfed. I'm hopeful at first : it looks like this code uses the USART HAL functions over the VCP, using a mysterious instance USARTx... except I look for its definition and it turns out to be USART2. I'm starting to get angry : how is a function named CDC_Itf_Init is supposed to work if it references USART2 ?

At this point I've spent the better part of 4 hours trying stuff, reading code, Googling left and right, and I know the pattern : once again, as with Ethernet, Cube is trying to sell me something that doesn't exist and I'm wasting my time.

So I'm going to ask : can anyone show me how to use the so-called Communication Device Class middleware that Cube claims to offer ? Namely, how do I open that serial port, setup its baud rate, and send and receive data ?

I swear, any time I try to use Cube for anything more complex than blinking an LED, this kind of crap happens. I may have to start billing ST for my time.

(Cue Spongebob meme) 5 hours later...

I've started reverse-engineering the stuff Cube vomited into my project and I'm getting somewhere...

First, regarding the enumeration issue : that was a bad cable on my part. Apparently I grabbed an old "charge only" cable from work, you know, those that don't let you steal work data using your phone. With an actual USB cable, the STM32 enumerated and a nice new COM port appeared on my system.

Next step was to figure out data transfers. I'll spare you the details but I ended up in a file named usbd_cdc_if.c and that file appeared to contain nearly everything I needed :

  • Tx and Rx buffer declarations
  • Transmit function
  • Receive function, that's apparently passed as a handler to... something
  • Assorted init functions

My stm32f1xx_it.c file also got a new interrupt handler : USB_LP_CAN1_RX0_IRQHandler, which my intuition tells me is in charge (among other things) of handling incoming data over the virtual COM port.

At that point it wasn't clear where I should look next; so I decided to try actually using what I found. Good news :

  • I can use the CDC_Transmit_FS function to send data over the VCP. It's non-blocking, by the way.
  • I can read incoming bytes directly from the receive buffer UserRxBufferFS though that's clearly not how it should be done.

I still need to figure out non-blocking reception of data. There's a CDC_Receive_FS function but... well here's what its comment says. If you understand what's supposed to happen don't hesitate to share :

 *     Data received over USB OUT endpoint are sent over CDC interface

 *     through this function.


 *     @note

 *     This function will block any OUT packet reception on USB endpoint

 *     untill exiting this function. If you exit this function before transfer

 *     is complete on CDC interface (ie. using DMA controller) it will result

 *     in receiving more data while previous ones are still not sent.

They say that "the code is its own documentation" is a stupid saying, but hey in this case it's better than any form of documentation I've come across. I'll keep at it, meanwhile don't hesitate to contribute. Thanks.

BREAKING NEWS : I've done it !

Sorry, I forgot to update this post afterwards but I eventually managed to understand how to use the Cube library. On the plus side, I've documented absolutely everything on my website, and you can find it at :

My site targets newbies, so there may be a lot of explanations you don't need, but I've tried to make it funny (depending on your sense of humor). There are four pages in that section, you can access them with the navigation menu on the right.

Constructive criticism is welcome !

On a personal note : the Cube library, while it works, is definitely not beginner-friendly. I'm far from a beginner and it was a painstaking process to use it. Perhaps I'm wrong to compare Cube to Arduino but if you need to develop something really quick, especially a proof of concept, Cube isn't for you.

Maybe next I'll tackle Ethernet and LWIP.

Pavel A.
Evangelist III

> I may have to start billing ST for my time

Then better hire a contractor to help with the CDC functionality. Unfortunately USB is hard, not anywhere close to U(S)ART.

All one can possibly get from ST is money return for their software.

-- pa

I am a contractor.

Ok, then hire a subcontractor 😉

UM1734: STM32Cube USB device library ?

I don't Cube.



I've read it, but it only helped me after I had gone through the code.

Associate II

Hi friends,

Did anyone of you manage to get STM32F103C8 USB VCP working through Cube eventually?

If you did, I really appreciate it if you share a minimum Cube project that only demonstrates simple communication over VCP in Cube.

I keep receiving "Device malfunctioned" message from Windows on connecting my board.

Thank you very much,



same with the STM32H745 on a nucleo-board. I'm also Looking for a minimum project that works with VCP. I got an older OlimexBoard with the STM32F103, it wasn't even showing the error-message when plugged in.

Maybe it's the same issue of the STM32CubeIDE?

Best Regards, Seppel


When you connect the USB cable, do you hear the windows USB connection sound?

If yes, and then you receive an error, then I have the same situation.

If you do not even hear the USB connection sound, then it means you forgot to activate the bus pull-up (it is usually an output digital pin that you should SET in order to activate the connection).

All the best,