2012-09-24

Revealing hidden awesomeness of the TI MSP430 LaunchPad

TI (Texas Instruments) is awesome, I've always known it. What I like the most is their extremely low-cost ($4.30, who beats that?) Launchpad development kit that includes 2 "value line" (pronounced "super-cheap") micro-controllers, USB programmer and development software. That is everything you need to dive into the wonderful world of the super-lower-power microcontrollers.


Picking the test project
There are so many options for the first project: flashing LED, doomsday device, iSomething…
Hm, iSomething sounds like a cool idea. How about making a poor-guy MP3 player? Maybe downgraded to the extreme: one song, poor audio quality, no control buttons?
To make digital audio player we need two major components: storage memory for digital audio and Digital-to-Analog  Converter (DAC). Expectedly, such a simple microcontroller does not have a built-in DAC, so sounds like I would need a separate chip. But wait,

Who needs a DAC for lousy quality audio?
There is an easy alternative to DAC – Pulse Width Modulation (PWM). The idea is to generate audio signal with variable-width digital pulses, with high enough pulse frequency it should produce acceptable quality audio. Sure enough TI has an application note to demonstrate exactly that (PWM for audio application). Since I decided not to worry about audio quality, I picked 8 bit for audio resolution (as a side note - it is supposed to be roughly equal to AM radio quality). 8 bit resolution gives me 256 possible PWM widths (for example, value 10 means that output stays on for 10 cycles and after that turns off for 255-10=245 cycles).
Assuming that my TI chip runs at the max speed (16 MHz) my complete PWM cycle would be: 16,000,000Hz/256=62,500 Hz. Wow, at such high PWM frequency I should be able to generate sound with frequencies up to 62,500Hz/2=31,250 Hz (this calculation is based on Whittaker–Nyquist–Kotelnikov–Shannon sampling theorem). But it also means that I have to store 31,250 bytes of data for 1 second of music. Where am I going to store my music?

External storage
MSP430G2231 only has 2KB of memory. Because I need 31,250 bytes to store 1 second of music, I could store the whole 0.06 seconds using internal storage. This is definitely not enough. Well, it just means that I need an external storage. How about  SD/MMC Card? It is a perfect external storage for microcontrollers because it is inexpensive and supports very microcontroller friendly SPI protocol. The Launchpad came with 2 chips: MSP430G2211 and MSP430G2231 the latest has built-in universal serial interface that supports SPI protocol, perfect! And of course after checking TI website, I found this application note to interface between MSP430 and SD Card. Now I need to decide how to store the music.

Audio format battle: mp3 vs au
It would be really cool to play mp3 files on the Launchpad, but it's not going to work. For example, the smallest Helix mp3 decoder needs ~20K of program memory, and my microcontroller has only 2K. Of course I could add an external mp3 decoder - but that's not fun.
Since mp3 is not going to work, I could just write audio as a stream of samples (bytes) and add simple header to tell how many samples in my file, sample rate, etc. But it would be nice to use a standard audio file format, so I choose arguably the simplest audio file format ever created: au format. Even it is a quite old format, but still is supported by many applications including my favorite (open source) audio editor – audacity.

Getting audio file to the SD card
To store file to a SD card is also tricky. For multiple reasons I decided not to use a file system on the SD card, so I have to write .au file to the card as a raw data. This could be done by HDD imaging tools, I had good experience with DiskImage, although other disk imaging software (such as dd) should work.

Hardware
There are only two external components to the Launchpad used: SD card and earbuds headphone. I connected SD card power to one of the Launchpad pins, so I can reset the card by toggling its power. Earbuds headphone connected to the Launchpad PWM output pin through a current limiting resistor. "But where is your low-pass filter?" curious reader will ask. Well, yes, I should be using a low-pass filter to smooth-out PWM pulses. But headphones work well enough as a low-pass filter due to their mechanical nature. So, cancel the filter and connect everything together!

SD card access time issue
After fixing a few software bugs I finally heard something in the headphones. It was sort-of a music, but with some strange clicking noise. Such a disappointment! I though I was done with it.
It turned out that data on the SD card stored in 512 byte blocks and sometimes switching these blocks takes some time, so every so often I was missing a few samples and it caused those clicks. I added a small (16 samples) FIFO buffer between SD card and PWM. Buffer made its magic and I was enjoying AM quality music for a whole 15 minutes or so.

Conclusion
It's totally possible to play an acceptable quality audio using the most basic microcontroller. Sample rate could be pretty high (~31kHz in my case) and allows to achieve a much better audio quality, although PWM resolution (8 bit) is a limiting factor.
One of the options to drastically improve audio quality would be to use two independent 8 bit PWMs and summing up their signals. This would increase audio resolution to 16 bits which should sound (almost) like a CD quality. Although, MSP430G2231 has only one PWM channel, so it's not an option here.

Video
Here is a video of the Launchpad playing (kind of) music, enjoy.



Source Code
Grab it here.