Serial communication protocol generic implementation
Dependents: ClassFRDM ClassLPC
DataComm.cpp
- Committer:
- askksa12543
- Date:
- 2015-03-19
- Revision:
- 1:9cfb17f74dcd
- Parent:
- 0:60c4436f7667
File content as of revision 1:9cfb17f74dcd:
#include "DataComm.h" //set pin for clock output, initialize it to zero void DataComm::setClockOut(PinName pin) { gpio_init_out_ex(&clock_out, pin, 0); } //set pin for clock input void DataComm::setClockIn(PinName pin) { gpio_init_in(&clock_in, pin); } //set pin for outgoing serial connection void DataComm::setSerialOut(PinName pin) { gpio_init_out_ex(&serial_out, pin, 0); } //set pin for incoming serial connection void DataComm::setSerialIn(PinName pin) { gpio_init_in(&serial_in, pin); } //listen for incoming data, check for preamble, return from function if preamble found void DataComm::listen() { //variables int pre = 0, data_flag = 1; char temp = 0; //while preamble not found, load data into the buffer at every clock pulse while(!pre) { //read in data if clock is 1 and data flag is 1 if(gpio_read(&clock_in) && 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) + gpio_read(&serial_in); data_flag = 0; //when preamble is found return from function if(temp == PREAMBLE) { pre = 1; } } //when clock returns to low - reset data flag to accept the next bit. if(!gpio_read(&clock_in) && !data_flag) { data_flag = 1; } } } //set clock speed for sending data, automatically calculate skew time void DataComm::setClock(int clock) { clock_time = clock; //skew time 90% of the clock skew_time = (clock * 9)/10; } //initiate a connection with a preamble void DataComm::initiate_connection() { //variables int j=128, done=0, skew_flag=0; //output preamble while(!done) { //start timer for clock t.start(); //wait until the timer has reached the set time. while(t.read_ms() < clock_time) { //extract data just before clock goes high if(!gpio_read(&clock_out) && skew_flag && t.read_ms() > skew_time) { //extract data bit gpio_write(&serial_out, ((PREAMBLE / 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 gpio_write(&clock_out, !gpio_read(&clock_out)); //reset skew flag skew_flag = 1; //last preamble bit sent - return from function set clock to zero if(j==0) { gpio_write(&clock_out, 0); done = 1; } } } //send data from character array of a specific size void DataComm::send_data(char data[], int size) { //variables int i=0, j=128, done=0, skew_flag=0; //output data while(!done) { //start timer for clock t.start(); //wait until the timer has reached the set time. while(t.read_ms() < clock_time) { //extract data just before clock goes high if(!gpio_read(&clock_out) && skew_flag && t.read_ms() > skew_time) { //extract data bit gpio_write(&serial_out, ((data[i] / 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 gpio_write(&clock_out, !gpio_read(&clock_out)); //reset skew flag skew_flag = 1; //last bit sent - move to next character or return from function if(j==0) { i++; if(i>size) { //return from function, set clock to zero done = 1; gpio_write(&clock_out, 0); } j=128; } } } //receive data return pointer to character array that data is stored in char* DataComm::receive_data() { //variables int i=0, j=0, done = 0, data_flag = 1; char temp, data[MAX]; //read characters until postamble is found while(!done) { //read in data if clock is 1 and data flag is 1 if(gpio_read(&clock_in) && 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) + gpio_read(&serial_in); data_flag = 0; j++; } //when clock returns to low - reset data flag to accept the next bit. if(!gpio_read(&clock_in) && !data_flag) { data_flag = 1; } //after filling a new byte check for postamble. if(j>7) { //finished when postamble found, otherwise store the byte if(temp == POSTAMBLE) done=1; else data[i] = temp; //increment i, reset j i++; j=0; } } return data; } //close connection by sending postamble void DataComm::close_connection() { //variables int j=128, done=0, skew_flag=0; //output postamble while(!done) { //start timer for clock t.start(); //wait until the timer has reached the set time. while(t.read_ms() < clock_time) { //extract data just before clock goes high if(!gpio_read(&clock_out) && skew_flag && t.read_ms() > skew_time) { //extract data bit gpio_write(&serial_out, ((POSTAMBLE / 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 gpio_write(&clock_out, !gpio_read(&clock_out)); //reset skew flag skew_flag = 1; //last postamble bit sent - return from function and set clock to zero if(j==0) { gpio_write(&clock_out, 0); done = 1; } } }