Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 81

The Terminator

<Hasta La Vista Baby>

Team 04

Revision Description
1 David Cox - Test Process, Line 1, Line 3
2 Kyle Santos – 1 (Scope), 3.3 (UI Block), 7(Software), 3(Overview)
3 Katherine Foster - Abbreviations, 1 (Scope), 4 (Hardware)
4 John Hill - 3 (Overview), 3.1(MSP Board), 3.2 (Power System), 3.3 (UI), 3.4(System Input), 3.5
(Motion System)
5 David Cox - Project 2 testing, 2(power systems)
6 Katherine Foster - 4 Hardware
7 David Cox – Line 2 4.2 User interface 4.3 Power System 3 –overview 3.3 Power system 10/3/13
8 David Cox – Overview diagram, MSP Diagram Power Diagram Scope, Table of contents 10/3/13
9 David Cox – Hardware, user interface diagram 10/3/13
10 Katherine Foster - Punctuation, 4.2 Power System 10/3/13
11 Kyle Santos – 8.1 Added software descriptions for all existing functions 10/3
Team 04 - Team Members
Santos, Kyle A
David Cox
Katherine Foster Checked: 11/20/2013 Released: 11/20/2013
John Hill (moved on to bigger things…) Filename: Document1
Kyle Santos
Title: The Terminator
Hasta la vista

This document contains information that is PRIVILEGED and Date: Document Number: Rev: Sheet:
CONFIDENTIAL; you are hereby notified that any dissemination of
this information is strictly prohibited.
10/23/2013 1-2013-ECE306- 12 1 of 81
T04Document1
0-0002-001-0001-00 Document Format Sheet
Printed 09/19/19 10:46 AM

12 Kyle Santos- 8.0 Added software flow chart 10/3/13


13 Kyle Santos – 7 added software description 10/3/13
14 Kyle Santos – 3.4 System Input Block 10/4/13
15 Kyle Santos – 6 Testing 10/4/13
16 Kyle Santos – Readjusted all fields to update embedded field definitions and dynamic linking
(document) 10/4/13
17 John Hill -- 3,4,5 Updated 10/4/13
18 Katherine Foster – Abbreviations, Sections 3, 3.1,3.2, 3.3, 4 Updated:10/16/13,
19 Kyle Santos – Update Section 3 Descriptions, Add/Link schematics, interrupts blocks 10/22/13
20 David Cox – Test Process Project 4 10/23/13 System input diagram
21 Katherine Foster - Section 3, 4, 6.4 Updated:11/4/13
22 David Cox - Test Process Project 5 11/6/13
23 David Cox - Hardware 11/6/13
24 David Cox - AtoD Verification 11/6/13
25 David Cox – Conclusion 11/6/13
26 Kyle Santos – Section 7 Software 11/6/13
27 Kyle Santos – Section 8: Flow Chart, Main, Initialize, Interrupt Blocks 11/6/13
28 Kyle Santos – Section 9; Software listing: Main.c, Ports.c, Switch.c, Interrupt.c 11/6/13
29 Kyle Santos – Section 9: Serial.c 11/19/13
30 Kyle Santos – Section 8 Interrupt Flow chart update and serial interrupt description 11/19/13
31 David Cox – Test Process Project 6 11/20/13
32 Katherine Foster- Section 8, Grammar/Punctuation, Review
33 Katherine Foster – Conclusion, Documentation, 5 Updated:12/4/2013

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 2 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

Table of Contents
1. Scope ..................................................................................................................................................................4
2. Abbreviations .......................................................................................................................................................4
3. Overview..............................................................................................................................................................4
3.1. MSP Board / Control Board ..........................................................................................................................5
3.2. Power System ..............................................................................................................................................5
3.3. User Interface ...............................................................................................................................................6
3.4. System Input Block ......................................................................................................................................6
3.5. Motion System..............................................................................................................................................6
4. Hardware .............................................................................................................................................................7
4.1. CPU ........................................................................................................................................................... 17
4.2. User Interface ............................................................................................................................................ 17
4.3. Power System ........................................................................................................................................... 17
4.4. Project 3 Power Update… ......................................................................................................................... 17
5. Power Analysis ................................................................................................................................................. 18
6. Test Process..................................................................................................................................................... 18
6.1 Project 1 ........................................................................................................................................................ 18
6.2 Project 2 ........................................................................................................................................................ 18
6.3 Project 3 ........................................................................................................................................................ 19
6.4 Project 4 ........................................................................................................................................................ 19
6.5 Project 5 ........................................................................................................................................................ 20
6.6 AtoD Verification ............................................................................................. Error! Bookmark not defined.
6.7 Circuit 1 ? ........................................................................................................ Error! Bookmark not defined.
6.8 Circuit 2 ? ........................................................................................................ Error! Bookmark not defined.
7. Software ........................................................................................................................................................... 21
8. Flow Chart ........................................................................................................................................................ 22
8.1. Main Blocks ............................................................................................................................................... 23
................................................................................................................................................................................. 23
8.2. Initialization Blocks .................................................................................................................................... 24
8.3. Interrupt Blocks ......................................................................................................................................... 34
9. Software Listing ................................................................................................................................................ 36
9.1. Main.c ........................................................................................................................................................ 36
9.2. Ports.c ....................................................................................................................................................... 38
9.3. Switch.c ..................................................................................................................................................... 44
9.4. System_Init.c ............................................................................................................................................. 49
9.5. Interrupt.c .................................................................................................................................................. 61
10. Conclusion .................................................................................................................................................... 81

Table of Figures.
Terminator Overview (Figure 1) ..................................................................................................................................5
MSP/Control Board Layout (Figure 2) ........................................................................................................................5
Power System (Figure 3) ............................................................................................................................................5
User Interface (Figure 4) ............................................................................................................................................6
System Input (Figure 5) … .........................................................................................................................................6
Motion System (Figure 6) … .......................................................................................................................................7
MSP 430 Schematics (Figure 7) .................................................................................................................................9
Power System Schematic (Figure 8) ....................................................................................................................... 10
Right Motor H-Bridge Schematic (Figure 9) ............................................................................................................ 11
Left Motor H-Bridge Schematic (Figure 10) ............................................................................................................. 12
Interconnect Schematic (Figure 11) ........................................................................................................................ 13
LCD Schematic (Figure 12) ..................................................................................................................................... 14
Early Stage Car Image (Figure 13) .............................................................................................................................7
Software Flow Chart (Figure 14) … ......................................................................................................................... 22

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 3 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

1. Scope
The Terminator is a seek and destroy machine designed to navigates its way to targets relentlessly. The brains of
the Terminator are the control boards with loaded software that will navigate terrain. The brains of the terminator
control the motion system of the board. The motion system is made up of two front wheel drive wheels and a caster
for rear support. Also housed in this machine is a power system. The power system supplies power to the wheel
motors, LCD, and control boards and is supplied by just 4 AA batteries. For user support, the Terminator also has
an LCD screen to output relevant information and switches to select preprogrammed missions. Overall the
Terminator should be your number 1 choice for a machine that can navigate black lines or take GPS coordinates
to reach a destination.
2. Abbreviations
Abbreviation Definitions
TI Texas Instruments
µ Micro
F Farads
k Kilo
n Nano
m Meter
IR Infrared
IC Input Controller
LED Light Emitting Diode
LCD Liquid Crystal Display
DC Direct Current
A Amperes
H Henry
awg American Wire Gauge
CPU Control Processing Unit
3. Overview
The Terminator is driven by the MSP430FR5739 Experiment and control board that contains the user interface and
CPU that are all powered by the Power System (Figure 9). The terminator will execute shapes, follow specified
lines, and will also receive GPS coordinates.

The Terminator

Control
Experiment
Board
Board

Power
CPU User Interface System

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 4 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

Terminator Overview (Figure 1)


3.1. MSP Board / Control Board
The MSP430FR5739 Board is the brains of the device and can be seen in Figure 8. It houses code that determines
the paths that the Motion System must take. The code allows the car to move along the lines, follow GPS
coordinates, or perform shapes as the user wishes. The control board directly responds to the code from the
MSP430FR5739 board. This gives the user interface the ability to interact with the user before executing an action.
The MSP430’s interface consists of two push-button, active low switches directly connected to the processor. The
board also features an array of LEDs for user use, along with a power LED.
The Control Board contains all circuitry for car operation along with a LCD for user interaction.

MSP-430 Control
Experiment Board
Board

User Power
User
Interface CPU System
Interface

MSP/Control Board Layout (Figure 2)


3.2. Power System

The Power System is composed of the power circuitry and battery pack that delivers power to the MSP Board and
the Motion System. The battery pack provides a range of voltage to the system depending on the drain that the
batteries have already endured. In order to provide every element with the proper voltage, the buck boost will
increase the voltage or the low drop out regulator will decrease the voltage supplied to the circuit element.

Power System

Low Drop Out Buck Boost Battery Pack


Regulator Converter

Power System (Figure 3)

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 5 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

3.3. User Interface


The User interface is composed of the Visual Studios code running on the computer, LEDs for a visual health-
check, and a LCD screen on the top-face of the car and switches to control the functionality of the car. These
elements of user interface can be directly influenced by the production of code to receive input from the switches.
The Terminator currently uses the switches in order to allow the user to seek a shape and execute it like a machine.
They are interrupt driven and are customizable via the Interrupt Service Routine program.
The LEDs featured on the MSP430 are 8 blue LEDs directly connected to the processor and one green LED as a
power indicator.
The LCD interface is a backlit, two line LCD display (Figure 13). The display can be updated real-time when the
car is operational as a convenient way to prompt or inform the user when necessary.

User Interface

LCD LEDs Switches

User Interface (Figure 4)


3.4. System Input Block
The system input for the design includes data to and from two on-board active-low switches, the mini USB
connector, data input from the IR LED system (used to follow a black line) and data from the GPS system (for GPS
field location). All inputs provide instruction to the overall programming with the switches, IRLED, and GPS
providing instruction in real-time. Our board also has a reset button for a hard reset of the MSP430 board.

Switch1 TI MSP430
Reset

Switch2
USB IR LED GPS

System Input (Figure 5) …


3.5. Motion System
The Motion System is composed of a rear caster and two front wheels which are driven by the left and right motors.
The motors receive their power through the H-Bridges (Figures 10 and 11) that are contained within the power
system. The H-bridges are composed of N-Ch Mosfets and P-Ch Mosfets. They cannot be used to power both
forward and reverse together otherwise there will be a short and will blow one of the mosfets.

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 6 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

Power System

Left Right
H-Bridge H-Bridge

Left
Right
Motor
Motor

Left Wheel Right Wheel

Caster

Motion System (Figure 6) …

4. Hardware
The Terminator is a combination of intricate design and hardware as seen in the following pictures.

Early Stage Car Image (Figure 7)

The main components of the hardware are:


 TI MSP430FR5739 Experimenter's board

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 7 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

 Control Board

Bottom of the Board

Top of the Board


On these major components of the hardware, there are several intricate circuits, including:

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 8 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

MSP 430 Schematics (Figure 8)

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 9 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

Power System Schematic (Figure 9)

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 10 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

Right Motor H-Bridge Schematic (Figure 10)

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 11 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

Left Motor H-Bridge Schematic (Figure 11)

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 12 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

Interconnect Schematic (Figure 12)

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 13 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

LCD Schematic (Figure 13)

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 14 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

These intricate circuits are made up of the following components:


 Capacitors:
o (3) 0.1 µF capacitors
o (7) 1.0 µF capacitors
o (6) 10 µF capacitors
o (1) 100 µF capacitor

 Resistors:
o (4) 0.0 ohm resistors
o (5) 33 ohm resistors
o (10) 1.0 kohm resistors
o (2) 4.99 kohm resistors
o (8) 10 kohm resistors
 (5) 30V Schottky diodes
 (9) 60V N-Ch Mosfet diodes
 (4) 40V P-Ch Mosfet diodes
 880 nm 5 millim IR emitting LED

Center Emitter Schematic (Figure 14)


 (2) 880 nm 5millim Black IC Photo transmitter IR

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 15 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

Right Detector (Figure 15)

Left Detector (Figure 16)


 LCD Character Display
 White LED Backlight
 Female Connection Header 10 Post .1" Tin
 4 "AA" Battery Holder
Date: Document Number: Rev: Sheet:
This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 16 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

 IC DC to DC converter
 100 milliA, Low noise regulator
 2 Bit Translator
 Slide Switch
 10 µH Power Inductor
 (3) Connection Header 3 Post .100 Vertical Tin
 10 kohm Thumbwheel Potentiometer
 (8) Machine Screw Pan Phillips 4-40
 (4) Hex Standoff 4-40 Aluminum 5/8"
 1' 26awg Black Stranded wire
 1' 26awg Red Stranded wire
 2 millim Shaft Adapter for Lego wheels
 (2) 120:1 Mini Plastic Gearmotor Offset 2millim Spline Output
 (2) Lego Wheels
4.1. CPU
The CPU is the MSP430FR573x made by Texas Instruments, an embedded microcontroller. It has a 16-bit RISC
Architecture with up to 24MHz clock. For our purposes, we use the SMCLK on a 2 MHz clock instead of the 8 MHz
assigned to it. This allows the car to run on a wide range of 2 to 3.6 volts. This allows for the car to run on optimized
Ultra-low power modes which increases the play time of the battery life. To ensure that our CPU is working we have
a user interface of LEDS that are connected to key parts of the board. If the car, unexpectedly, stops working, the
LED allows for the diagnosis to be quicker having a power, a wheel, forward, and reverse lights. There is also an
LCD screen that allows for the user to place a message on the screen. If programmed, the LCD screen can also be
used to help with diagnosis in showing error messages. All of this will not work though, unless we have a power
source. Our source uses four "AA" batteries, available in any household.
4.2. User Interface
The user interface thus far consists of the LCD, LEDs and switches on the board. The LCD provides a visual output
of preprogrammed strings. This output can be useful in determining what state the car is in or what action is currently
happening. The MSP-430 board also contains 8 LED’s that are part of the user interface. The LEDs can be
programmed through the port pins to be either on or off. The LEDs can be useful to determine the state that the car
is in or if a specific function in the programming is executing. These LEDs serve as a test to help the user debug
certain scenarios. The User interface also consists of the micro USB port and the Power switch. The Power switch
allows the battery pack to be toggled on and off to power the device. The USB allows the FRAM board to be attached
to a computer where hardware can be tested and software can be downloaded onto the machine.
4.3. Power System
There are two power sources for the system: the micro usb port and "AA" battery pack. The micro USB port supplies
power to the system but cannot be used to power the motors. The "AA" battery pack consists of 4 "AA" rechargeable
batteries. Once the battery pack is switched on, the Buck Boost Converter outputs 3.3V and the Low Drop Out
Regulator provides a 1.8V output. These circuits and specific voltages will be harnessed in later projects for specific
applications. The buck boost converter consists of a bulk tantalum 100 micro Farad capacitor connected to smaller
capacitors and resistors that feel a voltage regulator to output the specified 3.3 V.

4.4. Project 3 Power Update…


As discussed multiple times before, there are two power sources for the system. One is a micro usb that allows the
user to input the software to the car directly. This works as a two way link, allowing the users to test the system
using the Visual Studio if there is an error and to entrust that the system receives the proper coding, as well as
Date: Document Number: Rev: Sheet:
This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 17 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

powering it on. It is highly suggested though, that unless the cord is several feet long to not run the Terminator while
connected by micro usb. The other power source is the battery pack consisting of the four 'AA' batteries. Although,
this will only run the car with the code loaded to it, it is by far the safer method for the Terminator, the computer,
and the user. It applies power directly to the system in order to run the LEDS, LCD screen, and motors controlling
the wheels. Eventually, the batteries in the system will wear out, deteriorating in performance. If this happens,
please seek new batteries and the Terminator will say 'Hasta la vista, baby!' as it runs off into the sunset.
5. Power Analysis
The Power Supplied by the 4 "AA" batteries is 1900mAh at 1.2V giving a total power of 2200mW. This is sent
through a buck-boost convert with an efficiency of 94% at 3.3V and 1.8V.
The FRAM Board consumes 84.1 uA at 1.8V for a total of 0.1512mW(Fram Specifications). The motors each
consume 80mA at 3.3V when at full speed for a total of 528mW (http://www.pololu.com/product/1122/specs). So
when the system is on and the motors are running, the system pulls a total of 528.1512mW. In this state of motion,
the Terminator should last approximately 23.3 hours.
6. Test Process
Throughout the build of this device, all circuits and circuit elements were tested with the use of oscilloscopes,
multimeters, and visual magnifying equipment to ensure the correct implementation of all design elements. Every
capacitor, resistor, diode, etc., were visually checked to ensure proper soldering contact and, when possible, a
digital multimeter was employed to verify that contacts were true.
All code segments were incrementally checked as they were developed, ensuring as expected performance and
adjustment to underperforming programming. For project 3, each shape was tested once through to ensure timing
and calculations were valid, then the two shape multiplier was added and again tested. A special test for the
Triangle shape was required to power-balance uneven performing motors to keep the straight line segments as true
as possible. This required minor tweaking as the performance of each motor was inconsistent and extra testing
allowed for more educated generalities to be applied to the function of each motor.
The final test for Project 3 was to ensure that our calculations for motor and car performance fit the environment of
the demo room. Minor adjustments were made to timing of shapes as the test floor yielded a slightly different result
than development environments, but this was expected.
6.1 Project 1
The first order of business in Project 1 was to ensure that all of the parts were present. Next the connectors J2, J5,
and J7 were tested by the digital multi-meter to confirm that they were an open circuit. The multi-meter was set to
Ohms and a measured value of OL (overload) Ohms was confirmed at each connector location. Hardware_Test
was then tested with the FRAM board in the Visual Studios application for control over the LED's. After soldering
the capacitors in locations C14, C15 and resistors in locations R13, R23, the connectors were retested to ensure a
short did not existed. A reading of OL (overload) Ohms or a very large Ohm measurement (over 100) from the
digital multi-meter confirmed this. After the soldering of the Control Board and Diodes was completed,
Hardware_Test was again loaded and ran in the Visual Studios application to make sure the LED's still functioned
properly. Lastly after installing the LCD onto the board it was tested within the Visual Studios application to display
text and make sure the backlight came on. Our boards did not display text on the LCD due to some unknown bug
in the system, but the LED's and backlight of the LCD functioned properly. This concludes the testing done in Project
1.
6.2 Project 2
Project 2 Testing: After ensuring that all the parts for project 2 were present, the first test came after soldering U2
(part of the 3.3V Buck Boost Converter) in place. The U2 part was tested on all pins to make sure that there was
no short from an over lapse of solder or some other factor except on pins 4 and 5 which were supposed to be
shorted together. This was accomplished by using the probes of the multi-meter on the U2 pins and observing the
Ohm reading of the output. Readings of OL (overload) or any high reading in mega Ohms showed that no short
existed between the pins. The next test was to make sure the 3.3V Buck Boost Converter was actually outputting
3.3 V. The Battery pack was attached to the board with the switch in the off position this allowed the user to control
when to test the circuit. Next the probes of the multi-meter were placed on the 3.3V testing location; the square pad
was the positive terminal. Once the user was ready the switch was flipped and the 3.3V output was verified on the
multi-meter and then the battery pack shut off. If any problem existed the user needed to check his connections

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 18 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

and soldering very thoroughly before attempting the measurement again because testing a faulty circuit could be
disastrous. The next circuit to be tested on the board was the Low Drop Out (LDO) 1.8V regulator. After proper
soldering had been accomplished the LDO was tested just like the 3.3V Buck Boost Converter. The battery pack
was attached and the switch placed in the off position and after the multi-meter probes were connected to the 1.8V
location the switch was turned on and the ~1.8V output was verified on the multimeter. If 1.8V was not displayed
then the user needed to reexamine the circuit soldering before testing again. Once both the 3.3V and 1.8V outputs
were confirmed, the testing for Project 2 was concluded.
6.3 Project 3
Project 3 testing: The first test to be performed in project 3 was testing the N-FETS of the left and right H-Bridge. A
jumper wire was used and manually inserted into the pins of the J-2 jumper for testing purposes. The jumper wire
was fist inserted into JV2 pin 12 and 6 to test the right H-Bridge. The batteries then powered on the board and
testing probes of a digital multi-meter were placed at JV4. The output was confirmed to be between 6-6.4V
confirming a good right N-FET. Next the jumper wire was place between JV2 pins 12 and 4 to test the left H-Bridge.
The multi-meter probes were placed at JV9 and an output reading was taken once the batteries were switched on.
An output reading between 6-6.4V confirmed a properly operating left N-FET. Once the N-FETs were tested,
connectors were place on J4 and J9 concluding the testing for project 3.
6.4 Project 4
Project 4 testing: Project 4 concerned adding the reverse capability to the left and right H-bridge systems for the
wheels so naturally there was a lot of testing done to verify correct soldering. The first test involved testing the N-
FET Q2. The R_FORWARD pin on JV2 was jumped by the power pin and the testing was done between test points
TP1, TP3 and ground. First R_FORWARD was off and it was shown by the multi-meter probes that TP1 and TP3
both were approximately battery voltage. Once R_FORWARD was jumped the points were testing again and TP1
was about half the battery voltage and TP3 was around ground potential (a few millivolts). The next test was after
N-FET Q9 was installed. For this test, test points TP5 and TP7 were probed referenced to ground when
L_FORWARD was off and then on. When L_FORWARD was off, TP5 and TP7 were shown to be at battery voltage
by the multi-meter test probes. Next, L_FORWARD was turned on by jumping a wire from the power pin and TP5
was approximately half the battery voltage and TP7 was around ground potential (a few millivolts). The next
instillation was N-FETS Q1 and Q5 and the R_REVERSE pin on JV2 was used for testing. When R_REVERSE
was off test points TP2 and TP4 were shown to equal battery voltage. When R_REVERSE was turned on, TP2 was
around half the battery voltage and TP4 was near ground potential (a few millivolts). The last test for project 4 was
done after N-FETS Q8 and Q10 were soldered on the board. The pin that was tested was L_REVERSE and when
turned off, the voltage at test points TP6 and TP8 was a battery voltage. When L_REVERSE was turned on by
jumping a wire from the power pin, TP6 was measured at half the battery voltage and TP8 was found to be at
ground potential (a few millivolts).
6.5 Project 5
Project 5 testing: First in Project 5 the thumb wheel was soldered in, and a visual check was done to make sure
that no shorts existed between the thumb wheel and the LCD pins that were below. Before continuing with the
instillation of the detectors and emitter, it was necessary to get the software to display the thumb wheel value to the
LCD screen. This was accomplished by converting the ADC_Thumb value into a character array that can be put
into the display_line2 string and then sent out to the LCD screen. A check that was done within the software for the
thumbwheel was to ensure that the full range of values (0-1023) were available. Next the circuitry for the emitter
and detectors was installed onto the board including the IR_LED and two detectors. Once again, software checks
were needed to verify that they emitter and detectors were working properly. The check was done by putting the
values received from the ADC into a character array, and displaying them on the LCD. An extra step that is
necessary is to shield the back of the detectors from ambient light to get accurate measurements.
Analog to Digital convertor for 4 devices that were soldered onto the control board. These devices are: the
thumbwheel, left detector, right detector, and the center emitter. The initialization for the ADC was added into our
project code and it contained a single sequence which will get one value at a time and then increment through the
devices. Since our ADC is set to TEN BITS (highest resolution) the values that can be produced by the ADC range
from 0-1023. The verification for a working ADC was first done in Project 5 when testing the thumbwheel. In the
debugger, a watch window was opened that contained variables: ADC_Thumb, ADC_Left_Detector, and
ADC_Right_Detector. Once this was accomplished a user can watch the values change in the watch window for a
visual verification that the ADC is working and that the values are changing.
Date: Document Number: Rev: Sheet:
This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 19 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

6.6 Project 6
Project 6 testing: For project 6, there was practically no hardware added to the control board for the serial
communications. Specifically, a 2 pin header was added which could then be bridged by a connector to jump the
transmit and receive pins together. To achieve a successful serial communication, a baud rate had to be set up for
the data to be sent and receive without losing the sent data. To accomplish this the baud rate was set to 4800 as
specified by the project requirements. The setting of the baud rate was done within the UART initialization by
changing specific values. After the baud rate had been set in software, it was necessary to test it on an oscilloscope
to verify a correct baud rate. Pictured here is a oscilloscope capture of a transmission over the serial link.

From this oscilloscope picture, the Delta X value shown in the top right corner as 208 micro seconds is the baud
rate that was recorded for this transmission. Specifically the baud rate is Bd = 1/ (208microseconds) = 4807 Baud
which is roughly 4800. This concludes the testing for this project once successful transmission was established
6.7 Project 7
Project 7 testing: The goal of this project was to install the external GPS unit and successfully receive positional
data transmission. Fortunately, the main hardware installation was handled by Mr. Carlson (the installation of the
ribbon port to the FRAM board) and after the power circuit was built, all connections were tested using the digital
multimeters to verify conductivity and resistance.
Most of this project was software based, so new algorithms were written to handle the parsing of data received by
the GPS. The same buffer processing functions were used to handle moving data from the small gps buffer ring to
the larger GPS buffer ring, but instead of looking for the ‘N’ character from Project 6 we looked for the ‘$’ character
indicative of GPS data.
Upon receiving data, it became apparent that there exists many different satellite systems all sending different data.
My board would not connect via serial USB to my computer and allow me to stream data for inspection. So, I ran
the board in debug mode and spot checked the large GPS buffer for contents. After many inspections and research
on the types of transmissions possible, it became apparent that a second large array was needed to store only
desired data. As the small buffer processes at the rate of data transfer, it requires constant evaluation. So the first
large array looked for the ‘$’ and filled the array with subsequent data. A separate function then evaluated the first
buffer one character at a time to verify validity. We settled on data from GPGGA service and checked every
character in the buffer to have a final buffer with only fully transmitted data.

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 20 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

From that buffer the on-screen display was updated with characters in the specific array positions corresponding to
longitude and latitude. Final evaluation of proper functionality was done by walking in each cardinal direction and
checking for expected data change.

7. Software
Software for this version of the car currently allows for a scrollable LCD based menu, with switch 1 used for selecting
a menu option and switch 2 for resetting the menu selections. Menu options include:
1) Turn on the IR_LED emitter
2) Turn off the IR_LED emitter
3) Check the ADC Status – onscreen display of the values computed for the thumb wheel, left detector, and
right detector. Currently displayed in decimal form
4) Execute movement – Current movement is to move forward to a black line. Stop, reverse to the rear most
black line while counting the time lapsed during the trip, stop, travel forward half the time needed to reach
previous waypoint, stop, turn clockwise two revolutions, stop, turn counter clockwise two revolutions, stop.
5) Calibrate LED: used to find thresholds for black line and white background. Values stored in global variable
for use by Execute function.
6) NA
7) NA
8) NA

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 21 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

8. Flow Chart Interrupt

Power Up
Interrupt

switch_interrupt

Serial Comm Main()


Timer0_A0_ISR

ADC10_ISR
Initialization Timer1_A0_ISR

Timers Ports ADC


Switch

ADC_Start()

Menu_Process()
While(true) Loop

Black Line Test

Software Flow Chart (Figure 7) …

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 22 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

8.1. Main Blocks

Main()

Initializations

ADC_Start()

Menu_Process()

While(true) loop

Black Line Test

Main.c
Main() calls all initialization functions for all hardware/software aspects of the Terminator. After all initialization
is completed and the ADC values retrieval process has begun, the program enters an ALWAYS loop, where it
spends most of its time. Here, the general flow of the execution is slowed down with an if statement. LED 1 is
cycled on and off (blinked) to indicate activity and Menu_Process() is called to process the on-screen LCD
menu. Check_Execute() is called to check for execution of the selected on-screen menu option.
While the GPS module is currently configured and operational, it is not implemented in this design spec and is
configured during initialization, but not ever started.

void ADC_Start (void)


The ADC initialization function configures the ADC parameters and initializes the ADC value retrieval process.
For more information, see ADC section.

void Menu_Process(void)
Menu_Process uses global variables and readings of the ADC thumb wheel to process which menu item should
be displayed on the LCD. By checking the voltage registered by the ADC, the defined 8 item menu changes
and updates whenever that voltage read passes certain intervals.

void Check_Execute(void)
Check_Execute is a function that examines the state of a global variable to see if the user has ‘selected’ a
function. By pressing the on board Switch 2 once to select and again to confirm, the global variable is updated
to reflect a “Ready” status and this function implements the desired selection by means of a switch statement
and function calls.

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 23 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

8.2. Initialization Blocks

Main
Switch Init Init Ports Init Timers

Init_Switch Init_Port1 Init_TimerA0_A

sw1_enable Init_Port2 Init_Timer1_A

sw2_enable
Init_Port3 Init_Timer_B2

Switch_Process
Init_Port4

Check_Switch_Press
Init_PortJ
switch_control

Main
Init ADC Init Serial Init GPS

Init_ADC Init_Serial gps_system_init

gps_wakeup

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 24 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

Switches

clear P4 Flag

Enable SW1 interrupt


1 sw1_enable()

Init_Switch()

2
sw2_enable()
clear P4 Flag Main

Enable SW2 interrupt

The Switch initialization configures the general operation of both push-button switches on board the MSP430.
The Switches are implemented using interrupts configured for those two port pins (4.0 and 4.1). The are set to
HI/low trigger mode, meaning the interrupt will only be triggered when the processor senses a transition from the
default HI state to the low state (the pressing of the button).
The initialization consists of enabling the interrupts for both switch 1 and 2, as well as setting a ‘switch ready’
variable to READY.

Functions Defined:
void Init_Swtich(void)
The main initialization function call that in turn calls the initialization for each individual switch. The
switch_ready global is set to READY, or 1.

void sw1_enable(void)
This function enables the switch 1 interrupt by clearing the port4 interrupt flag and setting the interrupt to
active.

void sw2_enable(void)
This function enables the switch 1 interrupt by clearing the port4 interrupt flag and setting the interrupt to
active.

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 25 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

Ports
Ports: initializes all ports on the MSP430’s main microprocessor. Ports are defined based on manufacturer
specifications but all have the ability to be General Purpose IO pins if desired. Pin Data direction, default Hi/Low
state and pull-up/down resistance configuration is also configurable.
Ports Settings (General)
Function Select
Port Number Output Setting Direction Setting Misc
(Bit 1, Bit 0) Function
P1.0 – V_Detect_R (1,1) Analog Low Input
P1.1 – V_Detect_L (1,1) Analog Low Input
P1.2 – IR_LED (0,0) GPIO Low Output
P1.3 – V_Thumb (1,1) Analog Low Input
P1.4 – GPS_Reset (0,0) GPIO Low Output
P1.5 – GPS_PWRCHK (0,0) GPIO Low Input
P1.6 – SPI_SIMO (1,0) SPI Clock Hi Output SIMO, Pull-up Res
P1.7 – RS_LCD (0,0) GPIO Hi Output
P2.0 – USB_TXD (1,0) UART Low Output
P2.1 – USB_RXD (1,0) UART Low Input
P2.2 – SPI_SCK (1,0) SPI Hi Input Pull-up Resistor
P2.5 – CPU_TXD (1,0) UART Low Output
P2.6 – CPU_RXD (1,0) UART Low Input
P3.0 – Xcoor (0,0) GPIO Low Output
P3.1 – Ycoor (0,0) GPIO Low Output
P3.2 – Zcoor (0,0) GPIO Low Output
P3.3 – GPS_PWRCNTL (0,0) GPIO Low Input
P3.4 – R_Forward (0,0) GPIO Low Input
P3.5 – R_Reverse (0,0) GPIO Low Input
P3.6 – L_Forward (0,0) GPIO Low Input
P3.7 – R_Forward (0,0) GPIO Low Input
P4.0 – SW 1 (0,0) GPIO Hi Input Pull Up Res/ Hi/Lo Int
P4.1 – SW 2 (0,0) GPIO Hi Input Pull Up Res/ Hi/Lo Int
PJ0 (0,0) GPIO Low Output LED 1
PJ1 (0,0) GPIO Low Output LED 2
PJ2 (0,0) GPIO Low Output LED 3
PJ3 (0,0) GPIO Low Output LED 4

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 26 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

Timers
Timers are initialized based on requirements of current implementation. Currently, two timers based on Timer A
(Timer A0 and Timer A1) are configured and initialized. Timer A0 is based on SMCLK and is scaled to a frequency
of 1000Hz. Timer A0 is also not set to allow Overflow Flags and is set to “Continuous Up”.
Timer A1 is also set to SMCLK, 1000Hz, Continuous UP and no Overflow Flags. See code below for more
information.
Timers operate based on Timer interrupts, covered in the Interrupts section.

Functions Defined:
void Init_Timers(void);
Function to call each individual timer initialization function.
void Init_Timer0_A();
Initializes timer A0 to specs mentioned above. Uses SMCLK, 1000Hz, Continuous Up, no Overflow Flags.
void Init_Timer1_A();
Initializes timer A1 to specs mentioned above. Uses SMCLK, 1000Hz, Continuous Up, no Overflow Flags.
void Init_Timer_B2();
Initializes timer B2. Settings unknown as is precompiled code with no function definition.

ADC
The ADC functionality is currently set to single sequence, using MODCLK, 10 bit resolution, stores unsigned binary
to its two memory locations, and monitors Thumb Wheel (Port1.3), LED Right Detector (P1.0), LED Left Detector
(P1.1).
ADC is processed by an Interrupt Service Routine, occurring at the interval defined in the configuration. An integer
is stored in memory and processed by functions called within the ISR. The ADC is used to compare and convert
Analog measurements to digital values.
In this implementation, we are converting the values of the voltage drop across the Thumb Wheel and the voltage
drop across the IR LED receivers (both left and right). That value is then converted to Hex and Decimal and utilized
in creating and monitoring thresholds used in car movement (IR_LED receivers) and to process a LCD menu for
visual user interaction (Thumb Wheel).

Functions Defined:
void Init_ADC(void);
Function that initializes ADC sampling parameters. Single Sequence, use MODCLK, 10 bit resolution, store
unsigned binary and defines voltage compare registers. Also enables the interrupt.
void ADC_Start(void);
Checks for ADC status and when not busy, samples the ADC for values and stores values in defined
register.
void ADC_Process(void);
Calls processing functions ADC_Left_Detector(), ADC_Right_Detector(), ADC_Thumb(). These are to
process each value of globally stored ADC values.

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 27 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

void ADC_Left_Process(void);
Calls function to convert stored value in global ADC_Left_Detector variable to character array based on
decimal numbering system. Each character is then stored into a global char array L-Detect_Char[].
void ADC_Right_Process(void);
Calls function to convert stored value in global ADC_Right_Detector variable to character array based on
decimal numbering system. Each character is then stored into a global char array R-Detect_Char[].
void ADC_Thumb_Process();
Calls function to convert stored value in global ADC_Thumb variable to character array based on decimal
numbering system. Each character is then stored into a global char array Thumb _Char[].

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 28 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

Serial

Serial initialization sets up various parameters used in the sending and receiving of data and the MSP430.
While the port 2 on the MSP430 processor handles full serial communications, we only initialized pins 2.5 and 2.6
or use with inter board or GPS serial communications. The communications processing is handled primarily with
Interrupts and called functions that handle processing the data received on pin 2.6. This process is further
explained in the interrupts section.

When initializing, a baud rate must be established and buffer rings are cleared for initial application. To calculate
the baud rate, the following process is followed:

The serial UCA1 interrupt uses the SMCLK and has a baudrate set to 4800. Calculations are performed below.

4,800 Baud Rate Calculations


1. Calculate N = fBRCLK/Baudrate [if N > 16 continue with step 3, otherwise with step 2] N =
SMCLK / 4,800 => 8,000,000 / 4,800 = 1666.66666667
2. OS16 = 0, UCBRx = INT(N) [continue with step 4]
3. OS16 = 1, UCx = INT(N/16), UCFx = INT([(N/16) – INT(N/16)] × 16) UCBRx = INT(N/16) =
1666.66666667/16 => 104
UCFx = INT([(N/16) – INT(N/16)] × 16) = ([1666.66666667/16-INT(1666.66666667/16)]*16) =>
(104.16666667-104)*16=>0.16666667*16=2
4. UCSx can be found by looking up the fractional part of N ( = N - INT(N) ) in Table 18-4 Decimal of
SMCLK / 8,000,000 / 4,800 = 1666.66666667 => 0.6667 yields 0xD6
5. If OS16 = 0 was chosen, a detailed error calculation is recommended to be performed TX error
BRCLK Baudrate UCOS16 UCBRx UCFx UCSx neg pos neg pos
8000000 4800 1 104 2 0xD6 -.08 .04 -.1 .14
This port utilizes the SMCLK as the base clock and after configuration will interpret data transmission at a baud
rate of 4800 baud.

Functions Defined:
void Init_Serial_UCA1(void)
This function clears the GPS_Char_Rx[] global character array to contain all NULL values and resets the
read and write indexes to 0. The UCA1 control register is set to allow for a baud rate of 4800 baud and sets the
interrupt type for this serial port to be a receive interrupt. When set this way, an interrupt flag is generated and
the ISR triggered when the register in memory associated to this UCA processor is filled with an 8 bit word. When
the word is removed, the flag is cleared.

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 29 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

GPS

Reset GPS Enable GPS


gps_wakeup() Power
Wait 1 sedc
GPS_Init()

Return to Power Check GPS


GPS_Init() On? Power

The GPS initialization function powers up the GPS unit and waits for full power before exiting, to ensure proper
startup.
The GPS unit is an external unit installed to the MSP430. The power circuit attached to the GPS takes some time
to reach full voltage, so the process takes an extra function call to complete. Initially, the GPS system is reset by
enabling Port 1.4. After a brief one second pause, the function gps_wakeup is called. In GPS wakeup, the
power-up cycle begins by enabling Port 3.3 and the function waits in a while loop until the power check input (Port
1.5) is set HI by the GPS circuit.
The initializing function checks the status of the GPS’s power once again just before exiting.

The following image shows the circuit used to power the GPS

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 30 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

The U3 device will amplify the 1.8V output from the GPS unit to the 3.3V required by the MSP430 processor.

Functions Defined:
void gps_system_init(void)

This funciton initializes the GPS receiver attached to the MSP430 test board. The GPS_RESET port pin is
enabled and the system pauses slightly to allow the external hardware time to respond. Function gps_wakeup is
called, which powers on the gps device. Upon returning from the function call, GPS_PWRCHK port pin is
referenced for power signal. If no signal is found, system attempts to wake GPS again. LCD is updated at each
stage of function.

void gps_wakeup(void)

This funciton enables the pin that begins the power-up process for the GPS. The GPS will start low and needs to
be driven hi. GPS_PWCNTL is enabled and this signal enables the GPS to begin its power up stage. Once the
PWRCHK pin is hi and the GPS is at full power, the function returns.

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 31 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

8.3. Black Line Detection


Software Flow Chart

Function Descriptions:

void final_menu(void):
This function is the final menu that was created for the black line detection. The menu is based upon the
thumbwheel value received by the ADC and is divided down to provide exactly 4 menu options. These options
are: Black_Threshold, White_Threshold, Set_Thresholds, and Travel_Course. The first threee menu options are
provided to manually calculate and set a threshold if needed, but within the code a hard threshold is set for the
black line detection. The last menu option activates the Terminator to traverse the black line course by activating
a while loop that continually runs.
void Travel_Course(void):
This function is what controls the operation and direction of the Terminator while it navigates around the
black line course. It consists of a switch statement that will activate the Car direction based upon setting a
variable within the three sub functions that actually move the car depending on detector values. These sub
functions are Straight(), Right_Turn(), and Left_Turn().
void Straight(void):
Straight is the starting function for the Terminator because the car is originally placed straight on the black
line. This function pulses the left and right motors forward at the same speed to behave correctly when the car is
Date: Document Number: Rev: Sheet:
This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 32 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

straight along the black line. While both detectors are on the black line the function will continue straight but if one
detector changes the straight function will terminate and determine if a Left or Right turn is needed.
void Right_Turn(void):
This function is activated when the left detector reaches a white threshold value so the car must turn right
to reach the black line again. The right turn function has the left motor going forward and the right motor in
reverse for a very clean sharp turn so the car returns to the line very fast. Once the left detector hits the black line,
the turn is over and the car adjusts and then recalculates the direction for the car to travel in.
void Left_Turn(void):
The Left turn function activates when the right detector has gone off the black line and a left turn is
needed to find the black line again. within this function, the right motor is going forward and the left motor is in
reverse to provide a quick and accurate turn to reach the black line very quickly. Once the right detector hits the
black line again the left turn is finished and the car stops turning and adjusts to the black line. Then the code re-
evaluates what direction the car should go in before returning to the Travel_Course function which will call the
next direction.
void Turn_Around(void):
This function is outside of the Travel_Course() function and is activated after a certain time period which
was manually calculated. This time period is the time that the car takes to traverse the entire course and go part
the start point again. For our particular car and black line algorithm this time is around 36 seconds. The time
interval is controlled by the timer interrupt which I have set to go off every 1 millisecond. When the time interval
has been reached, the car first stops, then activates a 180 degree clockwise turn by setting the left motor forward
and the right motor in reverse. After the turn is completed, the car pauses for a second and then re-enables
GO_COURSE so that the Travel_Course function will take over and restart the course in reverse.

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 33 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

8.4. Interrupt Blocks


Interrupts contain ISRs for the Switches and TimerA0 and the ADC. The following is the current implementation of
the interrupts, though these are very configurable.
In the case of the Switches, Interrupts are triggered (Hi/Lo) when the switch is pressed.
The timer interrupt, when enabled, allows the preconfigured timer to count to a value defined in a control register
and triggers when that count is complete. The process repeats itself until the timer is disabled.

Serial Int

SWITCH 1 Int

MAIN Enable
TimerA0

SWITCH 2 Int

ADC Int

Switch Interrupt
The Switch interrupt is initiated upon switch press. The predefined interrupt vector ( PORT4_VECTOR) is defined
to trigger for either switch press. Within the interrupt service routine, an “if” statement checks which switch was
pressed based on the state of the interrupt flag and handles the press accordingly.
Switch 1:
The Interrupt is disabled, the flag is cleared, a global debounce_count_SW1 is reset, a global switch_press
is set to Switch 1 (indicating that switch 1 was pressed), Switch_Process() is called to perform desired action based
on SW1 press, and enable_TimerA0() is called.
Current implementation – Switch 1 is used as a select switch, so a user scrolls through available menu items and
by pressing switch 1, is ‘selecting’ that menu option.
Switch 2:
The Interrupt is disabled, the flag is cleared, a global debounce_count_SW2 is reset, a global switch_press
is set to Switch 2 (indicating that switch 2 was pressed), Switch_Process() is called to perform desired action based
on SW2 press, and enable_TimerA0() is called.
Current implementation – Switch 2 is currently set to reset the selection. It is a way to allow the user to ‘back out’
of any menu selection. It sets all global variables used in menu selection to reset, and clears the LCD of current
selected menu options.
Timer A0
Timer A0, when enabled, increments a count to the value stored in CCR0 register, triggers the interrupt, adds the
count value to the register and continues incrementing. The current count for Timer A0 is 500, which with the clock
and Timer configuration used makes its frequency about 1000Hz.
The Timer Interrupt increments the CCR0 registry to add more to the timer interval, increments the global
flash_count (used to flash the LED4 every 200 timer interrupts), calls Flash_LED4() (function that actually process
Date: Document Number: Rev: Sheet:
This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 34 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

the LED4 flash), and calls Check_Switch_Press(), which handles the switch press debounce and controls sensitivity
of the switch press.

Timer A1
Timer A1, when enabled, increments a count to the value stored in CCR0 register, triggers the interrupt, adds the
count value to the register and continues incrementing. The current count for Timer A0 is 500, which with the clock
and Timer configuration used makes its frequency about 1000Hz.
The Timer Interrupt increments the CCR0 registry to add more to the timer interval, the global timer_count is
incremented, increments the global flash_count (used to flash the LED4 every 200 timer interrupts), and calls
Flash_LED4() (function that actually process the LED4 flash). This timer is a dedicated timer used in the
fivemsec_timer(); function call. This dedicated usage is to allow for more accurate timing of the function.

ADC
The ADC interrupt processes the data collected and converted by the Analog to Digital Converter. The interrupt,
based on an internal timer, evaluates the manner of interrupt and within a switch statement, stores binary data in
global variables.
Within the switch statement, a global variable ADC_Channel, is incremented each time through. This variable
dictates which case within the switch will be executed. the cases are each individual ADC source and when in the
process of one source, the next source is ‘cued’ up.
For instance, when in the case for the LEFT_DETECTOR, the next source for the ADC to process is enabled,
disabling the LEFT_DETECTOR monitor. However, the memory location that is the storage for the ADC currently
contains data from the LEFT_DETECTOR and that data is stored in the global ADC_Left_Detector to be processed
outside of the ISR. After this data transfer has happened, the switch statement breaks and the next sample is
taken. When the ISR is again called, the switch statement will now look at the next channel (right detector) and the
process continues.

Serial
The Serial Communications interrupt operates by monitoring the RX pin on the processor (Port2.6). Currently,
serial communications configured by the ASC1 interrupt communicates at 4800 baud and handles one byte at a
time. Once the RX pin receives a byte of data, the interrupt flag is raised and in the ISR defined for this flag, the
data held in the RX memory location is written to the GPS_Char_Buff array. This array is a holding area for data
received from the Serial Communications UART.
In Main, a separate function is called every cycle to verify if any new data has been written to the GPS_Char_Buff
by comparing two global variables. If the two globals are not identical, new data has been written to the and
needs processing as the GPS_Char_Buff array is limited in size. GPS_Buff is a larger array which holds
ultimately will hold the data received from Serial Communications.

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 35 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

9. Software Listing
This is just a printout of the actual code, with each file in its own section.
9.1. Main.c
//******************************************************************************
// File: Main.c
// Description: This file contains the Main Routine - "While" Operating System
//
//
// Kyle Santos
// Sep 26 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************
//------------------------------------------------------------------------------
#include "msp430.h"
#include "functions.h"
#include "macros.h"
// Global Variables
volatile unsigned char control_state[CNTL_STATE_INDEX];
volatile char slow_input_down;
extern char *display_1;
extern char *display_2;
char led_smclk;
extern volatile int shape_sel = NULL;
extern volatile short int shape_exec = NOT_READY;
volatile short int debounce_count_SW1 = NULL;
volatile short int debounce_count_SW2 = NULL;
volatile int flash_count = NULL;
volatile short int switch_press = NULL;
volatile int sleep_timer= NULL;
int sleep_request = NULL;
//******************************************************************************
// Function: void main()
// Description: Main initialize all ports and variables. Upon finishing initialization
// main enters a loop, where a function call is made
// to handle current state. Button presses are handled as interrupts and state changes are handled through function calls.
// After switch press is handled, LCD is updated to reflect new state.
//
// Kyle Santos
// October 17 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 36 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

//******************************************************************************
void main(void){
led_smclk = USE_LED5;
// led_smclk = USE_SMCLK;
Init_Ports(); // Initialize Ports
Init_Clocks(); // Initialize Clock System
Init_Conditions(); // Initialize Variables and Initial Conditions
Init_Timers(); // Initialize Timers
fivemsec_timer(QUART_SEC); // 250 msec delay for the clock to settle
Init_SPI_B0(); // Initialize SPI Bus
Init_LEDs(); // Initialize LEDs
Init_LCD(); // Initialize LCD
fivemsec_timer(MEDIUM); // 375 msec delay for the clock to settle
Init_Switch(); // Initialize Switches
Init_ADC();

PJOUT |= LED1; // Turn LED 1 on to indicate boot

ADC_Start();

while(ALWAYS) { // Can the Operating system run


if(slow_input_down){
slow_input_down = NO; // No need to check for changes in commands
if(control_state[2] & BLINK_LED){ // Determine if GPS is available
PJOUT ^= LED1; // Change LED 1 to indicate operation
}
}
Menu_Process(); //Process/update menu LCD
Check_Execute(); //Check to see if function needs to be executed
}

}
//------------------------------------------------------------------------------

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 37 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

9.2. Ports.c
//******************************************************************************
// File: Ports.c
// Description: This file contains the Initiate Functions Routine
//
//
// Kyle Santos
// Sep 23 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************
//------------------------------------------------------------------------------
#include "msp430.h"
#include "functions.h"
#include "macros.h"
//------------------------------------------------------------------------------
//******************************************************************************
// FUNCTION: void Init_Ports()
// Description: This function calls separate initialization functions for all ports
// on the processor. Returns when done
//
// Kyle Santos
// Sep 23 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************
//------------------------------------------------------------------------------
void Init_Ports() {
extern volatile unsigned char control_state[CNTL_STATE_INDEX];

Init_Port1(); //initialize port 1


Init_Port2(); // initialize port 2
Init_Port3(NULL); //initialize port 3 with no argument
Init_Port4(); //initialize port 4
Init_PortJ(); //initialize J Ports

return;
}
//------------------------------------------------------------------------------
//******************************************************************************
// Function: void Init_Port1()
// Description: This Function initializes all pins on Port 1, setting function,

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 38 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

// direction, default output setting, and misc. other settings. Returns void when done.
//
// Kyle Santos
// Sep 23 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

//------------------------------------------------------------------------------
void Init_Port1(void){
// Set Selections bits*******************************************************
P1SEL0 = CLEAR; // P1 set default as I/0
P1SEL1 = CLEAR; // P1 set default as I/0
P1SEL0 &= ~SIMO_B; // SPI Function SIMO_B selected
P1SEL1 |= SIMO_B; // SPI Function SIMO_B selected
P1SEL0 |= V_DETECT_R; // Analog V_DETECT_R selected
P1SEL1 |= V_DETECT_R; // Analog V_DETECT_R selected
P1SEL0 |= V_DETECT_L; // Analog V_DETECT_L selected
P1SEL1 |= V_DETECT_L; // Analog V_DETECT_L selected
P1SEL0 |= V_THUMB; // Analog V_THUMB selected
P1SEL1 |= V_THUMB; // Analog V_THUMB selected
P1SEL0 &= ~IR_LED; // IR_LED set to GPIO
P1SEL1 &= ~IR_LED; // IR_LED set to GPIO
P1SEL0 &= ~GPS_RESET; // GPS_RESET set to GPIO
P1SEL1 &= ~GPS_RESET; // GPS_RESET set to GPIO
P1SEL0 &= ~GPS_PWRCHK; //GPS_PWRCHK set to GPIO
P1SEL1 &= ~GPS_PWRCHK; //GPS_PWRCHK set to GPIO
P1SEL0 &= ~RS_LCD; //RS_LCD set to GPIO
P1SEL1 &= ~RS_LCD; //RS_LCD set to GPIO

//P1 Default Output Settings**************************************************

P1OUT = LOW; // Set all outputs low


P1OUT &= ~GPS_RESET; // Set GPS_RESET low
P1OUT &= ~IR_LED; // Set IR_LED low
P1OUT |= SIMO_B; // Set high Configure for pull-up resistor
P1OUT |= RS_LCD; // Set high Configure for pull-up resistor

P1REN |= RS_LCD; // Enable pull-up resistor


P1REN |= SIMO_B; // Enable pull-up resistor

//P1 Direction Bits******************************************************


Date: Document Number: Rev: Sheet:
This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 39 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

P1DIR = CLEAR; // Set P1 default direction to input

//Output
P1DIR |= SIMO_B; // SIMO_B set to Output
P1DIR |= RS_LCD; // Set P1 RS_LCD direction to output
P1DIR |= GPS_RESET; // Set P1 GPS_RESET direction to output
P1DIR |= IR_LED; // Set P1 IR_LED direction to output

//INPUT
P1DIR &= ~V_DETECT_R; //V_DETECT_R set to input
P1DIR &= ~V_DETECT_L; //V_DETECT_L set to input
P1DIR &= ~V_THUMB; //V_THUMB set to input
P1DIR &= ~GPS_PWRCHK; //GPS_PWRCHK set to input
}
//------------------------------------------------------------------------------
//******************************************************************************
// Function: void Init_Port2()
// Description: This Function initializes all pins on Port 2, setting function,
// direction, default output setting, and misc. other settings. Returns void when done.
//
// Kyle Santos
// Sep 23 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

void Init_Port2(void){
// Set Selections bits*******************************************************
P2SEL0 |= CLEAR; //Set all select bits to GPIO
P2SEL1 |= CLEAR; //Set all select bits to GPIO
P2SEL0 &= ~SPI_SCK; // SPI Function SPI_SCK selected
P2SEL1 |= SPI_SCK; // SPI Function SPI_SCK selected
P2SEL0 &= ~(USB_TXD + USB_RXD); // Configure UART pins P2.0 & P2.1
P2SEL1 |= USB_TXD + USB_RXD; // Configure UART pins P2.0 & P2.1
P2SEL0 &= ~(CPU_RXD + CPU_TXD); // Configure UART pins P2.0 & P2.1
P2SEL1 |= CPU_RXD + CPU_TXD; // Configure UART pins P2.0 & P2.1

//P2 Default Output Settings**************************************************


P2OUT = LOW; //Set all output pins to default low
P2OUT |= SPI_SCK; //Set high configure for pull-up

P2REN |= SPI_SCK; // Enable pull-up resistor


Date: Document Number: Rev: Sheet:
This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 40 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

//P2 Direction Bits**********************************************************


P2DIR |= INPUT; //Set all select pins to input
P2DIR |= USB_TXD | CPU_TXD; //Set USB/CPU_TXT to outputs
// P2DIR |= SPI_SCK; // SPI_SCK set to Output
// P2DIR |= TEST_SIG;
// P2OUT &= ~TEST_SIG;

}
//------------------------------------------------------------------------------

//******************************************************************************
// Function: void Init_Port3()
// Description: This Function initializes all pins on Port 3, setting function,
// direction, default output setting, and misc. other settings. Returns void when done.
//
// Kyle Santos
// Sep 23 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

void Init_Port3(char clock_state){

// Set Selections bits*******************************************************


P3SEL0 = CLEAR; //Set all inputs to GPIO
P3SEL1 = CLEAR; //Set all inputs to GPIO

//P3 Default Output Settings**************************************************


P3OUT = LOW; //Set all output pins to default low

//P3 Direction Bits**********************************************************

P3DIR = INPUT;
P3DIR |= GPS_PWRCNTL | R_FORWARD | R_REVERSE | L_FORWARD | L_REVERSE; //Set GPS pwr cntr, R/L Forward,
R/L Reverse to output
}
//------------------------------------------------------------------------------

//******************************************************************************
// Function: void Init_Port4()
// Description: This Function initializes all pins on Port 4, setting function,

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 41 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

// direction, default output setting, and misc. other settings. Returns void when done.
//
// Kyle Santos
// Sep 23 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

void Init_Port4(void){
// Set Selections bits*******************************************************

P4SEL0 = INPUT; //Set all ports to GPIO


P4SEL1 = INPUT; //Set all ports to GPIO

//P4 Default Output Settings**************************************************


P4OUT = LOW; //Set all output pins to default low
P4OUT |= SW1 | SW2; //Configure Pull-up Resistor

P4REN |= SW1 | SW2; //Enable Pull up resistor


P4IES |= SW1 | SW2; //P4.0 Hi/Lo edge interrupt

//P4 Direction Bits**********************************************************


P4DIR = INPUT; //Set all ports to input
P4DIR &= ~(SW1 | SW2); //Set SW1 & SW2 to input
}
//------------------------------------------------------------------------------
//******************************************************************************
// Function: void Init_PortJ()
// Description: This Function initializes all pins on J Ports, setting function,
// direction, default output setting, and misc. other settings. Returns void when done.
//
// Kyle Santos
// Sep 23 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

void Init_PortJ(void){
// Set Selections bits*******************************************************
PJSEL0 = INPUT;
PJSEL1 = INPUT;

//PJ Default Output Settings**************************************************


Date: Document Number: Rev: Sheet:
This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 42 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

PJOUT = LED1 | LED2 | LED3 | LED4; //Set all outputs to default low
PJOUT &= ~LED1; control_state[SEC_CHAR] &= ~LED1; // Set INACTIVE record value in control_state
PJOUT &= ~LED2; control_state[SEC_CHAR] &= ~LED2; // Set INACTIVE record value in control_state
PJOUT &= ~LED3; control_state[SEC_CHAR] &= ~LED3; // Set INACTIVE record value in control_state
PJOUT &= ~LED4; control_state[SEC_CHAR] &= ~LED4; // Set INACTIVE record value in control_state

//PJ Direction Bits**********************************************************


PJDIR = INPUT; //Set all ports to input
PJDIR |= LED1 | LED2 | LED3 | LED4; //Set LED 1-4 to output
}
//------------------------------------------------------------------------------

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 43 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

9.3. Switch.c
//******************************************************************************
// File: switch.c
// Description: This file contains the Switch Routine. All switch states and corresponding
// functions to handle those states are defined here. Currently designed to handle
// shape selection and Project 5 functionality.
//
//
// Kyle Santos
// October 15 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

//------------------------------------------------------------------------------
#include "msp430.h"
#include "functions.h"
#include "macros.h"

//Global Variables for Switch.c


char switch_ready;
short int debounce1_count;
extern char *display_1;
extern char *display_2;
extern volatile short int switch_press;
extern volatile short int debounce_count_SW1;
extern volatile short int debounce_count_SW2;
extern volatile int shape_sel;
extern volatile short int shape_exec;
extern int short top_level;
extern int short bottom_level;
int short func_exe = NULL;
int short user_ready = NULL;

//******************************************************************************
// Function: Init_Switch();
// Description: This function initializes the switch settings. When function is
// called, display is set to default setting and switch ready indicator set to ready
// Switch 1 and 2 are both defined as interrupts and both interrupts are enabled. Both interrupts also
// set to hi/low edge interrupts

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 44 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

//
//
// Kyle Santos
// October 15 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

void Init_Switch(void){ //Switch initialization


P4IES &= ~SW1; // disable SW1 interrupt
P4IFG &= ~SW1; // remove any existing SW1 interrupt flags
P4IES &= ~SW2; // disable SW1 interrupt
P4IFG &= ~SW2; // remove any existing SW1 interrupt flags

switch_ready = READY; //Ready status se to READY

sw1_enable(); // Enable Switches


sw2_enable();

}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//******************************************************************************
// Function: sw1_enable();
// Description: Clears the interrupt flag and enables the interrupt for Switch 1
//
// Kyle Santos
// October 15 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

void sw1_enable(void) {
P4IFG &= ~SW1; //disable SW1 interrupt flag
P4IE |= SW1; //enable SW1 Interrupt

}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//******************************************************************************
// Function: sw2_enable();
Date: Document Number: Rev: Sheet:
This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 45 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

// Description: Clears the interrupt flag for Switch 2 and enables the interrupt for Switch 2
//
// Kyle Santos
// November 1 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************
void sw2_enable(void) {
P4IFG &= ~SW2; //disable SW1 interrupt flag
P4IE |= SW2; //enable SW1 Interrupt
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//******************************************************************************
// Function: Switch_Process();
// Description: This function is called by the port 4 interrupt to process the status of the button press,
// displaying the status of the interrupt on the LCD and enabling TimerA0.
// Current implementation: switch 1 is the select button (first press leads to verification, second press selects function)
// Switch 2 is the reset button
//
// Kyle Santos
// November 1 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************
void Switch_Process(){

switch(switch_press) {

case SW_1: //SW1 pressed, indicate on display line 2


if(user_ready == NULL) {
display_2 = " Execute? ";
// 123456789012345
user_ready = READY;
}else if(user_ready == READY) {
display_2 = " EXECUTING ";
// 123456789012345
func_exe = READY;
}

break;
case SW_2: // SW2 pressed, menu is to be reset!
Date: Document Number: Rev: Sheet:
This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 46 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

user_ready = NULL;
func_exe = NULL;
display_2 = " ";
// 1234567890123456

Splash_Display(); //update display


}
} // end of function
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//******************************************************************************
// Function: Check_Switch_Press();
// Description: This function checks the state of the onboard button press.
// If a port 4 interrupt is triggered, the ISR calls the TimerA0 interrupt which calls this function to check which
// button was pressed, increments a debounce global which returns to TimerA0 until the threshold is met
// Once the debounce threshold is met, the global switch variable is set to NULL, the switch is re-enabled and TimerA0 interrupt
is disabled.
// LED4 is disabled for consistency of MSP430.
//
// Kyle Santos
// November 1 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************
void Check_Switch_Press(void){

if (switch_press & SW1){


debounce_count_SW1++; // Add to debounce count
if (debounce_count_SW1 >= DEBOUNCE_THRESHOLD){ //if debounce met

switch_press &= ~SW1; //disable switch_press indicator


sw1_enable(); //reenable SW1
disable_TimerA0(); //Disable TimerA0
PJOUT &= ~LED4; //Set LED4 off
}
}
if (switch_press & SW2){
debounce_count_SW2++; // Add to debounce count
if (debounce_count_SW2 >= DEBOUNCE_THRESHOLD){//if debounce met

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 47 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

switch_press &= ~SW2; //disable switch_press indicator


sw2_enable(); //reenable SW2
disable_TimerA0(); //Disable timerA0
PJOUT &= ~LED4; //Set LED4
}
}

} // end of function
//------------------------------------------------------------------------------

// The following is to maintain compatibility between modules


//******************************************************************************
//------------------------------------------------------------------------------
void switch_control(void){
}
//------------------------------------------------------------------------------
//******************************************************************************

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 48 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

9.4. System_Init.c
Timers

Init_Timers(void)
//******************************************************************************
// Function: void Init_Timers(void)
// Description: This function initiallizes all programmable timers by calling their independant
// initialization functions. Currently, only TimerA0, TimerA1, and TimerB2 are initialized.
//
// Kyle Santos
// Sep 23 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)

//******************************************************************************

void Init_Timers(void){
Init_Timer0_A();
Init_Timer1_A(); //
// Init_Timer_B0(); //
// Init_Timer_B1(); //
Init_Timer_B2(); // Required for provided compiled code to work
}
//------------------------------------------------------------------------------

Init_Timer0_A(void)
//******************************************************************************
// Function: void Init_Timer0_A(void)
// Description: This function initiallizes all aspects of the TimerA0 configuration:
// SM Clock selected, reset of the divider and direction register settings.
// timer is set to count up continuous
// Timing: SMCLK = 8,000,000 / 2 /8 /TA0CCRO (500) = .001 seconds
//
// Kyle Santos
// October 12 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 49 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

//******************************************************************************

//------------------------------------------------------------------------------
// Timer A0 initialization sets up both A0_0 and A0_1-A0_2
void Init_Timer0_A(void) {

TA0CCTL0 = NULL; //clear capture/compare register


TA0CTL &= ~TAIFG; // Clear Overflow Interrupt flag
TA0CTL = TASSEL__SMCLK; // SMCLK source
TA0CTL |= TACLR; // Resets TA0R, clock divider, count direction
TA0CTL |= MC__CONTINOUS; // Continuous up
TA0CTL |= ID__2; // Divide clock by 2
TA0CTL &= ~TAIE; // Disable Overflow Interrupt

TA0EX0 = TAIDEX_7; // Divide clock by an additional 8

TA0CCTL0 &= ~CCIFG; //Clear timer A0 interrupt flag

TA0CCR0 = TA0CCR0_INTERVAL; // CCR0 - Divide clock by another 500 for 1 msec


//******************************************************************************

Init_Timer1_A(void)
//******************************************************************************
// Function: void Init_Timer1_A(void)
// Description: This function initiallizes all aspects of the TimerA1 configuration:
// SM Clock selected, reset of the divider and direction register settings.
// timer is set to count up continuous
// Timing: SMCLK = 8,000,000 / 2 /8 /TA1CCRO (500) = .001 seconds
// Redundant Timer for specific sleep timer (fivemsec_timer()) function call.
//
// Kyle Santos
// October 15 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//------------------------------------------------------------------------------
// Timer A1 initialization sets up both A1_0 and A1_1-A1_2
void Init_Timer1_A(void) {

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 50 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

TA1CCTL0 = NULL; //clear capture/compare register


TA1CTL &= ~TAIFG; // Clear Overflow Interrupt flag
TA1CTL = TASSEL__SMCLK; // SMCLK source
TA1CTL |= TACLR; // Resets TA0R, clock divider, count direction
TA1CTL |= MC__CONTINOUS; // Continuous up
TA1CTL |= ID__2; // Divide clock by 2
TA1CTL &= ~TAIE; // Disable Overflow Interrupt
TA1CTL &= ~TAIFG; // Clear Overflow Interrupt flag

TA1EX0 = TAIDEX_7; // Divide clock by an additional 8


TA1CCTL0 &= ~CCIFG; //Clear timer A1 interrupt flag
TA1CCR0 = TA1CCR0_INTERVAL; // CCR0

// TA0CCTL0 |= CCIE; // CCR0 enable interrupt

TA1CCR1 = TA1CCR1_INTERVAL; // CCR1


//------------------------------------------------------------------------------

Analog to Digital Converter

Init_ADC(void)
//******************************************************************************
// Function: void Init_ADC(void)
// Description: Initializes analog to digital converter. Set up in single sequence mode,
// 10-bit resolution, and currently monitors 3 analog voltage sources: Thumb wheel, left LED detect
// & right LED detect
//
// Kyle Santos
// October 17 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************
void Init_ADC(void){
ADC10CTL0 = RESET_STATE; // Clear ADC10CTL0
ADC10CTL0 |= ADC10SHT_2; // 16 ADC clocks
ADC10CTL0 &= ~ADC10MSC; // Single Sequence
ADC10CTL0 |= ADC10ON; // ADC ON - Core Enabled
ADC10CTL1 = RESET_STATE; // Clear ADC10CTL1
ADC10CTL1 |= ADC10SHS_0; // ADC10SC bit
Date: Document Number: Rev: Sheet:
This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 51 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

ADC10CTL1 |= ADC10SHP; // SAMPCON signal sourced from sampling timer


ADC10CTL1 &= ~ADC10ISSH; // The sample-input signal is not inverted.
ADC10CTL1 |= ADC10DIV_0; // ADC10_B clock divider – Divide by 1.
ADC10CTL1 |= ADC10SSEL_0; // MODCLK
ADC10CTL1 |= ADC10CONSEQ_0; // Single-channel, single-conversion
ADC10CTL2 = RESET_STATE; // Clear ADC10CTL2
ADC10CTL2 |= ADC10DIV_0; // Pre-divide by 1
ADC10CTL2 |= ADC10RES; // 10-bit resolution
ADC10CTL2 &= ~ADC10DF; // Binary unsigned
ADC10CTL2 &= ~ADC10SR; // supports up to approximately 200 ksps
ADC10MCTL0 = RESET_STATE; // Clear ADC10MCTL0
ADC10MCTL0 |= ADC10SREF_0; // V(R+) = AVCC and V(R-) = AVSS
ADC10MCTL0 |= ADC10INCH_0; // Channel A3 Thumb Wheel
ADC10IE |= ADC10IE0; // Enable ADC conversion complete interrupt
}
//------------------------------------------------------------------------------

Switches

Init_Swtich
//******************************************************************************
// Function: Init_Switch();
// Description: This function initializes the switch settings. When function is
// called, display is set to default setting and switch ready indicator set to ready
// Switch 1 and 2 are both defined as interrupts and both interrupts are enabled. Both interrupts also
// set to hi/low edge interrupts
//
//
// Kyle Santos
// October 15 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************
void Init_Switch(void){ //Switch initialization

sw1_enable();
sw2_enable();

switch_ready = READY; //Ready status se to READY

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 52 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

}
//------------------------------------------------------------------------------

sw1_enable(void)
//------------------------------------------------------------------------------
//******************************************************************************
// Function: sw1_enable(void);
// Description: Clears the interrupt flag and enables the interrupt for Switch 1
//
// Kyle Santos
// October 15 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

void sw1_enable(void) {
P4IFG &= ~SW1; //disable SW1 interrupt flag
P4IE |= SW1; //enable SW1 Interrupt

}
//------------------------------------------------------------------------------

sw2_enable(void)
//------------------------------------------------------------------------------
//******************************************************************************
// Function: sw2_enable();
// Description: Clears the interrupt flag for Switch 2 and enables the interrupt for Switch 2
//
// Kyle Santos
// November 1 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

void sw2_enable(void) {
P4IFG &= ~SW2; //disable SW1 interrupt flag
P4IE |= SW2; //enable SW1 Interrupt
Date: Document Number: Rev: Sheet:
This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 53 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

}
//------------------------------------------------------------------------------

Ports

Init_Ports(void)

//******************************************************************************
// FUNCTION: void Init_Ports()
// Description: This function calls separate initialization funcitons for all ports
// on the processor. Returns when done
//
// Kyle Santos
// Sep 23 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

//------------------------------------------------------------------------------
void Init_Ports() {
extern volatile unsigned char control_state[CNTL_STATE_INDEX];

Init_Port1(); //initialize port 1


Init_Port2(); // initialize port 2
Init_Port3(NULL); //initialize port 3 with no argument
Init_Port4(); //initialize port 4
Init_PortJ(); //initialize J Ports

return;
}

//------------------------------------------------------------------------------

Init_Port1(void)
//******************************************************************************
// Function: void Init_Port1()
// Description: This Funciton initializes all pins on Port 1, setting function,
// direction, default output setting, and misc. other settings. Returns void when done.
//
// Kyle Santos
// Sep 23 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

//------------------------------------------------------------------------------
void Init_Port1(void){
// Set Selections bits*******************************************************
P1SEL0 = CLEAR; // P1 set default as I/0
P1SEL1 = CLEAR; // P1 set default as I/0
P1SEL0 &= ~SIMO_B; // SPI Function SIMO_B selected
P1SEL1 |= SIMO_B; // SPI Function SIMO_B selected
P1SEL0 |= V_DETECT_R; // Analog V_DETECT_R selected
P1SEL1 |= V_DETECT_R; // Analog V_DETECT_R selected

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 54 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

P1SEL0 |= V_DETECT_L; // Analog V_DETECT_L selected


P1SEL1 |= V_DETECT_L; // Analog V_DETECT_L selected
P1SEL0 |= V_THUMB; // Analog V_THUMB selected
P1SEL1 |= V_THUMB; // Analog V_THUMB selected
P1SEL0 &= ~IR_LED; // IR_LED set to GPIO
P1SEL1 &= ~IR_LED; // IR_LED set to GPIO
P1SEL0 &= ~GPS_RESET; // GPS_RESET set to GPIO
P1SEL1 &= ~GPS_RESET; // GPS_RESET set to GPIO
P1SEL0 &= ~GPS_PWRCHK; //GPS_PWRCHK set to GPIO
P1SEL1 &= ~GPS_PWRCHK; //GPS_PWRCHK set to GPIO
P1SEL0 &= ~RS_LCD; //RS_LCD set to GPIO
P1SEL1 &= ~RS_LCD; //RS_LCD set to GPIO

//P1 Default Output Settings**************************************************

P1OUT = LOW; // Set all outputs low


P1OUT &= ~GPS_RESET; // Set GPS_RESET low
P1OUT &= ~IR_LED; // Set IR_LED low
P1OUT |= SIMO_B; // Set high Configure for pullup resistor
P1OUT |= RS_LCD; // Set high Configure for pullup resistor

P1REN |= RS_LCD; // Enable pullup resistor


P1REN |= SIMO_B; // Enable pullup resistor

//P1 Direction Bits******************************************************


P1DIR = CLEAR; // Set P1 default direction to input

//Output
P1DIR |= SIMO_B; // SIMO_B set to Output
P1DIR |= RS_LCD; // Set P1 RS_LCD direction to output
P1DIR |= GPS_RESET; // Set P1 GPS_RESET direction to output
P1DIR |= IR_LED; // Set P1 IR_LED direction to output

//INPUT
P1DIR &= ~V_DETECT_R; //V_DETECT_R set to input
P1DIR &= ~V_DETECT_L; //V_DETECT_L set to input
P1DIR &= ~V_THUMB; //V_THUMB set to input
P1DIR &= ~GPS_PWRCHK; //GPS_PWRCHK set to input

}
//------------------------------------------------------------------------------

Init_Port2(void)
//******************************************************************************
// Function: void Init_Port2()
// Description: This Funciton initializes all pins on Port 2, setting function,
// direction, default output setting, and misc. other settings. Returns void when done.
//
// Kyle Santos
// Sep 23 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

void Init_Port2(void){
// Set Selections bits*******************************************************

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 55 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

P2SEL0 |= CLEAR; //Set all select bits to GPIO


P2SEL1 |= CLEAR; //Set all select bits to GPIO
P2SEL0 &= ~SPI_SCK; // SPI Function SPI_SCK selected
P2SEL1 |= SPI_SCK; // SPI Function SPI_SCK selected
P2SEL0 &= ~(USB_TXD + USB_RXD); // Configure UART pins P2.0 & P2.1
P2SEL1 |= USB_TXD + USB_RXD; // Configure UART pins P2.0 & P2.1
P2SEL0 &= ~(CPU_RXD + CPU_TXD); // Configure UART pins P2.0 & P2.1
P2SEL1 |= CPU_RXD + CPU_TXD; // Configure UART pins P2.0 & P2.1

//P2 Default Output Settings**************************************************


P2OUT = LOW; //Set all output pins to default low
P2OUT |= SPI_SCK; //Set high configure for pullup

P2REN |= SPI_SCK; // Enable pullup resistor

//P2 Direction Bits**********************************************************


P2DIR |= INPUT; //Set all select pins to input
P2DIR |= USB_TXD | CPU_TXD; //Set USB/CPU_TXT to outputs
// P2DIR |= SPI_SCK; // SPI_SCK set to Output
// P2DIR |= TEST_SIG;
// P2OUT &= ~TEST_SIG;

}
//------------------------------------------------------------------------------

Init_Port3(void)
//******************************************************************************
// Function: void Init_Port3()
// Description: This Funciton initializes all pins on Port 3, setting function,
// direction, default output setting, and misc. other settings. Returns void when done.
//
// Kyle Santos
// Sep 23 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

void Init_Port3(char clock_state){

// Set Selections bits*******************************************************


P3SEL0 = CLEAR; //Set all inputs to GPIO
P3SEL1 = CLEAR; //Set all inputs to GPIO

//P3 Default Output Settings**************************************************


P3OUT = LOW; //Set all output pins to default low

//P3 Direction Bits**********************************************************

P3DIR = INPUT;
P3DIR |= GPS_PWRCNTL | R_FORWARD | R_REVERSE | L_FORWARD | L_REVERSE; //Set GPS pwr cntr,
R/L Forward, R/L Reverse to output

}
//------------------------------------------------------------------------------

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 56 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

Init_Port4(void)
//******************************************************************************
// Function: void Init_Port4()
// Description: This Funciton initializes all pins on Port 4, setting function,
// direction, default output setting, and misc. other settings. Returns void when done.
//
// Kyle Santos
// Sep 23 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

void Init_Port4(void){
// Set Selections bits*******************************************************

P4SEL0 = INPUT; //Set all ports to GPIO


P4SEL1 = INPUT; //Set all ports to GPIO

//P4 Default Output Settings**************************************************


P4OUT = LOW; //Set all output pins to default low
P4OUT |= SW1 | SW2; //Configure Pullup Resistor

P4REN |= SW1 | SW2; //Enable Pull up resistor


P4IES |= SW1 | SW2; //P4.0 Hi/Lo edge interupt

//P4 Direction Bits**********************************************************


P4DIR = INPUT; //Set all ports to input
P4DIR &= ~(SW1 | SW2); //Set SW1 & SW2 to input

}
//------------------------------------------------------------------------------

Init_PortJ(void)
//******************************************************************************
// Function: void Init_PortJ()
// Description: This Funciton initializes all pins on J Ports, setting function,
// direction, default output setting, and misc. other settings. Returns void when done.
//
// Kyle Santos
// Sep 23 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

void Init_PortJ(void){
// Set Selections bits*******************************************************
PJSEL0 = INPUT;
PJSEL1 = INPUT;

//PJ Default Output Settings**************************************************


PJOUT = LED1 | LED2 | LED3 | LED4; //Set all outputs to default low
PJOUT &= ~LED1; control_state[SEC_CHAR] &= ~LED1; // Set INACTIVE record value in control_state
PJOUT &= ~LED2; control_state[SEC_CHAR] &= ~LED2; // Set INACTIVE record value in control_state
PJOUT &= ~LED3; control_state[SEC_CHAR] &= ~LED3; // Set INACTIVE record value in control_state
PJOUT &= ~LED4; control_state[SEC_CHAR] &= ~LED4; // Set INACTIVE record value in control_state

//PJ Direction Bits**********************************************************

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 57 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

PJDIR = INPUT; //Set all ports to input


PJDIR |= LED1 | LED2 | LED3 | LED4; //Set LED 1-4 to output

}
//------------------------------------------------------------------------------

Serial
Init_Serial_UCA1(void)
//******************************************************************************
// Function: void Init_Serial_UCA1(void)
// Description: This function initializes serial processor UCA1 and its corresponding
// interrupts, configuring the default settings and global variables.
// Two global character arrays (GPS_Char_Tx/Rx) are cleared and global position counters
// (gps_rx_ring_wr/rd, gps_tx_ring_wr/tx) are NULLed. The Interrupt is set to trigger on
// data receipt.
//
// The serial UCA1 interrupt uses the SMCLK and has a baudrate set to 4800. Calculations are performed below.
//
//
// 4,800 Baud Rate Calculations
// 1. Calculate N = fBRCLK/Baudrate [if N > 16 continue with step 3, otherwise with step 2]
// N = SMCLK / 4,800 => 8,000,000 / 4,800 = 1666.66666667
// 2. OS16 = 0, UCBRx = INT(N) [continue with step 4]
// 3. OS16 = 1, UCx = INT(N/16), UCFx = INT([(N/16) – INT(N/16)] × 16)
// UCBRx = INT(N/16) = 1666.66666667/16 => 104
// UCFx = INT([(N/16) – INT(N/16)] × 16) = ([1666.66666667/16-INT(1666.66666667/16)]*16) =>
// (104.16666667-104)*16=>0.16666667*16=2
// 4. UCSx can be found by looking up the fractional part of N ( = N - INT(N) ) in Table 18-4
// Decicmal of SMCLK / 8,000,000 / 4,800 = 1666.66666667 => 0.6667 yields 0xD6
// 5. If OS16 = 0 was chosen, a detailed error calculation is recommended to be performed
// TX error (%) RX error (%)
// BRCLK Baudrate UCOS16 UCBRx UCFx UCSx neg pos neg pos
// 8000000 4800 1 104 2 0xD6 -0.08 0.04 -0.10 0.14
//
// Kyle Santos
// October 17 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

//----------------------------------------------------------------------------
void Init_Serial_UCA1(void){
int i;
for(i=NULL; i<SMALL_RING_SIZE; i++){
GPS_Char_Rx[i] = CLEAR;// USB Character
}

gps_rx_ring_wr = NULL;
gps_rx_ring_rd = NULL;

gps_tx_ring_wr = NULL;
gps_tx_ring_rd = NULL;
// Configure UART 1
UCA1CTLW0 = NULL; // Use word register
UCA1CTLW0 |= UCSSEL__SMCLK; // Set SMCLK as fBRCLK
UCA1CTLW0 |= UCSWRST; // Set Software reset enable
Date: Document Number: Rev: Sheet:
This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 58 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

UCA1BRW = 104 ; // 4,800 baud USE UCBRx


// UCA0MCTLW = UCSx concatenate UCFx concatenate UCOS16;
// UCA0MCTLW = 0xD6 concatenate 2 concatenate 1;
UCA1MCTLW = 0xD621 ;
UCA1CTL1 &= ~UCSWRST; // Release from reset
UCA1IE |= UCRXIE; // Enable RX interrupt
}
//----------------------------------------------------------------------------

GPS

gps_system_init(void)
//******************************************************************************
// Function: void gps_system_init(void)
// Description: This Funciton initializes the GPS receiver attached to the MSP430
// test board. The GPS_RESET port pin is enabled and the system pauses slightly to
// allow the external hardware time to respond. Function gps_wakeup is called, which
// powers on the gps device. Upon returning from the function call, GPS_PWRCHK port
// pin is referenced for power signal. If no signal is found, system attempts to
// wake GPS again. LCD is updated at each stage of function.
//
// Kyle Santos
// Sep 23 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

//---------------------------------------------------------// GPS Initialization


void gps_system_init(void){
time_pass = NULL;
P1OUT &= ~GPS_RESET; // GPS_RESET = GPS in Reset;
time_pass = NULL;
while (time_pass <= GPS_START_TIMER){ //pause to make sure GPS_RESET is low
fivemsec_timer(PULSE);
time_pass++;
}

time_pass = NULL;
P1OUT |= GPS_RESET; // GPS_RESET = GPS on Reset;
while (time_pass <= GPS_START_TIMER) { //pause to allow external GPS to reset
fivemsec_timer(PULSE);
time_pass++;
}
display_2 = " GPS Waking Up "; //update Display
// 1234567890123456
Splash_Display();
fivemsec_timer(ONE_SEC);

gps_wakeup(); //call gps_wakeup to turn on GPS


while(!(P1IN & GPS_PWRCHK)){ //check if GPS_PWRCHK pin is showing power from GPS
if (!(P1IN & GPS_PWRCHK)){ // if not, pause and try to start GPS again. Loop until GPS is on
while (time_pass <= GPS_START_TIMER){
fivemsec_timer(PULSE);
time_pass++;
}
Date: Document Number: Rev: Sheet:
This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 59 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

gps_wakeup();
}
}
display_2 = " GPS Ready! ";
// 1234567890123456
Splash_Display();
}
//-----------------------------------------------------------------

gps_wakeup(void)
//******************************************************************************
// Function: void gps_wakeup(void)
// Description: This Funciton enables the pin that begins the powerup process for the GPS.
// The GPS will start low and needs to be driven hi. GPS_PWCNTL is enabled and this signal
// enables the GPS to begin its power up stage. Once the PWRCHK pin is hi and the GPS is at
// full power, the function returns.
//
// Kyle Santos
// November 20 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

//-----------------------------------------------------------------
// GPS Wake-up
void gps_wakeup(void){
int kick_out = TRUE; //kick-out variable.
time_pass = NULL;
while (time_pass <= SHORT_PAUSE){ //pause before start
fivemsec_timer(PULSE);
time_pass++;
}
P3OUT |= GPS_PWRCNTL; // GPS_PWRCNTL = GPS_ON: begin power up process
time_pass = NULL; // reset timer
while ((time_pass <= WAKE_TIME) & kick_out){ //wait a certain amount of time. once time passes and kick-out
variable NULLED, leave
if (P1IN & GPS_PWRCHK){ //check the power check pin if HI...
kick_out = FALSE; // drop kick_out to low and leave loop.
}
fivemsec_timer(PULSE); //slight pause
time_pass++; //increment timer
}
P3OUT &= ~GPS_PWRCNTL; // GPS_PWRCNTL = GPS_Off;
}
//-----------------------------------------------------------------

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 60 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

9.5. Interrupt.c
Interrupt Ports
//******************************************************************************
// File: interrupts_ports.c
// Description: This file contains the Interrupt Routines for the Ports. Currently,
// only Port4 (switches) are enabled and configured. Current Implementation: each
// switch press has a corresponding algorithm assigned to it. SW1 Selects functions
// displayed on the LCD while Switch2 resets selections. All switch functions handled by other function
// ADC interrupt also defined and cycles through each ADC input and processes readings according to source
//
//
// Kyle Santos
// October 31 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

//------------------------------------------------------------------------------
#include "msp430.h"
#include "functions.h"
#include "macros.h"

//------------------------------------------------------------------------------

//******************************************************************************

//Globals Variables
// Switches
extern volatile char switch_states;
extern volatile short int debounce_count_SW1;
extern volatile short int debounce_count_SW2;
extern char *display_1;
extern char *display_2;
extern volatile short int switch_press;
extern volatile short int shape_exec;
extern volatile int shape_sel;
volatile int ADC_Thumb = NULL;
volatile int ADC_Right_Detector = NULL;
volatile int ADC_Left_Detector = NULL;

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 61 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

volatile int ADC_Temp = NULL;


volatile int ADC_Channel = NULL;
volatile int ADC_Bat = NULL;

//******************************************************************************
// Function: __interrupt void switch_interrupt (void);
// Description: This function is the Interrupt Service Routine for the Port 4 Switch interrupt
// When either switch 1 or 2 is pressed, the interrupt flag for that switch is set and this routine is called
// This routine first compares the flag to ID which switch was pressed, disables the corresponding switch interrupt,
// clears the flag, reset the global debounce counter for that switch, sets the global switch_press to indicate which switch was
pressed,
// then processes the function of that switch press by calling Switch_Process().
//
// Kyle Santos
// November 1 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

// Port 4 interrupt. For switches, they are disabled for the duration
// of the debounce timer. Flag is set that user space can check.
#pragma vector=PORT4_VECTOR
__interrupt void switch_interrupt(void) {
// Switch 1
if(P4IFG & SW1) { // if the interrupt flag is for SW1
P4IES &= ~SW1; // disable SW1 interrupt
P4IFG &= ~SW1; // remove any existing SW1 interrupt flags
debounce_count_SW1 = RESET; //reset the SW1 button debounce global
switch_press |= SW_1; // set the state of the switch_press global to indicate SW1 pressed
Switch_Process(); //process the switch press
enable_TimerA0(); //enable timerA0
}
// Switch 2
if (P4IFG & SW2) {// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
P4IES &= ~SW2; // disable SW1 interrupt
P4IFG &= ~SW2; // remove any existing SW1 interrupt flags
debounce_count_SW2 = RESET; //reset the SW1 button debounce global
switch_press |= SW_2; // set the state of the switch_press global to indicate SW1 pressed
Switch_Process(); //process the switch press
enable_TimerA0(); //enable timerA0
}
P4IFG &= ~SW1;

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 62 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

}
//------------------------------------------------------------------------------
//******************************************************************************
Interrupt ADC
//******************************************************************************
// Function: __interrupt void switch_interrupt (void);
// Description: This function is the Interrupt Service Routine for the Port 4 Switch interrupt
// When either switch 1 or 2 is pressed, the interrupt flag for that switch is set and this routine is called
// This routine first compares the flag to ID which switch was pressed, disables the corresponding switch interrupt,
// clears the flag, reset the global debounce counter for that switch, sets the global switch_press to indicate which switch was
pressed,
// then processes the function of that switch press by calling Switch_Process().
//******************************************************************************
// ADC10 interrupt service routine
// ADC_Left_Detector; // A00 ADC10INCH_0 - P1.0
// ADC_Right_Detector; // A01 ADC10INCH_1 - P1.1
// ADC_Thumb; // A03 ADC10INCH_3 - P1.3
// ADC_Temp; // A10 ADC10INCH_10 - Temperature diode from REF module
// ADC_Bat; // A11 ADC10INCH_11 - Internal
//
// Kyle Santos
// November 1 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void){
switch(__even_in_range(ADC10IV,12)){
case NO_INT: break; // No interrupt 0
case RESULT_OVER: break; // conversion result overflow 2
case TIME_OVER: break; // conversion time overflow 4
case ADC_HI: break; // ADC10HI 6
case ADC_LO: break; // ADC10LO 8
case ADC_IN: break; // ADC10IN 10
case ADC_INCHX:
// Need this to change the ADC10INCH_x value. 12
ADC10CTL0 &= ~ADC10ENC; // Toggle ENC bit.
switch (ADC_Channel++){
case LEFT_DETECTOR:
ADC10MCTL0 = ADC10INCH_1; // Next channel A1
ADC_Left_Detector = ADC10MEM0; // Read Channel A0
break;
Date: Document Number: Rev: Sheet:
This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 63 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

case RIGHT_DETECTOR:
ADC10MCTL0 = ADC10INCH_3; // Next channel A3
ADC_Right_Detector = ADC10MEM0; // Read Channel A1
break;
case THUMB:
ADC10MCTL0 = ADC10INCH_11; // Next channel A11
ADC_Thumb = ADC10MEM0; // Read Channel A3
break;
case TEMP:
ADC10MCTL0 = ADC10INCH_10; // Next channel A10
ADC_Temp = ADC10MEM0; // Read Channel A10
break;
case BATT:
ADC10MCTL0 = ADC10INCH_0; // Next channel A0
ADC_Bat = ADC10MEM0; // Read Channel A11
ADC_Channel=RESET;
break;
default:
break;
}
ADC10CTL0 |= ADC10ENC | ADC10SC; // Start next sample.
break;
default: break;
}
}
//------------------------------------------------------------------------------
//******************************************************************************

Interrupt Timers
//******************************************************************************
// File: interrupt_timers.c
// Description: This file contains the Interrupt Routines for Timers. All timer
// interrupt vectors are defined here for each desired ISR. Currently, ISRs are
// only explicitly defined for TimerA0 and TimerA1.
//
//
// Kyle Santos
// October 15 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 64 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

//------------------------------------------------------------------------------
#include "msp430.h"
#include "functions.h"
#include "macros.h"

//------------------------------------------------------------------------------
//Globals Defined in interrupts_timers.c
extern volatile short int debounce_count_SW1;
extern volatile short int debounce_count_SW2;
extern volatile int flash_count;
extern volatile short int switch_press;
extern volatile short int timer_count;
short int timer_on = NULL;
extern volatile int sleep_timer;

//******************************************************************************
// Function: __interrupt void Timer0_A0_ISR(void)
// Description: This function is the Interrupt Service Routine for the Timer A0 vector.
// This routine sets the capture/compare register CCR0 to the desired interval (TA0CCR0_INTERVAL = 500)
// Global flash_count is incremented to be used in Flash_LED4() according to design specifications.
// Flash_LED4 function is called to allow for LED4 flashing (once every 200ms), Check_Switch_Press checks for status of
// onboard switch triggering, and the timer function is checked for the desired timer duration
// This interrupt is configured to process for 1 millisecond
//
// Kyle Santos
// October 15 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//------------------------------------------------------------------------------
// TimerA0 0 Interrupt handler
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer0_A0_ISR(void){
TA0CCR0 += TA0CCR0_INTERVAL; // Add Offset to TACCR0
flash_count++; // Increment global for Flash_LED4()
Flash_LED4(); // Call Flash_LED4()
Check_Switch_Press(); // Call function to check switch

}
//------------------------------------------------------------------------------
/******************************************************************************
//******************************************************************************
// Function: __interrupt void Timer1_A0_ISR(void)
Date: Document Number: Rev: Sheet:
This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 65 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

// Description: This function is the Interrupt Service Routine for the Timer A1 vector.
// This routine sets the capture/compare register CCR0 to the desired interval (TA1CCR0_INTERVAL = 500)
// A flash interval count is incremented according to design specifications.
// Flash_LED4 function is called to allow for LED4 flashing, and the global timer_count is incremented for
// fivemsec_timer() function algorithm.
// This interrupt is configured to process every 1 millisecond when enabled
//
// Kyle Santos
// October 15 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// TimerA1 0 Interrupt handler
#pragma vector = TIMER1_A0_VECTOR
__interrupt void Timer1_A0_ISR(void){
TA1CCR0 += TA1CCR0_INTERVAL; // Add Offset to TACCR0
timer_count++; // Increment global variable for fivemsec_timer()
flash_count++; // Increment global variable for Flash_LED4()
Flash_LED4();
}
//------------------------------------------------------------------------------

Interrupt Serial

//******************************************************************************
// Function: void USCI_A1_ISR(void)
// Description: This function is the Interrupt Service Routine for the serial communications
// interrupt. Currently, the only interrupt defined for this channel is the Receiving
// interrupt. The two byte memory location (UCA1RXBUF) is emptied into a global character array
// GPS_Char_Rx and the array index is incremented. This array is a ring buffer of
// 8 characters total, which is constantly written over. The array must be referenced and its contents
// removed if data is to be preserved.
//
// Kyle Santos
// November 8 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

//------------------------------------------------------------------------------
#pragma vector=USCI_A1_VECTOR

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 66 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

__interrupt void USCI_A1_ISR(void){


unsigned int temp;
switch(__even_in_range(UCA1IV,0x08)){
case NULL: // Vector 0 - no interrupt
break;
case USCI_A1_RX: // Vector 2 - RXIFG
temp = gps_rx_ring_wr++;
GPS_Char_Rx[temp] = UCA1RXBUF; // RX -> USB_Char_Rx character
if (gps_rx_ring_wr > (SMALL_RING_SIZE)){
gps_rx_ring_wr = BEGINNING; // Circular buffer back to beginning
}

break;
case USCI_A1_TX:// Vector 4 – TXIFG

break;
default: break;
}
}
//----------------------------------------------------------------------------

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 67 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

9.6. Serial.c
Init_Serial_UCA1
//******************************************************************************
// Function: void Init_Serial_UCA1(void)
// Description: This function initializes serial processor UCA1 and its corresponding
// interrupts, configuring the default settings and global variables.
// Two global character arrays (GPS_Char_Tx/Rx) are cleared and global position counters
// (gps_rx_ring_wr/rd, gps_tx_ring_wr/tx) are NULLed. The Interrupt is set to trigger on
// data receipt.
//
// The serial UCA1 interrupt uses the SMCLK and has a baudrate set to 4800. Calculations are performed below.
//
//
// 4,800 Baud Rate Calculations
// 1. Calculate N = fBRCLK/Baudrate [if N > 16 continue with step 3, otherwise with step 2]
// N = SMCLK / 4,800 => 8,000,000 / 4,800 = 1666.66666667
// 2. OS16 = 0, UCBRx = INT(N) [continue with step 4]
// 3. OS16 = 1, UCx = INT(N/16), UCFx = INT([(N/16) – INT(N/16)] × 16)
// UCBRx = INT(N/16) = 1666.66666667/16 => 104
// UCFx = INT([(N/16) – INT(N/16)] × 16) = ([1666.66666667/16-INT(1666.66666667/16)]*16) =>
// (104.16666667-104)*16=>0.16666667*16=2
// 4. UCSx can be found by looking up the fractional part of N ( = N - INT(N) ) in Table 18-4
// Decimal of SMCLK / 8,000,000 / 4,800 = 1666.66666667 => 0.6667 yields 0xD6
// 5. If OS16 = 0 was chosen, a detailed error calculation is recommended to be performed
// TX error (%) RX error (%)
// BRCLK Baudrate UCOS16 UCBRx UCFx UCSx neg pos neg pos
// 8000000 4800 1 104 2 0xD6 -0.08 0.04 -0.10 0.14
//
// Kyle Santos
// October 17 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************
//----------------------------------------------------------------------------
void Init_Serial_UCA1(void){
int i;
for(i=NULL; i<SMALL_RING_SIZE; i++){
GPS_Char_Rx[i] = CLEAR;// USB Character
}
Date: Document Number: Rev: Sheet:
This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 68 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

gps_rx_ring_wr = NULL;
gps_rx_ring_rd = NULL;
for(i=NULL; i<LARGE_RING_SIZE; i++){
GPS_Char_Tx[i] = CLEAR;// USB Character
}
gps_tx_ring_wr = NULL;
gps_tx_ring_rd = NULL;
// Configure UART 1
UCA1CTLW0 = NULL; // Use word register
UCA1CTLW0 |= UCSSEL__SMCLK; // Set SMCLK as fBRCLK
UCA1CTLW0 |= UCSWRST; // Set Software reset enable

UCA1BRW = 104 ; // 4,800 baud USE UCBRx


// UCA0MCTLW = UCSx concatenate UCFx concatenate UCOS16;
// UCA0MCTLW = 0x49 concatenate 1 concatenate 1;
UCA1MCTLW = 0xD621 ;
UCA1CTL1 &= ~UCSWRST; // Release from reset
UCA1IE |= UCRXIE; // Enable RX interrupt
}
//----------------------------------------------------------------------------

gps_system_init()
//******************************************************************************
// Function: void gps_system_init(void)
// Description: This Funciton initializes the GPS receiver attached to the MSP430
// test board. The GPS_RESET port pin is enabled and the system pauses slightly to
// allow the external hardware time to respond. Function gps_wakeup is called, which
// powers on the gps device. Upon returning from the function call, GPS_PWRCHK port
// pin is referenced for power signal. If no signal is found, system attempts to
// wake GPS again. LCD is updated at each stage of function.
//
// Kyle Santos
// Sep 23 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 69 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

//---------------------------------------------------------// GPS Initialization


void gps_system_init(void){
time_pass = NULL;
P1OUT &= ~GPS_RESET; // GPS_RESET = GPS in Reset;
time_pass = NULL;
while (time_pass <= GPS_START_TIMER){ //pause to make sure GPS_RESET is low
fivemsec_timer(PULSE);
time_pass++;
}

time_pass = NULL;
P1OUT |= GPS_RESET; // GPS_RESET = GPS on Reset;
while (time_pass <= GPS_START_TIMER) { //pause to allow external GPS to reset
fivemsec_timer(PULSE);
time_pass++;
}
display_2 = " GPS Waking Up "; //update Display
// 1234567890123456
Splash_Display();
fivemsec_timer(ONE_SEC);

gps_wakeup(); //call gps_wakeup to turn on GPS


while(!(P1IN & GPS_PWRCHK)){ //check if GPS_PWRCHK pin is showing power from GPS
if (!(P1IN & GPS_PWRCHK)){ // if not, pause and try to start GPS again. Loop until GPS is on
while (time_pass <= GPS_START_TIMER){
fivemsec_timer(PULSE);
time_pass++;
}
gps_wakeup();
}
}
display_2 = " GPS Ready! ";
// 1234567890123456
Splash_Display();
}
//-----------------------------------------------------------------
//******************************************************************************

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 70 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

void Transmit_GPS(void) {

char transmit_string[] = {"NCSU #1"};


if(okay_to_transmit) {
while(gps_tx_ring_rd < SMALL_RING_SIZE) {

UCA1TXBUF = transmit_string[gps_tx_ring_rd]; //store tx byte to memory


while( !(UCA1IFG & UCTXIFG) ){;} //Wait for TX flag to clear
gps_tx_ring_rd++;
}
okay_to_transmit = NOT_READY;
gps_tx_ring_rd = BEGINNING;
}
}
//----------------------------------------------------------------------------

void gps_wakeup(void)
//******************************************************************************
// Function: void gps_wakeup(void)
// Description: This Funciton enables the pin that begins the powerup process for the GPS.
// The GPS will start low and needs to be driven hi. GPS_PWCNTL is enabled and this signal
// enables the GPS to begin its power up stage. Once the PWRCHK pin is hi and the GPS is at
// full power, the function returns.
//
// Kyle Santos
// November 20 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

//-----------------------------------------------------------------
// GPS Wake-up
void gps_wakeup(void){
int kick_out = TRUE; //kick-out variable.
time_pass = NULL;
while (time_pass <= SHORT_PAUSE){ //pause before start
fivemsec_timer(PULSE);
time_pass++;
}
Date: Document Number: Rev: Sheet:
This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 71 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

P3OUT |= GPS_PWRCNTL; // GPS_PWRCNTL = GPS_ON: begin power up process


time_pass = NULL; // reset timer
while ((time_pass <= WAKE_TIME) & kick_out){ //wait a certain amount of time. once time passes and kick-out
variable NULLED, leave
if (P1IN & GPS_PWRCHK){ //check the power check pin if HI...
kick_out = FALSE; // drop kick_out to low and leave loop.
}
fivemsec_timer(PULSE); //slight pause
time_pass++; //increment timer
}
P3OUT &= ~GPS_PWRCNTL; // GPS_PWRCNTL = GPS_Off;
}
//-----------------------------------------------------------------

void Receive_GPS(void)
//----------------------------------------------------------------------------
//******************************************************************************
// Function: void Receive_GPS(void)
// Description: This function analyzes the position of the global array indexes and compares
// where the read index is in relation to the write index. If they are off, then new data
// has been written to the GPS-Char_Rx by the A1 ISR and values can be added to the more
// flexible, larger array GPS_Buffer. From here, more time can be taken to analyze the
// received data and make the desired decisions on how to handle that data.
//
//
// Kyle Santos
// November 8 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

void Receive_GPS(void) {
int read = gps_rx_ring_rd;
int write= gps_rx_ring_wr;

if(read != write) {
GPS_Buffer[read] = GPS_Char_Rx[gps_rx_ring_rd++];
}
if(gps_rx_ring_rd > SMALL_RING_SIZE) gps_rx_ring_rd = BEGINNING;

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 72 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

}
//----------------------------------------------------------------------------
void disp_buff(void)

//******************************************************************************
// Function: void disp_buff(void)
// Description: This function displays the desired information on the LCD screen.
// In the current project, we're looking for the string transmitted - NCSU #1. First, we analyze the
// position of buff_read and see if it matches the gps_rx_ring_rd location. If not, something was written
// to GPS_Buff. After that analysis, we must next analyze the contents of the buffer. So,
// we analyze the GPS_Buffer for the character N. From there, we display the next 6 characters.
// We then set the global buff_read to match the position of gps_rx_ring_rd.
//
// Kyle Santos
// November 8 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

GPS_Display_Buffer(void)
//******************************************************************************
// Function: void GPS_Display_Buffer(void)
// Description: This Funciton processes the GPS_Rx_Buff array for content. As data content
// can contain garbage and be unusabel, this function parses data and throws away invalid data based on
// format of GPS_Rx_Buff. This helps ensure the final array's contents, GPS_Display_Buff, are valid and
// usable.
//
// Kyle Santos
// November 20 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

void GPS_Display_Buffer(void){
char temp[64];
int i = NULL;

//slow down data parsing.


if(GPS_Buffer[FIRST_CHAR] == '$') { //check for characteristic first icon $
if(GPS_Buffer[SEC_CHAR] != 'G') {new_gps = RESET; return;}

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 73 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

if(GPS_Buffer[THIRD_CHAR] != 'P') {new_gps = RESET; return;}


if(GPS_Buffer[FOURTH_CHAR] != 'G') {new_gps = RESET; return;}
if(GPS_Buffer[FIFTH_CHAR] != 'G') {new_gps = RESET; return;}
if(GPS_Buffer[SIXTH_CHAR] != 'A') {new_gps = RESET; return;}

for(i=NULL; i<LAT_INT; i++) { //copy contents over until Lat integers begin.
temp[i] = GPS_Buffer[i];
}
while(i<LAT_DEC) { //until the decimal in lat data
//check for valid char. These characters should be numbers from 0-9. If not, return and dump data.

if( !(GPS_Buffer[i] >= NUM_LOW) & (GPS_Buffer[i] <= NUM_HI)) {new_gps = RESET; return;}
temp[i] = GPS_Buffer[i]; //contents are valid, add to array.
i++;
}
if(GPS_Buffer[i] != '.') {new_gps = RESET; return;} //check for decimal. if not decimal, dump data
temp[i] = '.'; //decimal found, add to array
i++;

while(i<LAT_FRAC) { //check to end of fraction of latitude data


//check for valid char. These characters should be numbers from 0-9. If not, return and dump data.

if( !(GPS_Buffer[i] >= NUM_LOW) & (GPS_Buffer[i] <= NUM_HI) ) {new_gps = RESET; return;}
temp[i] = GPS_Buffer[i]; //contents valid, add
i++;
}
temp[i++] = ' '; //add space to array
temp[i] = GPS_Buffer[i]; //add content (either N or S)

i++;
i++; //increment to longitude integer location

while(i<LON_INT){ // for all integer values in array


//check for valid char. These characters should be numbers from 0-9. If not, return and dump data.

if( !(GPS_Buffer[i] >= NUM_LOW) & (GPS_Buffer[i] <= NUM_HI)) {new_gps = RESET; return;}
temp[i] = GPS_Buffer[i];// valid, add to content
Date: Document Number: Rev: Sheet:
This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 74 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

i++;
}
if(GPS_Buffer[i] != '.') {new_gps = RESET; return;} //check for decimal
temp[i] = '.';//add decimal
i++;
while(i<LON_DEC) { //until end of fraction of longitude
//check for valid char. These characters should be numbers from 0-9. If not, return and dump data.

if( !(GPS_Buffer[i] >= NUM_LOW) & (GPS_Buffer[i] <= NUM_HI)) {new_gps = RESET; return;}
temp[i] = GPS_Buffer[i];
i++;
}
temp[i++] = ' '; //add space
temp[i] = GPS_Buffer[i];// add char either E or W

while(i<XL_RING_SIZE) {
temp[i] = GPS_Buffer[i];
i++;
}

//GPS_LCD_Display(); //call function to process the display


for(i=NULL; i<XL_RING_SIZE; i++){
GPS_Display_Buff[i] = temp[i];
}
}

new_gps = NULL;//return new_gps to beginning state

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 75 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

Black Line Algorithm Code:


Main.c
//------------------------------------------------------------------------------
// Main Program
// This is the main routine for the program. Execution of code starts here.
// The operating system is Back Ground Fore Ground.
//
//------------------------------------------------------------------------------
void main(void){
led_smclk = USE_LED5;
// led_smclk = USE_SMCLK;
Init_Ports(); // Initialize Ports
Init_Clocks(); // Initialize Clock System
Init_Conditions(); // Initialize Variables and Initial Conditions
Init_Timers(); // Initialize Timers

five_msec_sleep(Fifty_delay); // 250 msec delay for the clock to settle


Init_SPI_B0(); // Initialize SPI Bus
//Init_Switches(); // Initialize Switches
Init_LEDs(); // Initialize LEDs
Init_LCD(); // Initialize LCD
Init_Switch(); // initialize switches after LCD
five_msec_sleep(SeventyFive_delay); // 375 msec delay for the clock to settle
Init_ADC(); // Initialize the ADC and Enable interrupt
Init_Serial_UCA1();
PJOUT |= LED1; // Turn LED 1 on to indicate boot

// lcd_command(CLEAR_DISPLAY);
// Place the contents of what you want on the display, in between the quotes
// Limited to 16 characters per line
//
// display_1 = " N.C. State ";
// display_2 = " Project5 ";
// 1234567890123456
// Splash_Display();

//------------------------------------------------------------------------------
// Begining of the "While" Operating System
//------------------------------------------------------------------------------

ADC_Process();

while(ALWAYS) { // Can the Operating system run


Display_Process();
if(slow_input_down){
slow_input_down = Zero_Test; // No need to check for changes in commands
//menu(); // Check for user commands
if(control_state[CTR_ST_2] & BLINK_LED){ // Determine if GPS is available
PJOUT ^= LED1; // Change LED 1 to indicate operation
}
}
Date: Document Number: Rev: Sheet:
This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 76 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

Switch_Process(); // Check for switch state change SW1 and SW2 (comented out for shapes.c)

if(FINAL_MENU){
// display_1 = " Menu Options ";
//1234567890123456
// Splash_Display();
final_menu();
}

}
//------------------------------------------------------------------------------

Final_menu.c

//*****************************************
//
//
// Function: void final_menu(void)
// Description: This is the final menu for the black line detection
// it contains 4 options based on the ADC_Thumb value
// Black_Threshold, White_Threhsold, Set_Thresholds and Travel_Course
//
//
//
// David Cox
// November 29 2013
// Built with IAR Embedded Workbench Version: V4.10A/W32 (5.40.1)
//******************************************************************************

// Menu functions : Black Threshold, White Threshold, Threshold, Black_Line_Algorithm


void final_menu(void){

int menu_options = ADC_Thumb >> Divide_Menu; // shifts ADC_thumb 8 bit positions giving 4 menu options
//display_1 = " Menu Options ";
//1234567890123456
// Splash_Display();
switch(menu_options){

// case to find the black value


case BLACK_THRESHOLD:

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 77 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

display_1 = "Black Threshold ";


//1234567890123456
Splash_Display();

if(switch_states & SW2){


Turn_Around();

}
break;

// Case to find the white value


case WHITE_THRESHOLD:

display_1 = "White_Threshold ";


//1234567890123456
Splash_Display();

if(switch_states & SW2){ //Switch 2 has been pressed, calibrate White threshold
White_Threshold();
int i;
outhex(ADC_Left_Detector);
for(i=NULL;i<Five;i++){
Left_Detect[i] = adc_char[i];
}

outhex(ADC_Right_Detector);
for(i=NULL;i<Five;i++){
Right_Detect[i] = adc_char[i];
}
Display_ADC();
}

break;

//case to set the white and black thresholds


case SET_THRESHOLDS:

display_1 = "Set_Thresholds ";


//1234567890123456
Splash_Display();

if(switch_states & SW2){


Threshold();
int i;
outhex(WHITE_THRESH); //convert threshold to hex array
for(i=NULL;i<Five;i++){
White_Thresh[i] = adc_char[i]; // put array in varaible
}
outhex(BLACK_THRESH);
for(i=NULL;i<Five;i++){
Black_Thresh[i] = adc_char[i];
}
Display_Threshold(); // display the white and black thresholds
}

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 78 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

break;

// case for function to travel the black line


case TRAVEL_COURSE:

display_1 = " Travel Course ";


//1234567890123456
Splash_Display();

if(switch_states & SW2){


turn_count = NULL;
while(GO_COURSE){

if(GO_TURN == NULL){
P1OUT |= IR_LED;

Travel_Course();
}
else{

Turn_Around();

turn_count = NULL;
GO_TURN = NULL;
}

}
L_FORWARD_OFF();
R_FORWARD_OFF();
}
break;

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 79 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 80 of 81
of this information is strictly prohibited.
Printed 09/19/19 10:46 AM

10. Conclusion
Throughout the projects there have been several large software and hardware tasks. Overall, the hardware is much
easier to install and check to verify correct operation. The hardware could be directly tested through using an
oscilloscope and a digital multi-meter by probing certain nodes of the specific hardware that was being tested.
Correct measurements of voltage, and waveforms produced on the oscilloscope along with using an Ohmmeter to
detect shorts was an effective technique to verify the hardware is working correctly. Also the visual studios code
that accompanies the projects can be used to test the functionality of the hardware through software. The main
challenges associated with the Projects and Homeworks in building this car are contained within software. The
creation of correct and streamlined software to take advantage of and operate the hardware of the car throughout
the different demonstrations was a daunting task. A large challenge was the cumulative nature of the software
design. After each project or homework assignment the previous software had to be updated to function correctly
with the new tasks to be performed. Although debugging is difficult and time consuming, the tools provided within
IAR used for all of the code provided a great environment for solving software problems. The watch window was
extremely useful to verify that variable are updating and contain correct values. Also within IAR breakpoints in the
code are very easy to set. Setting a breakpoint was extremely useful for debugging small sections of code and
finding specifically where a problem is. Overall, though the hardware was very critical, the software to control the
hardware effectively proved to be the hardest tasks in creating the embedded system.
Katherine Foster’s Conclusion
Overall, this class rates on the A+ scale of preparing one for a real-world job. For those who love hardware, the
projects in this course are easy. However, there is a lot of software and for people who would only tolerate it like
myself there will be struggles. It should be noted that if there are any bumps in the road that throw off one’s
schedule, it is essential to devote all time back to getting on track. I can say first hand that it is hard because the
TAs will have moved on, the class will have moved on, and you’ll need the help of your group to get back on
track. Beyond this, the only other negative I can think of would be for students working their way through college.
Make sure you have enough saved up, because this class will require your time first. Perhaps both an advantage
and disadvantage is the team. Make sure you choose a good team and not just ones you are friends with. This
class is a gateway to a good start on your career and skills to aide you in the future.

Date: Document Number: Rev: Sheet:


This document contains information that is PRIVILEGED and
CONFIDENTIAL; you are hereby notified that any dissemination 12/4/2013 6 12 81 of 81
of this information is strictly prohibited.

You might also like