Receive data and clock for data communications example

Dependencies:   C12832 mbed

main.cpp

Committer:
n02655194
Date:
2015-04-16
Revision:
15:0f8871dd3324
Parent:
14:5a55a41dc118
Child:
16:ca9f769ff024

File content as of revision 15:0f8871dd3324:

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


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("Testing receive data");

    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;
    }
        
    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))
                {
                    crc_passed=1;
                    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();       
    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]);
    }else{//if crc fails, send NOACK
        
        }
}

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
        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;
}