Uploading fails with STM32 "Blue Pill" Board

I have long and good experience with Platformio on vscode and the ESP-family. Now I started with the STM32 family, using STM32f103c8 Blue Pill, and already fail at the first uploading.

A small Blinky script compiles fine. Then clicking upload ends with this:

...
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [=         ]   5.5% (used 1132 bytes from 20480 bytes)
Flash: [=         ]   9.5% (used 12468 bytes from 131072 bytes)
Building .pio/build/bluepill_f103c8_128k/firmware.bin
Configuring upload protocol...
AVAILABLE: blackmagic, cmsis-dap, dfu, jlink, stlink
CURRENT: upload_protocol = dfu
Looking for upload port...
Using manually specified: /dev/ttyACM0
Uploading .pio/build/bluepill_f103c8_128k/firmware.bin
dfu-util 0.7
**No DFU capable USB device found**

Copyright 2005-2008 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2012 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to dfu-util@lists.gnumonks.org

Filter on vendor = 0x1eaf product = 0x0003
Waiting for /dev/ttyACM0 serial...Done

I guess “No DFU capable USB device found” is the culpprit, but what can I do about it?

My platformio.ini is:

[env:bluepill_f103c8_128k]
platform = ststm32
board = bluepill_f103c8_128k
framework = arduino

upload_port = /dev/ttyACM0
upload_protocol = dfu

If you are not in a hurry, get ST-LINK programmer, it’s cheap and works great, uploading is also much faster.

So you have a USB-to-UART adapter connected to the bootloader UART pins of the STM32F103, and the chip was booted in bootloader mode (BOOT0 = 1)? If you want to upload via UART, it needs to be upload_protocol = serial. Wiring see BluePill Arduino UART Programming - Phipps Electronics

Well, I was following the published guidance of the vendor of the Blue Chip, but this is not working, neither on the Arduino IDE, nor on platformio (my preference).

I do have the Blue Pill board and a ST-Link V2 programmer. I used the ST-LINK to upload the bootloader generic_boot20_pc13.bin from https://github.com/rogerclarkmelbourne/STM32duino-bootloader/ to the Blue Pill. Once done I could connect to the Blue Pill with the USB-micro plug to port /dev/ttyACM0 . This is what I defined as upload_port.

After compiling successfully, platformio tells me:

Configuring upload protocol...
AVAILABLE: blackmagic, cmsis-dap, dfu, jlink, stlink

but whichever of the available protocols I choose, it always fails.

I’d be happy to use the ST_LINK, but how? Whenever I use it instead of the BLue-Pill-USB-Port, platformio complains about not having an upload port?

If you did flash the generic_boot20_pc13.bin correctly onto the Bluepill (target address 0x8000000), that upload_protocol = dfu should work. Remove any upload_port = .. directive, PlatformIO will figure it out automatically. You can also check if the bootloader is running correctly by running lsusb, it should show up as something called Maple DFU.

Yes, upon uploading generic_boot20_pc13.bin port /dev/ttyACM0 did show up, and lsusb did show something maple & leaf, which you see in my first post to this topic.

But, as it also shows, “No DFU capable USB device found” was reported and the upload failed.

I now have followed the guidance to use ST_LINK and was able to upload my Blinky and have it blinking!

However, this procedure seems to overwrite everything else, and now my bootloader is gone. So I have no USB-Serial port anymore, and can’t even do a Serial.print.

How can I keep my bootloader providing me with a Serial-port and allowing me to upload via this serial port?

I not sure that is the case, because I use ST_LINK for firmware uploading and usb serial port for simple debugging and it all works good.
This how my ini file looks:

[env:genericSTM32F103CB]
platform = ststm32
board = genericSTM32F103CB
framework = arduino
build_flags = -D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC -Os
debug_tool = stlink
upload_protocol = stlink

I followed @noobmastha and with lots of fiddling I was able upload, run and even do Serial.prints!

However, in trying to repeat in an orderly fashion, I failed. Nothing works now :frowning: I think I am missing something fundamental.

How about these 2 Mini-Jumpers on the board? I have both BOOT0 and BOOT1 on the zero setting, and when uploading I put BOOT0 on 1, and leave BOOT1 on zero. Is that right? Is it even needed?

No man, leave both jumpers on “zero position” you don’t need to move them when uploading.

… but exactly this is what I was told to do by the vendor’s tutorial :frowning:

I set Boot0 to 1, used STMCubeProgrammer for uploading, got file generic_boot20_pc13.bin and uploaded, reset Boot0 to zero, and I had my ttyACM0 USB port. lsusb says:

ID 1eaf:0004 Leaflabs Maple serial interface

Looked ok to me.

I don’t need this STMCubeProgrammer? What steps do I need to take when doing bootloading and Blinky uploading all in platformio?

What vendor’s tutorial?
Look, I got the STM32F103 aka “blue pill” from Aliexpress and there is no need to move jumpers and mess with .bin files PlatformIO takes care of all…
Connect ST_LINK and usb cable, use settings for the .ini file I’ve sent you and that’s all.
When you hit the upload button, your chip is programmed over ST_LINK and you can print the Serial over the usb cable. It’s all automatic and easy.

And if you have a fake STM32 chip (like me), you just have to add one more upload flag to your ini file:

upload_flags = -c set CPUTAPID 0x2ba01477

The vendor is AZ-Delivery, a German company. You can download the tutorial here: "Bluepill" Development Board Module with ARM Cortex M3 processor

It is free, but you pay with an email address :frowning:

How do I know that a chip is fake?

@noobmastha I used your exact platformio.ini code, once without and once with your fake-flag. It failed in both cases with exactly the same output, except that there was an extra line when the fake-flag was used. I have marked it in the output:


 *  Executing task in folder blinky: platformio run --target upload

Processing genericSTM32F103CB (platform: ststm32; board: genericSTM32F103CB; framework: arduino)
-----------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/ststm32/genericSTM32F103CB.html
PLATFORM: ST STM32 (17.3.0) > STM32F103CB (20k RAM. 128k Flash)
HARDWARE: STM32F103CBT6 72MHz, 20KB RAM, 128KB Flash
DEBUG: Current (stlink) External (blackmagic, cmsis-dap, jlink, stlink)
PACKAGES:
 - framework-arduinoststm32 @ 4.20701.0 (2.7.1)
 - framework-cmsis @ 2.50900.0 (5.9.0)
 - tool-dfuutil @ 1.11.0
 - tool-dfuutil-arduino @ 1.11.0
 - tool-openocd @ 3.1200.0 (12.0)
 - tool-stm32duino @ 1.0.1
 - toolchain-gccarmnoneeabi @ 1.120301.0 (12.3.1)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 12 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Checking size .pio/build/genericSTM32F103CB/firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [==        ]  21.5% (used 4412 bytes from 20480 bytes)
Flash: [==        ]  18.6% (used 24340 bytes from 131072 bytes)
Configuring upload protocol...
AVAILABLE: blackmagic, cmsis-dap, dfu, jlink, serial, stlink
CURRENT: upload_protocol = stlink
Uploading .pio/build/genericSTM32F103CB/firmware.elf
xPack Open On-Chip Debugger 0.12.0-01004-g9ea7f3d64-dirty (2023-01-30-15:03)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
debug_level: 1

0x2ba01477          ### this is the extra line when fake-flag was given ###
hla_swd
Error: init mode failed (unable to connect to the target)
in procedure 'program'
** OpenOCD init failed **
shutdown command invoked

*** [upload] Error 1
====================================================== [FAILED] Took 1.71 seconds ======================================================

 *  The terminal process "platformio 'run', '--target', 'upload'" terminated with exit code: 1.
 *  Terminal will be reused by tasks, press any key to close it.

It’ supposed exactly like you said: You burn the bootloader into it once with an ST-LInk and reboot the chip. At all times, the BOOT0 and BOOT1 pins stay at their initial 0,0 position. Otherwise, you’ll enter the bootloader built in to the STM32 (only supports uart, i2c and some others, but not USB). You use upload_tool = dfu with no upload_port and you should be good to go. If dfu-util doesn’t find the board, your might have wrong permissions setup (see udev rules).

How is this free? :slight_smile:

https://www.az-delivery.de/en/products/stm32f103c8t6
This looks exactly like my dev board from Aliexpress, but with 3-4x higher price.
I think you are confused by that tutorial and you’re doing something wrong, but I don’t know what.

I decided to go “all-in” by purchasing not from a reputed German supplier but from some dubious Chinese shop on Amazon https://www.amazon.de/dp/B07Y83Q2HP

Both new boards look absolutely identical to the old AZD board even under detailed magnifying glass inspection.

Well, what can I say: using @noobmastha 's platform.ini config, both boards worked on the first try :-)). After uploading I now see a new USB port /dev/ttyACM1 reported as STMicroelectronics Virtual COM Port.

Beyond Blinky, a few more things, including the ADC, now also work.

So, what do I have:

  • is the AZD board defect?
  • is the AZD board a fake? How can I find out?
  • did I ruin the board with all my failed attempts? Is there some kind of factory reset possible to bring the board back to virgin state?

I doubt you can “ruin” it with attempts, contact AZD and ask them.