Kevin Anderson
/
DataCommFreedom
Using FRDM Board to output data and a clock for communications example.
main.cpp@11:aa30552269b2, 2015-04-30 (annotated)
- Committer:
- askksa12543
- Date:
- Thu Apr 30 14:05:24 2015 +0000
- Revision:
- 11:aa30552269b2
- Parent:
- 10:90cc064f7082
crc fixed
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
askksa12543 | 8:2b61de165543 | 1 | //project to include preamble, addressing, post amble, crc error control. |
askksa12543 | 2:11f32d8cfa11 | 2 | |
askksa12543 | 9:77ae456366f7 | 3 | //after sending - set clock to 0, set timer and check clock pin - if clock pin goes high read in response - 4 bit ack? |
askksa12543 | 9:77ae456366f7 | 4 | |
askksa12543 | 0:7c7f4b30d64f | 5 | #include "mbed.h" |
askksa12543 | 0:7c7f4b30d64f | 6 | #include "stdio.h" |
askksa12543 | 0:7c7f4b30d64f | 7 | |
askksa12543 | 8:2b61de165543 | 8 | #define MAX 100 //set the max size of the character data storage array |
askksa12543 | 8:2b61de165543 | 9 | #define BYTE 128 |
askksa12543 | 10:90cc064f7082 | 10 | #define NIBBLE 8 //used to set binary position of msb |
askksa12543 | 3:027d30718bbc | 11 | #define PREAMBLE 0x7E //preamble of 01111110 |
askksa12543 | 8:2b61de165543 | 12 | #define POSTAMBLE 0x81 //postamble of 10000001 |
askksa12543 | 8:2b61de165543 | 13 | //addressing 1st 4 bits indicate the network, 2nd 4 bits indicate the station id |
askksa12543 | 8:2b61de165543 | 14 | #define ADDRESS 0x12 //address of 00010010 network = 1, station id = 2 |
askksa12543 | 8:2b61de165543 | 15 | #define BROADCAST 0x00 //broadcast address of 00000000 |
askksa12543 | 8:2b61de165543 | 16 | #define MULTICAST 0x10 //broadcast to only network 1, all stations |
askksa12543 | 8:2b61de165543 | 17 | #define CRC 0x13 //crc of 10011 or x^4+x+1 or crc-5 |
askksa12543 | 2:11f32d8cfa11 | 18 | |
askksa12543 | 2:11f32d8cfa11 | 19 | DigitalOut myled(LED1); // red led on board |
askksa12543 | 8:2b61de165543 | 20 | DigitalOut clock_pin(D8), serial_out(D7); //send clock pulse and data |
askksa12543 | 0:7c7f4b30d64f | 21 | Timer t; //timer for controlling the clock and data skew |
askksa12543 | 2:11f32d8cfa11 | 22 | int msecs, sksecs; //clock time needed for data transfer and skew time |
askksa12543 | 8:2b61de165543 | 23 | unsigned char pre = PREAMBLE, add = BROADCAST, post = POSTAMBLE, crc_value = 0; //protocol overhead |
askksa12543 | 8:2b61de165543 | 24 | unsigned char data[MAX] = "Hi Kyle!\n"; //data output |
askksa12543 | 8:2b61de165543 | 25 | int crc_temp = 0; //temporary crc variable |
askksa12543 | 8:2b61de165543 | 26 | unsigned char sent = 0, i = 0, j = 0, skew_flag; //increment variables and flags |
askksa12543 | 8:2b61de165543 | 27 | |
askksa12543 | 8:2b61de165543 | 28 | //function prototypes |
askksa12543 | 8:2b61de165543 | 29 | //send a byte of data, for preamble, postamble, address, and data with BYTE, crc with NIBBLE |
askksa12543 | 8:2b61de165543 | 30 | void send_byte(unsigned char byte, int position); |
askksa12543 | 8:2b61de165543 | 31 | |
askksa12543 | 8:2b61de165543 | 32 | //calculate the crc value to send. |
askksa12543 | 8:2b61de165543 | 33 | unsigned char calculate_crc(int crc_bytes); |
askksa12543 | 8:2b61de165543 | 34 | |
askksa12543 | 8:2b61de165543 | 35 | |
askksa12543 | 8:2b61de165543 | 36 | int main() |
askksa12543 | 8:2b61de165543 | 37 | { |
askksa12543 | 8:2b61de165543 | 38 | |
askksa12543 | 8:2b61de165543 | 39 | //turn on red led to show programming has worked |
askksa12543 | 8:2b61de165543 | 40 | myled = 0; |
askksa12543 | 8:2b61de165543 | 41 | //initialize output pins |
askksa12543 | 8:2b61de165543 | 42 | clock_pin = 0; |
askksa12543 | 8:2b61de165543 | 43 | serial_out = 0; |
askksa12543 | 8:2b61de165543 | 44 | //skew flag |
askksa12543 | 8:2b61de165543 | 45 | skew_flag = 1; |
askksa12543 | 8:2b61de165543 | 46 | //set timers |
askksa12543 | 8:2b61de165543 | 47 | msecs = 100; |
askksa12543 | 8:2b61de165543 | 48 | sksecs = 80; |
askksa12543 | 0:7c7f4b30d64f | 49 | |
askksa12543 | 8:2b61de165543 | 50 | //output preamble |
askksa12543 | 8:2b61de165543 | 51 | send_byte(pre, BYTE); |
askksa12543 | 8:2b61de165543 | 52 | //output address |
askksa12543 | 8:2b61de165543 | 53 | send_byte(add, BYTE); |
askksa12543 | 8:2b61de165543 | 54 | //output data |
askksa12543 | 8:2b61de165543 | 55 | while(!sent) |
askksa12543 | 8:2b61de165543 | 56 | { |
askksa12543 | 8:2b61de165543 | 57 | //finished sending data when string termination found |
askksa12543 | 8:2b61de165543 | 58 | if(data[i] == '\n') |
askksa12543 | 8:2b61de165543 | 59 | { |
askksa12543 | 8:2b61de165543 | 60 | sent = 1; |
askksa12543 | 9:77ae456366f7 | 61 | //pad out sent data with 0's so crc is sent for all data. |
askksa12543 | 9:77ae456366f7 | 62 | while( (i%3) != 0) |
askksa12543 | 9:77ae456366f7 | 63 | { |
askksa12543 | 9:77ae456366f7 | 64 | //pad data with 0's |
askksa12543 | 9:77ae456366f7 | 65 | data[i] = 0x00; |
askksa12543 | 9:77ae456366f7 | 66 | send_byte(data[i], BYTE); |
askksa12543 | 9:77ae456366f7 | 67 | //store 0's into temp variable for crc calculation |
askksa12543 | 9:77ae456366f7 | 68 | crc_temp <<= 8; |
askksa12543 | 9:77ae456366f7 | 69 | crc_temp += data[i]; |
askksa12543 | 9:77ae456366f7 | 70 | i++; |
askksa12543 | 9:77ae456366f7 | 71 | } |
askksa12543 | 9:77ae456366f7 | 72 | //calculate and send crc |
askksa12543 | 9:77ae456366f7 | 73 | crc_value = calculate_crc(crc_temp); |
askksa12543 | 9:77ae456366f7 | 74 | send_byte(crc_value, NIBBLE); |
askksa12543 | 8:2b61de165543 | 75 | } |
askksa12543 | 8:2b61de165543 | 76 | //string still has data send next byte and handle crc. |
askksa12543 | 8:2b61de165543 | 77 | else |
askksa12543 | 8:2b61de165543 | 78 | { |
askksa12543 | 8:2b61de165543 | 79 | //send the data |
askksa12543 | 8:2b61de165543 | 80 | send_byte(data[i], BYTE); |
askksa12543 | 8:2b61de165543 | 81 | //store the sent data into temp variable for crc calculation |
askksa12543 | 9:77ae456366f7 | 82 | crc_temp <<= 8; |
askksa12543 | 8:2b61de165543 | 83 | crc_temp += data[i]; |
askksa12543 | 8:2b61de165543 | 84 | //increment array pointer |
askksa12543 | 8:2b61de165543 | 85 | i++; |
askksa12543 | 8:2b61de165543 | 86 | //wait until i increments and then check to see if 3 bytes have been sent |
askksa12543 | 8:2b61de165543 | 87 | //i here is the actual count of bytes sent, not the array location that was just sent |
askksa12543 | 9:77ae456366f7 | 88 | //this also avoids sending a crc nibble after no data has been sent |
askksa12543 | 8:2b61de165543 | 89 | if( (i % 3) == 0) |
askksa12543 | 8:2b61de165543 | 90 | { |
askksa12543 | 8:2b61de165543 | 91 | //calculate and send crc |
askksa12543 | 8:2b61de165543 | 92 | crc_value = calculate_crc(crc_temp); |
askksa12543 | 8:2b61de165543 | 93 | send_byte(crc_value, NIBBLE); |
askksa12543 | 8:2b61de165543 | 94 | //zero out crc temp variable |
askksa12543 | 8:2b61de165543 | 95 | crc_temp = 0; |
askksa12543 | 9:77ae456366f7 | 96 | crc_value = 0; |
askksa12543 | 8:2b61de165543 | 97 | } |
askksa12543 | 8:2b61de165543 | 98 | } |
askksa12543 | 8:2b61de165543 | 99 | } |
askksa12543 | 8:2b61de165543 | 100 | //output postamble |
askksa12543 | 8:2b61de165543 | 101 | send_byte(post, BYTE); |
askksa12543 | 8:2b61de165543 | 102 | //turn off red led to show sending has finished |
askksa12543 | 8:2b61de165543 | 103 | myled = 1; |
askksa12543 | 8:2b61de165543 | 104 | } |
askksa12543 | 8:2b61de165543 | 105 | |
askksa12543 | 8:2b61de165543 | 106 | void send_byte(unsigned char byte, int position) |
n02655194 | 6:4ef63169c970 | 107 | { |
askksa12543 | 8:2b61de165543 | 108 | //starting bit position to send msb first |
askksa12543 | 8:2b61de165543 | 109 | j = position; |
n02655194 | 6:4ef63169c970 | 110 | |
n02655194 | 6:4ef63169c970 | 111 | //output byte |
askksa12543 | 8:2b61de165543 | 112 | while(j>0) |
askksa12543 | 8:2b61de165543 | 113 | { |
askksa12543 | 3:027d30718bbc | 114 | //start timer for clock |
askksa12543 | 3:027d30718bbc | 115 | t.start(); |
askksa12543 | 3:027d30718bbc | 116 | //wait until the timer has reached the set time. |
askksa12543 | 8:2b61de165543 | 117 | while(t.read_ms() < msecs) |
askksa12543 | 8:2b61de165543 | 118 | { |
askksa12543 | 3:027d30718bbc | 119 | //extract data just before clock goes high |
askksa12543 | 8:2b61de165543 | 120 | if(!clock_pin && skew_flag && t.read_ms() > sksecs) |
askksa12543 | 8:2b61de165543 | 121 | { |
askksa12543 | 3:027d30718bbc | 122 | //extract data bit |
n02655194 | 6:4ef63169c970 | 123 | serial_out = (byte / j) % 2; |
askksa12543 | 3:027d30718bbc | 124 | skew_flag = 0; |
askksa12543 | 3:027d30718bbc | 125 | j /= 2; //decrement j to get to next bit location |
askksa12543 | 3:027d30718bbc | 126 | } |
askksa12543 | 3:027d30718bbc | 127 | } |
askksa12543 | 3:027d30718bbc | 128 | //stop and reset the timer |
askksa12543 | 3:027d30718bbc | 129 | t.stop(); |
askksa12543 | 3:027d30718bbc | 130 | t.reset(); |
askksa12543 | 3:027d30718bbc | 131 | //switch clock signal |
askksa12543 | 3:027d30718bbc | 132 | clock_pin = !clock_pin; |
askksa12543 | 3:027d30718bbc | 133 | //reset skew flag |
askksa12543 | 3:027d30718bbc | 134 | skew_flag = 1; |
n02655194 | 6:4ef63169c970 | 135 | } |
n02655194 | 6:4ef63169c970 | 136 | } |
n02655194 | 6:4ef63169c970 | 137 | |
askksa12543 | 8:2b61de165543 | 138 | unsigned char calculate_crc(int crc_bytes) |
n02655194 | 6:4ef63169c970 | 139 | { |
askksa12543 | 8:2b61de165543 | 140 | //temp variable |
askksa12543 | 9:77ae456366f7 | 141 | unsigned char temp; |
askksa12543 | 10:90cc064f7082 | 142 | //start at 2^25 / used to decrement through the bit places of the crc integer |
askksa12543 | 10:90cc064f7082 | 143 | int j = 16777216; |
askksa12543 | 8:2b61de165543 | 144 | |
askksa12543 | 10:90cc064f7082 | 145 | //shift crc over 4 spots |
askksa12543 | 10:90cc064f7082 | 146 | crc_bytes <<= 4; |
askksa12543 | 10:90cc064f7082 | 147 | |
askksa12543 | 10:90cc064f7082 | 148 | //initialize temp variable to the 8 msb from crc_bytes, then XOR with CRC constant |
askksa12543 | 10:90cc064f7082 | 149 | temp = crc_bytes / j; |
askksa12543 | 10:90cc064f7082 | 150 | temp ^= CRC; |
askksa12543 | 10:90cc064f7082 | 151 | //decrement j |
askksa12543 | 11:aa30552269b2 | 152 | j /= 2; |
askksa12543 | 8:2b61de165543 | 153 | |
askksa12543 | 10:90cc064f7082 | 154 | //crc loop - shift in each bit position and xor with CRC constant |
askksa12543 | 10:90cc064f7082 | 155 | while(j>0) |
askksa12543 | 10:90cc064f7082 | 156 | { |
askksa12543 | 10:90cc064f7082 | 157 | //left shift current temp value |
askksa12543 | 10:90cc064f7082 | 158 | temp <<= 1; |
askksa12543 | 10:90cc064f7082 | 159 | //shift in new bit from crc bytes |
askksa12543 | 10:90cc064f7082 | 160 | temp += (crc_bytes / j) % 2; |
askksa12543 | 10:90cc064f7082 | 161 | //xor with crc constant |
askksa12543 | 10:90cc064f7082 | 162 | temp ^= CRC; |
askksa12543 | 10:90cc064f7082 | 163 | //decrement j |
askksa12543 | 11:aa30552269b2 | 164 | j /= 2; |
askksa12543 | 10:90cc064f7082 | 165 | } |
askksa12543 | 10:90cc064f7082 | 166 | |
askksa12543 | 10:90cc064f7082 | 167 | //mask out 4 msb bits and return just the 4 bit CRC remainder |
askksa12543 | 10:90cc064f7082 | 168 | temp = temp & 0x0F; |
askksa12543 | 10:90cc064f7082 | 169 | |
askksa12543 | 8:2b61de165543 | 170 | return temp; |
askksa12543 | 1:4c0c28cc2b2c | 171 | } |
askksa12543 | 4:39a777388acd | 172 | //crc = x^4+x+1 |
askksa12543 | 8:2b61de165543 | 173 | //put char data into unsigned int temp variable, then shift << 4. % this number by the decimal equivalent of binary representation of |
askksa12543 | 8:2b61de165543 | 174 | //the crc code and save and send it as a separate 4 bits. On the receive side save each byte in the temp character and then the next five |
askksa12543 | 8:2b61de165543 | 175 | //bytes in a temp variable - after receiving 24 bits stick data in unsigned int variable << 4 add the recieved 4 bits and then % by |
askksa12543 | 8:2b61de165543 | 176 | //the crc decimal equivalent, if that equals 0, save the temp character in the permanent character array and receive the next bits. |