c STM32F4 USB Virtual COM Port
Wolin Labs :: fun toys for your iThingy & Droid


Don't Lose your Garmin GPS!

Cron Job with Random Start Delay

Git Submodule with Local Changes Example

Using Caltopo Maps on your Garmin GPS

Waffle Reuben

Copying a Single File with a Yocto Recipe

Semihosting Debugging on STM32F4

Realtime Audio DSP with the STM32F4

Tuning the Moog Etherwave Theremin

STM32 Discovery Development on Linux

STM32F4 USB Virtual COM Port (VCP)

Editing GoPro Hero2 Video with Cinelerra

Code Browsing with Emacs, GLOBAL, and Speedbar

Use a PC Power Supply as a Bench Supply the Easy Way

Android Activity Bar Framework

Generating an Audio Sine Wave with Java

Android Simple Yes/No MessageBox

Fox Talas 32 Oil/Seal Change Checklist

Creating a Bootloader Environment (Freescale ColdFire Example)

Pentomino Smackdown: Names That Didn't Make the Cut

STM32F4 USB Virtual COM Port (VCP)

Ross Wolin - last updated 2013.04.12


This sample code creates a USB connected virtual COM port, using the USB CDC class (Communications Device Class.) On Linux, this class does not require a driver: it is supported directly by the kernel. Simply put, it makes the STM32F4 function similar to a USB-serial adapter.

Uses single physical USART/UART: Some sample code I found used an abstraction accessible via printf/scanf on the microcontroller side. This example instead interfaces to a real physical hardware serial port on the microcontroller side, connected to a virtual COM port on the PC via USB.

Supports line control settings: This sample supports setting baud rate, word length, stop bits, and parity via the SET_LINE_CODING message from the USB side (i.e. from the PC's serial terminal program, etc.) It does not support using hardware flow control, nor controlling RTS and DTR (although these features could be added.)

Platform Background

The STM32F4 Discovery is a $15 development board, featuring a 168Mhz ARM Cortex M4 (STM32F407VGT6) The ARM is programmed via an STLINK/V2 interface connected to a PC's USB port (i.e. requires no JTAG plug, ICD, BDM, proprietary dongle, etc.)

Development Environment

This sample was built/used with Ubuntu 12.04 LTS, GNU Tools for ARM Embedded Processors 4.7.3, the 2013.03.06 commit of STLINK and PUTTY (terminal emulator.) It runs on an STM32F4 Discovery board. It may also work with versions, tools, boards, etc... some modification may be required.

I used the GNU Tools for ARM Embedded Processors toolchain, maintained by ARM Ltd for the Cortex-R/M families for "bare metal development." If you need to install and set up the toolchain + STLINK, refer to my previous blog posting: STM32 Discovery Development on Linux

Download VCP Example and STM32 Libraries

cd ~
git clone https://github.com/rowol/stm32_discovery_arm_gcc

The VCP example source will be in ~/stm32_discovery_arm_gcc/usb_cdc_vcp

I have also included a copy of STM's library source, needed to build the project, in the ~/stm32_discovery_arm_gcc/STM32F4-Discovery_FW_V1.1.0 directory. If you want the unmodified STM library source download that from STM's website (I've added Makefiles and linker files to build STM's example projects w/ the GNU/ARM toolchain, but left everything else intact..)


Edit the Makefile to set BINPATH to point to your toolchain:


Build the code by running make:


Code Highlights

main.c::hw_init() - initializes IO pins and other hardware, also initializes the USB CDC class driver via USBD_Init()

usbd_cpc_vcp.c::DISCOVERY_COM_IRQ_HANDLER() receives an interrupt when there is received USART data. It transmits this data over USB using VCP_DataTx()

usbd_cpc_vcp.c::VCP_DataRx() - is called by the USB driver framework when there is received USB data. This data is transmitted over the USART.

usbd_cpc_vcp.c::VCP_Ctrl() - processes the USB messages received from the USB CDC driver framework, particularly GET/SET_LINE_CODING used to manipulate serial port settings.

usart.c: higher level "USART driver"

RS232 Voltage Levels

The STM32F4 runs TX/RX lines at 0/3.3V levels. Traditional RS232 expects voltage levels of +/-12V (although a lot of modern devices work down to +/-5V levels.) In any event, you will need a level translator such as MAX3232 from Maxim to translate from 0/3.3V to RS232 voltage levels.

If you don't want to build the level translation circuit, these boards are available from Mouser, as well as others...


Send comments, questions, money in large denominations, etc to eng at mysticengineering.com

If you enjoyed this article, please consider buying my products ...

ATX PS Adapter Ultimate Serial Port
ATX PS Adapter

Use an ATX PC power supply as a 5V, 3.3V, and +12V/-12V bench supply the easy way, without cutting the case or mounting external connectors, resistors, LEDs, switches, and fuses.

Provides visual indication when supply is plugged in and turned on, also fuses the power voltage outputs for safety. Run USB powered development boards via the USB connectors on the 5V line.

Ultimate Serial Port (Debug Buddy)

USB serial port with standard, 5V and 3V RS232, plus integrated null modem and gender changer. Implements TX/RX and RTS#/CTS# for optional hardware handshake.

Also includes 3.3V<->5V level shifters, debug LEDs, and 13 clock sources. Valuable tool for hands on problem solving and hacking