Serial communication protocol generic implementation
Dependents: ClassFRDM ClassLPC
Diff: DataComm.cpp
- Revision:
- 0:60c4436f7667
- Child:
- 1:9cfb17f74dcd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DataComm.cpp Thu Mar 19 02:36:11 2015 +0000 @@ -0,0 +1,168 @@ +#include "DataComm.h" + +void DataComm::setClockOut(PinName pin) +{ + gpio_init_out_ex(&clock_out, pin, 0); +} + +void DataComm::setClockIn(PinName pin) +{ + gpio_init_in(&clock_in, pin); +} + +void DataComm::setSerialOut(PinName pin) +{ + gpio_init_out_ex(&serial_out, pin, 0); +} + +void DataComm::setSerialIn(PinName pin) +{ + gpio_init_in(&serial_in, pin); +} + +void DataComm::listen() +{ + int pre = 0, data_flag = 1; + char temp = 0; + + 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; + 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; + } + } +} + +void DataComm::setClock(int clock) +{ + clock_time = clock; + skew_time = (clock * 9)/10; +} + +void DataComm::initiate_connection() +{ + 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 + if(j==0) + { + done = 1; + } + } +} + +void DataComm::setDataSize(int size) +{ + data_size = size; +} + +void DataComm::send_data(char data[]) +{ + 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 preamble bit sent - return from function + if(j==0) + { + i++; + if(i>data_size) + done = 1; + j=128; + } + } +} + +char* DataComm::receive_data() +{ + int i=0, j=0, done = 0, data_flag = 1; + char temp[data_size]; + + 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[i] = (temp[i] << 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; + } + if(j>7) + { + i++; + if(i>data_size) + done=1; + j=0; + } + } + return temp; +}