Receive data and clock for data communications example

Dependencies:   C12832 mbed

Revision:
13:14002c51e465
Parent:
12:a7244ff9a00e
Child:
14:5a55a41dc118
diff -r a7244ff9a00e -r 14002c51e465 main.cpp
--- a/main.cpp	Thu Apr 02 14:45:26 2015 +0000
+++ b/main.cpp	Mon Apr 13 17:10:51 2015 +0000
@@ -3,100 +3,33 @@
 #include "C12832.h"
 
 #define MAX 100 //set the size of the character data storage array
+#define BYTE 8
+#define NIBBLE 4 //used to set size of data read
 #define PREAMBLE 0x7E //preamble of 01111110
-#define ADDRESS 0x02 //address of 00000010
+#define POSTAMBLE 0x81 //postamble of 10000001
+#define ADDRESS 0x12 //address of 00010010 - network of 1, id of 2.
+#define NETWORK 0x10 //network portion of the address
+#define ID 0x02 //id portion of the address
+#define BROADCAST 0x00 //address of 00000000
+//multicast using 4bit address / 4 bit network. network = 4 msb, address = 4 lsb. broadcast = all 0's. multicast = network id & address of 0's.
+#define CRC 0x13 //crc of 10011 or x^4+x+1 or crc-5
+
 
 C12832 lcd(p5, p7, p6, p8, p11); //LCD structure
 DigitalOut myled(LED1), myled2(LED2), myled3(LED3), myled4(LED4); //variables to access the four blue leds
 DigitalIn clock_pin(p21), serial_in(p22); //clock pulse input and data input pins
-unsigned char temp, data[MAX]; //temp byte storage and storage array
-int preamble, address, i, j; //increment variables
-int data_flag, rflag, d_flag; //data flag
-void check_byte(int value);
-int check_tbyte(int value);//Timed byte like 8 clock cycles
-int read_byte(void);
-
-void check_byte(int value)
-{
-    data_flag = 1;
-    temp = 0;
-    rflag=0;
-    //while loop
-    while(!rflag) {
-        //read in data if clock is 1 and data flag is 1
-        if(clock_pin && data_flag) {
-            //data is left shifted into our temporary variable.
-            //each new data bit is moved into the least significant bit after the rest of the bits are shifted to the left
-            //data must be sent from the other microcontroller shifted out from the most significant bit to the least significant bit.
-            temp = (temp << 1) + serial_in;
-            data_flag = 0;
-            if(temp == value) {
-                rflag = 1;
-            }
-        }
-        //when clock returns to low - reset data flag to accept the next bit.
-        if(!clock_pin && !data_flag) {
-            data_flag = 1;
-        }
-    }
-}
+Timer t; //timer for pausing after postamble received before displaying data
+unsigned char temp, data[MAX], crc_calc; //temp byte storage, storage array, transmitted crc value
+unsigned char preamble, address, i, j, k; //increment variables
+unsigned char data_flag, rflag, d_flag, done, temp_data; //data flags
+int temp_crc = 0; //stores values for crc check.
 
-int check_tbyte(int value)
-{
-    j = 0;
-    data_flag = 1;
-    temp = 0;
-    rflag=0;
-    //while loop
-    while(j<8) {
-        //read in data if clock is 1 and data flag is 1
-        if(clock_pin && data_flag) {
-            //data is left shifted into our temporary variable.
-            //each new data bit is moved into the least significant bit after the rest of the bits are shifted to the left
-            //data must be sent from the other microcontroller shifted out from the most significant bit to the least significant bit.
-            temp = (temp << 1) + serial_in;
-            j++;
-            data_flag = 0;
-            if(temp == value) {
-                rflag = 1;
-            }
-        }
-        //when clock returns to low - reset data flag to accept the next bit.
-        if(!clock_pin && !data_flag) {
-            data_flag = 1;
-        }
-    }
-          lcd.cls();
-        lcd.locate(0,3);
-        lcd.printf("Address Received: %h", temp);  
-    return rflag;
-}
+//funtion prototypes
+void check_byte(int value); //stays inside the function until the received byte matches the value passed into the function (PREAMBLE)
+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.
+int read_byte(int size); //reads received data and returns it a byte at a time.
+int check_crc(int temp_crc, unsigned char crc_calc); //double checks the sent crc value - data sent without error.
 
-int read_byte(void)
-{
-    j = 0;
-    data_flag = 1;
-    temp = 0;
-
-    //second loop / variable to increment through character array. (post amble also if implemented)
-    while(j<8) {
-        //read in data if clock is 1 and data flag is 1
-        if(clock_pin && data_flag) {
-            //data is left shifted into our temporary variable.
-            //each new data bit is moved into the least significant bit afater the rest of the bits are shifted to the left
-            //data must be sent from the other microcontroller shifted out from the most significant bit to the least significant bit.
-            temp = (temp << 1) + serial_in;
-            //increment j (tracks 8 bits received) - turn off data_flag until clock changes.
-            j++;
-            data_flag = 0;
-        }
-        //when clock returns to low - reset data flag to accept the next bit.
-        if(!clock_pin && !data_flag) {
-            data_flag = 1;
-        }
-    }
-    return temp;
-}
 
 int main()
 {
@@ -110,43 +43,196 @@
     //initialize variables
     i = 0;
     d_flag = 0;
+    done = 0;
 
     //clear lcd screen, print current build message
     lcd.cls();
     lcd.locate(0,3);
     lcd.printf("Testing receive data");
 
-    while(!d_flag){
-    //read input clock pulse and data checking for preamble.
-    //preamble while loop
-    check_byte(PREAMBLE);
+    while(!d_flag)
+    {
+        //read input clock pulse and data checking for preamble.
+        //preamble while loop
+        check_byte(PREAMBLE);
 
-    //clear lcd screen, print current build message
-    lcd.cls();
-    lcd.locate(0,3);
-    lcd.printf("Preamble Received");
-
-    //address while loop
-    if(check_tbyte(ADDRESS)) {
         //clear lcd screen, print current build message
         lcd.cls();
         lcd.locate(0,3);
-        lcd.printf("Address Received: %c", temp);
-        d_flag = 1;
-        }  
+        lcd.printf("Preamble Received");
+
+        //preamble received check address (next byte), returns to preamble check if not addressed to station
+        if(check_abyte())
+            d_flag = 1;
     }
         
-    while(i<3) {
-            //crc while loop / store data into character array if crc checks.
-            data[i] = 0; //initialize current array position to zero
-            data[i] = read_byte(); //store successfully transmitted data
-            j = 0; //reset data read loop
+    while(!done)
+    {     
+        //store data into character array if crc checks.
+        data[i] = 0; //initialize current array position to zero
+        temp_data = read_byte(BYTE); //store successfully transmitted data
+            
+        //check for postamble
+        if(temp_data == POSTAMBLE)
+        {
+            //break out of while loop - data finished sending
+            done = 1;
+            //clear lcd screen, print current build message
+            lcd.cls();
+            lcd.locate(0,3);
+            lcd.printf("Postamble Received");
+        }
+        
+        //store data in character array if not postamble - check crc when appropriate
+        else 
+        {
+            data[i] = temp_data;
             i++; //increment array position
+            //store the sent data into temp variable for crc calculation
+            temp_crc << 8;
+            temp_crc += temp_data;
+            //wait until i increments and then check to see if 3 bytes have been received
+            if( (i % 3) == 0)
+            {
+                //check crc
+                crc_calc = read_byte(NIBBLE);
+                if(check_crc(temp_crc, crc_calc))
+                {
+                    lcd.cls();
+                    lcd.locate(0,3);
+                    lcd.printf("Data passes CRC verification");    
+                }
+                //zero out crc temp variable
+                temp_crc = 0;
+            }
+        }
+    }
+    //pause after displaying postamble received and then display data.
+    t.start();
+    //wait until the timer has reached the set time.
+    while(t.read_ms() < 1000)
+    {
+        
+    }
+    //stop and reset the timer
+    t.stop();
+    t.reset();       
+    //clear debugging messages - and reset lcd to original position before printing data.
+    lcd.cls();
+    lcd.locate(0,3);
+    lcd.printf("Received: ");
+    for(k=0; k<=i; k++)
+        lcd.printf("%c", data[k]);
+}
+
+void check_byte(int value)
+{
+    data_flag = 1;
+    temp = 0;
+    rflag=0;
+    //while loop
+    while(!rflag)
+    {
+        //read in data if clock is 1 and data flag is 1
+        if(clock_pin && data_flag)
+        {
+            //data is left shifted into our temporary variable.
+            //each new data bit is moved into the least significant bit after the rest of the bits are shifted to the left
+            //data must be sent from the other microcontroller shifted out from the most significant bit to the least significant bit.
+            temp = (temp << 1) + serial_in;
+            data_flag = 0;
+            if(temp == value)
+                rflag = 1;
         }
-        //clear debugging message - and reset lcd to original position before printing data.
-        lcd.cls();
-        lcd.locate(0,3);
-        lcd.printf("Received: ");
-        for(i=0; i<3; i++)
-            lcd.printf("%c", data[i]);
+        //when clock returns to low - reset data flag to accept the next bit.
+        if(!clock_pin && !data_flag)
+            data_flag = 1;
+    }
 }
+
+int check_abyte()
+{
+    j = 0;
+    temp = 0;
+    rflag=0;
+    //while loop
+    while(j<8)
+    {
+        //read in data if clock is 1 and data flag is 1
+        if(clock_pin && data_flag)
+        {
+            //data is left shifted into our temporary variable.
+            //each new data bit is moved into the least significant bit after the rest of the bits are shifted to the left
+            //data must be sent from the other microcontroller shifted out from the most significant bit to the least significant bit.
+            temp = (temp << 1) + serial_in;
+            j++;
+            data_flag = 0;
+        }
+        //when clock returns to low - reset data flag to accept the next bit.
+        if(!clock_pin && !data_flag)
+            data_flag = 1;
+    }
+    
+    //clear lcd screen, print current build message
+    lcd.cls();
+    lcd.locate(0,3);
+    if(temp == ADDRESS)
+    {
+        rflag = 1;
+        lcd.printf("Address Received");
+    }
+    else if(temp == BROADCAST)
+    {
+        rflag = 1;
+        lcd.printf("Broadcast received");
+    }
+    else if(((temp & 0xF0) == NETWORK) && ((temp & 0x0F) == 0))
+    {
+        rflag = 1;
+        lcd.printf("Multicast received");
+    }
+    else
+        printf("Wrong address received");
+    
+    return rflag;
+}
+
+int read_byte(int size)
+{
+    j = 0;
+    temp = 0;
+
+    //read a byte/nibble at a time and return it to main
+    while(j<size)
+    {
+        //read in data if clock is 1 and data flag is 1
+        if(clock_pin && data_flag) {
+            //data is left shifted into our temporary variable.
+            //each new data bit is moved into the least significant bit afater the rest of the bits are shifted to the left
+            //data must be sent from the other microcontroller shifted out from the most significant bit to the least significant bit.
+            temp = (temp << 1) + serial_in;
+            //increment j (tracks bits received) - turn off data_flag until clock changes.
+            j++;
+            data_flag = 0;
+        }
+        //when clock returns to low - reset data flag to accept the next bit.
+        if(!clock_pin && !data_flag)
+            data_flag = 1;
+    }
+    return temp;
+}
+
+int check_crc(int temp_crc, unsigned char crc_calc)
+{
+    //assume data sent incorrectly, check crc to see if data sent correctly
+    int data_correct = 0;
+    
+    //shift temp 3 bytes by 4 and add transmitted crc
+    temp_crc << 4;
+    temp_crc += crc_calc;
+    //check for crc correctness
+    if( (temp_crc % CRC) == 0)
+        data_correct = 1;
+        
+    return data_correct;
+}
\ No newline at end of file