Serial communication protocol generic implementation
Dependents: ClassFRDM ClassLPC
DataComm.cpp
00001 #include "DataComm.h" 00002 00003 //set pin for clock output, initialize it to zero 00004 void DataComm::setClockOut(PinName pin) 00005 { 00006 gpio_init_out_ex(&clock_out, pin, 0); 00007 } 00008 00009 //set pin for clock input 00010 void DataComm::setClockIn(PinName pin) 00011 { 00012 gpio_init_in(&clock_in, pin); 00013 } 00014 00015 //set pin for outgoing serial connection 00016 void DataComm::setSerialOut(PinName pin) 00017 { 00018 gpio_init_out_ex(&serial_out, pin, 0); 00019 } 00020 00021 //set pin for incoming serial connection 00022 void DataComm::setSerialIn(PinName pin) 00023 { 00024 gpio_init_in(&serial_in, pin); 00025 } 00026 00027 //listen for incoming data, check for preamble, return from function if preamble found 00028 void DataComm::listen() 00029 { 00030 //variables 00031 int pre = 0, data_flag = 1; 00032 char temp = 0; 00033 00034 //while preamble not found, load data into the buffer at every clock pulse 00035 while(!pre) 00036 { 00037 //read in data if clock is 1 and data flag is 1 00038 if(gpio_read(&clock_in) && data_flag) 00039 { 00040 //data is left shifted into our temporary variable. 00041 //each new data bit is moved into the least significant bit after the rest of the bits are shifted to the left 00042 //data must be sent from the other microcontroller shifted out from the most significant bit to the least significant bit. 00043 temp = (temp << 1) + gpio_read(&serial_in); 00044 data_flag = 0; 00045 //when preamble is found return from function 00046 if(temp == PREAMBLE) 00047 { 00048 pre = 1; 00049 } 00050 } 00051 //when clock returns to low - reset data flag to accept the next bit. 00052 if(!gpio_read(&clock_in) && !data_flag) 00053 { 00054 data_flag = 1; 00055 } 00056 } 00057 } 00058 00059 //set clock speed for sending data, automatically calculate skew time 00060 void DataComm::setClock(int clock) 00061 { 00062 clock_time = clock; 00063 //skew time 90% of the clock 00064 skew_time = (clock * 9)/10; 00065 } 00066 00067 //initiate a connection with a preamble 00068 void DataComm::initiate_connection() 00069 { 00070 //variables 00071 int j=128, done=0, skew_flag=0; 00072 00073 //output preamble 00074 while(!done) 00075 { 00076 //start timer for clock 00077 t.start(); 00078 //wait until the timer has reached the set time. 00079 while(t.read_ms() < clock_time) 00080 { 00081 //extract data just before clock goes high 00082 if(!gpio_read(&clock_out) && skew_flag && t.read_ms() > skew_time) 00083 { 00084 //extract data bit 00085 gpio_write(&serial_out, ((PREAMBLE / j) % 2)); 00086 skew_flag = 0; 00087 j /= 2; //decrement j to get to next bit location 00088 } 00089 } 00090 //stop and reset the timer 00091 t.stop(); 00092 t.reset(); 00093 //switch clock signal 00094 gpio_write(&clock_out, !gpio_read(&clock_out)); 00095 //reset skew flag 00096 skew_flag = 1; 00097 //last preamble bit sent - return from function set clock to zero 00098 if(j==0) 00099 { 00100 gpio_write(&clock_out, 0); 00101 done = 1; 00102 } 00103 } 00104 } 00105 00106 //send data from character array of a specific size 00107 void DataComm::send_data(char data[], int size) 00108 { 00109 //variables 00110 int i=0, j=128, done=0, skew_flag=0; 00111 00112 //output data 00113 while(!done) 00114 { 00115 //start timer for clock 00116 t.start(); 00117 //wait until the timer has reached the set time. 00118 while(t.read_ms() < clock_time) 00119 { 00120 //extract data just before clock goes high 00121 if(!gpio_read(&clock_out) && skew_flag && t.read_ms() > skew_time) 00122 { 00123 //extract data bit 00124 gpio_write(&serial_out, ((data[i] / j) % 2)); 00125 skew_flag = 0; 00126 j /= 2; //decrement j to get to next bit location 00127 } 00128 } 00129 //stop and reset the timer 00130 t.stop(); 00131 t.reset(); 00132 //switch clock signal 00133 gpio_write(&clock_out, !gpio_read(&clock_out)); 00134 //reset skew flag 00135 skew_flag = 1; 00136 //last bit sent - move to next character or return from function 00137 if(j==0) 00138 { 00139 i++; 00140 if(i>size) 00141 { 00142 //return from function, set clock to zero 00143 done = 1; 00144 gpio_write(&clock_out, 0); 00145 } 00146 j=128; 00147 } 00148 } 00149 } 00150 00151 //receive data return pointer to character array that data is stored in 00152 char* DataComm::receive_data() 00153 { 00154 //variables 00155 int i=0, j=0, done = 0, data_flag = 1; 00156 char temp, data[MAX]; 00157 00158 //read characters until postamble is found 00159 while(!done) 00160 { 00161 //read in data if clock is 1 and data flag is 1 00162 if(gpio_read(&clock_in) && data_flag) 00163 { 00164 //data is left shifted into our temporary variable. 00165 //each new data bit is moved into the least significant bit after the rest of the bits are shifted to the left 00166 //data must be sent from the other microcontroller shifted out from the most significant bit to the least significant bit. 00167 temp = (temp << 1) + gpio_read(&serial_in); 00168 data_flag = 0; 00169 j++; 00170 } 00171 //when clock returns to low - reset data flag to accept the next bit. 00172 if(!gpio_read(&clock_in) && !data_flag) 00173 { 00174 data_flag = 1; 00175 } 00176 //after filling a new byte check for postamble. 00177 if(j>7) 00178 { 00179 //finished when postamble found, otherwise store the byte 00180 if(temp == POSTAMBLE) 00181 done=1; 00182 else 00183 data[i] = temp; 00184 //increment i, reset j 00185 i++; 00186 j=0; 00187 } 00188 } 00189 return data; 00190 } 00191 00192 //close connection by sending postamble 00193 void DataComm::close_connection() 00194 { 00195 //variables 00196 int j=128, done=0, skew_flag=0; 00197 00198 //output postamble 00199 while(!done) 00200 { 00201 //start timer for clock 00202 t.start(); 00203 //wait until the timer has reached the set time. 00204 while(t.read_ms() < clock_time) 00205 { 00206 //extract data just before clock goes high 00207 if(!gpio_read(&clock_out) && skew_flag && t.read_ms() > skew_time) 00208 { 00209 //extract data bit 00210 gpio_write(&serial_out, ((POSTAMBLE / j) % 2)); 00211 skew_flag = 0; 00212 j /= 2; //decrement j to get to next bit location 00213 } 00214 } 00215 //stop and reset the timer 00216 t.stop(); 00217 t.reset(); 00218 //switch clock signal 00219 gpio_write(&clock_out, !gpio_read(&clock_out)); 00220 //reset skew flag 00221 skew_flag = 1; 00222 //last postamble bit sent - return from function and set clock to zero 00223 if(j==0) 00224 { 00225 gpio_write(&clock_out, 0); 00226 done = 1; 00227 } 00228 } 00229 }
Generated on Wed Jul 13 2022 11:41:11 by 1.7.2