Receive data and clock for data communications example

Dependencies:   C12832 mbed

main.cpp

Committer:
askksa12543
Date:
2015-04-30
Revision:
21:874a80ebcab5
Parent:
20:38caf615a9e1

File content as of revision 21:874a80ebcab5:

#include "mbed.h"
#include "stdio.h"
#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 POSTAMBLE 0x81 //postamble of 10000001
#define ADDRESS 0x11 //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
Timer t; //timer for pausing after postamble received before displaying data
unsigned char temp, data[MAX], crc_calc=0; //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 crc_passed = 0; //crc flag
int temp_crc = 0; //stores values for crc check.

//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.

//Improvements
//if crc correct display correct crc
//if crc correct send ACK(1) to Master
//if crc wrong, display incorrect crc
//if crc wrong, send NoACK(0) to Master
//if crc wrong adjust for retransmit


int main()
{

    //turn off leds
    myled = 0;
    myled2 = 0;
    myled3 = 0;
    myled4 = 0;

    //initialize variables
    i = 0;
    d_flag = 0;
    done = 0;
    crc_passed=0;
    //clear lcd screen, print current build message
    lcd.cls();
    lcd.locate(0,3);
    lcd.printf("Serial Communication Device Started");

    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");

        //preamble received check address (next byte), returns to preamble check if not addressed to station
        if(check_abyte())
            d_flag = 1;
        else
        {
            //pause after incorrect address - so message is visible, then display waiting for preamble
            t.start();
            //wait until the timer has reached the set time.
            while(t.read_ms() < 500)
            {
                
            }
            //stop and reset the timer
            t.stop();
            t.reset(); 
            //clear lcd screen, print current build message
            lcd.cls();
            lcd.locate(0,3);
            lcd.printf("Waiting for preamble");
        }
    }
        
    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 postamble 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))
                {
                    //crc_passed=1;
                    lcd.cls();
                    lcd.locate(0,3);
                    lcd.printf("Data passes CRC verification.");    
                }
                else
                {
                    lcd.cls();
                    lcd.locate(0,3);
                    lcd.printf("Data fails CRC verification, Int Data: %x, CRC Byte %x.", temp_crc, crc_calc);
                    //pause after displaying postamble received and then display data.
                    t.start();
                    //wait until the timer has reached the set time.
                    while(t.read_ms() < 10000)
                    {
        
                    }
                    //stop and reset the timer
                    t.stop();
                    t.reset(); 
                }
                //zero out crc temp variables
                temp_crc = 0;
                crc_calc = 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();       
    //if(crc_passed){//if crc passes display data, send ACK
    //clear debugging messages - and reset lcd to original position before printing data.
    //send ACK
    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;
        }
        //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");
    }//can add if Network==0 and address==x send to x in every network
    else
        lcd.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)
{
    //temp variable
    unsigned char temp;
    //start at 2^25 / used to decrement through the bit places of the crc integer
    int j = 16777216;
    //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;
    
    //initialize temp variable to the 8 msb from temp_crc, then XOR with CRC constant
    temp = temp_crc / 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 temp_crc
        temp += (temp_crc / j) % 2;
        //xor with crc constant
        temp ^= CRC;
        //decrement j
        j /= 2;        
    }    
    
    //check for crc correctness
    if(temp == 0)
        data_correct = 1;
        
    return data_correct;
}