Tuesday, June 23, 2015

STM32 Nucleo and DFU USB Bootloading

Over the last few months I have been playing with the Nucleo development boards from STMicroelectronics. If you're unfamiliar with them, they are fast, mbed and Arduino (headers) compatible. This makes it easy like an Arduino to program and use. What sets them apart is that they are 32bit and have, depending on the model, tons of memory and flash. The Nucleo boards maintain the Arduino footprint but also have headers for the extra pins which gives this board plenty of GPIO for your projects.  In turn, you end up with multiple buses such as SPI, I2C, and UARTs for your consumption. They are priced very well and come in different flavors based on your needs. Each flavor is based on different ARM Cortex architectures such as M0, M3, and M4. One of the best features is real debugging via ST-Link/V2-1. The unfortunate thing due to the nature of mbed, you can only use the debugging features using a full desktop IDE such as Keil or some of the other free alternatives. But mbed allows you to export your code from the online IDE to the project format for those IDE's. So there's that.

Most of my projects spend very little time on the development board. Once they are working, I usually want to design a PCB for it. Therefore I prefer to use microcontrollers that support native USB programming, such as the popular ATMega32U4. With some AVR chips you can use the Arduino bootloader but most chips come with a DFU bootloader that can support flashing over serial and USB. In the case of STM32, it additionally supports CAN, I2C, and SPI bootloading. For some reason the Nucleo boards don't have the native USB connector onboard, but the needed pins are available for easy access. (The discovery boards do.)

Connecting USB Pins

To access these pins you can use a USB breakout or a USB Tester. Of course you could always cut open a USB cable, but seriously, why create a mess? If you have one of my USB, Testers it makes it much easier, plus all of the other features it provides. BUY ONE NOW!! Just kidding! The pins for D+ and D- are not labeled on the pin out of the Nucleo board out but if you look up the datasheet you can find them and match the pin names with the Nucleo pin out as shown below.

So far I have tested the L152 and F411 and both have been PA12, PA11 (D+, D-). Which is pin 6,7 from the top on the right most column of male headers.

STM32 Nucleo USB DFU Connections

USB Tester as USB Breakout

Note: You may need to connect ground as well from the USB Tester to the Nucleo. I didn't because the red USB cable I am using has a common ground since it has a built in USB hub. Also, my computer is connected to both which provides a common ground. It's the 3 headed cable beast from Sparkfun.

Bootloader Mode

Finally, you need to set BOOT0 pin high which will enable the bootloader on power up or reset. The USB data lines don't need any extra hardware such as pullups, at least on the L152 and F411 Nucleo boards but you can double check the datasheets for the others.

There are ways to get into bootloader mode from software without user intervention, which is ideal if you decide to sell your widget.  Here are some links I have found, of which I've yet to try. I am sure when I do, another blog post will be drafted. So far, what I like is using an RC circuit on BOOT0 controlled by a GPIO.



Converting mbed to DFU

mbed compiles into .bin for download to the mass storage device that is mounted when you plug in an mbed compatible device. The problem with this however, is that the STM32 DfuSe Demo app wants a DFU file which is basically a .bin file with the start memory address of where to load your code in flash specific for your microcontroller plus other settings. Not all is lost! There is a way to still get the code loaded and tell it where to flash.

Here is the download for DfuSe Demo app:  http://www.st.com/web/en/catalog/tools/FM147/CL1794/SC961/SS1533/PF257916#

This is where I will save you lots of time. Originally when I was figuring this all out, I spent a lot of time trying to get the .bin into a .dfu. Tons of searching and trying various things - even a python script. It turns out the DfuSe app comes with the DFU File Manager which can load various file formats along with the device IDs and the starting memory address and then spit out a DFU file! Sweet!

I entered the same USB Device IDs as is loaded when connected to the DfuSe app. I believe if you have your own you can enter it here and it will be the ID that Windows sees when you run your USB enabled application. Then just use the Multi BIN button to select the BIN file from mbed and enter the flash start address. So far I have been using 0x08000000. Then click generate after selecting a save location.

Flashing via Bootloader

Now for what you have been waiting for: the fun part where you can watch the electrons of code flow into the chip! If you haven't already, run the DfuSe and it should see the STM device if everything is connected and powered. Make sure you have the BOOT0 pin high before powering up or before resetting. I would connect the DFU USB connection after it's powered up. It seems to work better. In the DfuSe app, I left everything as default. Be sure Target ID 00 is selected which should be named 'Internal Flash'. Which is precisely what I just realized while writing this! You can double click target ID 00 to view the starting address, useful when generating the DFU file. Cool!

Then on the bottom right section, "Upgrade or Verify Action" choose to load your DFU file and finally Upgrade to start the flashing process. You can verify if you'd like. Also, if needed, you can download the current code from the microcontroller back to a DFU file by using the bottom left section labeled "Upload Action."

Remember to remove the BOOT0 jumper before you reset to start your code.

Note: If you run into problems with the DfuSe app not working, try version 3.0.3. I had to downgrade for it to work. There was a forum post somewhere about that. Oddly enough I checked back and the DfuSe shows 3.0.4 but the DFU File manager show 3.0.3. Either way, one of the two versions should work for you.


I hope this helps anyone starting to play with the STM32 boards! Or at the very least, looking to take their widget to a custom board. Granted this isn't as simple as the Arduino setup, but it's not too bad if you do most of your work on the development board with the mbed drag n' drop interface and DFU for final code. Maybe this process can be automated. Remember if you want to debug, you still need the attached ST-Link/V2-1 and a desktop IDE. I plan to start developing projects with STM32 now that I know I can easily flash without a programmer. The part is to get USB serial communications working over the USB connector without ST-Link/V2-1. It should be just a matter of using the VCP (Virtual COM Port) library. I believe in mbed this should be as easy as using the USB Device library instead of serial UART interface that links with the attached ST-Link/V2-1.

Interesting: I found this https://github.com/UmbrelaSmart/android-stm32-dfu-programmer which can program a DFU file via OTG on Android. I will have to try this!

Reference Links

Datasheet STM32F152  Page 43 - USB Pins
DfuSe Version Issue Info - Has solution to fix problem in 3.0.4
Nucleo L152 Pinout
Nucleo F411 Pinout
Application Note AN2606  - System Memory Boot Mode (Contains bootloading pinouts for each bus)
Application Note AN3156 - USB DFU Bootloader Protocol


  1. comandline programming is also possible, use "DfuSeCommand.exe -c -d --fn %ImageName%" to flash an existing dfu file

    DfuSe v3.0.4 is a buggy, especcialy when flashing, i recomend using DfuSe v3.0.3

    1. Thanks I will give that a try. I did have issues with 3.0.4 and used 3.0.3 but then when I wrote the post 3.0.4 was working go figure.

  2. Hello,
    I use the board Nucleo-F401RE. When i connect pins PA12, PA11 and GND to USB D+, D- and Ground I don't view the Available USB devices. Please what is run ?

    1. Hmm, maybe they are reversed? Do you have BOOT0 tied high?