MSP430 Assembly Code Examples from Class: Difference between revisions

From Class Wiki
Jump to navigation Jump to search
 
(18 intermediate revisions by the same user not shown)
Line 4: Line 4:
; MSP430 Assembler Code Template for use with TI Code Composer Studio
; MSP430 Assembler Code Template for use with TI Code Composer Studio
;
;
; This is the Fibonacci Sequence Program.
; This is the Fibonacci Sequence Program. f0=0, f1=1, fn=(fn-1)+(fn-2).
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
.cdecls C,LIST,"msp430.h" ; Include device header file
.cdecls C,LIST,"msp430.h" ; Include device header file
Line 58: Line 58:
.short RESET
.short RESET
</nowiki>
</nowiki>

====Stack Manipulation Demonstration====
<nowiki>


;-------------------------------------------------------------------------------
; MSP430 Assembler Code Template for use with TI Code Composer Studio
; This program demonstrates the use of the stack.
; Rob Frohne November, 2015
; This program is to play around and see how the stack is manipulated. Try it!
;-------------------------------------------------------------------------------
.cdecls C,LIST,"msp430.h" ; Include device header file
;-------------------------------------------------------------------------------
.def RESET ; Export program entry-point to
; make it known to linker.
;-------------------------------------------------------------------------------
.text ; Assemble into program memory.
.retain ; Override ELF conditional linking
; and retain current section.
.retainrefs ; And retain any sections that have
; references to current section.

;-------------------------------------------------------------------------------
RESET mov.w #__STACK_END,SP ; Initialize stackpointer
StopWDT mov.w #WDTPW|WDTHOLD,&WDTCTL ; Stop watchdog timer


;-------------------------------------------------------------------------------
; Main loop here
;-------------------------------------------------------------------------------
mov.w #0xffff,r6
mov.w #0x000f,r7
loop1 push r6
dec r7
jnz loop1

mov.w #0x000f,r7
loop2 pop r6
dec r7
jnz loop2

mov.w #0x0004,r4
mov.w #0x0005,r5
mov.b #0xff06,r6
call #subroutine1
mov.w r4,&0x43f2
jmp $

subroutine1 push.w r4
push.w r5
push.b r6
mov.w #0x4444,r4
mov.w #0x5555,r5
mov.w #0x6666,r6
pop.b r6
pop.w r5
pop.w r4
ret


;-------------------------------------------------------------------------------
; Stack Pointer definition
;-------------------------------------------------------------------------------
.global __STACK_END
.sect .stack
;-------------------------------------------------------------------------------
; Interrupt Vectors
;-------------------------------------------------------------------------------
.sect ".reset" ; MSP430 RESET Vector
.short RESET


</nowiki>


====Solutions to Exam 1b from 2015====
<nowiki>;-------------------------------------------------------------------------------
; MSP430 Assembler Code Template for use with TI Code Composer Studio
;
;
;-------------------------------------------------------------------------------
.cdecls C,LIST,"msp430.h" ; Include device header file
;-------------------------------------------------------------------------------
.def RESET ; Export program entry-point to
; make it known to linker.
;-------------------------------------------------------------------------------
.text ; Assemble into program memory.
.retain ; Override ELF conditional linking
; and retain current section.
.retainrefs ; And retain any sections that have
; references to current section.
.global add_32
add1l .word 0xffff ; First addend lower word
add1h .word 0x0003 ; First addend upper word
add2l .word 0x1 ; Second addend lower word
add2h .word 0x0 ; Second addend upper word
;-------------------------------------------------------------------------------
RESET
mov.w #__STACK_END,SP ; Initialize stackpointer
StopWDT mov.w #WDTPW|WDTHOLD,&WDTCTL ; Stop watchdog timer
;Problem statement:
;Write and debug an assembly program for your EXP-MSP430F5529LP launchpad board that does the following:
;The main work will be done in a callee-save subroutine that adds two 32 bit signed integers.
;The addends are stored in little endian format in two sets of two 16 bit variables, called add1l, add1h,
;add2l, add2h, where subscript l denotes the low word and h the high word, and the number denotes which
;addend it is for.
;The addresses of the low words of the addends are to be passed in R14 and R15 to the subroutine.
;The resultant sum in 2's compliment is to be passed back in R15 for the low word, and R14 for the high word.
;The flags should be correct for the 32 bit result after return from the subroutine.
;Comment your program.
;-------------------------------------------------------------------------------
; Main loop here
;-------------------------------------------------------------------------------
mov.w #add1l,r15
mov.w #add2l,r14
call #add_32
jmp $

add_32: ; Adds the 32 bit numbers in addresses in R14 and R15
; Not fully tested.... Make sure you test this yourself and understand what it does.
push.w r13
push.w r12
mov.w @r14+, r13
add.w @r15+, r13
mov.w @r14, r12
addc.w @r15, r12
mov.w r13, r15
mov.w r12, r14
pop.w r12
pop.w r13
ret

;-------------------------------------------------------------------------------
; Stack Pointer definition
;-------------------------------------------------------------------------------
.global __STACK_END
.sect .stack
;-------------------------------------------------------------------------------
; Interrupt Vectors
;-------------------------------------------------------------------------------
.sect ".reset" ; MSP430 RESET Vector
.short RESET
</nowiki>

====Use S2 (P1.1) to turn on and off LED1 (P1.0).====
====Use S2 (P1.1) to turn on and off LED1 (P1.0).====
<nowiki>
<nowiki>
Line 92: Line 243:
on bis.b #BIT0, &P1OUT ; Toggle the LED
on bis.b #BIT0, &P1OUT ; Toggle the LED
jmp loop
jmp loop
off bic.w #BIT0, &P1OUT ; Turn the LED off to start with.
off bic.b #BIT0, &P1OUT ; Turn the LED off to start with.
jmp loop
jmp loop
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
Line 168: Line 319:
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
.text ; Assemble into program memory
.text ; Assemble into program memory
.global RESET ; Remember to set linker option to enter at RESET.
.global RESET ; Remember to set linker option to enter at RESET.
.retain ; Override ELF conditional linking
.retain ; Override ELF conditional linking
; and retain current section
; and retain current section
Line 186: Line 337:
bis.w #TACLR, &TA0CTL ; Clear the timer TAR.
bis.w #TACLR, &TA0CTL ; Clear the timer TAR.
bis.w #TASSEL__ACLK, &TA0CTL ; Use ACLK (32 KHz). This means 2 seconds a period.
bis.w #TASSEL__ACLK, &TA0CTL ; Use ACLK (32 KHz). This means 2 seconds a period.
bic.w #ID0|ID1, &TA0CTL ; Divide by 4.
bic.w #ID0|ID1, &TA0CTL ; Divide by 1.
bic.w #TAIFG, &TA0CTL ; Clear the interrupt flag.
bic.w #TAIFG, &TA0CTL ; Clear the interrupt flag.
bis.w #MC0, &TA0CTL ; Set timer mode to count to TA0CCR0.
bis.w #MC0, &TA0CTL ; Set timer mode to count to TA0CCR0.
Line 218: Line 369:
.end
.end
</nowiki>
</nowiki>

====Change the Blink Period of an LED running on Timer TA0, Using Interrupts on P1.1 (S2)====
====Change the Blink Period of an LED running on Timer TA0, Using Interrupts on P1.1 (S2)====
<nowiki>
<nowiki>
Line 232: Line 384:
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
.text ; Assemble into program memory
.text ; Assemble into program memory
.global RESET ; Remember to set linker option to enter at RESET.
.global RESET ; Remember to set linker option to enter at RESET.
.retain ; Override ELF conditional linking
.retain ; Override ELF conditional linking
; and retain current section
; and retain current section
Line 245: Line 397:
; Main loop here
; Main loop here
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
bis.b #BIT0, &P1DIR ; Set the LED at P1.0 as output.
bis.b #BIT0, &P1DIR ; Set the LED at P1.0 as output.
bic.b #BIT0, &P1OUT ; Ensure the LED is off to start with.
bic.b #BIT0, &P1OUT ; Ensure the LED is off to start with.
bic.w #MC0|MC1, &TA0CTL ; Turn off timer TA0.
bic.w #MC0|MC1, &TA0CTL ; Turn off timer TA0.
bis.w #TACLR, &TA0CTL ; Clear the timer TAR.
bis.w #TACLR, &TA0CTL ; Clear the timer TAR.
bis.w #TASSEL__ACLK, &TA0CTL ; Use ACLK (32 KHz). This means 2 seconds a period.
bis.w #TASSEL__ACLK, &TA0CTL ; Use ACLK (32 KHz). This means 2 seconds a period.
bic.w #ID0|ID1, &TA0CTL ; Divide by 1.
bic.w #ID0|ID1, &TA0CTL ; Divide by 1.
bic.w #TAIFG, &TA0CTL ; Clear the interrupt flag.
bic.w #TAIFG, &TA0CTL ; Clear the interrupt flag.
bis.w #MC0, &TA0CTL ; Set timer mode to count to TA0CCR0.
bis.w #MC0, &TA0CTL ; Set timer mode to count to TA0CCR0.
bis.w #TAIE, &TA0CTL ; Enable timer TA0 interrupts.
bis.w #TAIE, &TA0CTL ; Enable timer TA0 interrupts.
mov.w #0x3fff, &TA0CCR0 ; Make it count up to 1/4 maximum, meaning 1 second on off period.
mov.w #0x3fff, &TA0CCR0 ; Make it count up to 1/4 maximum, meaning 1 second on off period.
bis.b #BIT1, &P1REN ; Enable resistor on P1.
bis.b #BIT1, &P1REN ; Enable resistor on P1.
bis.b #BIT1, &P1OUT ; Make it a pull up resistor.
bis.b #BIT1, &P1OUT ; Make it a pull up resistor.
bis.b #BIT1, &P1IE ; Enable the interrupt on P1.1.
bis.b #BIT1, &P1IE ; Enable the interrupt on P1.1.
bic.b #BIT1, &P1IFG ; Clear the P1.1 interrupt flag.
bic.b #BIT1, &P1IFG ; Clear the P1.1 interrupt flag.
bis.b #BIT1, &P1IES ; Look for high to low transitions only.
bis.b #BIT1, &P1IES ; Look for high to low transitions only.
mov.w #0, r4 ; This will toggle to make a delay for the switch on P1.1.
mov.w #0, r4 ; This will toggle to make a delay for the switch on P1.1.
nop
nop
bis.w #LPM3|GIE, SR ; Put the processor in Low Power Mode 3 (ACLK still active) & Enable Interrupts.
bis.w #LPM3|GIE, SR ; Put the processor in Low Power Mode 3 (ACLK still active) & Enable Interrupts.
nop
nop
; No loop necessary. All done by interrupts.
; No loop necessary. All done by interrupts.
TA0_ISR
TA0_ISR
cmp.w #TA0IV_TAIFG, &TA0IV ; Check if the timer overflowed. (Other opitons exist.)
cmp.w #TA0IV_TAIFG, &TA0IV ; Check if the timer overflowed. (Other opitons exist.)
jnz not_correct_flag ; If TA0IV not equal to 0x000e, it wasn't an overflow.
jnz not_correct_flag ; If TA0IV not equal to 0x000e, it wasn't an overflow.
xor.b #BIT0, &P1OUT ; Toggle the LED at P1.0.
xor.b #BIT0, &P1OUT ; Toggle the LED at P1.0.
cmp #1, r4 ; Check flag to see if we need to debounce the switch.
cmp #1, r4 ; Check flag to see if we need to debounce the switch.
jnz debounce
jnz debounce
bis.b #BIT1, &P1IE ; Enable the interrupt on P1.1 if it isn't the first time after the button was pressed.
bis.b #BIT1, &P1IE ; Enable the interrupt on P1.1 if it isn't the first time after the button was pressed.
debounce
debounce
mov.w #0, r4 ; Reset the flag on the button switch.
mov.w #0, r4 ; Reset the flag on the button switch.
not_correct_flag
not_correct_flag
bic.w #TAIFG, &TA0CTL ; This is the ISR. Clear interrupt flag
bic.w #TAIFG, &TA0CTL ; This is the ISR. Clear interrupt flag
reti
reti


PORT1_ISR ; This is the ISR that gets called when you push the S2 (P1.1 button).
PORT1_ISR ; This is the ISR that gets called when you push the S2 (P1.1 button).
bic.w #MC0|MC1, &TA0CTL ; Turn off timer TA0.
bic.w #MC0|MC1, &TA0CTL ; Turn off timer TA0.
bis.w #ID0|ID1, &TA0CTL ; Divide by 8.
bis.w #ID0|ID1, &TA0CTL ; Divide by 8.
bis.w #MC0, &TA0CTL ; Set timer mode to count to TA0CCR0.
bis.w #MC0, &TA0CTL ; Set timer mode to count to TA0CCR0.
bis.w #TAIE, &TA0CTL ; Enable timer TA0 interrupts.
bis.w #TAIE, &TA0CTL ; Enable timer TA0 interrupts.
bic.b #BIT1, &P1IFG ; Clear the Port 1 interrupt flag.
bic.b #BIT1, &P1IFG ; Clear the Port 1 interrupt flag.
bic.b #BIT1, &P1IE ; Disable the interrupt on P1.1.
bic.b #BIT1, &P1IE ; Disable the interrupt on P1.1.
mov.w #1, r4 ; This is the flag that the button was just pushed.
mov.w #1, r4 ; This is the flag that the button was just pushed.
reti
reti
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
Line 298: Line 450:
.sect ".reset" ; MSP430 RESET Vector
.sect ".reset" ; MSP430 RESET Vector
.short RESET
.short RESET
.sect ".int52" ; Timer0_A5 Interrupt Service Routine /* 0xFFE8 Timer0_A5 CC1-4, TA */
.sect ".int52" ; Timer0_A5 Interrupt Service Routine /* 0xFFE8 Timer0_A5 CC1-4, TA */
.short TA0_ISR ; page 49, http://www.ti.com/lit/ug/slau157af/slau157af.pdf
.short TA0_ISR ; page 49, http://www.ti.com/lit/ug/slau157af/slau157af.pdf
.sect ".int47" ; Port1 Interrupt vector (FFDE).
.sect ".int47" ; Port1 Interrupt vector (FFDE).
.short PORT1_ISR
.short PORT1_ISR


Line 365: Line 517:
.end
.end
</nowiki>
</nowiki>
====PWM to drive the 2014 Robot Wheels====
Note: this is for the 2014 robot which uses continuous servos to drive wheels, not the DC motors and H-Bridge used in the 2015 robot.
<nowiki>
;-------------------------------------------------------------------------------
; MSP430 Assembler Code Template for use with TI Code Composer Studio
;
; This program blinks the LED on P1.0 at one Hz period using TimerA0
; and interrupts.
; Rob Frohne, 11/17/2014.
;-------------------------------------------------------------------------------
.cdecls C,LIST,"msp430.h" ; Include device header file

;-------------------------------------------------------------------------------
.text ; Assemble into program memory
.global RESET ; Remember to set linker option to enter at RESET.
.retain ; Override ELF conditional linking
; and retain current section
.retainrefs ; Additionally retain any sections
; that have references to current
; section
;-------------------------------------------------------------------------------
RESET mov.w #__STACK_END,SP ; Initialize stackpointer
StopWDT mov.w #WDTPW|WDTHOLD,&WDTCTL ; Stop watchdog timer

;-------------------------------------------------------------------------------
; Main loop here
;-------------------------------------------------------------------------------
; Use Output Mode 2 (Toggle/Reset) with timer up then down counting. Then TAxCCRn will determine the duty cycle.
; Use P1.2 and P1.3 (TA0.1 and TA0.2) for the left and right wheels respectively.
; If we use the ACLK, the smallest step in pulse is 30.518 microseconds. The SMCLK gives .125 microseconds.
; The servo needs a resolution of at least 5 microseconds, so we better use the SMCLK.
bis.b #BIT2|BIT3, &P1DIR ; Set P1.2 and P1.3 as output.
bis.b #BIT2|BIT3, &P1SEL ; Select the peripheral (TA0.2 and TA0.3)
bic.w #MC0|MC1, &TA0CTL ; Turn off timer TA0.
bis.w #TACLR, &TA0CTL ; Clear the timer TAR.
bis.w #TASSEL__SMCLK, &TA0CTL ; Use SMCLK (not 8 MHz, about 1 MHz). C example ta0_16 says 1.045 MHz.
bis.w #ID1, &TA0CTL ; Divide by 4. Gives 1uS per tic, because we are using up and down mode.
bic.w #ID0, &TA0CTL ; The other bit to divide by 4.
bis.w #MC0|MC1, &TA0CTL ; Set timer mode to count to TA0CCR0 and then back down.
bic.w #CM0|CM1, &TA0CCTL1 ; One wheel, turn off capture mode.
bic.w #CM0|CM1, &TA0CCTL2 ; The other wheel....
bic.w #CAP, &TA0CCTL1 ; Set compare mode.
bic.w #CAP, &TA0CCTL2 ; The other wheel....
bis.w #OUTMOD_2, &TA0CCTL1 ; Toggle/Reset mode
bis.w #OUTMOD_2, &TA0CCTL2 ; The other wheel....
bic.w #CCIE, &TA0CCTL1 ; No interrupts needed for the PWM.
bic.w #CCIE, &TA0CCTL2 ; The other wheel....
mov.w #0x0a6a, &TA0CCR0 ; This gives a 20 mS period. Was 4e20. Experimentally determined to be 0xa6a.
mov.w #0x00d0, &TA0CCR1 ; Makes both wheels stopped. (1500 uS) Experimentally determined to be 0xc8.
mov.w #0x00b8, &TA0CCR2 ; The other wheel....
bis.w #MC0|MC1, &TA0CTL ; Turn on the timer.

nop
bis.w #LPM0, SR ; Put the processor in Low Power Mode 0 (SMCLK still active).
nop
; No loop necessary. All done by interrupts.
;-------------------------------------------------------------------------------
; Stack Pointer definition
;-------------------------------------------------------------------------------
.global __STACK_END
.sect .stack

;-------------------------------------------------------------------------------
; Interrupt Vectors
;-------------------------------------------------------------------------------
.sect ".reset" ; MSP430 RESET Vector
.short RESET

.end
</nowiki>

====Analog to Digital Conversion Example====
====Analog to Digital Conversion Example====
<nowiki>
<nowiki>
Line 384: Line 607:
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
.text ; Assemble into program memory
.text ; Assemble into program memory
.global RESET ; Remember to set linker option to enter at RESET.
.global RESET ; Remember to set linker option to enter at RESET.
.retain ; Override ELF conditional linking
.retain ; Override ELF conditional linking
; and retain current section
; and retain current section
Line 398: Line 621:
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
mov.w #ADC12SHT02|ADC12ON, & ADC12CTL0 ; Sampling time, ADC 12 on
mov.w #ADC12SHT02|ADC12ON, & ADC12CTL0 ; Sampling time, ADC 12 on
mov.w #ADC12SHP, &ADC12CTL1 ; Use sampling timer.
mov.w #ADC12SHP, &ADC12CTL1 ; Use sampling timer.
mov.w #BIT0, &ADC12IE ; Enable interrupt.
mov.w #BIT0, &ADC12IE ; Enable interrupt.
bis.w #ADC12ENC, &ADC12CTL0 ;
bis.w #ADC12ENC, &ADC12CTL0 ;
bis.w #BIT0, &P6SEL ; Select ADC instead of GPIO.
bis.w #BIT0, &P6SEL ; Select ADC instead of GPIO.
bis.w #BIT0, &P1DIR ; P1.0 as output.
bis.w #BIT0, &P1DIR ; P1.0 as output.


bis.w #ADC12SC, &ADC12CTL0 ; Start conversion
bis.w #ADC12SC, &ADC12CTL0 ; Start conversion
nop
nop
bis.w #LPM0|GIE, SR ; bis.w #LPM0|GIE, SR doesn't quite work. Put the processor in Low Power Mode 0 and enable interrupts.
bis.w #LPM0|GIE, SR ; bis.w #LPM0|GIE, SR doesn't quite work. Put the processor in Low Power Mode 0 and enable interrupts.
nop
nop
; no loop needed. We go to sleep forever.
; no loop needed. We go to sleep forever.


ADC12_ISR:
ADC12_ISR:
cmp.w #ADC12IV_ADC12IFG0, &ADC12IV ; ADC12IFG0
cmp.w #ADC12IV_ADC12IFG0, &ADC12IV ; ADC12IFG0
jnz finish
jnz finish
cmp.w #0x7ff, &ADC12MEM0 ; compare r8 to AVdd/2
cmp.w #0x7ff, &ADC12MEM0 ; compare r8 to AVdd/2
jge on
jge on
bic.b #BIT0, &P1OUT ; Turn off the LED on P1.0.
bic.b #BIT0, &P1OUT ; Turn off the LED on P1.0.
jmp there
jmp there
on: bis.b #BIT0, &P1OUT ; Turn on LED
on: bis.b #BIT0, &P1OUT ; Turn on LED
there:
there:
bic.w #ADC12IV_ADC12IFG0, &ADC12IV ; Clear interrupt flag.
bic.w #ADC12IV_ADC12IFG0, &ADC12IV ; Clear interrupt flag.
finish: reti
finish: reti


Line 434: Line 657:
.sect ".reset" ; MSP430 RESET Vector
.sect ".reset" ; MSP430 RESET Vector
.short RESET
.short RESET
.sect ".int54" ; ADC12 interrupt
.sect ".int54" ; ADC12 interrupt
.short ADC12_ISR
.short ADC12_ISR


.end
.end
</nowiki>
</nowiki>

====Calling Assembly from C/C++====
====Calling Assembly from C/C++====
<nowiki>
<nowiki>
Line 454: Line 678:
and the Assembly Function called....
and the Assembly Function called....
<nowiki>
<nowiki>
.global asmfunc
.global asmfunc
.global gvar
.global gvar
asmfunc:
asmfunc:
MOV &gvar,R11
mov.w &gvar,R11
ADD R11,R12
add.w R11,R12
ret
RET

.end
</nowiki>
</nowiki>
You can in C also use the asm() function.
asm(";*** this is an assembly language comment");
Also, when moving from assembly to C it is handy to read about the extrinsic functions that you can call in C that do handy little things in assembly. They begin with __. See Section 6.5 of the [http://www.ti.com/lit/ug/slau132j/slau132j.pdf C/C++ Manual]. For example, the eint instruction is:
__enable_interrupt(void);

Latest revision as of 19:56, 6 November 2016

Fibonacci Sequence (Mystery Program from ece382.com)

;-------------------------------------------------------------------------------
; MSP430 Assembler Code Template for use with TI Code Composer Studio
;
; This is the Fibonacci Sequence Program. f0=0, f1=1, fn=(fn-1)+(fn-2).
;-------------------------------------------------------------------------------
            .cdecls C,LIST,"msp430.h"       ; Include device header file

;-------------------------------------------------------------------------------
            .text                           ; Assemble into program memory
            .global RESET
            .retain                         ; Override ELF conditional linking
                                            ; and retain current section
            .retainrefs                     ; Additionally retain any sections
                                            ; that have references to current
                                            ; section
;-------------------------------------------------------------------------------
RESET       mov.w   #__STACK_END,SP         ; Initialize stackpointer
StopWDT     mov.w   #WDTPW|WDTHOLD,&WDTCTL  ; Stop watchdog timer

;-------------------------------------------------------------------------------
                                            ; Main loop here
;-------------------------------------------------------------------------------
            mov.w   #0x2400, r9
            mov.w   #10, r10

            mov.w   #0, r11
            mov.w   r11, 0(r9)

            mov.w   #1, r12
            incd    r9
            mov.w   r12, 0(r9)

loop        tst     r10
            jz      forever

            incd    r9
            dec     r10

            mov.w   r12, r13
            add.w   r11, r12
            mov.w   r12, 0(r9)
            mov.w   r13, r11
            jmp     loop

forever     jmp     forever
;-------------------------------------------------------------------------------
;           Stack Pointer definition
;-------------------------------------------------------------------------------
            .global __STACK_END
            .sect 	.stack

;-------------------------------------------------------------------------------
;           Interrupt Vectors
;-------------------------------------------------------------------------------
            .sect   ".reset"                ; MSP430 RESET Vector
            .short  RESET

Stack Manipulation Demonstration



;-------------------------------------------------------------------------------
; MSP430 Assembler Code Template for use with TI Code Composer Studio
; This program demonstrates the use of the stack.
; Rob Frohne November, 2015
; This program is to play around and see how the stack is manipulated.  Try it!
;-------------------------------------------------------------------------------
            .cdecls C,LIST,"msp430.h"       ; Include device header file
            
;-------------------------------------------------------------------------------
            .def    RESET                   ; Export program entry-point to
                                            ; make it known to linker.
;-------------------------------------------------------------------------------
            .text                           ; Assemble into program memory.
            .retain                         ; Override ELF conditional linking
                                            ; and retain current section.
            .retainrefs                     ; And retain any sections that have
                                            ; references to current section.

;-------------------------------------------------------------------------------
RESET       mov.w   #__STACK_END,SP         ; Initialize stackpointer
StopWDT     mov.w   #WDTPW|WDTHOLD,&WDTCTL  ; Stop watchdog timer


;-------------------------------------------------------------------------------
; Main loop here
;-------------------------------------------------------------------------------
			mov.w	#0xffff,r6
			mov.w	#0x000f,r7
loop1		push	r6
			dec		r7
			jnz		loop1

			mov.w	#0x000f,r7
loop2		pop		r6
			dec		r7
			jnz		loop2

			mov.w	#0x0004,r4
			mov.w	#0x0005,r5
			mov.b	#0xff06,r6
			call	#subroutine1
			mov.w	r4,&0x43f2
			jmp	$

subroutine1	push.w	r4
			push.w	r5
			push.b	r6
			mov.w	#0x4444,r4
			mov.w	#0x5555,r5
			mov.w	#0x6666,r6
			pop.b	r6
			pop.w	r5
			pop.w	r4
			ret

                                            

;-------------------------------------------------------------------------------
; Stack Pointer definition
;-------------------------------------------------------------------------------
            .global __STACK_END
            .sect   .stack
            
;-------------------------------------------------------------------------------
; Interrupt Vectors
;-------------------------------------------------------------------------------
            .sect   ".reset"                ; MSP430 RESET Vector
            .short  RESET
            




Solutions to Exam 1b from 2015

;-------------------------------------------------------------------------------
; MSP430 Assembler Code Template for use with TI Code Composer Studio
;
;
;-------------------------------------------------------------------------------
            .cdecls C,LIST,"msp430.h"       ; Include device header file
            
;-------------------------------------------------------------------------------
            .def    RESET                   ; Export program entry-point to
                                            ; make it known to linker.
;-------------------------------------------------------------------------------
            .text                           ; Assemble into program memory.
            .retain                         ; Override ELF conditional linking
                                            ; and retain current section.
            .retainrefs                     ; And retain any sections that have
                                            ; references to current section.
		.global add_32
add1l	.word 0xffff			; First addend lower word
add1h	.word 0x0003			; First addend upper word
add2l	.word 0x1				; Second addend lower word
add2h	.word 0x0				; Second addend upper word
;-------------------------------------------------------------------------------
RESET
 			mov.w	#__STACK_END,SP			; Initialize stackpointer
StopWDT 	mov.w	#WDTPW|WDTHOLD,&WDTCTL 	; Stop watchdog timer
;Problem statement:
;Write and debug an assembly program for your EXP-MSP430F5529LP launchpad board that does the following:
;The main work will be done in a callee-save subroutine that adds two 32 bit signed integers.
;The addends are stored in little endian format in two sets of two 16 bit variables, called add1l, add1h,
;add2l, add2h, where subscript l denotes the low word and h the high word, and the number denotes which
;addend it is for.
;The addresses of the low words of the addends are to be passed in R14 and R15 to the subroutine.
;The resultant sum in 2's compliment is to be passed back in R15 for the low word, and R14 for the high word.
;The flags should be correct for the 32 bit result after return from the subroutine.
;Comment your program.
;-------------------------------------------------------------------------------
; Main loop here
;-------------------------------------------------------------------------------
			mov.w #add1l,r15
			mov.w #add2l,r14
			call #add_32
			jmp $

add_32:		; Adds the 32 bit numbers in addresses in R14 and R15
 ; Not fully tested....  Make sure you test this yourself and understand what it does.
			push.w r13
			push.w r12
			mov.w @r14+, r13
			add.w @r15+, r13
			mov.w @r14, r12
			addc.w @r15, r12
			mov.w r13, r15
			mov.w r12, r14
			pop.w r12
			pop.w r13
			ret

;-------------------------------------------------------------------------------
; Stack Pointer definition
;-------------------------------------------------------------------------------
            .global __STACK_END
            .sect   .stack
            
;-------------------------------------------------------------------------------
; Interrupt Vectors
;-------------------------------------------------------------------------------
            .sect   ".reset"                ; MSP430 RESET Vector
            .short  RESET
            

Use S2 (P1.1) to turn on and off LED1 (P1.0).

;-------------------------------------------------------------------------------
; MSP430 Assembler Code Template for use with TI Code Composer Studio
;
;
;
;-------------------------------------------------------------------------------
            .cdecls C,LIST,"msp430.h"       ; Include device header file

;-------------------------------------------------------------------------------
            .text                           ; Assemble into program memory
            .global RESET
            .retain                         ; Override ELF conditional linking
                                            ; and retain current section
            .retainrefs                     ; Additionally retain any sections
                                            ; that have references to current
                                            ; section
;-------------------------------------------------------------------------------
RESET       mov.w   #__STACK_END,SP         ; Initialize stackpointer
StopWDT     mov.w   #WDTPW|WDTHOLD,&WDTCTL  ; Stop watchdog timer

;-------------------------------------------------------------------------------
                                            ; Main loop here
;-------------------------------------------------------------------------------
 			bis.b	#BIT0, &P1DIR			; Set the P1.0 as output for the LED.
 			bic.b	#BIT1, &P1DIR			; Set P1.1 for input.
			bis.b	#BIT1, &P1REN ; Set pull up for switch on P1.1
			bis.b	#BIT1, &P1OUT ; Make the pull up pull up not down.forever

loop		bit.b	#BIT1, &P1IN  ; Check if the button is switched.
			jnz 	off
on			bis.b	#BIT0, &P1OUT ; Toggle the LED
			jmp 	loop
off			bic.b	#BIT0, &P1OUT ; Turn the LED off to start with.
			jmp     loop
;-------------------------------------------------------------------------------
;           Stack Pointer definition
;-------------------------------------------------------------------------------
            .global __STACK_END
            .sect 	.stack

;-------------------------------------------------------------------------------
;           Interrupt Vectors
;-------------------------------------------------------------------------------
            .sect   ".reset"                ; MSP430 RESET Vector
            .short  RESET

Simple Blink the LED without Interrupts

;-------------------------------------------------------------------------------
; MSP430 Assembler Code Template for use with TI Code Composer Studio
;
; Blink the LED using no interrupts.
; Rob Frohne, 2014
;-------------------------------------------------------------------------------
            .cdecls C,LIST,"msp430.h"       ; Include device header file

;-------------------------------------------------------------------------------
            .text                           ; Assemble into program memory
            .global RESET
            .retain                         ; Override ELF conditional linking
                                            ; and retain current section
            .retainrefs                     ; Additionally retain any sections
                                            ; that have references to current
                                            ; section
;-------------------------------------------------------------------------------
RESET       mov.w   #__STACK_END,SP         ; Initialize stackpointer
StopWDT     mov.w   #WDTPW|WDTHOLD,&WDTCTL  ; Stop watchdog timer

;-------------------------------------------------------------------------------
                                            ; Main loop here
;-------------------------------------------------------------------------------
; This program is to blink the red LED on the MSP430F5529 LaunchPad.
			bis.b   #1,&PADIR
outer
			xor.b   #1,&PAOUT
			mov.w   #0x2710,r5
inner
			dec.w   r5
			tst.w   r5
			jne inner
			jmp outer
;-------------------------------------------------------------------------------
;           Stack Pointer definition
;-------------------------------------------------------------------------------
            .global __STACK_END
            .sect 	.stack

;-------------------------------------------------------------------------------
;           Interrupt Vectors
;-------------------------------------------------------------------------------
            .sect   ".reset"                ; MSP430 RESET Vector
            .short  RESET


Blink the LED Using Timer TA0 and Interrupts

;-------------------------------------------------------------------------------
; MSP430 Assembler Code Template for use with TI Code Composer Studio
;
; This program blinks the LED on P1.0 at one Hz period using TimerA0
; and interrupts.
; Rob Frohne, 11/17/2014.
;-------------------------------------------------------------------------------
            .cdecls C,LIST,"msp430.h"       ; Include device header file

;-------------------------------------------------------------------------------
            .text                           ; Assemble into program memory
            .global RESET		    ; Remember to set linker option to enter at RESET.
            .retain                         ; Override ELF conditional linking
                                            ; and retain current section
            .retainrefs                     ; Additionally retain any sections
                                            ; that have references to current
                                            ; section
;-------------------------------------------------------------------------------
RESET       mov.w   #__STACK_END,SP         ; Initialize stackpointer
StopWDT     mov.w   #WDTPW|WDTHOLD,&WDTCTL  ; Stop watchdog timer

;-------------------------------------------------------------------------------
                                            ; Main loop here
;-------------------------------------------------------------------------------
	    bis.b	#BIT0, &P1DIR	                ; Set the LED at P1.0 as output.
	    bic.b	#BIT0, &P1OUT			; Ensure the LED is off to start with.
	    bic.w	#MC0|MC1, &TA0CTL		; Turn off timer TA0.
	    bis.w	#TACLR, &TA0CTL			; Clear the timer TAR.
	    bis.w	#TASSEL__ACLK, &TA0CTL	        ; Use ACLK (32 KHz).  This means 2 seconds a period.
	    bic.w	#ID0|ID1, &TA0CTL		; Divide by 1.
	    bic.w 	#TAIFG, &TA0CTL			; Clear the interrupt flag.
	    bis.w	#MC0, &TA0CTL			; Set timer mode to count to TA0CCR0.
	    bis.w	#TAIE, &TA0CTL			; Enable timer TA0 interrupts.
	    mov.w	#0x3fff, &TA0CCR0		; Make it count up to 1/4 maximum, meaning 1 second on off period.
	    nop
	    bis.w	#LPM3|GIE, SR			; Put the processor in Low Power Mode 3 (ACLK still active) & Enable Interrupts.
	    nop
											; No loop necessary.  All done by interrupts.
TA0_ISR
	    cmp.w	#TA0IV_TAIFG, &TA0IV	        ; Check if the timer overflowed.  (Other opitons exist.)
			jnz  not_correct_flag		; If TA0IV not equal to 0x000e, it wasn't an overflow.
	    xor.b	#BIT0, &P1OUT			; Toggle the LED at P1.0.
not_correct_flag
	    bic.w	#TAIFG, &TA0CTL			; This is the ISR.  Clear interrupt flag
			reti
;-------------------------------------------------------------------------------
;           Stack Pointer definition
;-------------------------------------------------------------------------------
            .global __STACK_END
            .sect 	.stack

;-------------------------------------------------------------------------------
;           Interrupt Vectors
;-------------------------------------------------------------------------------
            .sect   ".reset"                ; MSP430 RESET Vector
            .short  RESET
	    .sect   ".int52"		    ; Timer0_A5 Interrupt Service Routine /* 0xFFE8 Timer0_A5 CC1-4, TA */
	    .short  TA0_ISR		    ; page 49, http://www.ti.com/lit/ug/slau157af/slau157af.pdf

	    .end

Change the Blink Period of an LED running on Timer TA0, Using Interrupts on P1.1 (S2)

;-------------------------------------------------------------------------------
; MSP430 Assembler Code Template for use with TI Code Composer Studio
;
; This program blinks the LED on P1.0 at one Hz period using TimerA0
; and interrupts, until you press the button S2 connected to P1.1,
; then it changes the blink rate.
; Rob Frohne, 11/17/2014.
;-------------------------------------------------------------------------------
            .cdecls C,LIST,"msp430.h"       ; Include device header file

;-------------------------------------------------------------------------------
            .text                           ; Assemble into program memory
            .global RESET		    ; Remember to set linker option to enter at RESET.
            .retain                         ; Override ELF conditional linking
                                            ; and retain current section
            .retainrefs                     ; Additionally retain any sections
                                            ; that have references to current
                                            ; section
;-------------------------------------------------------------------------------
RESET       mov.w   #__STACK_END,SP         ; Initialize stackpointer
StopWDT     mov.w   #WDTPW|WDTHOLD,&WDTCTL  ; Stop watchdog timer

;-------------------------------------------------------------------------------
                                            ; Main loop here
;-------------------------------------------------------------------------------
			bis.b	#BIT0, &P1DIR		; Set the LED at P1.0 as output.
			bic.b	#BIT0, &P1OUT		; Ensure the LED is off to start with.
			bic.w	#MC0|MC1, &TA0CTL	; Turn off timer TA0.
			bis.w	#TACLR, &TA0CTL		; Clear the timer TAR.
			bis.w	#TASSEL__ACLK, &TA0CTL	; Use ACLK (32 KHz).  This means 2 seconds a period.
			bic.w	#ID0|ID1, &TA0CTL	; Divide by 1.
			bic.w 	#TAIFG, &TA0CTL		; Clear the interrupt flag.
			bis.w	#MC0, &TA0CTL		; Set timer mode to count to TA0CCR0.
			bis.w	#TAIE, &TA0CTL		; Enable timer TA0 interrupts.
			mov.w	#0x3fff, &TA0CCR0	; Make it count up to 1/4 maximum, meaning 1 second on off period.
			bis.b	#BIT1, &P1REN		; Enable resistor on P1.
			bis.b	#BIT1, &P1OUT		; Make it a pull up resistor.
			bis.b	#BIT1, &P1IE		; Enable the interrupt on P1.1.
			bic.b	#BIT1, &P1IFG		; Clear the P1.1 interrupt flag.
			bis.b	#BIT1, &P1IES		; Look for high to low transitions only.
			mov.w	#0,	r4		; This will toggle to make a delay for the switch on P1.1.
			nop
			bis.w	#LPM3|GIE, SR		; Put the processor in Low Power Mode 3 (ACLK still active) & Enable Interrupts.
			nop
							; No loop necessary.  All done by interrupts.
TA0_ISR
			cmp.w	#TA0IV_TAIFG, &TA0IV	; Check if the timer overflowed.  (Other opitons exist.)
			jnz	not_correct_flag	; If TA0IV not equal to 0x000e, it wasn't an overflow.
			xor.b	#BIT0, &P1OUT		; Toggle the LED at P1.0.
			cmp 	#1, r4			; Check flag to see if we need to debounce the switch.
			jnz		debounce
			bis.b	#BIT1, &P1IE		; Enable the interrupt on P1.1 if it isn't the first time after the button was pressed.
debounce
			mov.w	#0, r4			; Reset the flag on the button switch.
not_correct_flag
			bic.w	#TAIFG, &TA0CTL		; This is the ISR.  Clear interrupt flag
			reti

PORT1_ISR						; This is the ISR that gets called when you push the S2 (P1.1 button).
			bic.w	#MC0|MC1, &TA0CTL	; Turn off timer TA0.
			bis.w	#ID0|ID1, &TA0CTL	; Divide by 8.
			bis.w	#MC0, &TA0CTL		; Set timer mode to count to TA0CCR0.
			bis.w	#TAIE, &TA0CTL		; Enable timer TA0 interrupts.
			bic.b	#BIT1, &P1IFG		; Clear the Port 1 interrupt flag.
			bic.b	#BIT1, &P1IE		; Disable the interrupt on P1.1.
			mov.w	#1, r4			; This is the flag that the button was just pushed.
			reti
;-------------------------------------------------------------------------------
;           Stack Pointer definition
;-------------------------------------------------------------------------------
            .global __STACK_END
            .sect 	.stack

;-------------------------------------------------------------------------------
;           Interrupt Vectors
;-------------------------------------------------------------------------------
            .sect   ".reset"                ; MSP430 RESET Vector
            .short  RESET
			.sect	".int52"	; Timer0_A5 Interrupt Service Routine /* 0xFFE8 Timer0_A5 CC1-4, TA */
			.short	TA0_ISR		; page 49, http://www.ti.com/lit/ug/slau157af/slau157af.pdf
			.sect	".int47"	; Port1 Interrupt vector (FFDE).
			.short  PORT1_ISR

			.end

Put PWM on Port P1.2

;-------------------------------------------------------------------------------
; MSP430 Assembler Code Template for use with TI Code Composer Studio
;
; This program blinks the LED if you hook it up to P1.2 at one Hz period using TimerA0
; and no interrupts.  The duty cycle is TA0CCR1/TA0CCR0.
; Rob Frohne, 11/17/2014.
;-------------------------------------------------------------------------------
            .cdecls C,LIST,"msp430.h"       ; Include device header file

;-------------------------------------------------------------------------------
            .text                           ; Assemble into program memory
            .global RESET					; Remember to set linker option to enter at RESET.
            .retain                         ; Override ELF conditional linking
                                            ; and retain current section
            .retainrefs                     ; Additionally retain any sections
                                            ; that have references to current
                                            ; section
;-------------------------------------------------------------------------------
RESET       mov.w   #__STACK_END,SP         ; Initialize stackpointer
StopWDT     mov.w   #WDTPW|WDTHOLD,&WDTCTL  ; Stop watchdog timer

;-------------------------------------------------------------------------------
                                            ; Main loop here
;-------------------------------------------------------------------------------
			bis.b	#BIT2, &P1DIR			; Set the LED at P1.2 as output.
			bis.b	#BIT2, &P1SEL			; Select the TA0.2 instead of GPIO.
			bic.w	#MC0|MC1, &TA0CTL		; Turn off timer TA0.
			bis.w	#TACLR, &TA0CTL			; Clear the timer TAR.
			bis.w	#TASSEL__ACLK, &TA0CTL	; Use ACLK (32768 Hz).
			bis.w	#ID1, &TA0CTL			; Divide by 4.  Gives 1/4096 uS per tic, because we are using up and down mode.
			bic.w 	#ID0, &TA0CTL			; The other bit to divide by 4.
			bis.w	#MC0|MC1, &TA0CTL		; Set timer mode to count to TA0CCR0 and then back down.
			bic.w	#CAP,	&TA0CCTL1		; Set compare mode.
			bis.w	#OUTMOD_2, &TA0CCTL1	; Toggle/Reset mode: this gives duty cycle of TA0CCR1/TA0CCR0.
			mov.w	#4096, &TA0CCR0			; This gives a 1 second period.
			mov.w	#1024, &TA0CCR1			; 25% duty cycle.
			bis.w	#MC0|MC1, &TA0CTL		; Turn on timer TA0.

			nop
			bis.w	#LPM3, SR				; Put the processor in Low Power Mode 3 (ACLK still active).
			nop
											; No loop necessary.  All done by interrupts.

;-------------------------------------------------------------------------------
;           Stack Pointer definition
;-------------------------------------------------------------------------------
            .global __STACK_END
            .sect 	.stack

;-------------------------------------------------------------------------------
;           Interrupt Vectors
;-------------------------------------------------------------------------------
            .sect   ".reset"                ; MSP430 RESET Vector
            .short  RESET

			.end

PWM to drive the 2014 Robot Wheels

Note: this is for the 2014 robot which uses continuous servos to drive wheels, not the DC motors and H-Bridge used in the 2015 robot.

;-------------------------------------------------------------------------------
; MSP430 Assembler Code Template for use with TI Code Composer Studio
;
; This program blinks the LED on P1.0 at one Hz period using TimerA0
; and interrupts.
; Rob Frohne, 11/17/2014.
;-------------------------------------------------------------------------------
            .cdecls C,LIST,"msp430.h"       ; Include device header file

;-------------------------------------------------------------------------------
            .text                           ; Assemble into program memory
            .global RESET					; Remember to set linker option to enter at RESET.
            .retain                         ; Override ELF conditional linking
                                            ; and retain current section
            .retainrefs                     ; Additionally retain any sections
                                            ; that have references to current
                                            ; section
;-------------------------------------------------------------------------------
RESET       mov.w   #__STACK_END,SP         ; Initialize stackpointer
StopWDT     mov.w   #WDTPW|WDTHOLD,&WDTCTL  ; Stop watchdog timer

;-------------------------------------------------------------------------------
                                            ; Main loop here
;-------------------------------------------------------------------------------
; Use Output Mode 2 (Toggle/Reset) with timer up then down counting.  Then TAxCCRn will determine the duty cycle.
; Use P1.2 and P1.3 (TA0.1 and TA0.2) for the left and right wheels respectively.
; If we use the ACLK, the smallest step in pulse is 30.518 microseconds.  The SMCLK gives .125 microseconds.
; The servo needs a resolution of at least 5 microseconds, so we better use the SMCLK.
			bis.b	#BIT2|BIT3, &P1DIR		; Set P1.2 and P1.3 as output.
			bis.b	#BIT2|BIT3, &P1SEL		; Select the peripheral (TA0.2 and TA0.3)
			bic.w	#MC0|MC1, &TA0CTL		; Turn off timer TA0.
			bis.w	#TACLR, &TA0CTL			; Clear the timer TAR.
			bis.w	#TASSEL__SMCLK, &TA0CTL	; Use SMCLK (not 8 MHz, about 1 MHz).  C example ta0_16 says 1.045 MHz.
			bis.w	#ID1, &TA0CTL			; Divide by 4.  Gives 1uS per tic, because we are using up and down mode.
			bic.w 	#ID0, &TA0CTL			; The other bit to divide by 4.
			bis.w	#MC0|MC1, &TA0CTL		; Set timer mode to count to TA0CCR0 and then back down.
			bic.w	#CM0|CM1, &TA0CCTL1		; One wheel, turn off capture mode.
			bic.w	#CM0|CM1, &TA0CCTL2		; The other wheel....
			bic.w	#CAP,	&TA0CCTL1		; Set compare mode.
			bic.w	#CAP,	&TA0CCTL2		; The other wheel....
			bis.w	#OUTMOD_2, &TA0CCTL1	; Toggle/Reset mode
			bis.w	#OUTMOD_2, &TA0CCTL2	; The other wheel....
			bic.w	#CCIE,	&TA0CCTL1		; No interrupts needed for the PWM.
			bic.w 	#CCIE,	&TA0CCTL2		; The other wheel....
			mov.w	#0x0a6a, &TA0CCR0		; This gives a 20 mS period. Was 4e20. Experimentally determined to be 0xa6a.
			mov.w	#0x00d0, &TA0CCR1		; Makes both wheels stopped.  (1500 uS) Experimentally determined to be 0xc8.
			mov.w	#0x00b8, &TA0CCR2		; The other wheel....
			bis.w   #MC0|MC1, &TA0CTL		; Turn on the timer.

			nop
			bis.w	#LPM0, SR				; Put the processor in Low Power Mode 0 (SMCLK still active).
			nop
											; No loop necessary.  All done by interrupts.
;-------------------------------------------------------------------------------
;           Stack Pointer definition
;-------------------------------------------------------------------------------
            .global __STACK_END
            .sect 	.stack

;-------------------------------------------------------------------------------
;           Interrupt Vectors
;-------------------------------------------------------------------------------
            .sect   ".reset"                ; MSP430 RESET Vector
            .short  RESET

			.end

Analog to Digital Conversion Example

;-------------------------------------------------------------------------------
; MSP430 Assembler Code Template for use with TI Code Composer Studio
;
; This program demonstrates reading the A0  with reference to AVcc.
; A single conversion is done, then it sleeps forever.
; Software sets ADC12SC to start the sample and conversion and automatically
; ADC12SC is cleared at end of conversion.  ADC12 internal oscillator times
; sample (16x) and conversion.  In main loop we wait in LPM0 to save power until
; conversion is complete, ADC12_ISR will force exit from LPM0 on reti.
; If A0 > (1/2) AVcc, P1.0 LED is lit, else not.

; Rob Frohne, 12/4/2014.
;-------------------------------------------------------------------------------
            .cdecls C,LIST,"msp430.h"       ; Include device header file

;-------------------------------------------------------------------------------
            .text                           ; Assemble into program memory
            .global RESET		    ; Remember to set linker option to enter at RESET.
            .retain                         ; Override ELF conditional linking
                                            ; and retain current section
            .retainrefs                     ; Additionally retain any sections
                                            ; that have references to current
                                            ; section
;-------------------------------------------------------------------------------
RESET       mov.w   #__STACK_END,SP         ; Initialize stackpointer
StopWDT     mov.w   #WDTPW|WDTHOLD,&WDTCTL  ; Stop watchdog timer

;-------------------------------------------------------------------------------
                                            ; Main loop here
;-------------------------------------------------------------------------------
			mov.w	#ADC12SHT02|ADC12ON, & ADC12CTL0		; Sampling time, ADC 12 on
			mov.w	#ADC12SHP,	&ADC12CTL1	; Use sampling timer.
			mov.w	#BIT0, &ADC12IE			; Enable interrupt.
			bis.w	#ADC12ENC, &ADC12CTL0		;
			bis.w	#BIT0, &P6SEL			; Select ADC instead of GPIO.
			bis.w	#BIT0, &P1DIR			; P1.0 as output.

			bis.w	#ADC12SC, &ADC12CTL0	; Start conversion
			nop
			bis.w	#LPM0|GIE, SR		; bis.w	#LPM0|GIE, SR doesn't quite work.  Put the processor in Low Power Mode 0 and enable interrupts.
			nop
							; no loop needed. We go to sleep forever.

ADC12_ISR:
			cmp.w	#ADC12IV_ADC12IFG0, &ADC12IV	; ADC12IFG0
			jnz	finish
			cmp.w	#0x7ff, &ADC12MEM0		; compare r8 to AVdd/2
			jge on
			bic.b 	#BIT0, 	&P1OUT			; Turn off the LED on P1.0.
			jmp there
on:			bis.b 	#BIT0,	&P1OUT			; Turn on LED
there:
			bic.w 	#ADC12IV_ADC12IFG0, &ADC12IV	; Clear interrupt flag.
finish:		reti


;-------------------------------------------------------------------------------
;           Stack Pointer definition
;-------------------------------------------------------------------------------
            .global __STACK_END
            .sect 	.stack

;-------------------------------------------------------------------------------
;           Interrupt Vectors
;-------------------------------------------------------------------------------
            .sect   ".reset"                ; MSP430 RESET Vector
            .short  RESET
			.sect	".int54"    ; ADC12 interrupt
			.short	ADC12_ISR

			.end

Calling Assembly from C/C++

extern "C" {
extern int asmfunc(int a); /* declare external asm function */
int gvar = 0; /* define global variable */
}
void main()
{
int var = 5;
var = asmfunc(var); /* call function normally */
}


and the Assembly Function called....

         .global asmfunc
         .global gvar
asmfunc:
          mov.w &gvar,R11
          add.w R11,R12
          ret

         .end

You can in C also use the asm() function.

asm(";*** this is an assembly language comment");

Also, when moving from assembly to C it is handy to read about the extrinsic functions that you can call in C that do handy little things in assembly. They begin with __. See Section 6.5 of the C/C++ Manual. For example, the eint instruction is:

__enable_interrupt(void);