Kevin Anderson / Mbed 2 deprecated DataCommFreedom

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //project to include preamble, addressing, post amble, crc error control.
00002 
00003 //after sending - set clock to 0, set timer and check clock pin - if clock pin goes high read in response - 4 bit ack?
00004 
00005 #include "mbed.h"
00006 #include "stdio.h"
00007 
00008 #define MAX 100 //set the max size of the character data storage array
00009 #define BYTE 128
00010 #define NIBBLE 8 //used to set binary position of msb
00011 #define PREAMBLE 0x7E //preamble of 01111110
00012 #define POSTAMBLE 0x81 //postamble of 10000001
00013 //addressing 1st 4 bits indicate the network, 2nd 4 bits indicate the station id
00014 #define ADDRESS 0x12 //address of 00010010 network = 1, station id = 2
00015 #define BROADCAST 0x00 //broadcast address of 00000000
00016 #define MULTICAST 0x10 //broadcast to only network 1, all stations
00017 #define CRC 0x13 //crc of 10011 or x^4+x+1 or crc-5
00018 
00019 DigitalOut myled(LED1); // red led on board
00020 DigitalOut clock_pin(D8), serial_out(D7); //send clock pulse and data
00021 Timer t; //timer for controlling the clock and data skew
00022 int msecs, sksecs; //clock time needed for data transfer and skew time
00023 unsigned char pre = PREAMBLE, add = BROADCAST, post = POSTAMBLE, crc_value = 0; //protocol overhead
00024 unsigned char data[MAX] = "Hi Kyle!\n"; //data output
00025 int crc_temp = 0; //temporary crc variable
00026 unsigned char sent = 0, i = 0, j = 0, skew_flag; //increment variables and flags
00027 
00028 //function prototypes
00029 //send a byte of data, for preamble, postamble, address, and data with BYTE, crc with NIBBLE
00030 void send_byte(unsigned char byte, int position);
00031 
00032 //calculate the crc value to send.
00033 unsigned char calculate_crc(int crc_bytes);
00034 
00035 
00036 int main()
00037 {
00038 
00039     //turn on red led to show programming has worked
00040     myled = 0;
00041     //initialize output pins
00042     clock_pin = 0;
00043     serial_out = 0;
00044     //skew flag
00045     skew_flag = 1;
00046     //set timers
00047     msecs = 100;
00048     sksecs = 80;
00049 
00050     //output preamble
00051     send_byte(pre, BYTE);
00052     //output address
00053     send_byte(add, BYTE);
00054     //output data
00055     while(!sent)
00056     {
00057         //finished sending data when string termination found
00058         if(data[i] == '\n')
00059         {
00060             sent = 1;
00061             //pad out sent data with 0's so crc is sent for all data.
00062             while( (i%3) != 0)
00063             {
00064                 //pad data with 0's
00065                 data[i] = 0x00;
00066                 send_byte(data[i], BYTE);
00067                 //store 0's into temp variable for crc calculation
00068                 crc_temp <<= 8;
00069                 crc_temp += data[i];
00070                 i++;       
00071             }
00072             //calculate and send crc
00073             crc_value = calculate_crc(crc_temp);
00074             send_byte(crc_value, NIBBLE);
00075         }
00076         //string still has data send next byte and handle crc.
00077         else
00078         {
00079             //send the data
00080             send_byte(data[i], BYTE);
00081             //store the sent data into temp variable for crc calculation
00082             crc_temp <<= 8;
00083             crc_temp += data[i];
00084             //increment array pointer
00085             i++;
00086             //wait until i increments and then check to see if 3 bytes have been sent
00087             //i here is the actual count of bytes sent, not the array location that was just sent
00088             //this also avoids sending a crc nibble after no data has been sent
00089             if( (i % 3) == 0)
00090             {
00091                 //calculate and send crc
00092                 crc_value = calculate_crc(crc_temp);
00093                 send_byte(crc_value, NIBBLE);
00094                 //zero out crc temp variable
00095                 crc_temp = 0;
00096                 crc_value = 0;
00097             }
00098         }
00099     }
00100     //output postamble
00101     send_byte(post, BYTE);   
00102     //turn off red led to show sending has finished
00103     myled = 1;
00104 }
00105 
00106 void send_byte(unsigned char byte, int position)
00107 {
00108     //starting bit position to send msb first
00109     j = position;
00110 
00111     //output byte
00112     while(j>0)
00113     {
00114         //start timer for clock
00115         t.start();
00116         //wait until the timer has reached the set time.
00117         while(t.read_ms() < msecs)
00118         {
00119             //extract data just before clock goes high
00120             if(!clock_pin && skew_flag && t.read_ms() > sksecs)
00121             {
00122                 //extract data bit
00123                 serial_out = (byte / j) % 2;
00124                 skew_flag = 0;
00125                 j /= 2; //decrement j to get to next bit location
00126             }
00127         }
00128         //stop and reset the timer
00129         t.stop();
00130         t.reset();
00131         //switch clock signal
00132         clock_pin = !clock_pin;
00133         //reset skew flag
00134         skew_flag = 1;
00135     }
00136 }
00137 
00138 unsigned char calculate_crc(int crc_bytes)
00139 {
00140     //temp variable
00141     unsigned char temp;
00142     //start at 2^25 / used to decrement through the bit places of the crc integer
00143     int j = 16777216;
00144     
00145     //shift crc over 4 spots
00146     crc_bytes <<= 4;
00147     
00148     //initialize temp variable to the 8 msb from crc_bytes, then XOR with CRC constant
00149     temp = crc_bytes / j;
00150     temp ^= CRC;
00151     //decrement j
00152     j /= 2;
00153     
00154     //crc loop - shift in each bit position and xor with CRC constant
00155     while(j>0)
00156     {
00157         //left shift current temp value
00158         temp <<= 1;
00159         //shift in new bit from crc bytes
00160         temp += (crc_bytes / j) % 2;
00161         //xor with crc constant
00162         temp ^= CRC;
00163         //decrement j
00164         j /= 2;        
00165     }
00166     
00167     //mask out 4 msb bits and return just the 4 bit CRC remainder
00168     temp = temp & 0x0F;
00169     
00170     return temp;     
00171 }
00172 //crc = x^4+x+1
00173 //put char data into unsigned int temp variable, then shift << 4. % this number by the decimal equivalent of binary representation of
00174 //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
00175 //bytes in a temp variable - after receiving 24 bits stick data in unsigned int variable << 4 add the recieved 4 bits and then % by
00176 //the crc decimal equivalent, if that equals 0, save the temp character in the permanent character array and receive the next bits.