April 2011 Workshop on TI MSP430, part 1
This month, we installed tools to program the TI MSP430 microcontroller.
Local company Texas Instruments makes a nice little microcontroller called the MSP430. It is close to the power of a low end Atmel AVR, but has some advantages. I plan to write a follow up article comparing the microcontrollers. I have been avoiding the msp430 because TI only supports Windows as a development environment and we like to have our workshops support whichever OS participants want to use. Personally, I don’t even use Windows, so I was not interested, anyway. I have been reading lately that there seem to be good working open source solutions that run, at least on Linux. They would probably work on FreeBSD and the Mac. I believe FreeBSD was tested, and I will update this article with results when I get them.
TI has a very inexpensive development board for the MSP430. It is called the Launchpad. It is a lot like an Arduino that someone forgot to put the shield base on. TI sells it for $4.30 plus free shipping at this time. You can order up to 3 boards from TI. Other distributors have it with no limit on the number you can order. We arranged some purchases, so we can all have boards at a future meeting. The plan is to see if we can get the boards before the next meeting after April and build some circuits with the TI chip. This month, we will setup the development environment. If you are using Windows, TI gives you a pointer to free, downloadable tools. You can find it in the TI student guide linked below. The guide also has some exercises, so it is useful for all msp430 beginners. If you are using Linux, the first two links here are to articles about setting up the tool chain. I will use the first one, but the second was tested by someone else at the meeting.
http://www.sakoman.com/OMAP/how-to-develop-msp430-launchpad-code-on-linux.html
http://hackaday.com/2010/08/11/how-to-launchpad-programming-with-linux/
Here is an article on porting Atmel AVR code to the TI msp430.
http://jumptuck.wordpress.com/2010/08/12/porting-avr-code-for-msp430-chips/
Here is a student guide from TI about the Launchpad.
http://software-dl.ti.com/trainingTTO/trainingTTO_public_sw/MSP430_LaunchPad_Workshop/LaunchPad.pdf
Here is a project that built an include file you can use for Arduino programs to let them compile and run on the Launchpad. Not tested yet, but too good not to pass on.
https://github.com/chrishulbert/friendly_launchpad
This is an article showing one way to use the Launchpad with a breadboard. We like breadboarded circuits for our workshops because they are quick to setup and test.
http://www.43oh.com/forum/viewtopic.php?f=8&t=138
The Linux tools run from the command line, so you get to pick your editor. The Linux tools are open source, and don’t have the code size restrictions that you get with the free Windows tools. The free Windows compilers will only create programs up to 2K or 4K in size. Neither limit is a problem for the chips included with the development board. I have seen MSP430 chips with up to 32K of program space, so these chips need the open source tools or a very expensive commercial tool. Being open source gives them a big edge in my mind, but not everyone agrees, I expect.
The Launchpad comes with two 14 pin microcontrollers in DIP form. After programming, they can easily be used in breadboard projects. The Launchpad board can program larger chips. It supports 14 and 20 pin processors. I have not seen any of the 20 pin devices yet, but they do seem to be available for ordering. A 20 pin ZIF socket with long enough pins for breadboard use would be handy to install on a breadboard or the Launchpad board. I am still looking for such sockets at a reasonable price.
I completed the building of the msp430-gcc and mspdebug tools and then tried the blink program in the sakoman article linked above. On my 700 MHz P3, the build took a couple of hours. As you might guess, msp430-gcc is the cross compiler for the msp430. The program mspdebug is useful for uploading code to the Launchpad. Everything worked fine. Once you have these two tools built, we can try putting a program on the msp430. I started with the MSP430G2231. Here is a simple bash script to drive the compile and upload cycle.
#!/bin/sh
die () {
echo >&2 "$@"
exit 1
}
[ "$#" -eq 1 ] || die "1 argument required, $# provided"
/opt/msp430-gcc-4.4.5/bin/msp430-gcc -oS -o launchpad.elf $1.c
echo "return status is " $?
rc=$?
if [[ $rc != 0 ]] ; then
echo "compile failed, rc = " $rc
exit $rc
fi
sudo /usr/local/bin/mspdebug rf2500 "prog launchpad.elf"
Save that as 430cc.sh, and make it executable. Then, to compile and upload the blink.c program, you just have to type: ./430cc.sh blink
A local developer for the msp430 wrote a short program that I think is a better place to begin experimenting with the code, so I will include it here. I only changed the first include statement. The one here is correct for using the msp430-gcc compiler. I don’t know what compiler he used, but I will update this when I find out.
// Changes to the 'demo-breathing-led' code by Rusty Haddock.
// Removed 1-sin(x) data array and now calculate an x^2 curve
// on the fly.
#include <msp430g2231.h>
#include <signal.h>
int idx = 0; // idx to PWM's duty cycle curve (= brightness)
int main(void)
{
// Stop watchdog
WDTCTL = WDTPW + WDTHOLD;
// Set clock to 1 MHz
DCOCTL= 0;
BCSCTL1= CALBC1_1MHZ;
DCOCTL= CALDCO_1MHZ;
// SMCLK = 1 MHz / 8 = 125 KHz (SLAU144E p.5-15)
BCSCTL2 |= DIVS_3;
// Make P1.6 (green led) an output. SLAU144E p.8-3
P1DIR |= BIT6;
// P1.6 = TA0.1 (timer A's output). SLAS694C p.41
P1SEL |= BIT6;
// PWM period = 125 KHz / 625 = 200 Hz
TACCR0 = 625;
// Source Timer A from SMCLK (TASSEL_2), up mode (MC_1).
// Up mode counts up to TACCR0. SLAU144E p.12-20
TACTL = TASSEL_2 | MC_1;
// OUTMOD_7 = Reset/set output when the timer counts to TACCR1/TACCR0
// CCIE = Interrupt when timer counts to TACCR1
TACCTL1 = OUTMOD_7 | CCIE;
// Initial CCR1 (= brightness)
TACCR1 = 0;
// LPM0 (shut down the CPU) with interrupts enabled
__bis_SR_register(CPUOFF | GIE);
// Silly return to make gcc happy
return 0;
}
// This will be called when timer counts to TACCR1.
interrupt(TIMERA1_VECTOR) ta1_isr(void)
{
int new_ccr1 = 1;
static unsigned int next_sqr = 1, sqr_step = 3;
// Clear interrupt flag
TACCTL1 &= ~CCIFG;
new_ccr1 = (next_sqr >> 9) + 1;
if (!(idx++ & 1)) { // send each value twice.
if (idx < 500) {
next_sqr += sqr_step;
sqr_step += 2;
} else if (idx < 1000) {
sqr_step -= 2;
next_sqr -= sqr_step;
} else {
idx = 0;
}
}
// Wait to set the new TACCR1 until TAR has gone past it, so that we
// don't get interrupted again in this period.
while (TAR <= new_ccr1)
;
TACCR1 = new_ccr1;
}
Save that as breathe.c and then run it on your launchpad by typing: ./430cc.sh breathe