Automation
(Last updated: Thursday, February 24, 2011)
TI MSP430 Notes
I have a large number of micro-controllers but I've been picking up more of the TI MSP430 chips to work with. Currently I have the EZ430-T2012, EZ430-T2013, LaunchPad, EZ430-RF2500 kits and 2 boards from Sparkfun/Olimex (the F1121A and the F1231).
The whole kit and kaboodle under Linux
Date: February 24, 2011
There are several parts to setting up and using GCC for the TI MSP430 processors. If you can't find ready made packages you will have to download and compile them yourself. This requires that you have GIT, the C development packages, Autoconfig and other tools to compile the MSP packages.
Things you'll need
- MSP430 processor board
- MSP430 JTAG or SPY-BI-Wire kit
- MSPGCC suite
- MSPDebug suite
Hardware
TI makes it easy to get started. They have the EZ430-T2013 Dev Kit, the EZ430-RF2500 Dev Kit and the LaunchPad Dev Kit. Each of these will give you a USB interface to program the device and a processor to work with.
MSPGCC 4
git clone git://mspgcc4.git.sourceforge.net/gitroot/mspgcc4/mspgcc4
cd mspgcc4 && perl buildgcc.pl
MSPDebug
MSPDebug
cd /opt/mspgcc/bin
get http://www.soft-switch.org/downloads/mspgcc/msp430-gdbproxy
chmod 777 msp430-gdbproxy
cd /usr/lib
sudo wget http://www.soft-switch.org/downloads/mspgcc/libHIL.so
sudo wget http://www.soft-switch.org/downloads/mspgcc/libMSP430.so
Build Project Code, download and debug
Below you will find a Makefile that I use to compile the TI C code (below) with MSPGCC 4. Note that I've added the PATH to the Makefile. I did this because I support many processors and develeopment environments. This reduces the length of my shell PATH. Also note the indentation used on the Makefile. It's indented with tabs (^I, 0x08, etc. - a real tab) and not spaces. This gets a lot of new users of make. If you should uses spaces instead of a tab you may see the following error:
$ make -f Makefile.ta_01 test
Makefile.ta_01:31: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.
Makefile
# ------------------------------------------------------------------------------
#
NOM=msp430x20x3_ta_01
#
CC=msp430-gcc
#
MCU=mcu=msp430x2012
MSPPATH=/opt/msp430-gcc-4.4.5
CFLAGS=-Os -Wall -g -m$(MCU) -I$(MSPPATH)/include/ -I$(MSPPATH)/include/msp430/ -D__MSP430_2012__
OBJS=$(NOM).o
PATH := ${PATH}:${MSPPATH}/bin
# ------------------------------------------------------------------------------
#all:
all: $(OBJS)
$(CC) $(CFLAGS) -o $(NOM).elf $(OBJS)
%.o: %.c
$(CC) $(CFLAGS) -c $<
asm:
$(CC) -S -g -m$(MCU) -I$(MSPPATH)/include/ -I$(MSPPATH)/include/msp430/ -D__MSP430_2012__ $(NOM).c -o $(NOM).a
clean:
rm -fr $(NOM).elf core *~ foo bar $(OBJS)
# -[ Fini ]---------------------------------------------------------------------
$ make -f Makefile.ta_01
msp430-gcc -Os -Wall -g -mmcu=msp430x2012 -I/opt/msp430-gcc-4.4.5/include/ \
-I/opt/msp430-gcc-4.4.5/include/msp430/ -D__MSP430_2012__ -c msp430x20x3_ta_01.c
msp430x20x3_ta_01.c:29: warning: return type of ‘main’ is not ‘int’
msp430-gcc -Os -Wall -g -mmcu=msp430x2012 -I/opt/msp430-gcc-4.4.5/include/ \
-I/opt/msp430-gcc-4.4.5/include/msp430/ -D__MSP430_2012__ \
-o msp430x20x3_ta_01.elf msp430x20x3_ta_01.o
Sample C code
This sampel code is taken from TI's slac080h.zip (found on this TI MSP430F2012 page)
//******************************************************************************
// MSP430F20xx Demo - Timer_A, Toggle P1.0, CCR0 Cont. Mode ISR, DCO SMCLK
//
// Description: Toggle P1.0 using software and TA_0 ISR. Toggles every
// 50000 SMCLK cycles. SMCLK provides clock source for TACLK.
// During the TA_0 ISR, P1.0 is toggled and 50000 clock cycles are added to
// CCR0. TA_0 ISR is triggered every 50000 cycles. CPU is normally off and
// used only during TA_ISR.
// ACLK = n/a, MCLK = SMCLK = TACLK = default DCO
//
// MSP430F20xx
// ---------------
// /|\| XIN|-
// | | |
// --|RST XOUT|-
// | |
// | P1.0|-->LED
//
// M. Buccini / L. Westlund
// Texas Instruments Inc.
// October 2005
// Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.40A
//******************************************************************************
//#include // Included in io.h & cpu defined on the CLI
#include
#include
void main(void) {
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P1DIR |= 0x01; // P1.0 output (our LED)
CCTL0 = CCIE; // CCR0 interrupt enabled
CCR0 = 50000;
TACTL = TASSEL_2 + MC_2; // SMCLK, contmode
_BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt
}
// Timer A0 interrupt service routine
// TI's CCE
// #pragma vector=TIMERA0_VECTOR
// __interrupt void Timer_A (void) {
// GCC
interrupt(TIMERA0_VECTOR) TIMERA0_ISR(void) {
P1OUT ^= 0x01; // Toggle P1.0
CCR0 += 50000; // Add Offset to CCR0
}
Sample Assembly code
.file "msp430x20x3_ta_01.c"
.arch msp430x2012
.section .debug_abbrev,"",@progbits
.Ldebug_abbrev0:
.section .debug_info,"",@progbits
.Ldebug_info0:
.section .debug_line,"",@progbits
.Ldebug_line0:
.text
.Ltext0:
.p2align 1,0
.global main
.type main,@function
/***********************
* Function `main'
***********************/
main:
.LFB0:
.file 1 "msp430x20x3_ta_01.c"
.loc 1 29 0
mov #__stack, r1
mov r1, r4
.LCFI0:
/* prologue ends here (frame size = 0) */
.L__FrameSize_main=0x0
.L__FrameOffset_main=0x2
.loc 1 30 0
mov #23168, &0x0120
.loc 1 31 0
mov.b &0x0022, r15
bis.b #1, r15
mov.b r15, &0x0022
.loc 1 32 0
mov #16, &0x0162
.loc 1 33 0
mov #llo(-15536), &0x0172
.loc 1 34 0
mov #544, &0x0160
.loc 1 36 0
/* #APP */
; 36 "msp430x20x3_ta_01.c" 1
bis #24, r2
; 0 "" 2
/* epilogue: frame size = 0 */
.loc 1 37 0
/* #NOAPP */
br #__stop_progExec__
.LFE0:
.Lfe1:
.size main,.Lfe1-main
;; End of function
.p2align 1,0
.global TIMERA0_ISR
.global vector_fff2
.type TIMERA0_ISR,@function
/***********************
* Interrupt Service Routine `TIMERA0_ISR' at 0xfff2
***********************/
vector_fff2:
TIMERA0_ISR:
.LFB1:
.loc 1 44 0
push r15
.LCFI1:
push r4
.LCFI2:
mov r1, r4
.LCFI3:
/* prologue ends here (frame size = 0) */
.L__FrameSize_TIMERA0_ISR=0x0
.L__FrameOffset_TIMERA0_ISR=0x4
.loc 1 45 0
mov.b &0x0021, r15
xor.b #1, r15
mov.b r15, &0x0021
.loc 1 46 0
mov &0x0172, r15
add #llo(-15536), r15
mov r15, &0x0172
/* epilogue: frame size = 0 */
.loc 1 47 0
pop r4
pop r15
reti
.LFE1:
.Lfe2:
.size TIMERA0_ISR,.Lfe2-TIMERA0_ISR
;; End of function
.section .debug_frame,"",@progbits
.Lframe0:
.4byte .LECIE0-.LSCIE0
.LSCIE0:
.4byte 0xffffffff
.byte 0x1
.string ""
.uleb128 0x1
.sleb128 -2
.byte 0x11
.byte 0xc
.uleb128 0x1
.uleb128 0x2
.byte 0x11
.uleb128 0x11
.sleb128 1
.p2align 1,0
.LECIE0:
.LSFDE0:
.4byte .LEFDE0-.LASFDE0
.LASFDE0:
.4byte .Lframe0
.2byte .LFB0
.2byte .LFE0-.LFB0
.byte 0x4
.4byte .LCFI0-.LFB0
.byte 0xd
.uleb128 0x4
.p2align 1,0
.LEFDE0:
.LSFDE2:
.4byte .LEFDE2-.LASFDE2
.LASFDE2:
.4byte .Lframe0
.2byte .LFB1
.2byte .LFE1-.LFB1
.byte 0x4
.4byte .LCFI1-.LFB1
.byte 0xe
.uleb128 0x4
.byte 0x4
.4byte .LCFI2-.LCFI1
.byte 0xe
.uleb128 0x6
.byte 0x11
.uleb128 0x4
.sleb128 3
.byte 0x11
.uleb128 0xf
.sleb128 2
.byte 0x4
.4byte .LCFI3-.LCFI2
.byte 0xd
.uleb128 0x4
.p2align 1,0
.LEFDE2:
.text
.Letext0:
.section .debug_loc,"",@progbits
.Ldebug_loc0:
.LLST0:
.2byte .LFB0-.Ltext0
.2byte .LCFI0-.Ltext0
.2byte 0x2
.byte 0x71
.sleb128 2
.2byte .LCFI0-.Ltext0
.2byte .LFE0-.Ltext0
.2byte 0x2
.byte 0x74
.sleb128 2
.2byte 0x0
.2byte 0x0
.LLST1:
.2byte .LFB1-.Ltext0
.2byte .LCFI1-.Ltext0
.2byte 0x2
.byte 0x71
.sleb128 2
.2byte .LCFI1-.Ltext0
.2byte .LCFI2-.Ltext0
.2byte 0x2
.byte 0x71
.sleb128 4
.2byte .LCFI2-.Ltext0
.2byte .LCFI3-.Ltext0
.2byte 0x2
.byte 0x71
.sleb128 6
.2byte .LCFI3-.Ltext0
.2byte .LFE1-.Ltext0
.2byte 0x2
.byte 0x74
.sleb128 6
.2byte 0x0
.2byte 0x0
.file 2 "/opt/crosstool/msp430-gcc-4.4.5/bin/../lib/gcc/msp430/4.4.5/../../../../msp430/include/msp430x20x2.h"
.section .debug_info
.4byte 0xee
.2byte 0x2
.4byte .Ldebug_abbrev0
.byte 0x2
.uleb128 0x1
.4byte .LASF21
.byte 0x1
.4byte .LASF22
.4byte .LASF23
.2byte .Ltext0
.2byte .Letext0
.4byte .Ldebug_line0
.uleb128 0x2
.byte 0x1
.byte 0x6
.4byte .LASF0
.uleb128 0x2
.byte 0x1
.byte 0x8
.4byte .LASF1
.uleb128 0x3
.byte 0x2
.byte 0x5
.string "int"
.uleb128 0x2
.byte 0x2
.byte 0x7
.4byte .LASF2
.uleb128 0x2
.byte 0x4
.byte 0x5
.4byte .LASF3
.uleb128 0x2
.byte 0x4
.byte 0x7
.4byte .LASF4
.uleb128 0x2
.byte 0x8
.byte 0x5
.4byte .LASF5
.uleb128 0x2
.byte 0x8
.byte 0x7
.4byte .LASF6
.uleb128 0x4
.byte 0x1
.4byte .LASF7
.byte 0x1
.byte 0x1d
.byte 0x1
.2byte .LFB0
.2byte .LFE0
.4byte .LLST0
.uleb128 0x4
.byte 0x1
.4byte .LASF8
.byte 0x1
.byte 0x2c
.byte 0x1
.2byte .LFB1
.2byte .LFE1
.4byte .LLST1
.uleb128 0x5
.4byte .LASF9
.byte 0x2
.2byte 0x184
.4byte .LASF11
.4byte 0x8d
.byte 0x1
.byte 0x1
.uleb128 0x6
.4byte 0x28
.uleb128 0x5
.4byte .LASF10
.byte 0x2
.2byte 0x186
.4byte .LASF12
.4byte 0x8d
.byte 0x1
.byte 0x1
.uleb128 0x5
.4byte .LASF13
.byte 0x2
.2byte 0x1ab
.4byte .LASF14
.4byte 0xb6
.byte 0x1
.byte 0x1
.uleb128 0x6
.4byte 0x36
.uleb128 0x5
.4byte .LASF15
.byte 0x2
.2byte 0x1ad
.4byte .LASF16
.4byte 0xb6
.byte 0x1
.byte 0x1
.uleb128 0x5
.4byte .LASF17
.byte 0x2
.2byte 0x1b3
.4byte .LASF18
.4byte 0xb6
.byte 0x1
.byte 0x1
.uleb128 0x5
.4byte .LASF19
.byte 0x2
.2byte 0x254
.4byte .LASF20
.4byte 0xb6
.byte 0x1
.byte 0x1
.byte 0x0
.section .debug_abbrev
.uleb128 0x1
.uleb128 0x11
.byte 0x1
.uleb128 0x25
.uleb128 0xe
.uleb128 0x13
.uleb128 0xb
.uleb128 0x3
.uleb128 0xe
.uleb128 0x1b
.uleb128 0xe
.uleb128 0x11
.uleb128 0x1
.uleb128 0x12
.uleb128 0x1
.uleb128 0x10
.uleb128 0x6
.byte 0x0
.byte 0x0
.uleb128 0x2
.uleb128 0x24
.byte 0x0
.uleb128 0xb
.uleb128 0xb
.uleb128 0x3e
.uleb128 0xb
.uleb128 0x3
.uleb128 0xe
.byte 0x0
.byte 0x0
.uleb128 0x3
.uleb128 0x24
.byte 0x0
.uleb128 0xb
.uleb128 0xb
.uleb128 0x3e
.uleb128 0xb
.uleb128 0x3
.uleb128 0x8
.byte 0x0
.byte 0x0
.uleb128 0x4
.uleb128 0x2e
.byte 0x0
.uleb128 0x3f
.uleb128 0xc
.uleb128 0x3
.uleb128 0xe
.uleb128 0x3a
.uleb128 0xb
.uleb128 0x3b
.uleb128 0xb
.uleb128 0x27
.uleb128 0xc
.uleb128 0x11
.uleb128 0x1
.uleb128 0x12
.uleb128 0x1
.uleb128 0x40
.uleb128 0x6
.byte 0x0
.byte 0x0
.uleb128 0x5
.uleb128 0x34
.byte 0x0
.uleb128 0x3
.uleb128 0xe
.uleb128 0x3a
.uleb128 0xb
.uleb128 0x3b
.uleb128 0x5
.uleb128 0x2007
.uleb128 0xe
.uleb128 0x49
.uleb128 0x13
.uleb128 0x3f
.uleb128 0xc
.uleb128 0x3c
.uleb128 0xc
.byte 0x0
.byte 0x0
.uleb128 0x6
.uleb128 0x35
.byte 0x0
.uleb128 0x49
.uleb128 0x13
.byte 0x0
.byte 0x0
.byte 0x0
.section .debug_pubnames,"",@progbits
.4byte 0x27
.2byte 0x2
.4byte .Ldebug_info0
.4byte 0xf2
.4byte 0x59
.string "main"
.4byte 0x6a
.string "TIMERA0_ISR"
.4byte 0x0
.section .debug_aranges,"",@progbits
.4byte 0x10
.2byte 0x2
.4byte .Ldebug_info0
.byte 0x2
.byte 0x0
.2byte .Ltext0
.2byte .Letext0-.Ltext0
.2byte 0x0
.2byte 0x0
.section .debug_str,"MS",@progbits,1
.LASF5:
.string "long long int"
.LASF2:
.string "unsigned int"
.LASF14:
.string "*0x0160"
.LASF11:
.string "*0x0021"
.LASF12:
.string "*0x0022"
.LASF7:
.string "main"
.LASF10:
.string "P1DIR"
.LASF16:
.string "*0x0162"
.LASF13:
.string "TACTL"
.LASF4:
.string "long unsigned int"
.LASF6:
.string "long long unsigned int"
.LASF15:
.string "TACCTL0"
.LASF18:
.string "*0x0172"
.LASF1:
.string "unsigned char"
.LASF21:
.string "GNU C 4.4.5"
.LASF22:
.string "msp430x20x3_ta_01.c"
.LASF8:
.string "TIMERA0_ISR"
.LASF17:
.string "TACCR0"
.LASF23:
.string "/home/njc/dev/msp430"
.LASF3:
.string "long int"
.LASF19:
.string "WDTCTL"
.LASF20:
.string "*0x0120"
.LASF0:
.string "signed char"
.LASF9:
.string "P1OUT"
/*********************************************************************
* File msp430x20x3_ta_01.c: code size: 13 words (0xd)
* incl. words in prologues: 6, epilogues: 7
*********************************************************************/
Links
- TI MSP430™ - 16-bit Ultra-Low Power MCUs
- MSPGCC4 - GCC 4.x toolchain for Texas Instruments MSP430 MCUs
- MSPDebug is a free debugger for use with MSP430 MCUs. It supports FET430UIF, eZ430, RF2500 and Olimex MSP-JTAG-TINY programmers. It can be used as a proxy for gdb or as an independent debugger with support for programming, disassembly and reverse engineering.