00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include "serialcomm_s300.h"
00045
00046 #include <assert.h>
00047 #include <math.h>
00048 #include <errno.h>
00049 #include <fcntl.h>
00050 #include <stdio.h>
00051 #include <stdlib.h>
00052 #include <string.h>
00053 #include <netinet/in.h>
00054 #include <sys/types.h>
00055 #include <sys/stat.h>
00056
00057 #include <termios.h>
00058 #include <unistd.h>
00059 #include <sys/ioctl.h>
00060
00061 #include <iostream>
00062
00063 SerialCommS300::SerialCommS300()
00064 {
00065 m_rxCount = 0;
00066 m_ranges = NULL;
00067 }
00068
00069 SerialCommS300::~SerialCommS300()
00070 {
00071 disconnect();
00072 }
00073
00074 int SerialCommS300::connect(const std::string& deviceName, unsigned int baudRate)
00075 {
00076
00077 m_fd = ::open(deviceName.c_str(), O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
00078 if (m_fd < 0)
00079 {
00080 std::cout << "SerialCommS300: unable to open serial port " << deviceName << "\n";
00081 return -1;
00082 }
00083
00084 setFlags();
00085 if (setBaudRate(baudRateToBaudCode(baudRate)))
00086 return -1;
00087
00088 tcflush(m_fd, TCIOFLUSH);
00089 usleep(1000);
00090 tcflush(m_fd, TCIFLUSH);
00091
00092 return 0;
00093
00094 }
00095
00096 void SerialCommS300::setFlags()
00097 {
00098
00099
00100 struct termios term;
00101 memset(&term, 0, sizeof(term));
00102
00103 tcgetattr(m_fd, &term);
00104
00105 term.c_cc[VMIN] = 0;
00106 term.c_cc[VTIME] = 0;
00107 term.c_cflag = CS8 | CREAD;
00108 term.c_iflag = INPCK;
00109 term.c_oflag = 0;
00110 term.c_lflag = 0;
00111
00112 if (tcsetattr(m_fd, TCSANOW, &term) < 0)
00113 std::cout << "SerialCommS300: failed to set tty device attributes";
00114 tcflush(m_fd, TCIOFLUSH);
00115
00116 }
00117
00118 int SerialCommS300::setBaudRate(int baudRate)
00119 {
00120
00121 struct termios term;
00122
00123 if (tcgetattr(m_fd, &term) < 0)
00124 {
00125 std::cout << "SerialCommS300: unable to get device attributes\n";
00126 return 1;
00127 }
00128
00129 if (cfsetispeed(&term, baudRate) < 0 || cfsetospeed(&term, baudRate) < 0)
00130 {
00131 std::cout << "SerialCommS300: failed to set serial baud rate " << baudRate << "\n";
00132 return 1;
00133 }
00134
00135 if (tcsetattr(m_fd, TCSAFLUSH, &term) < 0)
00136 {
00137 std::cout << "SerialCommS300: unable to set device attributes\n";
00138 return 1;
00139 }
00140
00141 return 0;
00142 }
00143
00144 int SerialCommS300::baudRateToBaudCode(int baudRate)
00145 {
00146 switch (baudRate)
00147 {
00148 case 38400:
00149 return B38400;
00150 case 115200:
00151 return B115200;
00152 case 500000:
00153 return B500000;
00154 default:
00155 return B500000;
00156 };
00157 }
00158
00159 int SerialCommS300::disconnect()
00160 {
00161 ::close(m_fd);
00162 return 0;
00163 }
00164
00165 static const unsigned short crc_table[256] = {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108,
00166 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210,
00167 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b,
00168 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401,
00169 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee,
00170 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6,
00171 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d,
00172 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
00173 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5,
00174 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc,
00175 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4,
00176 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd,
00177 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13,
00178 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a,
00179 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e,
00180 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
00181 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1,
00182 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb,
00183 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0,
00184 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8,
00185 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657,
00186 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9,
00187 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882,
00188 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
00189 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e,
00190 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07,
00191 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d,
00192 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74,
00193 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0};
00194
00195 unsigned short SerialCommS300::createCRC(unsigned char* data, ssize_t length)
00196 {
00197
00198 unsigned short CRC_16 = 0xFFFF;
00199 unsigned short i;
00200
00201 for (i = 0; i < length; i++)
00202 {
00203 CRC_16 = (CRC_16 << 8) ^ (crc_table[(CRC_16 >> 8) ^ (data[i])]);
00204 }
00205
00206 return CRC_16;
00207
00208 }
00209
00210 int SerialCommS300::readData()
00211 {
00212
00213 if (RX_BUFFER_SIZE - m_rxCount > 0)
00214 {
00215
00216
00217 int len = read(m_fd, &m_rxBuffer[m_rxCount], RX_BUFFER_SIZE - m_rxCount);
00218 if (len == 0)
00219 {
00220 return -1;
00221 }
00222
00223 if (len < 0)
00224 {
00225 std::cout << "SerialCommS300: error reading form serial port: " << strerror(errno) << "\n";
00226 return -1;
00227 }
00228
00229 m_rxCount += len;
00230
00231 }
00232
00233 while (m_rxCount >= 22)
00234 {
00235
00236
00237 int ii;
00238 bool found = false;
00239 for (ii = 0; ii < m_rxCount - 22; ++ii)
00240 {
00241 if (memcmp(&m_rxBuffer[ii], "\0\0\0\0\0\0", 6) == 0 && memcmp(&m_rxBuffer[ii+8], "\xFF", 1) == 0)
00242 {
00243 memmove(m_rxBuffer, &m_rxBuffer[ii], m_rxCount - ii);
00244 m_rxCount -= ii;
00245 found = true;
00246 break;
00247 }
00248 }
00249
00250 if (!found)
00251 {
00252 memmove(m_rxBuffer, &m_rxBuffer[ii], m_rxCount - ii);
00253 m_rxCount -= ii;
00254 return -1;
00255 }
00256
00257
00258
00259
00260 unsigned short size = 2 * htons(*reinterpret_cast<unsigned short *> (&m_rxBuffer[6]));
00261
00262 if (size > RX_BUFFER_SIZE - 26)
00263 {
00264 std::cout << "SerialCommS300: Requested Size of data is larger than the buffer size\n";
00265 memmove(m_rxBuffer, &m_rxBuffer[1], --m_rxCount);
00266 return -1;
00267 }
00268
00269
00270 if (size > m_rxCount - 4)
00271 return -1;
00272
00273
00274 unsigned short protocol = (*reinterpret_cast<unsigned short *> (&m_rxBuffer[10]));
00275 if (protocol != PROTOCOL_1_02 && protocol != PROTOCOL_1_03)
00276 {
00277 std::cout << "SerialCommS300: protocol version " << std::hex << protocol << std::dec << " is unsupported\n";
00278 return -1;
00279 }
00280
00281
00282 unsigned short packet_checksum, calc_checksum;
00283 if (protocol == PROTOCOL_1_02)
00284 {
00285 packet_checksum = *reinterpret_cast<unsigned short *> (&m_rxBuffer[size + 2]);
00286 calc_checksum = createCRC(&m_rxBuffer[4], size - 2);
00287 }
00288 else if (protocol == PROTOCOL_1_03)
00289 {
00290 packet_checksum = *reinterpret_cast<unsigned short *> (&m_rxBuffer[size + 12]);
00291 calc_checksum = createCRC(&m_rxBuffer[4], size + 8);
00292 }
00293
00294 if (packet_checksum != calc_checksum)
00295 {
00296 std::cout << "SerialCommS300: Checksum's dont match, thats bad (data packet size " << size << ")\n";
00297 memmove(m_rxBuffer, &m_rxBuffer[1], --m_rxCount);
00298 continue;
00299 }
00300 else
00301 {
00302 uint8_t* data = &m_rxBuffer[20];
00303 if (data[0] != data[1])
00304 {
00305 std::cout << "SerialCommS300: Bad type header bytes dont match\n";
00306 }
00307 else
00308 {
00309 if (data[0] == 0xAA)
00310 {
00311 std::cout << "SerialCommS300: We got a I/O data packet we dont know what to do with it\n";
00312 }
00313 else if (data[0] == 0xBB)
00314 {
00315 int data_count;
00316 if (protocol == PROTOCOL_1_02)
00317 data_count = (size - 22) / 2;
00318 else if (protocol == PROTOCOL_1_03)
00319 data_count = (size - 12) / 2;
00320
00321 if (data_count < 0)
00322 {
00323 std::cout << "SerialCommS300: bad data count (" << data_count << ")\n";
00324 memmove(m_rxBuffer, &m_rxBuffer[size + 4], m_rxCount - (size + 4));
00325 m_rxCount -= (size + 4);
00326 continue;
00327 }
00328
00329 if (m_ranges)
00330 delete[] m_ranges;
00331
00332 m_ranges = new float[data_count];
00333 m_rangesCount = data_count;
00334
00335 for (int ii = 0; ii < data_count; ++ii)
00336 {
00337 unsigned short distance_cm = (*reinterpret_cast<unsigned short *> (&data[4 + 2 * ii]));
00338 distance_cm &= 0x1fff;
00339 m_ranges[ii] = static_cast<double> (distance_cm) / 100.0;
00340 }
00341
00342 memmove(m_rxBuffer, &m_rxBuffer[size + 4], m_rxCount - (size + 4));
00343 m_rxCount -= (size + 4);
00344
00345 return 0;
00346
00347 }
00348 else if (data[0] == 0xCC)
00349 {
00350 std::cout << "SerialCommS300: We got a reflector data packet we dont know what to do with it\n";
00351 }
00352 else
00353 {
00354 std::cout << "SerialCommS300: We got an unknown packet\n";
00355 }
00356 }
00357 }
00358
00359 memmove(m_rxBuffer, &m_rxBuffer[size + 4], m_rxCount - (size + 4));
00360 m_rxCount -= (size + 4);
00361 continue;
00362 }
00363
00364 return -1;
00365
00366 }
00367