Showing results for 
Search instead for 
Did you mean: 

Help deciphering the STM32F072 USB CDC example

I've got the USB CDC VCOM standalone example compiled and running from

The documentation has some noteable gaps, some of which would be obvious if the CubeMX project file were available.

The example is a "USB to UART bridge" application, which is not really how most use would use the STM32F072 as a USB CDC end point. Certainly I want to parse the incoming characters to make my system do something. The example just plumbs bytes to a UART, and the way the code is structured there's no visibility of execution flow. What I've discovered is:

1. The 'UART' plumbed to the USB VCP is USART2, based on the fact that it's the only one enabled.

2. USART2 RXD and TXD aren't routed to any pins, PD6 and PD5 don't count as they don't exist on 64 pin package.


Most examples aren't generated from CubeMX, hence the lack of an IOC file.

Characters are received in CDC_Itf_Receive one packet at a time. In your implementation, replace the contents of that function with what you want to do with the data, such as put it into a buffer which is then read in the main loop, or parse it there, or whatever.

If you feel a post has answered your question, please click "Accept as Solution".

This code seems insane to me. The call stack shows the USART being configured from inside an ISR, which is no way to create a responsive and reliable system.

Anyway, I figured I need to move to USART1 on GPIO PA9-10 and tried it like that. No joy, no activity when I type on the terminal.

What event can I breakpoint on when the micro receives a USB packet? Maybe then I can step through and figure out how it's supposed to work.

Just some comments how USB CDC (often also called USB VCP) works:

  • there is not a real UART device/peripheral involved: no need to initialize a UART2 (there is no UART on MCU side)
  • after USB stack is initialized and the "USB enumeration works" properly - you should see now a new UART device on Windows Device Manager (something with VCP, STM, or also a UART COM which is not there if MCU is disconnect/hold in reset)
  • This is you UART COM port: all the UART traffic is now received by the MCU in the USB stack: you have to find where the USB UART characters come in and how to send via USB UART.
    All inside the USB functions, nothing related to a "real" UART (and no need to do anything for a "real" UART).
  • And bear in mind: a USB VCP (CDC) packet coming in, or sending out (to host) can have up to 64 characters. When you "copy and paste" a string in UART terminal (e.g. TeraTerm) - you could get up to 64 characters as "one shot"
  • The baudrate, when you open Terminal (TeraTerm), usually does not matter: any baudrate is fine and it anyway set by the USB speed (e.g. FS or HS).
    But there might be code to act on UART configuration, e.g. to set the bits per bytes (actually also getting a baudrate request), parity etc. Myself: I do not use and let it run with the defaults.

My suggestion:

Check, if you get the USB enumeration working (a "USB ding" sound on Windows), if you see a new COM port in Device Manager. If so: pretty great: now the USB UART is actually established.

Now you can check on which function you will be notified (in MCU FW) that something was received, actually in which buffer the received characters are stored (it should be done "automatically" to store the received bytes, by the USB stack).

Just find the hooks (functions and buffers) where the USB UART traffic is going.

Thanks. USB enumeration seems to be working because Windows shows a COM port in the device manager.

The example configures the STM32F072 as a 'USB to UART' bridge, so the readme.txt says that traffic is routed to and from a USART peripheral, so yes, a real UART is involved. Although the VCP doesn't care about bit rate etc, these settings are processed and applied to the USART peripheral.

My question comes back to your last point, finding the hooks and the callback functions that get fired by traffic. The buffers are easy, they are documented in the readme.txt. A reference search by name for the buffer shows where the buffers are passed into initialisation code, so after that the code uses some private pointer.

Breakpointing on the ISR, all I see is SOF activity. The search for the hooks goes on.


> What event can I breakpoint on when the micro receives a USB packet?

Again, packets come in via the CDC_Itf_Receive function. If you want to route them somewhere else, change that function.

If you feel a post has answered your question, please click "Accept as Solution".
Pavel A.
Evangelist III

What event can I breakpoint on when the micro receives a USB packet? Maybe then I can step through

@Oliver Sedlacek I'm not familiar with this specific example, just a note: breakpoints and stepping through USB device code won't work because the USB link is time sensitive. The host expect real time response, a delay may cause device reset and re-enumeration. You can set a breakpoint to find whether execution runs to certain point but it will be hit only once. 

For a supported, production quality USB device library look somewhere else.


Yes, I know that USB may crash if you breakpoint. I've got to start somewhere though. :(

Put a breakpoint on CDC_Itf_Receive, never gets hit.

CDC_Itf_Control gets hit if I change bit rate.

After looking at properties in devcie manager I'm wondering what this means.



I've run the installer downloaded from ST, so that's not it. Windows can't find a better driver.