Sunday, 15 January 2017

Getting to Blinky - With a STM32 "Blue Pill" devboard

For the newbie embedded developer, the Arduino ecosystem is the perfect place to start. It's really easy to get up and running with a new development board. All you have to do is buy one of the branded boards, like an Arduino/Genuino Uno, download and install the single software package, then run the IDE. All the required drivers are installed and the interface, while fairly spartan, is easy to use. Just select the board type and load one of the example pieces of code.

The popularity of the Arduino ecosystem of software and dev board hardware, along with its open source heart, has meant that a range of clones or compatible products are also available. This means that you can buy a really cheap development board from places like eBay or AliExpress. Even though Arduino hardware started with 8 Bit Atmel ATMega microcontrollers, they have now evolved to include a range of modern 32 bit microcontrollers, like the Atmel (now Microchip) SAMD21 in the Arduino Zero. Others have adapted the Arduino IDE to be used with a variety of hardware, like the really cheap WiFi chip ESP8266. This proved very popular with tinkerers the world over, so much so that the newer version of the Arduino software included support to be able to run code directly on these little modules. This required someone to adapt the Arduino bootloader to the chip. The "bootloader" is a little piece of code that runs when the device first boots up, providing a mechanism for people to load custom code onto the chip using a simple serial protocol.

One of the simplest and smallest 8-bit Arduino modules is the Pro Mini. It requires an external USB to UART adapter in order to program it. Sparkfun Electronics designed it as a module to be included in electronics projects. It's only $10USD, although it's more like $20AUD by the time it gets here. plus you need the USB to UART adapter, which at $15USD costs more than the dev board itself!! So even trying to do it cheaply, here in Australia you're looking at something around $40, which is about the cost of the UNO board that includes the communication IC.

I use the 3.3V version of the Pro Mini in several projects, because many (most) sensors these days only speak at a 3.3v level. If you use the usual 5V Arduino, you need things like "level shifters" to make sure the voltage level of the signalling circuit doesn't fry the expensive sensor. Instead of spending alot of cash mucking around with the brand name boards, you can buy cheap clones of these from Aliexpress, so it's really easy to leave these inside whatever project you're making, and not worry if it gets zapped or blown up. Sure, there are some issues using these instead of the proper branded ones, but sometimes cash is king. The lowest cost often wins!

 But how cheap? Try around $2 a piece!

But what if you need something more powerful, like one of these 32 bit Arduinos? The Arduino branded ones with the 32bit microcontroller still cost around the same as the 8-bit ones, but most of them incorporate a USB interface on the chip, removing the need to have any external programming board. So what cheap 32 bit option is there?

It turns out that there aren't many clones of 32 bit Arduino devices. But China does have an equivalent to the Pro Mini. It's often called a "STM32 Minimum System Development Board", or a "Red Pill" or "Blue Pill" depending on the PCB colour. It uses a STM32F103 microcontroller, and has a breadboard friendly form factor. I first read about it on the CNX Software blog . It can be loaded with a modified bootloader so that it can be programmed using the Arduino IDE. Given the cost was so low, I thought I'd buy one and have a tinker. Proper embedded developers use a hardware debug tool to program similar hardware, so I bought a cheap one of these to match. I didn't know if I'd need it, but I figured it was cheap enough to have on hand if I ever needed it.
STM32F103 Blue Pill board and ST-LINK V2 debug tool

Enough of the background story. I ended up trying a few things before I finally managed to get the onboard LED to obey my flashing commands!!! Here's a summary of the process.

  1. Download and install the latest Arduino IDE. Currently 
  2. Turns out that the ST-LINK V2 dongle IS useful. Rather than just install the drivers for it that can be sourced from the ST website, download the entire "ST-LINK Utility", which includes the driver AND relevant application. Run the installer and follow the prompts.
  3. Download the STM32-duino bootloader repository. Save and extract it to a temporary location. Thanks to Roger Clarke for making the mods to suit the STM32F103 boards!
  4. I probably did this step wrong, but in the end it seemed to work. The instructions for this step are here. Roger Clarke has another Github repo for all the board hardware files, so that the STM32F103 and others can work with the Arduino IDE. Follow the instructions and download and extract the repo into the correct location. If this doesn't work, and you have the latest version of Arduino with the "Boards Manager", instead of downloading the repo,  just add "" as an additional boards manager url in the IDE preferences. Restart the IDE, then go to the Boards Manager (Tools > Board:xxxx > Boards Manager). Scroll to the bottom of the list and you should find the one labelled "STM32F1XX/GD32F1XX boards by stm32duino". Click the name, then click the Install button that appears. Wait for it to download and install, then restart the IDE for good measure.
At this point, you should be able to select the "Generic STM32F103C series board, then select the "STM32F103C8 (20k RAM. 64k Flash)" variant, and the CPU speed of 72Mhz. You then need to connect the ST-LINK V2 to the dev board. The end connectors opposite the Micro-USB socket are the ones to connect. From top to bottom, the pins are labelled "GND, SWCLK, SWDIO, and 3.3". On mine, the SW is hidden by the pin header.

Connect these to the corresponding 4 pins on the bottom row of the ST-LINK tool. The case shows the pinout. Make sure you plug the power into 3.3V, not the 5V pin. You can then plug the ST-LINK into your computers USB port. Back in the Arduino IDE, in the "Tools" menu, choose "SWD" as the upload method. Now you can write some code, or choose one of the examples in the "Generic STM32F103 series" section.

In my case, the onboard LED is marked as being connected to the pin PC13. I used this name as the reference in the Blink example, and voila!!! Flashing LED.

Now if you don't want to use the ST-LINK, and just want to use the onboard Micro-USB port, then you'll need to install the bootloader. First, make sure the dev board is wired up to the ST-LINK as before. On your computer, run the "STM32 ST-LINK utility". Click "Target" then "Connect". Information should appear in the "Device" area at the top right of the window - like this:

Then click File > Open File, and navigate to the extracted bootloader files you downloaded at step 3. Navigate into the folder named "binaries", and find the file named "generic_boot20_pc13.bin". This is because the LED is on PC13!! Then click "Target" then "Program". In the next window, ensure the 
start address is "0x08000000", then click "Start". Wait about 4 seconds til it's finished, then you're almost there. The last step is to install the DFU utilities that were part of the download in step 4. Inside the extracted ZIP of the Github repo, navigate to "\Arduino_STM32\tools\win\dfu-util-0.9-win64\" folder, and run the "dfu-util.exe" program. This will install the drivers for the "Maple Serial" device, and the DFU driver. DFU means "Device Firmware Update". It's a mode where firmware can be loaded from an external source. 

Now in the Arduino IDE, you need to select the upload method of "STM32duino bootloader". Write some more code, then click upload......and nothing happens!! But it says "Done Uploading" ???
With this board, you need to press the reset button just after the IDE shows that it is uploading, otherwise the process will timeout and fail. Try uploading again, and press reset at the right time.

Well done! You've got to Blinky 2 ways - via SWD and via the STM32duino bootloader!