Go to file
Riku Viitanen 8fcf0a4d41 Add phony rule to just make libopencm3
Signed-off-by: Riku Viitanen <riku.viitanen@protonmail.com>
2023-09-11 14:25:05 +03:00
boards Add new board: Nucleo-F042K6 2023-09-07 00:05:57 +03:00
flashrom@554a01f9a6 Fix submodule link 2021-03-22 03:40:56 +02:00
libopencm3@458250dc61 Fix submodule link 2021-03-22 03:40:56 +02:00
pcb add parameters in sch 2017-04-24 23:36:29 -05:00
.gitignore add test/benchmark support 2017-05-23 03:37:14 -05:00
.gitmodules switch flashrom git url to mirror on GitHub 2021-04-18 17:01:24 +08:00
.travis.yml Add a Travis-CI script 2018-10-22 00:52:35 +02:00
LICENSE switch to GPLv3 2015-12-26 02:06:12 -06:00
Makefile Add phony rule to just make libopencm3 2023-09-11 14:25:05 +03:00
README.md expected autolink... added link manually 2018-11-19 14:00:14 -08:00
serprog.h Include serprog.h and BUS_SPI 2023-09-11 12:58:11 +03:00
spi.c Fix SPI baudrate for STM32F0 targets 2021-10-13 22:29:14 +02:00
spi.h Adds command to enable/disable output buffers. 2018-10-28 14:22:53 -03:00
usbcdc.c Set iInterface==serprog 2023-09-07 00:32:35 +03:00
usbcdc.h more testing on GD32, SPI not working 2016-01-23 02:00:26 -06:00
vserprog.c Include serprog.h and BUS_SPI 2023-09-11 12:58:11 +03:00


flashrom serprog programmer based on STM32 MCU & USB CDC protocol.

This project deprecates previous serprog-stm32vcp project, which uses STMicro's proprietary firmware library. Most functions are the same.


  • Fully open-source: now with libopencm3 instead of STMicro's proprietary firmware library.
  • Affordable and simple hardware:
    • An STM32F103C8T6 MCU, an 8MHz crystal, a 3.3V 1117 LDO, some 0805 capacitors, resistors and LEDs along with dedicated PCB available on OSH Park (V2 or V3)
    • Or some general-purpose STM32 development boards, just add a new header file under "boards" folder to assign correct GPIO for USB D+ pull-up (STM32F1 only) and LEDs.
    • Hardware USB 2.0 Full-Speed and efficient virtual COM port with USB CDC protocol operates at any baud rates, eliminates the need of USB-to-UART bridges and the headache that comes with them.
    • Ironically, you will still have to buy or borrow a USB-to-UART bridge (not RS-232 but TTL level) to program the programmer itself, unless you are using an STM32F0x2 device (which has USB ISP capability) or boards with embedded ST-Link (see @FabianInostroza's fork).
  • Hardware full-duplex SPI with DMA, multiple clock speeds available (default at the one closest to but under 10MHz), e.g. on STM32F103 targets:
    • 36MHz
    • 18MHz
    • 9MHz (Default)
    • 4.5MHz
    • 2.25MHz
    • 1.125MHz
    • 562.5kHz
    • 281.25kHz
  • 2 status LEDs (controlled with 1 GPIO):
    • Busy is lit during operation (inverse for boards with only one LED).
    • Different operations cause different patterns of blinking: mostly busy = reading, both on = writing, flashing alternatively = erasing.
    • Busy blinks alone if a hard fault or NMI is detected. Please unplug and replug the programmer. If the situation persists, please consider opening a new ticket.
  • flashrom "serprog" protocol:
    • Operates on all major platforms (see flashrom wiki).
    • Driver-free on Linux. On Windows may require ST's VCP driver (or just hack the .inf file of other CDC drivers, not confirmed).
  • Firmware is interrupt-free except for low-level USB handling -- robust, easy to debug and modify.
  • Fast:
    • Read speed up to 850KiB/s @ 36MHz SPI operation.
    • Dumps an EN25Q64 in 11 seconds and programs in 85 seconds (including flashrom's calibration time).
    • Way faster than many commercial CH341-based USB programmers, especially for reading.
  • Supports 25 and 26 series SPI flash chips. 45 series flash chips have different pinouts. Thus for the V2 PCB mentioned above, you will need an adapter.


  1. Install stm32flash and the gcc-arm-none-eabi toolchain.

On Debian, simply do the following:

sudo apt-get install stm32flash gcc-arm-none-eabi

NOTE: some systems may require installing newlib (e.g. libnewlib-arm-none-eabi) manually. See #27.

  1. Clone and compile.

Simply type (change the board name accordingly, for details see the header of the Makefile or just type make):

git clone --recurse-submodules https://github.com/dword1511/stm32-vserprog.git
make BOARD=stm32-vserprog-v2
  1. Program.

Connect the USB-to-UART bridge to your computer first. Then connect TXD and RXD lines to your STM32 board with wires. On V2 or V3 boards mentioned above, connect BOOT0 (labeled BT0 on boards) to the 3.3V output of the USB-to-UART bridge. For other boards, find the BOOT0 jumper or ISP switch, put it into high or enabled. On some boards, you will also need to ensure BOOT1 is pulled low. Then, connect your STM32 board to your computer via USB to power it up. Finally, type:

make BOARD=stm32-vserprog-v2 flash-uart
  1. Done!

Throw the USB-to-UART bridge away and enjoy. Do not forget to pull BOOT0 low before resetting or replugging the board.


The following assumes Linux platform, and that the programmer appears as /dev/ttyACM0.

  1. To read a flash chip:
  • Connect a 25 type SPI Flash to the board's DIP-8 slot or according to the schematics.
  • Connect your board to your PC via USB.
  • Type:
flashrom -p serprog:dev=/dev/ttyACM0:4000000 -r file-to-save.bin
  • Sometimes flashrom will ask you to choose a chip, add something like:
-c SST25VF040B

This is because sometimes different devices with distinct timing requirements can only be distinguished by the device code, however currently flashrom will not read it as it is not returned by the RDID command.

  1. To erase a flash chip:
  • Erase is automatically done during writing. However, if you simply want an empty chip, you will need to erase manually.
  • Type:
flashrom -p serprog:dev=/dev/ttyACM0:4000000 -E
  • For certain chips like MX25L6445E, the first pass could fail with some old flashrom version, but if you try a second pass, everything will be alright. Seems that the first block needs more delay to be erased.
  • Flash contents are verified to be empty automatically.
  • The whole process can take a few minutes.
  1. To write a flash chip:
  • Type:
flashrom -p serprog:dev=/dev/ttyACM0:4000000 -w file-to-load.bin
  • Flash chips are checked and blocks that are not empty are automatically erased.
  • Images are verified after writing automatically.
  • The whole process can take a few minutes.


  1. If you encountered something like "Error: Cannot open serial port: Device or resource busy", please try to stop or remove ModemManager.
  2. Check your wirings and flashrom version. Do not forget to power the flash chip itself if operating on a breadboard or prototype board.
  3. If you are sure it is caused by bugs in the programmer's firmware, please open a new ticket and provide details, e.g. the board you are using and flashrom's output. I appreciate your feedback.