Using FRDM Board to output data and a clock for communications example.

Dependencies:   mbed

main.cpp

Committer:
askksa12543
Date:
2015-04-29
Revision:
10:90cc064f7082
Parent:
9:77ae456366f7
Child:
11:aa30552269b2

File content as of revision 10:90cc064f7082:

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