Kyle McKeehan
/
DataCommFRDM2
FRDM2
main.cpp@0:906202f8e2f2, 2015-04-16 (annotated)
- Committer:
- n02655194
- Date:
- Thu Apr 16 14:13:01 2015 +0000
- Revision:
- 0:906202f8e2f2
- Child:
- 1:2bba0fcfda85
FRDM2
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
n02655194 | 0:906202f8e2f2 | 1 | #include "mbed.h" |
n02655194 | 0:906202f8e2f2 | 2 | #include "stdio.h" |
n02655194 | 0:906202f8e2f2 | 3 | #include "C12832.h" |
n02655194 | 0:906202f8e2f2 | 4 | |
n02655194 | 0:906202f8e2f2 | 5 | #define MAX 100 //set the size of the character data storage array |
n02655194 | 0:906202f8e2f2 | 6 | #define BYTE 8 |
n02655194 | 0:906202f8e2f2 | 7 | #define NIBBLE 4 //used to set size of data read |
n02655194 | 0:906202f8e2f2 | 8 | #define PREAMBLE 0x7E //preamble of 01111110 |
n02655194 | 0:906202f8e2f2 | 9 | #define POSTAMBLE 0x81 //postamble of 10000001 |
n02655194 | 0:906202f8e2f2 | 10 | #define ADDRESS 0x11 //address of 00010010 - network of 1, id of 2. |
n02655194 | 0:906202f8e2f2 | 11 | #define NETWORK 0x10 //network portion of the address |
n02655194 | 0:906202f8e2f2 | 12 | #define ID 0x02 //id portion of the address |
n02655194 | 0:906202f8e2f2 | 13 | #define BROADCAST 0x00 //address of 00000000 |
n02655194 | 0:906202f8e2f2 | 14 | //multicast using 4bit address / 4 bit network. network = 4 msb, address = 4 lsb. broadcast = all 0's. multicast = network id & address of 0's. |
n02655194 | 0:906202f8e2f2 | 15 | #define CRC 0x13 //crc of 10011 or x^4+x+1 or crc-5 |
n02655194 | 0:906202f8e2f2 | 16 | |
n02655194 | 0:906202f8e2f2 | 17 | |
n02655194 | 0:906202f8e2f2 | 18 | C12832 lcd(p5, p7, p6, p8, p11); //LCD structure |
n02655194 | 0:906202f8e2f2 | 19 | DigitalOut myled(LED1), myled2(LED2), myled3(LED3), myled4(LED4); //variables to access the four blue leds |
n02655194 | 0:906202f8e2f2 | 20 | DigitalIn clock_pin(p21), serial_in(p22); //clock pulse input and data input pins |
n02655194 | 0:906202f8e2f2 | 21 | Timer t; //timer for pausing after postamble received before displaying data |
n02655194 | 0:906202f8e2f2 | 22 | unsigned char temp, data[MAX], crc_calc; //temp byte storage, storage array, transmitted crc value |
n02655194 | 0:906202f8e2f2 | 23 | unsigned char preamble, address, i, j, k; //increment variables |
n02655194 | 0:906202f8e2f2 | 24 | unsigned char data_flag, rflag, d_flag, done, temp_data; //data flags |
n02655194 | 0:906202f8e2f2 | 25 | int crc_passed = 0; //crc flag |
n02655194 | 0:906202f8e2f2 | 26 | int temp_crc = 0; //stores values for crc check. |
n02655194 | 0:906202f8e2f2 | 27 | |
n02655194 | 0:906202f8e2f2 | 28 | //funtion prototypes |
n02655194 | 0:906202f8e2f2 | 29 | void check_byte(int value); //stays inside the function until the received byte matches the value passed into the function (PREAMBLE) |
n02655194 | 0:906202f8e2f2 | 30 | int check_abyte();//after preamble received checks the next byte for address. Returns 1 if address received matches ADDRESS, BROADCAST, or multicast; 0 if not. |
n02655194 | 0:906202f8e2f2 | 31 | int read_byte(int size); //reads received data and returns it a byte at a time. |
n02655194 | 0:906202f8e2f2 | 32 | int check_crc(int temp_crc, unsigned char crc_calc); //double checks the sent crc value - data sent without error. |
n02655194 | 0:906202f8e2f2 | 33 | |
n02655194 | 0:906202f8e2f2 | 34 | //Improvements |
n02655194 | 0:906202f8e2f2 | 35 | //if crc correct display correct crc |
n02655194 | 0:906202f8e2f2 | 36 | //if crc correct send ACK(1) to Master |
n02655194 | 0:906202f8e2f2 | 37 | //if crc wrong, display incorrect crc |
n02655194 | 0:906202f8e2f2 | 38 | //if crc wrong, send NoACK(0) to Master |
n02655194 | 0:906202f8e2f2 | 39 | //if crc wrong adjust for retransmit |
n02655194 | 0:906202f8e2f2 | 40 | |
n02655194 | 0:906202f8e2f2 | 41 | |
n02655194 | 0:906202f8e2f2 | 42 | int main() |
n02655194 | 0:906202f8e2f2 | 43 | { |
n02655194 | 0:906202f8e2f2 | 44 | |
n02655194 | 0:906202f8e2f2 | 45 | //turn off leds |
n02655194 | 0:906202f8e2f2 | 46 | myled = 0; |
n02655194 | 0:906202f8e2f2 | 47 | myled2 = 0; |
n02655194 | 0:906202f8e2f2 | 48 | myled3 = 0; |
n02655194 | 0:906202f8e2f2 | 49 | myled4 = 0; |
n02655194 | 0:906202f8e2f2 | 50 | |
n02655194 | 0:906202f8e2f2 | 51 | //initialize variables |
n02655194 | 0:906202f8e2f2 | 52 | i = 0; |
n02655194 | 0:906202f8e2f2 | 53 | d_flag = 0; |
n02655194 | 0:906202f8e2f2 | 54 | done = 0; |
n02655194 | 0:906202f8e2f2 | 55 | crc_passed=0; |
n02655194 | 0:906202f8e2f2 | 56 | |
n02655194 | 0:906202f8e2f2 | 57 | |
n02655194 | 0:906202f8e2f2 | 58 | while(!d_flag) |
n02655194 | 0:906202f8e2f2 | 59 | { |
n02655194 | 0:906202f8e2f2 | 60 | //clear lcd screen, print current build message |
n02655194 | 0:906202f8e2f2 | 61 | lcd.cls(); |
n02655194 | 0:906202f8e2f2 | 62 | lcd.locate(0,3); |
n02655194 | 0:906202f8e2f2 | 63 | lcd.printf("Waiting for Preamble"); |
n02655194 | 0:906202f8e2f2 | 64 | //read input clock pulse and data checking for preamble. |
n02655194 | 0:906202f8e2f2 | 65 | //preamble while loop |
n02655194 | 0:906202f8e2f2 | 66 | check_byte(PREAMBLE); |
n02655194 | 0:906202f8e2f2 | 67 | |
n02655194 | 0:906202f8e2f2 | 68 | //clear lcd screen, print current build message |
n02655194 | 0:906202f8e2f2 | 69 | lcd.cls(); |
n02655194 | 0:906202f8e2f2 | 70 | lcd.locate(0,3); |
n02655194 | 0:906202f8e2f2 | 71 | lcd.printf("Preamble Received"); |
n02655194 | 0:906202f8e2f2 | 72 | |
n02655194 | 0:906202f8e2f2 | 73 | //preamble received check address (next byte), returns to preamble check if not addressed to station |
n02655194 | 0:906202f8e2f2 | 74 | if(check_abyte()) |
n02655194 | 0:906202f8e2f2 | 75 | d_flag = 1; |
n02655194 | 0:906202f8e2f2 | 76 | } |
n02655194 | 0:906202f8e2f2 | 77 | |
n02655194 | 0:906202f8e2f2 | 78 | while(!done) |
n02655194 | 0:906202f8e2f2 | 79 | { |
n02655194 | 0:906202f8e2f2 | 80 | //store data into character array if crc checks. |
n02655194 | 0:906202f8e2f2 | 81 | data[i] = 0; //initialize current array position to zero |
n02655194 | 0:906202f8e2f2 | 82 | temp_data = read_byte(BYTE); //store successfully transmitted data |
n02655194 | 0:906202f8e2f2 | 83 | |
n02655194 | 0:906202f8e2f2 | 84 | //check for postamble |
n02655194 | 0:906202f8e2f2 | 85 | if(temp_data == POSTAMBLE) |
n02655194 | 0:906202f8e2f2 | 86 | { |
n02655194 | 0:906202f8e2f2 | 87 | //break out of while loop - data finished sending |
n02655194 | 0:906202f8e2f2 | 88 | done = 1; |
n02655194 | 0:906202f8e2f2 | 89 | //clear lcd screen, print current build message |
n02655194 | 0:906202f8e2f2 | 90 | lcd.cls(); |
n02655194 | 0:906202f8e2f2 | 91 | lcd.locate(0,3); |
n02655194 | 0:906202f8e2f2 | 92 | lcd.printf("Postamble Received"); |
n02655194 | 0:906202f8e2f2 | 93 | } |
n02655194 | 0:906202f8e2f2 | 94 | |
n02655194 | 0:906202f8e2f2 | 95 | //store data in character array if not postamble - check crc when appropriate |
n02655194 | 0:906202f8e2f2 | 96 | else |
n02655194 | 0:906202f8e2f2 | 97 | { |
n02655194 | 0:906202f8e2f2 | 98 | data[i] = temp_data; |
n02655194 | 0:906202f8e2f2 | 99 | i++; //increment array position |
n02655194 | 0:906202f8e2f2 | 100 | //store the sent data into temp variable for crc calculation |
n02655194 | 0:906202f8e2f2 | 101 | temp_crc << 8; |
n02655194 | 0:906202f8e2f2 | 102 | temp_crc += temp_data; |
n02655194 | 0:906202f8e2f2 | 103 | //wait until i increments and then check to see if 3 bytes have been received |
n02655194 | 0:906202f8e2f2 | 104 | if( (i % 3) == 0) |
n02655194 | 0:906202f8e2f2 | 105 | { |
n02655194 | 0:906202f8e2f2 | 106 | //check crc |
n02655194 | 0:906202f8e2f2 | 107 | crc_calc = read_byte(NIBBLE); |
n02655194 | 0:906202f8e2f2 | 108 | if(check_crc(temp_crc, crc_calc)) |
n02655194 | 0:906202f8e2f2 | 109 | { |
n02655194 | 0:906202f8e2f2 | 110 | crc_passed=1; |
n02655194 | 0:906202f8e2f2 | 111 | lcd.cls(); |
n02655194 | 0:906202f8e2f2 | 112 | lcd.locate(0,3); |
n02655194 | 0:906202f8e2f2 | 113 | lcd.printf("Data passes CRC verification"); |
n02655194 | 0:906202f8e2f2 | 114 | }else{ |
n02655194 | 0:906202f8e2f2 | 115 | lcd.cls(); |
n02655194 | 0:906202f8e2f2 | 116 | lcd.locate(0,3); |
n02655194 | 0:906202f8e2f2 | 117 | lcd.printf("Data fails CRC verification"); |
n02655194 | 0:906202f8e2f2 | 118 | } |
n02655194 | 0:906202f8e2f2 | 119 | //zero out crc temp variable |
n02655194 | 0:906202f8e2f2 | 120 | temp_crc = 0; |
n02655194 | 0:906202f8e2f2 | 121 | } |
n02655194 | 0:906202f8e2f2 | 122 | } |
n02655194 | 0:906202f8e2f2 | 123 | } |
n02655194 | 0:906202f8e2f2 | 124 | //pause after displaying postamble received and then display data. |
n02655194 | 0:906202f8e2f2 | 125 | t.start(); |
n02655194 | 0:906202f8e2f2 | 126 | //wait until the timer has reached the set time. |
n02655194 | 0:906202f8e2f2 | 127 | while(t.read_ms() < 1000) |
n02655194 | 0:906202f8e2f2 | 128 | { |
n02655194 | 0:906202f8e2f2 | 129 | |
n02655194 | 0:906202f8e2f2 | 130 | } |
n02655194 | 0:906202f8e2f2 | 131 | //stop and reset the timer |
n02655194 | 0:906202f8e2f2 | 132 | t.stop(); |
n02655194 | 0:906202f8e2f2 | 133 | t.reset(); |
n02655194 | 0:906202f8e2f2 | 134 | if(crc_passed){//if crc passes display data, send ACK |
n02655194 | 0:906202f8e2f2 | 135 | //clear debugging messages - and reset lcd to original position before printing data. |
n02655194 | 0:906202f8e2f2 | 136 | //send ACK |
n02655194 | 0:906202f8e2f2 | 137 | lcd.cls(); |
n02655194 | 0:906202f8e2f2 | 138 | lcd.locate(0,3); |
n02655194 | 0:906202f8e2f2 | 139 | lcd.printf("Received: "); |
n02655194 | 0:906202f8e2f2 | 140 | for(k=0; k<=i; k++) |
n02655194 | 0:906202f8e2f2 | 141 | lcd.printf("%c", data[k]); |
n02655194 | 0:906202f8e2f2 | 142 | }else{//if crc fails, send NOACK |
n02655194 | 0:906202f8e2f2 | 143 | //send NoACK |
n02655194 | 0:906202f8e2f2 | 144 | } |
n02655194 | 0:906202f8e2f2 | 145 | } |
n02655194 | 0:906202f8e2f2 | 146 | |
n02655194 | 0:906202f8e2f2 | 147 | void check_byte(int value) |
n02655194 | 0:906202f8e2f2 | 148 | { |
n02655194 | 0:906202f8e2f2 | 149 | data_flag = 1; |
n02655194 | 0:906202f8e2f2 | 150 | temp = 0; |
n02655194 | 0:906202f8e2f2 | 151 | rflag=0; |
n02655194 | 0:906202f8e2f2 | 152 | //while loop |
n02655194 | 0:906202f8e2f2 | 153 | while(!rflag) |
n02655194 | 0:906202f8e2f2 | 154 | { |
n02655194 | 0:906202f8e2f2 | 155 | //read in data if clock is 1 and data flag is 1 |
n02655194 | 0:906202f8e2f2 | 156 | if(clock_pin && data_flag) |
n02655194 | 0:906202f8e2f2 | 157 | { |
n02655194 | 0:906202f8e2f2 | 158 | //data is left shifted into our temporary variable. |
n02655194 | 0:906202f8e2f2 | 159 | //each new data bit is moved into the least significant bit after the rest of the bits are shifted to the left |
n02655194 | 0:906202f8e2f2 | 160 | //data must be sent from the other microcontroller shifted out from the most significant bit to the least significant bit. |
n02655194 | 0:906202f8e2f2 | 161 | temp = (temp << 1) + serial_in; |
n02655194 | 0:906202f8e2f2 | 162 | data_flag = 0; |
n02655194 | 0:906202f8e2f2 | 163 | if(temp == value) |
n02655194 | 0:906202f8e2f2 | 164 | rflag = 1; |
n02655194 | 0:906202f8e2f2 | 165 | } |
n02655194 | 0:906202f8e2f2 | 166 | //when clock returns to low - reset data flag to accept the next bit. |
n02655194 | 0:906202f8e2f2 | 167 | if(!clock_pin && !data_flag) |
n02655194 | 0:906202f8e2f2 | 168 | data_flag = 1; |
n02655194 | 0:906202f8e2f2 | 169 | } |
n02655194 | 0:906202f8e2f2 | 170 | } |
n02655194 | 0:906202f8e2f2 | 171 | |
n02655194 | 0:906202f8e2f2 | 172 | int check_abyte() |
n02655194 | 0:906202f8e2f2 | 173 | { |
n02655194 | 0:906202f8e2f2 | 174 | j = 0; |
n02655194 | 0:906202f8e2f2 | 175 | temp = 0; |
n02655194 | 0:906202f8e2f2 | 176 | rflag=0; |
n02655194 | 0:906202f8e2f2 | 177 | //while loop |
n02655194 | 0:906202f8e2f2 | 178 | while(j<8) |
n02655194 | 0:906202f8e2f2 | 179 | { |
n02655194 | 0:906202f8e2f2 | 180 | //read in data if clock is 1 and data flag is 1 |
n02655194 | 0:906202f8e2f2 | 181 | if(clock_pin && data_flag) |
n02655194 | 0:906202f8e2f2 | 182 | { |
n02655194 | 0:906202f8e2f2 | 183 | //data is left shifted into our temporary variable. |
n02655194 | 0:906202f8e2f2 | 184 | //each new data bit is moved into the least significant bit after the rest of the bits are shifted to the left |
n02655194 | 0:906202f8e2f2 | 185 | //data must be sent from the other microcontroller shifted out from the most significant bit to the least significant bit. |
n02655194 | 0:906202f8e2f2 | 186 | temp = (temp << 1) + serial_in; |
n02655194 | 0:906202f8e2f2 | 187 | j++; |
n02655194 | 0:906202f8e2f2 | 188 | data_flag = 0; |
n02655194 | 0:906202f8e2f2 | 189 | } |
n02655194 | 0:906202f8e2f2 | 190 | //when clock returns to low - reset data flag to accept the next bit. |
n02655194 | 0:906202f8e2f2 | 191 | if(!clock_pin && !data_flag) |
n02655194 | 0:906202f8e2f2 | 192 | data_flag = 1; |
n02655194 | 0:906202f8e2f2 | 193 | } |
n02655194 | 0:906202f8e2f2 | 194 | |
n02655194 | 0:906202f8e2f2 | 195 | //clear lcd screen, print current build message |
n02655194 | 0:906202f8e2f2 | 196 | lcd.cls(); |
n02655194 | 0:906202f8e2f2 | 197 | lcd.locate(0,3); |
n02655194 | 0:906202f8e2f2 | 198 | if(temp == ADDRESS) |
n02655194 | 0:906202f8e2f2 | 199 | { |
n02655194 | 0:906202f8e2f2 | 200 | rflag = 1; |
n02655194 | 0:906202f8e2f2 | 201 | lcd.printf("Address Received"); |
n02655194 | 0:906202f8e2f2 | 202 | } |
n02655194 | 0:906202f8e2f2 | 203 | else if(temp == BROADCAST) |
n02655194 | 0:906202f8e2f2 | 204 | { |
n02655194 | 0:906202f8e2f2 | 205 | rflag = 1; |
n02655194 | 0:906202f8e2f2 | 206 | lcd.printf("Broadcast received"); |
n02655194 | 0:906202f8e2f2 | 207 | } |
n02655194 | 0:906202f8e2f2 | 208 | else if(((temp & 0xF0) == NETWORK) && ((temp & 0x0F) == 0)) |
n02655194 | 0:906202f8e2f2 | 209 | { |
n02655194 | 0:906202f8e2f2 | 210 | rflag = 1; |
n02655194 | 0:906202f8e2f2 | 211 | lcd.printf("Multicast received"); |
n02655194 | 0:906202f8e2f2 | 212 | }//can add if Network==0 and address==x send to x in every network |
n02655194 | 0:906202f8e2f2 | 213 | else |
n02655194 | 0:906202f8e2f2 | 214 | printf("Wrong address received"); |
n02655194 | 0:906202f8e2f2 | 215 | |
n02655194 | 0:906202f8e2f2 | 216 | return rflag; |
n02655194 | 0:906202f8e2f2 | 217 | } |
n02655194 | 0:906202f8e2f2 | 218 | |
n02655194 | 0:906202f8e2f2 | 219 | int read_byte(int size) |
n02655194 | 0:906202f8e2f2 | 220 | { |
n02655194 | 0:906202f8e2f2 | 221 | j = 0; |
n02655194 | 0:906202f8e2f2 | 222 | temp = 0; |
n02655194 | 0:906202f8e2f2 | 223 | |
n02655194 | 0:906202f8e2f2 | 224 | //read a byte/nibble at a time and return it to main |
n02655194 | 0:906202f8e2f2 | 225 | while(j<size) |
n02655194 | 0:906202f8e2f2 | 226 | { |
n02655194 | 0:906202f8e2f2 | 227 | //read in data if clock is 1 and data flag is 1 |
n02655194 | 0:906202f8e2f2 | 228 | if(clock_pin && data_flag) { |
n02655194 | 0:906202f8e2f2 | 229 | //data is left shifted into our temporary variable. |
n02655194 | 0:906202f8e2f2 | 230 | //each new data bit is moved into the least significant bit afater the rest of the bits are shifted to the left |
n02655194 | 0:906202f8e2f2 | 231 | //data must be sent from the other microcontroller shifted out from the most significant bit to the least significant bit. |
n02655194 | 0:906202f8e2f2 | 232 | temp = (temp << 1) + serial_in; |
n02655194 | 0:906202f8e2f2 | 233 | //increment j (tracks bits received) - turn off data_flag until clock changes. |
n02655194 | 0:906202f8e2f2 | 234 | j++; |
n02655194 | 0:906202f8e2f2 | 235 | data_flag = 0; |
n02655194 | 0:906202f8e2f2 | 236 | } |
n02655194 | 0:906202f8e2f2 | 237 | //when clock returns to low - reset data flag to accept the next bit. |
n02655194 | 0:906202f8e2f2 | 238 | if(!clock_pin && !data_flag) |
n02655194 | 0:906202f8e2f2 | 239 | data_flag = 1; |
n02655194 | 0:906202f8e2f2 | 240 | } |
n02655194 | 0:906202f8e2f2 | 241 | return temp; |
n02655194 | 0:906202f8e2f2 | 242 | } |
n02655194 | 0:906202f8e2f2 | 243 | |
n02655194 | 0:906202f8e2f2 | 244 | int check_crc(int temp_crc, unsigned char crc_calc) |
n02655194 | 0:906202f8e2f2 | 245 | { |
n02655194 | 0:906202f8e2f2 | 246 | //assume data sent incorrectly, check crc to see if data sent correctly |
n02655194 | 0:906202f8e2f2 | 247 | int data_correct = 0; |
n02655194 | 0:906202f8e2f2 | 248 | |
n02655194 | 0:906202f8e2f2 | 249 | //shift temp 3 bytes by 4 and add transmitted crc |
n02655194 | 0:906202f8e2f2 | 250 | temp_crc << 4; |
n02655194 | 0:906202f8e2f2 | 251 | temp_crc += crc_calc; |
n02655194 | 0:906202f8e2f2 | 252 | //check for crc correctness |
n02655194 | 0:906202f8e2f2 | 253 | if( (temp_crc % CRC) == 0) |
n02655194 | 0:906202f8e2f2 | 254 | data_correct = 1; |
n02655194 | 0:906202f8e2f2 | 255 | |
n02655194 | 0:906202f8e2f2 | 256 | return data_correct; |
n02655194 | 0:906202f8e2f2 | 257 | } |