Sunday, December 22, 2013

Balsamo Reloaded

A whole lot of time ago, I started a homebrew project called Balsamo: a gadget to block unwanted calls on standard PSTN lines. The first revision of Balsamo (Rev.A) featured a FSK decoder and an implementation of the CID protocols needed to obtain the caller number (and also to get the date and time). Caller number was printed on the LCD, and if it was inside a blacklist (stored in the microcontroller internal Flash memory), Balsamo picked up the call and hung it a second later. It worked well, but I wanted to make a lot more improvements. Unfortunately I didn't have the time to work in this project until recently. I have made a new PCB (Rev.B) and added a lot of improvements. Here comes Balsamo Reloaded (or just Balsamo Rev.B):

The heart of the system is the same: a dsPIC30F6014, a 2x16 LCD, some analog chips (amplifiers and a linear regulator) and some more discrete components. The RS-232 serial port connector and the level transtator have been removed (I used them only for debugging), but a lot more things have been added. Balsamo's features are:

  • Caller ID (CID) decoding. Decoding is done entirely inside the dsPIC. No external CID decoder has been used.
  • Capability to blacklist/whitelist calls, based on caller's number and on whether the caller number is private/hidden.
  • Both blacklist/whitelist modes are supported. Also private/hidden calls can be configured to be allowed or blocked.
  • FAT formatted microSD card support. The microSD card holds the configuration file (that includes the blacklist/whitelist), the RAW audio files played when a call is rejected, and the call log file.
  • Now when a call is rejected, an audio message is played, to inform the caller about why the call has been rejected.
  • Two different audio messages can be played to the caller: one for blocked numbers (blacklisted or not in the whitelist) and the other for blocked private/hidden calls.
  • Logs to microSD card all the calls, and the action performed for each of them (ALLOW/BLOCK).
  • Clock function. The user has only to set the year. All the other date/time parameters are automatically set each time a call is received (they are extracted from the CID data).
  • Simple user interface with a 2x16 LCD, 4 LEDs and 5 pushbuttons (only 4 of them are used so far: up, down, enter, esc). The user interface is complete and easy to use: you can add/remove numbers to the blacklist/whitelist, enable/disable the call filter, browse the list, browse recent calls, add recent calling numbers to the list, etc.
  • Low power design: the system drains 4.4 mA while idle (most of the time, while waiting for a call) and around 20 mA when active. The design is entirely 3.3 V, but uses a low drop-out input regulator to be able to use a wide input voltage range.
  • Backup battery capability: the PCB allows for a battery to be used along with a wall AC adapter. If there is a power fail, the backup battery allows the system to continue working until power is restored.
The new PCB has been designed using the GPL licensed gEDA suite. Schematics have been drawn with gschem and PCB has been routed with PCB. This is the first time I seriously use PCB, and the learning curve is really steep, but I'm pretty pleased with the results. I also tested KiCad and Eagle (warning, the last one is not free), but I find PCB more professional (and also harder to learn). I have used its experimental (and buggy) toporouter and I really like the way it draws tracks, in any angle, with curved corners and minimizing track length. Too bad it needs a lot of polish. For the track to pin connections, I have used the Teardrops plugin by DJ Delorie.

You will not find any digital chips in the design, other than the dsPIC and the LCD. The dsPIC does almost all the work, there is no external ADC, DAC, SD/FAT controller, CID decoder, etc. Only a dsPIC, some analog chips and discrete parts. FSK signal is sampled using the internal 12-bit ADC inside the dsPIC, and audio messages are played using a 32 kHz PWM signal. SD card FAT filesystem is handled by the impressive FatFs by Elm Chan software implementation.

Another addition to the Rev.B PCB is an audio amplifier. It can drive a small speaker. The amplifier has been tested and works, but it is still unused. It might be used in the future to play acoustic notifications when a call is blocked, and to implement answering machine capabilities (to play recorded messages). There are also plenty pins available to hack and extend the board functionality, including two UARTs, an SPI bus and an I2C bus, but I don't think I'll need them in the future.

Now this is where a video of the gadget working would be nice. Unfortunately I don't want to mess right now with video editing for removing real telephone numbers and that kind of stuff, so we will have to forget about it (at least until I get the time and motivation).

You can find a lot more information about this project, along with the source code, design files (schematics and PCB), GERBER files, etc. on my Balsamo GitHub repository. Everything is GPLv3+ licensed, so feel free to grab and modify it as you wish.

Happy hacking!

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!