Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "KNI/cplSerial.h"
00022 #include "KNI/CRC.h"
00023 #include <assert.h>
00024 #include <iostream>
00025
00026 #include <cstring>
00027
00028
00029
00030 #include <stdio.h>
00031
00032
00033 bool CCplSerialCRC::load_tbl() {
00034
00035 bool status = true;
00036
00037
00038 memset(cmd,0,sizeof(cmd));
00039
00040
00041 cmd[(int)'B'].send_sz = 1;
00042 cmd[(int)'B'].read_sz = 3;
00043 cmd[(int)'X'].send_sz = 1;
00044 cmd[(int)'X'].read_sz = 181;
00045 cmd[(int)'Y'].send_sz = 1;
00046 cmd[(int)'Y'].read_sz = 84;
00047 cmd[(int)'Z'].send_sz = 1;
00048 cmd[(int)'Z'].read_sz = 1;
00049 cmd[(int)'C'].send_sz = 5;
00050 cmd[(int)'C'].read_sz = 3;
00051 cmd[(int)'D'].send_sz = 2;
00052 cmd[(int)'D'].read_sz = 8;
00053 cmd[(int)'E'].send_sz = 2;
00054 cmd[(int)'E'].read_sz = 18;
00055 cmd[(int)'V'].send_sz = 3;
00056 cmd[(int)'V'].read_sz = 13;
00057 cmd[(int)'N'].send_sz = 3;
00058 cmd[(int)'N'].read_sz = 13;
00059 cmd[(int)'G'].send_sz = 14;
00060 cmd[(int)'G'].read_sz = 2;
00061 cmd[(int)'G'+128].send_sz = 3;
00062 cmd[(int)'G'+128].read_sz = 2;
00063 cmd[(int)'H'].send_sz = 75;
00064 cmd[(int)'H'].read_sz = 3;
00065 cmd[(int)'A'].send_sz = 3;
00066 cmd[(int)'A'].read_sz = 2;
00067 cmd[(int)'S'].send_sz = 6;
00068 cmd[(int)'S'].read_sz = 6;
00069 cmd[(int)'I'].send_sz = 2;
00070 cmd[(int)'I'].read_sz = 3;
00071 cmd[(int)'M'].send_sz = 5;
00072 cmd[(int)'M'].read_sz = 4;
00073 cmd[(int)'T'].send_sz = 5;
00074 cmd[(int)'T'].read_sz = 2;
00075
00076 return status;
00077 }
00078
00079 void CCplSerialCRC::defineProtocol(byte _kataddr) {
00080 hdr.size = 3;
00081 hdr.data[0] = 1;
00082 hdr.data[1] = _kataddr;
00083 }
00084
00085 bool CCplSerialCRC::init(CCdlBase* _device, byte _kataddr) {
00086 device = _device;
00087 defineProtocol(_kataddr);
00088 return load_tbl();
00089 }
00090
00091
00092 void CCplSerialCRC::comm(const byte* pack, byte* buf, byte* size) {
00093
00094
00095 memset(send_buf,0,256);
00096 hdr.data[hdr.size-1] = cmd[pack[0]].send_sz;
00097 memcpy(send_buf, hdr.data, hdr.size);
00098 memcpy(send_buf+hdr.size,pack,hdr.data[hdr.size-1]);
00099
00100 short crc = CRC_CHECKSUM((uint8*)pack,hdr.data[hdr.size-1]);
00101 byte bufsz = hdr.size + hdr.data[hdr.size-1];
00102 send_buf[bufsz++] = (byte)(crc >> 8);
00103 send_buf[bufsz++] = (byte)(crc & 0xFF);
00104
00105 memset(read_buf,0,256);
00106 byte read_sz = cmd[pack[0]].read_sz + 2;
00107
00108 short tries_recv = 0;
00109 while(true) {
00110
00111
00112 try {
00113
00114
00115
00116
00117
00118
00119
00120
00121 send(send_buf, bufsz, NUMBER_OF_RETRIES_SEND);
00122 }
00123 catch(...){
00124 throw;
00125 }
00126
00127 try {
00128 recv(read_buf,read_sz,size);
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 memcpy(buf,read_buf,*size);
00139 } catch ( ReadNotCompleteException & ) {
00140 if(tries_recv < NUMBER_OF_RETRIES_RECV) {
00141 ++tries_recv;
00142 continue;
00143 }
00144 throw;
00145
00146 } catch ( WrongCRCException & ) {
00147 if(tries_recv < NUMBER_OF_RETRIES_RECV) {
00148 ++tries_recv;
00149 continue;
00150 } else {
00151 throw;
00152 }
00153 } catch ( FirmwareException & ) {
00154 throw;
00155 } catch ( Exception & ) {
00156 throw;
00157
00158
00159
00160 } catch(...){
00161 throw;
00162 }
00163 break;
00164
00165 }
00166 }
00167
00168 void CCplSerialCRC::getMasterFirmware(short* fw, short* rev) {
00169 *fw = mMasterVersion;
00170 *rev = mMasterRevision;
00171 }
00172
00173 void CCplSerialCRC::send(byte* send_buf, byte bufsz, short retries) {
00174 short r = 0;
00175 while(true) {
00176 try {
00177 device->send(send_buf, bufsz);
00178 } catch ( WriteNotCompleteException & ) {
00179 if(r < retries) {
00180 ++r;
00181 continue;
00182 } else {
00183 throw;
00184 }
00185 } catch ( Exception & ) {
00186 throw;
00187 }
00188 break;
00189 }
00190 }
00191
00192 void CCplSerialCRC::recv(byte* read_buf, byte read_sz, byte* size) {
00193
00194
00195 *size = device->recv(read_buf, read_sz);
00196
00197 bool getErrorMessage = false;
00198
00199 if(read_buf[0] == KATANA_ERROR_FLAG){
00200 std::cout << "Error flag received:\n";
00201 assert(*size == 3);
00202 getErrorMessage = true;
00203 read_sz = *size;
00204 } else {
00205 if (*size != read_sz) {
00206 throw ReadNotCompleteException("?");
00207 }
00208 }
00209
00210 *size -= 2;
00211 byte bhi = read_buf[read_sz-2];
00212 byte blo = read_buf[read_sz-1];
00213
00214 short crc = CRC_CHECKSUM((uint8*)read_buf,*size);
00215 byte hi = (byte)(crc >> 8);
00216 byte lo = (byte)(crc & 0xFF);
00217
00218 if ((hi != bhi) || (lo != blo)) {
00219 std::cout << "warning: crc error, throwing exception" << std::endl;
00220 throw WrongCRCException();
00221 }
00222
00223 if (getErrorMessage) {
00224 byte buf[57];
00225 buf[0] = 0;
00226 buf[1] = 0;
00227 buf[2] = 0;
00228 buf[3] = KATANA_ERROR_FLAG+1;
00229 try {
00230 send(buf, 4, 1);
00231 byte size_errormsg = 57;
00232 recv(buf, 57, &size_errormsg);
00233 } catch (...) {
00234 std::cout << "Error while requesting error message!\n";
00235 }
00236
00237 if (buf[0] != KATANA_ERROR_FLAG+1) {
00238 std::cout << "bad response to error request\n";
00239 }
00240 byte lastCommand = buf[1];
00241 byte errorCode = buf[2];
00242 byte device = buf[3];
00243 std::string errorString((char*)buf+4);
00244 if (device != 0) {
00245 errorString += " (axis ";
00246 errorString += '0' + device;
00247 errorString += ")";
00248 }
00249
00250 throw FirmwareException(errorString, static_cast<signed char>(errorCode), device, lastCommand);
00251 }
00252 }