-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.c
188 lines (148 loc) · 6.42 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#include <msp430.h>
#include "robot.h"
/*
* main.c
* Created on: Nov 23, 2014
* Author: C16Erik.Thompson
*/
int32 packet;
int16 packetData[48];
int8 newIRPacket = FALSE;
int8 packetIndex = 0;
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
void main(void) {
initMSP430(); // Setup MSP to process IR and buttons
moveForward();
TA1CTL = ID_3 | TASSEL_2 | MC_1; // Use 1:8 presclar off MCLK
TA1CCR0 = 100; // set signal period
TA1CCR1 = 50;
// TA1CCTL1 = OUTMOD_7; // set TACCTL1 to Reset / Set mode
TA1CCR2 = 50;
// TA1CCTL2 = OUTMOD_3; // set TACCTL2 to Set / Reset mode
while(1) {
//If there is a new packet detected, perform function, otherwise moveforward.
if(newIRPacket){
_disable_interrupt();
if(packet == TWO){
moveForward();
}else if(packet == ZER){
moveBackward();
}else if(packet == THR ){
rotateRight();
}else if(packet == ONE){
rotateLeft();
}else if(packet == PWR){
stop();
}else{
moveForward();
}
_enable_interrupt();
initMSP430();
newIRPacket= FALSE;
}
} // end infinite loop
} // end main
// -----------------------------------------------------------------------
// In order to decode IR packets, the MSP430 needs to be configured to
// tell time and generate interrupts on positive going edges. The
// edge sensitivity is used to detect the first incoming IR packet.
// The P2.6 pin change ISR will then toggle the edge sensitivity of
// the interrupt in order to measure the times of the high and low
// pulses arriving from the IR decoder.
//
// The timer must be enabled so that we can tell how long the pulses
// last. In some degenerate cases, we will need to generate a interrupt
// when the timer rolls over. This will indicate the end of a packet
// and will be used to alert main that we have a new packet.
// -----------------------------------------------------------------------
void initMSP430() {
IFG1=0; // clear interrupt flag1
WDTCTL=WDTPW+WDTHOLD; // stop WD
BCSCTL1 = CALBC1_8MHZ;
DCOCTL = CALDCO_8MHZ;
P2SEL &= ~BIT6; // Setup P2.6 as GPIO not XIN
P2SEL2 &= ~BIT6;
P2DIR &= ~BIT6;
P2IFG &= ~BIT6; // Clear any interrupt flag
P2IE |= BIT6; // Enable PORT 2 interrupt on pin change
HIGH_2_LOW;
//P1DIR |= BIT0 | BIT6; // Enable updates to the LED
//P1OUT &= ~(BIT0 | BIT6); // An turn the LED off
TA0CCR0 = 0xFFFF; // create a 16mS roll-over period
TACTL &= ~TAIFG; // clear flag before enabling interrupts = good practice
TACTL = ID_3 | TASSEL_2 | MC_1; // Use 1:1 presclar off MCLK and enable interrupts
_enable_interrupt();
}
// -----------------------------------------------------------------------
// Since the IR decoder is connected to P2.6, we want an interrupt
// to occur every time that the pin changes - this will occur on
// a positive edge and a negative edge.
//
// Negative Edge:
// The negative edge is associated with end of the logic 1 half-bit and
// the start of the logic 0 half of the bit. The timer contains the
// duration of the logic 1 pulse, so we'll pull that out, process it
// and store the bit in the global packet variable. Going forward there
// is really nothing interesting that happens in this period, because all
// the logic 0 half-bits have the same period. So we will turn off
// the timer interrupts and wait for the next (positive) edge on P2.6
//
// Positive Edge:
// The positive edge is associated with the end of the logic 0 half-bit
// and the start of the logic 1 half-bit. There is nothing to do in
// terms of the logic 0 half bit because it does not encode any useful
// information. On the other hand, we going into the logic 1 half of the bit
// and the portion which determines the bit value, the start of the
// packet, or if the timer rolls over, the end of the ir packet.
// Since the duration of this half-bit determines the outcome
// we will turn on the timer and its associated interrupt.
// -----------------------------------------------------------------------
#pragma vector = PORT2_VECTOR // This is from the MSP430G2553.h file
__interrupt void pinChange (void) {
int8 pin;
int16 pulseDuration; // The timer is 16-bits
if (IR_PIN) pin=1; else pin=0;
switch (pin) { // read the current pin level
case 0: // !!!!!!!!!NEGATIVE EDGE!!!!!!!!!!
pulseDuration = TAR;
//determines if the incomming signal is a 0 or a 1. This is determined by
//the length with the signal is held high, as defined in the header.
if((pulseDuration<maxLogic0Pulse) && (pulseDuration>minLogic0Pulse)){
packet = (packet << 1) | 0;
}
if((pulseDuration<maxLogic1Pulse) && (pulseDuration>minLogic1Pulse)){
packet = (packet << 1) | 1;
}
packetData[packetIndex++] = pulseDuration;
TACTL = 0; //turns off the timer
LOW_2_HIGH; // Setup pin interrupr on positive edge
break;
case 1: // !!!!!!!!POSITIVE EDGE!!!!!!!!!!!
TAR = 0x0000; // time measurements are based at time 0
TA0CCR0=0xFFFF; //need to make sure we set the number we are counting up to.
//this should be enough time.
TACTL = ID_3 | TASSEL_2 | MC_1 | TAIE; //this just sets up how we are counting
//each count will take 8 times as long.
HIGH_2_LOW; // Setup pin interrupr on positive edge
break;
} // end switch
P2IFG &= ~BIT6; // Clear the interrupt flag to prevent immediate ISR re-entry
} // end pinChange ISR
// -----------------------------------------------------------------------
// The main purpose of this interrupt is to create a time gap for every wave that comes in,
// to ensure that the end part of it is not cut off. Also, it serves to reset the packet index
// so that the new packet can be recorded in it's entirety and recorded from the beginning, so
// the signal is not mixed up or placed out of order. Also, it lets the system
// know that a new packet has arrived and that it has been recorded. This allows the
// if statement in the while loop to be satisfied so that we can carry out the purpose
// of the signal received.
// -----------------------------------------------------------------------
#pragma vector = TIMER0_A1_VECTOR // This is from the MSP430G2553.h file
__interrupt void timerOverflow (void) {
TACTL = 0;
TACTL &= ~TAIE;
packetIndex = 0; //get ready for the next one.
newIRPacket = TRUE; //decode the new signal!!!
TACTL &= ~TAIFG; //resets the flag :)
}