MSP430 programming using GCC

We should try to compile some code for the Launchpad using GCC. I have prepared a tutorial project so it is not necessary to type any code – just compile and run it. Let us start by downloading the code. The code resides at GitHub, so we need the git tool to get it.

$ sudo apt-get install git
$ git clone msp430
$ ls msp430
cycle_led_asm  cycle_led_c  LICENSE.TXT

We can see that there are two directories for a project called “Cycle LED”, one using C and one using assembler. We leave the assembler for a coming tutorial, but let us try building the C project.

$ cd msp430/cycle_led_c/
$ make
msp430-gcc  -Os -Wall -g -mmcu=msp430g2553 -c cycle_led.c
msp430-gcc -Os -Wall -g -mmcu=msp430g2553 -o cycle_led.elf cycle_led.o
   text	   data	    bss	    dec	    hex	filename
    218	      0	      2	    220	     dc	cycle_led.elf

If all goes well during the compilation, we see that msp430-gcc has been used to compile cycle_led.c into cycle_led.o, and then to link cycle_led.o into cycle_led.elf. As a final step, I have set up msp430-size to display the size of the executable, 218 bytes of program plus 2 bytes of bss data. The bss section consists of uninitialized file-level variables and static local variables, that will be zero-initialized at runtime.

A couple of comments about some specific lines in the cycle_led.c file:

#include <msp430.h>
#include <isr_compat.h>

The msp430.h file will include a device-specific header file, depending on what the mcu argument is set to on the command line. The isr_compat.h file is included for having a convenient way of defining an interrupt routine. Also, it makes the code more compatible with different compilers, but this is not our main purpose right now.

#define RED_LED   BIT0
#define GREEN_LED BIT6
#define BUTTON    BIT3

Whereas the MSP-EXP430G2 LaunchPad User’s Guide p. 20 says that LED1 (bit 0) is green and LED2 (bit 6) is red, at least on my Launchpad LED1 is the red one and LED2 is the green one.


The MSP430 starts with the watchdog up and running, which will reset the board in 32768 clock cycles. The first thing we should do is reconfigure it or turn it off. Any writes to the watchdog must have a fixed “password” pattern in the upper bits, or the MSP will be reset upon write. (Although I believe it might also be possible to disable the watchdog using a compiler command line argument.)


A change from previous Launchpad versions to version 1.5 is that there is no external pull-up resistor for the push-button. Even though the user’s guide circuit diagram shows an R34 resistor for this purpose, there is no component soldered at R34. It also states in the beginning of the document that it has been removed to reduce power consumption. So instead we need to enable the internal resistor for this I/O pin (using P1REN) and set it to pull the pin high (using P1OUT). At first it seems somewhat counter-intuitive to write to the output for an input pin, but that is how we set the internal resistor to be pull-up or pull-down.

return 0;

We are using the input pin connected to the push-button to generate an interrupt, so we need to enable interrupts. Instead of entering an infinite loop at the end of the program, we can use one of the low-power modes to put the MSP to sleep until it is woken up by an interrupt. As we are not using any clocks for this program, we can use the lowest power mode, LPM4. This mode will then be resumed after an interrupt is handled, unless we change power mode in the interrupt routine, so we will never actually reach the return statement.

ISR(PORT1, button_press) {
  if (P1IFG & BUTTON) {

The MPS430 has a common interrupt vector used for all the I/O pins in port 1, so we should check whether the interrupt occurred from the pin that is connected to the button.

We can now run the compiled code on the Launchpad.

$ mspdebug rf2500
(mspdebug) prog cycle_led.elf
Writing  186 bytes to c000 [section: .text]...
Writing   32 bytes to ffe0 [section: .vectors]...
Done, 218 bytes written
(mspdebug) run
Running. Press Ctrl+C to interrupt...

Now press the left push-button on the Launchpad to see the LEDs light up in sequence: OFF – GREEN – RED – GREEN and RED – OFF. The right button will reset the Launchpad, which will interfere with running the software under a debugger.