Taming the STMicros Discovery Boards
(Last modified 4 Jan 2014)

Updated 27 Feb 2014
A reader pointed out an error in my schematic; I got two of the signals to the SD card routed to the wrong pins on the Discovery board.  I've updated the schematic below.

I have been asked about how to change the USART used for the console.  This assignment happens in build_config.lua and is only available to you if you have installed the appropriate GCC toolchain and the elua-master source tree, as described below.  Below is the build_config.lua I used in building my eLua system.

The USART assignments used in this file are needlessly cryptic.  Ports are numbered from 0 to 3, not A to D.  Thus, setting con_rx_port to 3 selects PORTD.  So the assignment below, for the table 'required', uses PD.9 for the USART Rx pin and PD.8 for the USART Tx pin, which in turn selects USART3.  In the commented-out line immediately above the USART3 assignment, you can see the assignment for selecting USART1, which is wired to PB.7 (Rx) and PB.6 (Tx).  You can find the tables defining the permissible USART assignments in the file \elua-master\src\platform\stm32f4\platform.c, starting around line 495.

Selecting the correct alternate assignments for pins on the Discovery board is tough to begin with, because there are so many options.  But the STMicros reference manual for the chip provides no help that I've been able to find.  Scot Kornak has provided an Excel spreadsheet that can help make sense of it all; here's a link.  (Thanks, Scot, for this tool!)

========== My build_config.lua ==============

-- This is the platform specific board configuration file
-- It is used by the generic board configuration system (config/)

module( ..., package.seeall )
local at = require "attributes"
local comps = require "components"

-- Add specific components to the 'components' table
function add_platform_components( t, board, cpu )
  t.cdc = comps.cdc_uart()

-- Add specific configuration to the 'configs' table
function add_platform_configs( t, board, cpu )
  t.stm32f4_uart_pins = {
    attrs = {
      con_rx_port = at.int_attr( 'STM32F4_CON_RX_PORT', 0 ),
      con_rx_pin = at.int_attr( 'STM32F4_CON_RX_PIN', 0 ),
      con_tx_port = at.int_attr( 'STM32F4_CON_TX_PORT', 0 ),
      con_tx_pin = at.int_attr( 'STM32F4_CON_TX_PIN', 0 )
-- The following table selects the console port.  It should be changed
-- to use a single UART identifier, such as UART0.  The pin and port
-- definitions for each UART are already declared in the board's
-- platform.c file.  Redefining hardware assignments here causes
-- a lot of frustration when you try to modify the console UART.
    --    required = { con_rx_port = 1, con_rx_pin = 7, con_tx_port = 1, con_tx_pin = 6 }
    required = { con_rx_port = 3, con_rx_pin = 9, con_tx_port = 3, con_tx_pin = 8 }        -- UART3 on PORTD

-- Return an array of all the available platform modules for the given cpu
function get_platform_modules( board, cpu )

Updated 4 Jan 2014

I finally got around to creating an Eagle device for the STM32F4 Discovery board.  I replaced the original table of SPI connections with a schematic.

Note also that there was an error in the SPI connection table; sorry about that.  If you tried to build this project and couldn't make the SD card work, check the schematic.

You can also download the Eagle 5.1 device I built so you can use it in your own schematics.  Note that this is not a complete device.  It has no outline or markings.  It is just a schematic symbol and a simple pad layout.  If you update this device to provide more info or if you correct any errors you might find in the device, please pass it along.

The STMicros Discovery boards, such as the STM32F4 Discovery (S4D), offer excellent value for their price.  For example, the S4D sports 1 MB of flash, 192 KB of RAM, six UARTs, and an assortment of other goodies such as DACs, ADCs, I2C, SPI, and CAN.  But the best part is the price of the board; just US$15 each in singles.

Unfortunately, the Discovery boards are some of the most hobbyist-unfriendly boards I've dealt with.  The PCBs are large and contain 100 header pins, arranged as two 2x25 connectors.  The boards are so large, in fact, that they don't fit on most experimenter plug boards, even assuming you could find the proper 2x25 female connectors to isolate the signals when you plug it into your board.

And having all pins from the MCU available might be great for developers, but it can make life tough for the hobbyist.  If you want to test out an idea that only requires a few I/O lines, good luck making a few quick connections easily.

I also wanted to install a minimal set of peripherals on my Discovery boards, using as little external circuitry and connectors as possible.  Finally, the resulting board needed to support my experiments with the eLua programming language.

This page describes my efforts in creating a basic hobbyist configuration for the S4D board.

Step 1: The SD card
It's always nice to have some non-volatile data storage, and adding an SD card through SPI has become pretty standard on large embedded systems.  For this mod, I chose to use a micro-SD adapter as my SD card connector.  I soldered wirewrap wires to the relevant pins on the adapter and ran them to the proper pins on the S4D board.  I then used double-sided foam tape to fasten the adapter to the underside of the S4D board.

If you use a microSD adapter this way, be sure your soldering iron is set to a fairly low termperature, say 700 degF, and don't overheat the connections.  It's easy to leave the iron on the connection point too long and melt the terminal into the adapter's body, ruining the adapter.

Wiring the microSD adapter

My eLua image has support for an SD card already built in.  I just chucked the microSD card into my laptop, formatted it, then moved the card into the microSD adapter on the S4D.  Now I can store programs and data on an 8 GB microSD card.

Here is a PDF of a schematic for my STM32F4 Discovery project.  This schematic replaces my SPI connection table in an earlier version of this page.  Note that this schematic fixes an error in the previous table of connections.  If you couldn't get the SD card to work, update your project per the schematic (replace PB11 with PB13) and you should be golden.  (Actually, I still got it wrong.  Updated the schematic again on 27 Feb 14.  This one should be good.  I mean, there's only about nine wires...)

Here is my Eagle 5.1 device for the STM32F4 Discovery board, used in the above schematic.  Feel free to add this library to your own Eagle library collection.  This is a very simple device, little more than a pad layout and a schematic symbol.  If you expand on this, or fix any errors you might find, please let me know.

Step 2: The UART
eLua wants to use a serial console, either through one of the six available UARTs or through the USB CDC connection.  On the S4D, this CDC connection appears on a USB microB connector, and the default configuration for eLua is CDC.

Unfortunately, my efforts to use USB CDC as a serial console were totally frustrating.  Even finding the STMicros driver for this connection took hours of hunting on the web.  When I finally found what looked like a suitable driver (not on the STMicros site), the installation didn't work on one of my laptops (WinXP, SP3).  I had instead to install the driver on a second laptop (also WinXP, SP3), then copy the installed folder over to the first laptop.

Although I could now use the CDC connection for my console, some combination of the eLua CDC code, the STMicros driver, and my laptop installation made the experience too painful.  Every time I reset my S4D board, TeraTerm would lose contact with the serial device and could not reconnect; the CDC serial port would no longer appear in the TeraTerm drop-down list.  The only way to reconnect with TeraTerm was to exit TeraTerm, reset the board, wait for the OS to discover the serial port, restart TeraTerm, and reconnect to the CDC serial port.

I don't know exactly where the problem lies and I don't care.  I simply wired a serial port connection to the S4D's UART3, recoded eLua to use that serial port rather than CDC, and called it good.

Making the connection to UART3 involved adding a four-pin quick-connect header to the underside of the S4D board.  This connector is wired per the schematic provided above.  I have a cable I made that includes RS-232 level shifters and a matching connector, so I simply plug this cable into my new four-pin header and I have RS-232 comm with the S4D.

The UART connection

Here you can see the UART connectpr (white header) immediately below the microSD adapter on the underside of the S4D board.  I've fastened the UART connector down with hot glue.

Step 3: I/O expansion
The biggest headache with the S4D is accessing the I/O pins easily when you want to try out an idea.  I chose to add five four-pin mini screw-terminal blocks to a piece of perfboard, along with one 2x25 female header.  Plugging this header into the S4D's P1 I/O connector gives me access to 12 selected I/O lines plus several power and ground connections.  The perfboard I used is big enough to take more terminal blocks, but that's all I had in my junkbox at the time.

Closeup of expansion board

I chose a group of I/O pins from the SD4 board.  The pins I selected give me a good mix of A/D inputs, digital I/O, one SPI channel, and one I2C channel, plus an assortment of timer channels.  Feel free to change this list for your needs.

I added labeling to this perfboard so I could quickly determine which connector terminal maps to which I/O pin on the S4D board.  I created a small document in Word and used 6-point Courier bold to label the pins, then cut up the printed page and glued the labels to the perfboard with white glue.

S4D board with expansion

Here's a picture of my S4D board with the attached expansion board.  As mentioned above, I have plans to add more terminal blocks for extra I/O, but this is a good start.

The first test
I already had some eLua code for playing with the G35 RGB LED Christmas lights.  I edited that program to use PB2 as the G35 network data line.  Using a small screwdriver, I connected my G35 network wire to a GND terminal and the PB2 terminal on my expansion board, then powered up the G35 string.  When I executed the G35 test program in eLua, the string of lights lit right up.  Total time to make the I/O connections: about ten seconds.

More info
As you can see in the photos, I made my connections to the S4D I/O pins using 30 AWG wirewrap wire.  Note that the pins on the S4D connectors do NOT have square corners and will NOT make a gas-tight connection if you wrap to them!  To be safe, add a bit of solder on each wrap after you are sure you have the right connection.

My expansion board connects to the 3 VDC output on the S4D board, which means that all of the peripherals I connect to my board are limited to 3 VDC.  If you need to use 5 VDC peripherals, you can tie into the 5 VDC output on the S4D board, but make sure any I/O line you connect to is 5V-tolerant.

Other pages on my site that describe using eLua on a Discovery board expect the serial console on UART2.  The above descriptions that mention UART3 are not an error; I am using (yet another) custom eLua image for my STM32F4 Discovery board.  The only reason I changed UARTs was to leave access to the UART2 Rx and Tx pins empty, should I want to use them later.  If you are using the other eLua image, you won't have any problems.  Just select whatever I/O pins you want to use and wire up your expansion board accordingly.