I am trying to establish communication between my host machine (running Ubuntu 22.04) and the STM32 Nucleo F401RE board. I only need to transmit data from the board to the host computer (only single direction). I have successfully achieved this via USART2 with the following function:

HAL_UART_Transmit(&huart2, (uint8_t*)test_buffer, s_test_buffer, HAL_MAX_DELAY);

However, when I try to do the same with USB_OTG_FS configuration, I receive no data on my host machine. I use the following function to transmit the data:

CDC_Transmit_FS((uint8_t*)test_buffer, s_test_buffer);

When I configure USB_OTG_FS, I can see that it uses pins PA11 and PA12 as USB_OTG_FS_DM and USB_OTG_FS_DP respectively. At the same time, USART2 is configured on PA2 and PA3 as USART_TX and USART_RX respectively. Since there is an embedded ST-Link on this board, I don't need to attach anything extra for receiving and transmitting data via UART, meaning I am able to receive data through the on-board USB port.

I also have an RS232 UART adapter for receiving and transmitting serial data. I have tried attaching the RX and TX pins to pins PA11 and PA12 as illustrated in the CubeMX screenshot, but still I do not receive any data.

My question is: How can I transmit data from the nucleo board to the host machine using the CDC (VPC) configuration?

Any help shall be greatly appreciated. Please let me know if you need more information for understanding the issue.


Here is a screenshot of my CubeMX Pin Layout. CubeMX Pin Layout

Here is a screenshot of USB_OTG_FS configuration.

USB_OTG_FS Configuration

Here is a screenshot of the USB_DEVICE configuration.

Middleware Configuration

  • 1
    \$\begingroup\$ You need to connect a USB connector to PA11, PA12 and GND and then connect your PC to it. The on-board USB connector is for the ST-Link. It is separate and not related to the STM32F401s USB/CDC connection. \$\endgroup\$
    – Codo
    Commented Nov 30, 2022 at 12:34
  • 1
    \$\begingroup\$ USB doesn't have RX and TX. It has D+ and D-. And if you use USB CDC, you don't need a USB adapter. Please add more information about your hardware setup. \$\endgroup\$
    – Codo
    Commented Nov 30, 2022 at 13:33
  • 1
    \$\begingroup\$ If you use USB CDC, it will enable to USB connection on PA11/PA12 and you have to connect an additional USB connector. If you don't want that, USB CDC is not the solution. You might need to take a step back and describe what you actually want achieve. Why not continue with USART2? \$\endgroup\$
    – Codo
    Commented Nov 30, 2022 at 15:58
  • 1
    \$\begingroup\$ "extra work for parsing the data with START, and END markers": This sounds as if you are assuming that each call of CDC_Transmit_FS() will result in a separate message on the receiving PC. That's not the case. If data is sent in quick succession or the receiving application does not immediately process the data, multiple packets will be combined and may even arbitrarily split in different units. It don't see any difference for the receiving end between UART via USB adapter and direct communication via USB CDC. \$\endgroup\$
    – Codo
    Commented Dec 1, 2022 at 13:55
  • 1
    \$\begingroup\$ Your challenge is probably how to split the data stream into valid messages. I've just two approaches. (1) Delimiter separating messages, e.g. text messages and new line as separator. (2) Messages with header and checksum, e.g. consisting of magic header bytes / size / payload / checksum. Once magic bytes (1 or 2 bytes) are detected, the size is read and buffering starts. When the message has the expected size, the checksum is verified. If it is invalid, the next header is searched. \$\endgroup\$
    – Codo
    Commented Dec 1, 2022 at 14:36

1 Answer 1


As Codo mentioned, I need to use a USB connector not an RS232 Adapter. The CDC works via a two-wire interface with D+ and D- terminals. I had to use a USB cable and attach the respective pins to the terminals on the nucleo board (not to forget the GND connection). Here is my pin connection to the USB connector:

  • D+ -> PA12
  • D- -> PA11
  • GND -> GND

I am able to use both USART and CDC simultaneously now. It was a little tricky to figure out the necessary clock configuration. Here is what works for me (for both USART2 and CDC):

Clock Configuration for USART and CDC


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.