Serial communication protocol generic implementation
Dependents: ClassFRDM ClassLPC
DataComm.cpp@2:ba93026839a9, 2015-03-19 (annotated)
- Committer:
- askksa12543
- Date:
- Thu Mar 19 12:02:52 2015 +0000
- Revision:
- 2:ba93026839a9
- Parent:
- 1:9cfb17f74dcd
initial receive test
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
askksa12543 | 0:60c4436f7667 | 1 | #include "DataComm.h" |
askksa12543 | 0:60c4436f7667 | 2 | |
askksa12543 | 1:9cfb17f74dcd | 3 | //set pin for clock output, initialize it to zero |
askksa12543 | 0:60c4436f7667 | 4 | void DataComm::setClockOut(PinName pin) |
askksa12543 | 0:60c4436f7667 | 5 | { |
askksa12543 | 0:60c4436f7667 | 6 | gpio_init_out_ex(&clock_out, pin, 0); |
askksa12543 | 0:60c4436f7667 | 7 | } |
askksa12543 | 0:60c4436f7667 | 8 | |
askksa12543 | 1:9cfb17f74dcd | 9 | //set pin for clock input |
askksa12543 | 0:60c4436f7667 | 10 | void DataComm::setClockIn(PinName pin) |
askksa12543 | 0:60c4436f7667 | 11 | { |
askksa12543 | 0:60c4436f7667 | 12 | gpio_init_in(&clock_in, pin); |
askksa12543 | 0:60c4436f7667 | 13 | } |
askksa12543 | 0:60c4436f7667 | 14 | |
askksa12543 | 1:9cfb17f74dcd | 15 | //set pin for outgoing serial connection |
askksa12543 | 0:60c4436f7667 | 16 | void DataComm::setSerialOut(PinName pin) |
askksa12543 | 0:60c4436f7667 | 17 | { |
askksa12543 | 0:60c4436f7667 | 18 | gpio_init_out_ex(&serial_out, pin, 0); |
askksa12543 | 0:60c4436f7667 | 19 | } |
askksa12543 | 0:60c4436f7667 | 20 | |
askksa12543 | 1:9cfb17f74dcd | 21 | //set pin for incoming serial connection |
askksa12543 | 0:60c4436f7667 | 22 | void DataComm::setSerialIn(PinName pin) |
askksa12543 | 0:60c4436f7667 | 23 | { |
askksa12543 | 0:60c4436f7667 | 24 | gpio_init_in(&serial_in, pin); |
askksa12543 | 0:60c4436f7667 | 25 | } |
askksa12543 | 0:60c4436f7667 | 26 | |
askksa12543 | 1:9cfb17f74dcd | 27 | //listen for incoming data, check for preamble, return from function if preamble found |
askksa12543 | 0:60c4436f7667 | 28 | void DataComm::listen() |
askksa12543 | 0:60c4436f7667 | 29 | { |
askksa12543 | 1:9cfb17f74dcd | 30 | //variables |
askksa12543 | 0:60c4436f7667 | 31 | int pre = 0, data_flag = 1; |
askksa12543 | 0:60c4436f7667 | 32 | char temp = 0; |
askksa12543 | 0:60c4436f7667 | 33 | |
askksa12543 | 1:9cfb17f74dcd | 34 | //while preamble not found, load data into the buffer at every clock pulse |
askksa12543 | 0:60c4436f7667 | 35 | while(!pre) |
askksa12543 | 0:60c4436f7667 | 36 | { |
askksa12543 | 0:60c4436f7667 | 37 | //read in data if clock is 1 and data flag is 1 |
askksa12543 | 0:60c4436f7667 | 38 | if(gpio_read(&clock_in) && data_flag) |
askksa12543 | 0:60c4436f7667 | 39 | { |
askksa12543 | 0:60c4436f7667 | 40 | //data is left shifted into our temporary variable. |
askksa12543 | 0:60c4436f7667 | 41 | //each new data bit is moved into the least significant bit after the rest of the bits are shifted to the left |
askksa12543 | 0:60c4436f7667 | 42 | //data must be sent from the other microcontroller shifted out from the most significant bit to the least significant bit. |
askksa12543 | 0:60c4436f7667 | 43 | temp = (temp << 1) + gpio_read(&serial_in); |
askksa12543 | 0:60c4436f7667 | 44 | data_flag = 0; |
askksa12543 | 1:9cfb17f74dcd | 45 | //when preamble is found return from function |
askksa12543 | 0:60c4436f7667 | 46 | if(temp == PREAMBLE) |
askksa12543 | 0:60c4436f7667 | 47 | { |
askksa12543 | 0:60c4436f7667 | 48 | pre = 1; |
askksa12543 | 0:60c4436f7667 | 49 | } |
askksa12543 | 0:60c4436f7667 | 50 | } |
askksa12543 | 0:60c4436f7667 | 51 | //when clock returns to low - reset data flag to accept the next bit. |
askksa12543 | 0:60c4436f7667 | 52 | if(!gpio_read(&clock_in) && !data_flag) |
askksa12543 | 0:60c4436f7667 | 53 | { |
askksa12543 | 0:60c4436f7667 | 54 | data_flag = 1; |
askksa12543 | 0:60c4436f7667 | 55 | } |
askksa12543 | 0:60c4436f7667 | 56 | } |
askksa12543 | 0:60c4436f7667 | 57 | } |
askksa12543 | 0:60c4436f7667 | 58 | |
askksa12543 | 1:9cfb17f74dcd | 59 | //set clock speed for sending data, automatically calculate skew time |
askksa12543 | 0:60c4436f7667 | 60 | void DataComm::setClock(int clock) |
askksa12543 | 0:60c4436f7667 | 61 | { |
askksa12543 | 0:60c4436f7667 | 62 | clock_time = clock; |
askksa12543 | 1:9cfb17f74dcd | 63 | //skew time 90% of the clock |
askksa12543 | 0:60c4436f7667 | 64 | skew_time = (clock * 9)/10; |
askksa12543 | 0:60c4436f7667 | 65 | } |
askksa12543 | 0:60c4436f7667 | 66 | |
askksa12543 | 1:9cfb17f74dcd | 67 | //initiate a connection with a preamble |
askksa12543 | 0:60c4436f7667 | 68 | void DataComm::initiate_connection() |
askksa12543 | 0:60c4436f7667 | 69 | { |
askksa12543 | 1:9cfb17f74dcd | 70 | //variables |
askksa12543 | 0:60c4436f7667 | 71 | int j=128, done=0, skew_flag=0; |
askksa12543 | 0:60c4436f7667 | 72 | |
askksa12543 | 0:60c4436f7667 | 73 | //output preamble |
askksa12543 | 0:60c4436f7667 | 74 | while(!done) |
askksa12543 | 0:60c4436f7667 | 75 | { |
askksa12543 | 0:60c4436f7667 | 76 | //start timer for clock |
askksa12543 | 0:60c4436f7667 | 77 | t.start(); |
askksa12543 | 0:60c4436f7667 | 78 | //wait until the timer has reached the set time. |
askksa12543 | 0:60c4436f7667 | 79 | while(t.read_ms() < clock_time) |
askksa12543 | 0:60c4436f7667 | 80 | { |
askksa12543 | 0:60c4436f7667 | 81 | //extract data just before clock goes high |
askksa12543 | 0:60c4436f7667 | 82 | if(!gpio_read(&clock_out) && skew_flag && t.read_ms() > skew_time) |
askksa12543 | 0:60c4436f7667 | 83 | { |
askksa12543 | 0:60c4436f7667 | 84 | //extract data bit |
askksa12543 | 0:60c4436f7667 | 85 | gpio_write(&serial_out, ((PREAMBLE / j) % 2)); |
askksa12543 | 0:60c4436f7667 | 86 | skew_flag = 0; |
askksa12543 | 0:60c4436f7667 | 87 | j /= 2; //decrement j to get to next bit location |
askksa12543 | 0:60c4436f7667 | 88 | } |
askksa12543 | 0:60c4436f7667 | 89 | } |
askksa12543 | 0:60c4436f7667 | 90 | //stop and reset the timer |
askksa12543 | 0:60c4436f7667 | 91 | t.stop(); |
askksa12543 | 0:60c4436f7667 | 92 | t.reset(); |
askksa12543 | 0:60c4436f7667 | 93 | //switch clock signal |
askksa12543 | 0:60c4436f7667 | 94 | gpio_write(&clock_out, !gpio_read(&clock_out)); |
askksa12543 | 0:60c4436f7667 | 95 | //reset skew flag |
askksa12543 | 0:60c4436f7667 | 96 | skew_flag = 1; |
askksa12543 | 1:9cfb17f74dcd | 97 | //last preamble bit sent - return from function set clock to zero |
askksa12543 | 0:60c4436f7667 | 98 | if(j==0) |
askksa12543 | 0:60c4436f7667 | 99 | { |
askksa12543 | 1:9cfb17f74dcd | 100 | gpio_write(&clock_out, 0); |
askksa12543 | 0:60c4436f7667 | 101 | done = 1; |
askksa12543 | 0:60c4436f7667 | 102 | } |
askksa12543 | 0:60c4436f7667 | 103 | } |
askksa12543 | 0:60c4436f7667 | 104 | } |
askksa12543 | 0:60c4436f7667 | 105 | |
askksa12543 | 1:9cfb17f74dcd | 106 | //send data from character array of a specific size |
askksa12543 | 1:9cfb17f74dcd | 107 | void DataComm::send_data(char data[], int size) |
askksa12543 | 0:60c4436f7667 | 108 | { |
askksa12543 | 1:9cfb17f74dcd | 109 | //variables |
askksa12543 | 0:60c4436f7667 | 110 | int i=0, j=128, done=0, skew_flag=0; |
askksa12543 | 0:60c4436f7667 | 111 | |
askksa12543 | 0:60c4436f7667 | 112 | //output data |
askksa12543 | 0:60c4436f7667 | 113 | while(!done) |
askksa12543 | 0:60c4436f7667 | 114 | { |
askksa12543 | 0:60c4436f7667 | 115 | //start timer for clock |
askksa12543 | 0:60c4436f7667 | 116 | t.start(); |
askksa12543 | 0:60c4436f7667 | 117 | //wait until the timer has reached the set time. |
askksa12543 | 0:60c4436f7667 | 118 | while(t.read_ms() < clock_time) |
askksa12543 | 0:60c4436f7667 | 119 | { |
askksa12543 | 0:60c4436f7667 | 120 | //extract data just before clock goes high |
askksa12543 | 0:60c4436f7667 | 121 | if(!gpio_read(&clock_out) && skew_flag && t.read_ms() > skew_time) |
askksa12543 | 0:60c4436f7667 | 122 | { |
askksa12543 | 0:60c4436f7667 | 123 | //extract data bit |
askksa12543 | 0:60c4436f7667 | 124 | gpio_write(&serial_out, ((data[i] / j) % 2)); |
askksa12543 | 0:60c4436f7667 | 125 | skew_flag = 0; |
askksa12543 | 0:60c4436f7667 | 126 | j /= 2; //decrement j to get to next bit location |
askksa12543 | 0:60c4436f7667 | 127 | } |
askksa12543 | 0:60c4436f7667 | 128 | } |
askksa12543 | 0:60c4436f7667 | 129 | //stop and reset the timer |
askksa12543 | 0:60c4436f7667 | 130 | t.stop(); |
askksa12543 | 0:60c4436f7667 | 131 | t.reset(); |
askksa12543 | 0:60c4436f7667 | 132 | //switch clock signal |
askksa12543 | 0:60c4436f7667 | 133 | gpio_write(&clock_out, !gpio_read(&clock_out)); |
askksa12543 | 0:60c4436f7667 | 134 | //reset skew flag |
askksa12543 | 0:60c4436f7667 | 135 | skew_flag = 1; |
askksa12543 | 1:9cfb17f74dcd | 136 | //last bit sent - move to next character or return from function |
askksa12543 | 0:60c4436f7667 | 137 | if(j==0) |
askksa12543 | 0:60c4436f7667 | 138 | { |
askksa12543 | 0:60c4436f7667 | 139 | i++; |
askksa12543 | 1:9cfb17f74dcd | 140 | if(i>size) |
askksa12543 | 1:9cfb17f74dcd | 141 | { |
askksa12543 | 1:9cfb17f74dcd | 142 | //return from function, set clock to zero |
askksa12543 | 0:60c4436f7667 | 143 | done = 1; |
askksa12543 | 1:9cfb17f74dcd | 144 | gpio_write(&clock_out, 0); |
askksa12543 | 1:9cfb17f74dcd | 145 | } |
askksa12543 | 0:60c4436f7667 | 146 | j=128; |
askksa12543 | 0:60c4436f7667 | 147 | } |
askksa12543 | 0:60c4436f7667 | 148 | } |
askksa12543 | 0:60c4436f7667 | 149 | } |
askksa12543 | 0:60c4436f7667 | 150 | |
askksa12543 | 1:9cfb17f74dcd | 151 | //receive data return pointer to character array that data is stored in |
askksa12543 | 0:60c4436f7667 | 152 | char* DataComm::receive_data() |
askksa12543 | 0:60c4436f7667 | 153 | { |
askksa12543 | 1:9cfb17f74dcd | 154 | //variables |
askksa12543 | 0:60c4436f7667 | 155 | int i=0, j=0, done = 0, data_flag = 1; |
askksa12543 | 1:9cfb17f74dcd | 156 | char temp, data[MAX]; |
askksa12543 | 0:60c4436f7667 | 157 | |
askksa12543 | 1:9cfb17f74dcd | 158 | //read characters until postamble is found |
askksa12543 | 0:60c4436f7667 | 159 | while(!done) |
askksa12543 | 0:60c4436f7667 | 160 | { |
askksa12543 | 0:60c4436f7667 | 161 | //read in data if clock is 1 and data flag is 1 |
askksa12543 | 0:60c4436f7667 | 162 | if(gpio_read(&clock_in) && data_flag) |
askksa12543 | 0:60c4436f7667 | 163 | { |
askksa12543 | 0:60c4436f7667 | 164 | //data is left shifted into our temporary variable. |
askksa12543 | 0:60c4436f7667 | 165 | //each new data bit is moved into the least significant bit after the rest of the bits are shifted to the left |
askksa12543 | 0:60c4436f7667 | 166 | //data must be sent from the other microcontroller shifted out from the most significant bit to the least significant bit. |
askksa12543 | 1:9cfb17f74dcd | 167 | temp = (temp << 1) + gpio_read(&serial_in); |
askksa12543 | 0:60c4436f7667 | 168 | data_flag = 0; |
askksa12543 | 0:60c4436f7667 | 169 | j++; |
askksa12543 | 0:60c4436f7667 | 170 | } |
askksa12543 | 0:60c4436f7667 | 171 | //when clock returns to low - reset data flag to accept the next bit. |
askksa12543 | 0:60c4436f7667 | 172 | if(!gpio_read(&clock_in) && !data_flag) |
askksa12543 | 0:60c4436f7667 | 173 | { |
askksa12543 | 0:60c4436f7667 | 174 | data_flag = 1; |
askksa12543 | 0:60c4436f7667 | 175 | } |
askksa12543 | 1:9cfb17f74dcd | 176 | //after filling a new byte check for postamble. |
askksa12543 | 0:60c4436f7667 | 177 | if(j>7) |
askksa12543 | 0:60c4436f7667 | 178 | { |
askksa12543 | 1:9cfb17f74dcd | 179 | //finished when postamble found, otherwise store the byte |
askksa12543 | 1:9cfb17f74dcd | 180 | if(temp == POSTAMBLE) |
askksa12543 | 1:9cfb17f74dcd | 181 | done=1; |
askksa12543 | 1:9cfb17f74dcd | 182 | else |
askksa12543 | 1:9cfb17f74dcd | 183 | data[i] = temp; |
askksa12543 | 1:9cfb17f74dcd | 184 | //increment i, reset j |
askksa12543 | 0:60c4436f7667 | 185 | i++; |
askksa12543 | 0:60c4436f7667 | 186 | j=0; |
askksa12543 | 0:60c4436f7667 | 187 | } |
askksa12543 | 0:60c4436f7667 | 188 | } |
askksa12543 | 1:9cfb17f74dcd | 189 | return data; |
askksa12543 | 0:60c4436f7667 | 190 | } |
askksa12543 | 1:9cfb17f74dcd | 191 | |
askksa12543 | 1:9cfb17f74dcd | 192 | //close connection by sending postamble |
askksa12543 | 1:9cfb17f74dcd | 193 | void DataComm::close_connection() |
askksa12543 | 1:9cfb17f74dcd | 194 | { |
askksa12543 | 1:9cfb17f74dcd | 195 | //variables |
askksa12543 | 1:9cfb17f74dcd | 196 | int j=128, done=0, skew_flag=0; |
askksa12543 | 1:9cfb17f74dcd | 197 | |
askksa12543 | 1:9cfb17f74dcd | 198 | //output postamble |
askksa12543 | 1:9cfb17f74dcd | 199 | while(!done) |
askksa12543 | 1:9cfb17f74dcd | 200 | { |
askksa12543 | 1:9cfb17f74dcd | 201 | //start timer for clock |
askksa12543 | 1:9cfb17f74dcd | 202 | t.start(); |
askksa12543 | 1:9cfb17f74dcd | 203 | //wait until the timer has reached the set time. |
askksa12543 | 1:9cfb17f74dcd | 204 | while(t.read_ms() < clock_time) |
askksa12543 | 1:9cfb17f74dcd | 205 | { |
askksa12543 | 1:9cfb17f74dcd | 206 | //extract data just before clock goes high |
askksa12543 | 1:9cfb17f74dcd | 207 | if(!gpio_read(&clock_out) && skew_flag && t.read_ms() > skew_time) |
askksa12543 | 1:9cfb17f74dcd | 208 | { |
askksa12543 | 1:9cfb17f74dcd | 209 | //extract data bit |
askksa12543 | 1:9cfb17f74dcd | 210 | gpio_write(&serial_out, ((POSTAMBLE / j) % 2)); |
askksa12543 | 1:9cfb17f74dcd | 211 | skew_flag = 0; |
askksa12543 | 1:9cfb17f74dcd | 212 | j /= 2; //decrement j to get to next bit location |
askksa12543 | 1:9cfb17f74dcd | 213 | } |
askksa12543 | 1:9cfb17f74dcd | 214 | } |
askksa12543 | 1:9cfb17f74dcd | 215 | //stop and reset the timer |
askksa12543 | 1:9cfb17f74dcd | 216 | t.stop(); |
askksa12543 | 1:9cfb17f74dcd | 217 | t.reset(); |
askksa12543 | 1:9cfb17f74dcd | 218 | //switch clock signal |
askksa12543 | 1:9cfb17f74dcd | 219 | gpio_write(&clock_out, !gpio_read(&clock_out)); |
askksa12543 | 1:9cfb17f74dcd | 220 | //reset skew flag |
askksa12543 | 1:9cfb17f74dcd | 221 | skew_flag = 1; |
askksa12543 | 1:9cfb17f74dcd | 222 | //last postamble bit sent - return from function and set clock to zero |
askksa12543 | 1:9cfb17f74dcd | 223 | if(j==0) |
askksa12543 | 1:9cfb17f74dcd | 224 | { |
askksa12543 | 1:9cfb17f74dcd | 225 | gpio_write(&clock_out, 0); |
askksa12543 | 1:9cfb17f74dcd | 226 | done = 1; |
askksa12543 | 1:9cfb17f74dcd | 227 | } |
askksa12543 | 1:9cfb17f74dcd | 228 | } |
askksa12543 | 1:9cfb17f74dcd | 229 | } |