Sunday, January 27, 2013

CMSIS DSP Software Library

We all know the real fun when working with microcontrollers, is interfacing the real world. Sometimes, you only need to read some pushbuttons and drive some LEDs. But now you have a powerful ARM 32-bit, 80 MHz, FPU enabled microcontroller. Sure you can do more complex things than driving LEDs. You can, for example, connect a microphone to the ADC and do some audio signal processing. You could build a frequency analyzer, like the nice one EuphonistiHack made some time ago.

If you want to do some signal processing, you'll be happy to read, there's an open library containing over 60 signal processing functions, including FIR and IIR filters, FFT, convolution, etc. This library is part of CMSIS (Cortex Microcontroller Software Interface Standard), and is called CMSIS DSP Software Library (we will call it CMSIS DSPLib or just DSPLib for short).

Building CMSIS DSPLib

  1. The first step is downloading the library. Go to the ARM website and clic the "Download CMSIS" tab. You need an ARM account to access the downloads, so if you don't have one, register first. Then access the download. At the time of writing this tutorial, CMSIS version is 3.0.
  2. Once downloaded, extract the contents to "~/src/stellaris/cmsis-src". If you did it right, inside the "cmsis-src" directory you should have the directories CMSIS, Device and packages, and the file Version 3.00 (or whatever version it is the library you downloaded). DSPLib already comes with some projects for building it using Keil uVision IDE and some compilers (including GCC). But to use these projects, you need a Windows machine, and of course a copy of Keil uVision IDE. If you want to build the library using Code Composer Studio, there's also an application note with a step by step guide. Be warned it is a bit outdated though, and some CCS dialogs have changed and will require you to guess what are the correct options.
  3. To build the library under GNU/Linux using GCC, I have coded some makefiles. The first one has some common definitions. The second one is the top level makefile, that will call the bottom level makefiles. You have to download and copy them to the right locations:
cd ~/src/stellaris/cmsis-src/CMSIS
wget -O
wget -O Makefile
cd DSP_Lib/Source
wget -O Makefile
cp Makefile BasicMathFunctions
cp Makefile CommonTables
cp Makefile ComplexMathFunctions
cp Makefile ControllerFunctions
cp Makefile FastMathFunctions
cp Makefile FilteringFunctions
cp Makefile MatrixFunctions
cp Makefile StatisticsFunctions
cp Makefile SupportFunctions
mv Makefile TransformFunctions
  1. Supposing you have already set-up the toolchain, we can start building the library now:
cd ~/src/stellaris/cmsis-src/CMSIS
And that's all. Easy, right? When make finishes doing its magic, the library should be sitting at "~/src/stellaris/cmsis-src/CMSIS/Lib/libdsplib_lm4f.a". We can test it building an example.


Once the library is built, using DSPLib is very easy. You have just to add the include directory and the library file and path to your project/makefile. You can test the library with the included examples under "~/src/stellaris/cmsis-src/CMSIS/DSP_Lib/Examples". I'll tell you how to build "arm-fir-example" (a FIR filter example) using Eclipse.
  1. Create a new project. Complete the first 3 steps detailed here.
  2. When doing step 4, replace "template" with "arm-fir-example" and continue until step 7.
  3. When doing step 7, also add the symbol __FPU_PRESENT
  4. Then jump to step 8, and also add the path to the CMSIS headers. It should be in the "src/stellaris/cmsis-src/CMSIS/Include" directory, under your home:
  1. Continue until step 10. In step 10 also add "m" and "dsplib_lm4f" to libraries. Then add the path to the CMSIS DSPLib library ("src/stellaris/cmsis-src/CMSIS/Lib" under your home):
  1. Continue until step 16. For the step 16, copy the files required for startup, but don't copy main.c. We will replace it with arm-fir-example.c. We will also have to copy the math_helper files:
cd ~/src/stellaris/stellaris-launchpad-template-gcc
cp LM4F.ld LM4F_startup.c ../projects/arm-fir-example
cd ~/src/stellaris/cmsis-src/CMSIS/DSP_Lib/Examples
cp arm_fir_example/*.c ~/src/stellaris/projects/arm-fir-example
cp Common/Source/math_helper.c Common/Include/math_helper.h ~/src/stellaris/projects/arm-fir-example
  1. Complete the tutorial, but each time it tells you to enter "template", replace it with "arm-fir-example". Before building and debugging the code, you will have to do just one modification to the "arm_fir_example_f32.c" file. Scompo's startup code doesn't initialize the FPU, so we will have to do it ourselves. Open "arm_fir_example_f32.c" and add the following includes after the "#include "math_helper.h" line:
#include <inc/hw_nvic.h>
#include <inc/hw_types.h>
  1. Then add the following code inside the "main()" function, just after the "float32_t *inputF32, *outputF32;" declaration line:
                       ~(NVIC_CPAC_CP10_M | NVIC_CPAC_CP11_M)) |
                      NVIC_CPAC_CP10_FULL | NVIC_CPAC_CP11_FULL);
And that's all. Now you should be able to build and debug the code. You can add a breakpoint at the last line of the main function (the last "while(1)" sentence), and if when you run the program, it stops at the breakpoint, everything went fine. CMSIS DSPLib is working and has passed the test!

This tiny microcontroller is powerful enough to perform some signal processing algorithms that in the past were only possible for DSPs. If you do something interesting with this library, please drop me a comment, I'll be pleased to see your project!