Kevin Anderson
/
DataCommFreedom
Using FRDM Board to output data and a clock for communications example.
main.cpp
- Committer:
- askksa12543
- Date:
- 2015-04-30
- Revision:
- 11:aa30552269b2
- Parent:
- 10:90cc064f7082
File content as of revision 11:aa30552269b2:
//project to include preamble, addressing, post amble, crc error control. //after sending - set clock to 0, set timer and check clock pin - if clock pin goes high read in response - 4 bit ack? #include "mbed.h" #include "stdio.h" #define MAX 100 //set the max size of the character data storage array #define BYTE 128 #define NIBBLE 8 //used to set binary position of msb #define PREAMBLE 0x7E //preamble of 01111110 #define POSTAMBLE 0x81 //postamble of 10000001 //addressing 1st 4 bits indicate the network, 2nd 4 bits indicate the station id #define ADDRESS 0x12 //address of 00010010 network = 1, station id = 2 #define BROADCAST 0x00 //broadcast address of 00000000 #define MULTICAST 0x10 //broadcast to only network 1, all stations #define CRC 0x13 //crc of 10011 or x^4+x+1 or crc-5 DigitalOut myled(LED1); // red led on board DigitalOut clock_pin(D8), serial_out(D7); //send clock pulse and data Timer t; //timer for controlling the clock and data skew int msecs, sksecs; //clock time needed for data transfer and skew time unsigned char pre = PREAMBLE, add = BROADCAST, post = POSTAMBLE, crc_value = 0; //protocol overhead unsigned char data[MAX] = "Hi Kyle!\n"; //data output int crc_temp = 0; //temporary crc variable unsigned char sent = 0, i = 0, j = 0, skew_flag; //increment variables and flags //function prototypes //send a byte of data, for preamble, postamble, address, and data with BYTE, crc with NIBBLE void send_byte(unsigned char byte, int position); //calculate the crc value to send. unsigned char calculate_crc(int crc_bytes); int main() { //turn on red led to show programming has worked myled = 0; //initialize output pins clock_pin = 0; serial_out = 0; //skew flag skew_flag = 1; //set timers msecs = 100; sksecs = 80; //output preamble send_byte(pre, BYTE); //output address send_byte(add, BYTE); //output data while(!sent) { //finished sending data when string termination found if(data[i] == '\n') { sent = 1; //pad out sent data with 0's so crc is sent for all data. while( (i%3) != 0) { //pad data with 0's data[i] = 0x00; send_byte(data[i], BYTE); //store 0's into temp variable for crc calculation crc_temp <<= 8; crc_temp += data[i]; i++; } //calculate and send crc crc_value = calculate_crc(crc_temp); send_byte(crc_value, NIBBLE); } //string still has data send next byte and handle crc. else { //send the data send_byte(data[i], BYTE); //store the sent data into temp variable for crc calculation crc_temp <<= 8; crc_temp += data[i]; //increment array pointer i++; //wait until i increments and then check to see if 3 bytes have been sent //i here is the actual count of bytes sent, not the array location that was just sent //this also avoids sending a crc nibble after no data has been sent if( (i % 3) == 0) { //calculate and send crc crc_value = calculate_crc(crc_temp); send_byte(crc_value, NIBBLE); //zero out crc temp variable crc_temp = 0; crc_value = 0; } } } //output postamble send_byte(post, BYTE); //turn off red led to show sending has finished myled = 1; } void send_byte(unsigned char byte, int position) { //starting bit position to send msb first j = position; //output byte while(j>0) { //start timer for clock t.start(); //wait until the timer has reached the set time. while(t.read_ms() < msecs) { //extract data just before clock goes high if(!clock_pin && skew_flag && t.read_ms() > sksecs) { //extract data bit serial_out = (byte / j) % 2; skew_flag = 0; j /= 2; //decrement j to get to next bit location } } //stop and reset the timer t.stop(); t.reset(); //switch clock signal clock_pin = !clock_pin; //reset skew flag skew_flag = 1; } } unsigned char calculate_crc(int crc_bytes) { //temp variable unsigned char temp; //start at 2^25 / used to decrement through the bit places of the crc integer int j = 16777216; //shift crc over 4 spots crc_bytes <<= 4; //initialize temp variable to the 8 msb from crc_bytes, then XOR with CRC constant temp = crc_bytes / j; temp ^= CRC; //decrement j j /= 2; //crc loop - shift in each bit position and xor with CRC constant while(j>0) { //left shift current temp value temp <<= 1; //shift in new bit from crc bytes temp += (crc_bytes / j) % 2; //xor with crc constant temp ^= CRC; //decrement j j /= 2; } //mask out 4 msb bits and return just the 4 bit CRC remainder temp = temp & 0x0F; return temp; } //crc = x^4+x+1 //put char data into unsigned int temp variable, then shift << 4. % this number by the decimal equivalent of binary representation of //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 //bytes in a temp variable - after receiving 24 bits stick data in unsigned int variable << 4 add the recieved 4 bits and then % by //the crc decimal equivalent, if that equals 0, save the temp character in the permanent character array and receive the next bits.