\documentclass[letterpaper]{article} \author{Jonathan Chan (15354146)} \title{PHYS 319\\Labs 3 and 4 Notes} \usepackage{fullpage} \usepackage{minted} %{\renewcommand\fcolorbox[4][]{\textcolor{red}{\strut#4}} \begin{document} \maketitle To compile the C programs to .asm and .elf, I've modified my Makefile as below. \begin{minted}{makefile} SOURCES = $(wildcard *.c) EXEC = $(patsubst %.c, %.elf, $(SOURCES)) DEVICE = msp430g2553 INSTALL_DIR=$(HOME)/ti/msp430_gcc GCC_DIR = $(INSTALL_DIR)/bin SUPPORT_FILE_DIRECTORY = $(INSTALL_DIR)/include CC = $(GCC_DIR)/msp430-elf-gcc GDB = $(GCC_DIR)/msp430-elf-gdb #O0 works, O1 works, O2 doesn't -Os works CFLAGS = -I $(SUPPORT_FILE_DIRECTORY) -mmcu=$(DEVICE) -Os -g LFLAGS = -L $(SUPPORT_FILE_DIRECTORY) -T $(DEVICE).ld all: prog1 prog2 adc pwm prog1: prog1.c $(CC) $(CFLAGS) $(LFLAGS) $? -o prog1.elf $(CC) $(CFLAGS) $(LFLAGS) $? -S -o prog1.asm prog2: prog2.c $(CC) $(CFLAGS) $(LFLAGS) $? -o prog2.elf $(CC) $(CFLAGS) $(LFLAGS) $? -S -o prog2.asm adc: adc.c $(CC) $(CFLAGS) $(LFLAGS) $? -o adc.elf $(CC) $(CFLAGS) $(LFLAGS) $? -S -o adc.asm pwm: pwm.c $(CC) $(CFLAGS) $(LFLAGS) $? -o pwm.elf $(CC) $(CFLAGS) $(LFLAGS) $? -S -o pwm.asm debug: all $(GDB) ${EXEC} clean: rm prog1.elf prog2.elf adc.elf pwm.elf prog1.asm prog2.asm adc.asm pwm.asm \end{minted} \section{Program 1} Compiling from C, the produced Assembly file has a \textit{lot} of extra code, and appears to have been optimized differently. Below is the relevant section of the compiled .asm with some comments comparing lines to last lab's prog1.asm code. \begin{minted}{gas} .LCFI0: .loc 1 21 0 MOV.W #23168, &WDTCTL ; turn off watchdog .loc 1 22 0 MOV.B #65, &P1DIR ; set output direction (P1.6 and P1.0 for LEDs) .loc 1 23 0 MOV.B #1, &P1OUT ; set initial state (LED1 on) .LBB2: .loc 1 27 0 MOV.W #-5536, R12 ; amount to decrement by (60000 shown as signed word) .L6: .LVL0: MOV.W R12, @R1 ; use R1 as working register to decrement (first loop) .L3: .loc 1 28 0 MOV.W @R1, R13 ; use R13 as working register for this loop CMP.W #0, R13 { JEQ .L2 ; go to next countdown if this one has reached zero .loc 1 29 0 ADD.W #-1, @R1 ; decrement counter BR #.L3 ; loop .L2: .LVL1: .loc 1 27 0 MOV.W R12, @R1 ; reset R1 as working register to decrement (second loop) .L5: .loc 1 28 0 MOV.W @R1, R13 ; use R13 as working register for this loop CMP.W #0, R13 { JEQ .L4 ; break if countdown has reached zero .loc 1 29 0 ADD.W #-1, @R1 ; decrement counter BR #.L5 ; loop .L4: .LVL2: .LBE2: .loc 1 32 0 discriminator 1 XOR.B #65, &P1OUT ; switch LEDs .loc 1 26 0 discriminator 1 BR #.L6 ; loop from top of loops \end{minted} \newpage This was generated using the following C code that doubles the count and thus halves the blinking rate. \begin{minted}{c} #include void main(void) { volatile unsigned int count; WDTCTL = WDTPW + WDTHOLD; // Stop WDT P1DIR = 0x41; // Set P1 output direction P1OUT = 0x01; // Set the output while (1) { // Loop forever for (volatile unsigned char i = 0; i < 2; i++) { // decrement by 60000 twice count = 60000; while (count != 0) { count--; // decrement } } P1OUT = P1OUT ^ 0x41; // bitwise xor the output with 0x41 } } \end{minted} \section{Program 2} Below is the C code used to make the LEDs blink in the red--green--both--none pattern, using the same XOR trick described in the last lab notes. \begin{minted}{c} #include volatile unsigned char stateChanger; void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer P1DIR = 0xF7; // C does not have a convenient way of // representing numbers in binary; use hex instead P1OUT = 0x08; // LEDs off P1REN = 0x08; // enable resistor P1IE = 0x08; // Enable input at P1.3 as an interrupt stateChanger = 0x1; // 0x01 to toggle LED0; 0x40 to toggle LED1 _BIS_SR (LPM4_bits + GIE); // Turn on interrupts and go into the lowest // power mode (the program stops here) // Notice the strange format of the function, it is an "intrinsic" // ie. not part of C; it is specific to this chipset } // Port 1 interrupt service routine void __attribute__ ((interrupt(PORT1_VECTOR))) PORT1_ISR(void) { P1OUT ^= stateChanger; // toggle the LEDS stateChanger ^= 0x40; // 0x01 -> 0x41 -> 0x01 P1IFG &= ~0x08; // Clear P1.3 IFG. If you don't, it just happens again. } \end{minted} \section{Analogue to Digital Conversion} \section{Pulse Width Modulation} \section{LED Dimmer} \end{document}