Environment setup

This page describes setting up a simple cross-compiling environment for the STM32F401, STM32F405 and STM32F103 on a linux system.

If altering and compiling the firmware yourself is not a requirement, I recommend you use the precompiled binary (the file with the suffix .bin) included in the zips in the Downloads-section. To program the STM32F401 simply copy this file to the USB-drive that appears when attaching the nucleo-board.

The following steps yields an environment for coding with your text-editor of choice be it vi, emacs, gedit or notepad, and compiling from the terminal with make.

  • Download the gcc-arm-none-eabi cross-compiler. Unzip to a directory, and add the compiler to path by adding this line to .bashrc:
    export PATH=/home/user/gcc-arm-none-eabi-4_9-2015q1/bin:$PATH


  • Download and unzip the standard peripherals library (SPL) for the STM32F4.
  • Set the correct HSE-value in:

    On the nucleo F401RE that I have X1 is 8.000MHz, so I would change HSE from 25000000 to 8000000.

  • Download the TCD1304-driver firmware for the Nucleo F401RE and unzip to the directory the SPL unzipped to.

Copy the entire directory for every new project to ensure the MCU’s clock doesn’t get messed up. Don’t forget to edit the makefile in case you add or remove .c files in the src directory. Notice that as of sep. 10th 2016 the STM32F401RE clock settings have been updated, notably the timer clocks which are now 84 MHz before prescaling.


  • Download and unzip the STM32 SPL USB OTG host and device library.
  • Download the TCD1304-driver firmware for the F405 and place the zip-file in the above directory and unzip.
  • Set the correct HSE-value in:
  • Modify this file:

    Specifically line 98. Change the declaration of *pIf_DataTx from
    uint16_t (*pIf_DataTx) (void);
    uint16_t (*pIf_DataTx) (uint8_t* Buf, uint32_t Len);


The most obvious thing to change is the CCD clock. Edit main.h and change the defines. Type ‘make clean’ and ‘make’ in the directory of the makefile.

The original posts at erossel.wordpress.com :
Programming an ARM-processor (I)
Programming an ARM-processor (II)

The A is for asynchronous