Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
BaseEmuISP.cpp
00001 // BaseEmuISP.cpp 2016/3/24 00002 #include <stdio.h> 00003 #include <stdlib.h> 00004 #include <string.h> 00005 #include <stdarg.h> 00006 #include "BaseEmuISP.h" 00007 00008 void BaseEmuISP::Reset() { 00009 mode = M_RESET; 00010 } 00011 00012 void BaseEmuISP::Poll() { 00013 Mode_t prev_mode = mode; 00014 int result; 00015 char buf[32]; 00016 switch(mode) { 00017 case M_RESET: 00018 echoFlag = true; 00019 lockFlag = true; 00020 version.Major = BootCodeVersion() >>8; 00021 version.Minor = BootCodeVersion() & 0xff; 00022 mode = M_SYNC; 00023 break; 00024 case M_SYNC: 00025 if (sync()) { 00026 mode = M_CMD; 00027 } 00028 break; 00029 case M_CMD: 00030 if (lineProc()) { 00031 result = cmd(line.c_str()); 00032 snprintf(buf, sizeof(buf), "%d", result); 00033 putln(buf); 00034 line.clear(); 00035 } 00036 break; 00037 case M_CMD_W_DATA: 00038 if (cmd_w_data()) { 00039 mode = M_CMD; 00040 } 00041 break; 00042 case M_CMD_R_DATA: 00043 if (cmd_r_data()) { 00044 mode = M_CMD; 00045 } 00046 break; 00047 case M_CMD_J: 00048 snprintf(buf, sizeof(buf), "%d", PartID()); 00049 putln(buf); 00050 mode = M_CMD; 00051 break; 00052 case M_CMD_K: 00053 snprintf(buf, sizeof(buf), "%d", version.Major); 00054 putln(buf); 00055 snprintf(buf, sizeof(buf), "%d", version.Minor); 00056 putln(buf); 00057 mode = M_CMD; 00058 break; 00059 case M_CMD_N: 00060 mode = M_CMD; 00061 break; 00062 case M_CMD_S: 00063 mode = M_CMD; 00064 break; 00065 } 00066 if (prev_mode != mode) { 00067 seq = 0; 00068 line.clear(); 00069 } 00070 } 00071 00072 bool BaseEmuISP::sync() { 00073 switch(seq) { 00074 case 0: 00075 if (Getch() == '?') { 00076 putln("Synchronized"); 00077 line.clear(); 00078 echoFlag = true; 00079 seq++; 00080 } 00081 break; 00082 case 1: 00083 if (lineProc()) { 00084 if (line == "Synchronized") { 00085 putln("OK"); 00086 line.clear(); 00087 seq++; 00088 } else { 00089 seq = 0; 00090 } 00091 } 00092 break; 00093 case 2: 00094 if (lineProc()) { 00095 freq = atoi(line.c_str()); 00096 putln("OK"); 00097 return true; 00098 } 00099 break; 00100 } 00101 return false; 00102 } 00103 00104 static int split(vec_charPtr_t ¶m, char *buf, const char* delimiters = " ") { 00105 param.clear(); 00106 char* p = strtok(buf, delimiters); 00107 while(p != NULL) { 00108 param.push_back(p); 00109 p = strtok(NULL, delimiters); 00110 } 00111 return param.size(); 00112 } 00113 00114 ReturnCode_t BaseEmuISP::cmd(const char *str) { 00115 char buf[strlen(str) + 1]; 00116 strcpy(buf, str); 00117 myvector<char*> p; 00118 if (split(p, buf) == 0) { 00119 return INVALID_COMMAND; 00120 } 00121 vec_int_t param; 00122 param.push_back(p[0][0]); 00123 for(size_t i = 1; i < p.size(); i++) { 00124 param.push_back(atoi(p[i])); 00125 } 00126 switch(param[0]) { 00127 case 'U': return cmd_u(param); 00128 case 'A': return cmd_a(param); 00129 case 'W': return cmd_w(param); 00130 case 'R': return cmd_r(param); 00131 case 'P': return cmd_p(param); 00132 case 'C': return cmd_c(param); 00133 case 'E': return cmd_e(param); 00134 case 'I': return cmd_i(param); 00135 case 'J': return cmd_j(param); 00136 case 'K': return cmd_k(param); 00137 case 'N': return cmd_n(param); 00138 case 'S': return cmd_s(param); 00139 default: return INVALID_COMMAND; 00140 } 00141 } 00142 00143 ReturnCode_t BaseEmuISP::cmd_a(vec_int_t ¶m) { 00144 if (param.size() > 1) { 00145 if (param[1] == 0 || param[1] == 1) { 00146 echoFlag = (param[1] == 1) ? true : false; 00147 return CMD_SUCCESS; 00148 } 00149 } 00150 return PARAM_ERROR; 00151 } 00152 00153 ReturnCode_t BaseEmuISP::cmd_u(vec_int_t ¶m) { 00154 if (param.size() > 1) { 00155 if (param[1] == 23130) { 00156 lockFlag = false; 00157 return CMD_SUCCESS; 00158 } 00159 } 00160 return PARAM_ERROR; 00161 } 00162 00163 ReturnCode_t BaseEmuISP::cmd_w(vec_int_t ¶m) { 00164 if (param.size() > 2) { 00165 if (param[1] % 4 != 0) { 00166 return ADDR_ERROR; 00167 } 00168 if (param[2] % 4 != 0) { 00169 return COUNT_ERROR; 00170 } 00171 addr = param[1]; 00172 data.Count = param[2]; 00173 mode = M_CMD_W_DATA; 00174 return CMD_SUCCESS; 00175 } 00176 return PARAM_ERROR; 00177 } 00178 00179 ReturnCode_t BaseEmuISP::cmd_r(vec_int_t ¶m) { 00180 if (param.size() > 2) { 00181 if (param[1] % 4 != 0) { 00182 return ADDR_ERROR; 00183 } 00184 if (param[2] % 4 != 0) { 00185 return COUNT_ERROR; 00186 } 00187 addr = param[1]; 00188 data.Count = param[2]; 00189 mode = M_CMD_R_DATA; 00190 return CMD_SUCCESS; 00191 } 00192 return PARAM_ERROR; 00193 } 00194 00195 ReturnCode_t BaseEmuISP::cmd_p(vec_int_t ¶m) { 00196 if (param.size() > 2) { 00197 for(int sector = param[1]; sector <= param[2]; sector++) { 00198 if (!Prepare(sector)) { 00199 return INVALID_SECTOR; 00200 } 00201 } 00202 return CMD_SUCCESS; 00203 } 00204 return PARAM_ERROR; 00205 } 00206 00207 ReturnCode_t BaseEmuISP::cmd_c(vec_int_t ¶m) { 00208 if (lockFlag) { 00209 return CMD_LOCKED; 00210 } 00211 if (param.size() > 3) { 00212 if (param[1] % 4 != 0) { 00213 return DST_ADDR_ERROR; 00214 } 00215 if (param[2] % 4 != 0) { 00216 return SRC_ADDR_ERROR; 00217 } 00218 if (param[3] != 64 && param[3] != 128 && param[3] != 256 && 00219 param[3] != 512 && param[3] != 1024) { 00220 return COUNT_ERROR; 00221 } 00222 CopyData(param[1], param[2], param[3]); 00223 return CMD_SUCCESS; 00224 } 00225 return PARAM_ERROR; 00226 } 00227 00228 ReturnCode_t BaseEmuISP::cmd_e(vec_int_t ¶m) { 00229 if (lockFlag) { 00230 return CMD_LOCKED; 00231 } 00232 if (param.size() > 2) { 00233 for(int sector = param[1]; sector <= param[2]; sector++) { 00234 if (!Erase(sector)) { 00235 return INVALID_SECTOR; 00236 } 00237 } 00238 return CMD_SUCCESS; 00239 } 00240 return PARAM_ERROR; 00241 } 00242 00243 ReturnCode_t BaseEmuISP::cmd_i(vec_int_t ¶m) { 00244 if (param.size() > 2) { 00245 for(int sector = param[1]; sector <= param[2]; sector++) { 00246 if (!Blank(sector)) { 00247 return SECTOR_NOT_BLANK; 00248 } 00249 } 00250 return CMD_SUCCESS; 00251 } 00252 return PARAM_ERROR; 00253 } 00254 00255 ReturnCode_t BaseEmuISP::cmd_j(vec_int_t ¶m) { 00256 mode = M_CMD_J; 00257 return CMD_SUCCESS; 00258 } 00259 00260 ReturnCode_t BaseEmuISP::cmd_k(vec_int_t ¶m) { 00261 mode = M_CMD_K; 00262 return CMD_SUCCESS; 00263 } 00264 00265 ReturnCode_t BaseEmuISP::cmd_m(vec_int_t ¶m) { 00266 if (param.size() > 3) { 00267 if (param[1] % 4 != 0 || param[2] % 4 != 0) { 00268 return ADDR_ERROR; 00269 } 00270 if (param[3] % 4 != 0) { 00271 return COUNT_ERROR; 00272 } 00273 if (!Compare(param[1], param[2], param[3])) { 00274 return COMPARE_ERROR; 00275 } 00276 return CMD_SUCCESS; 00277 } 00278 return PARAM_ERROR; 00279 } 00280 00281 ReturnCode_t BaseEmuISP::cmd_n(vec_int_t ¶m) { 00282 mode = M_CMD_N; 00283 return CMD_SUCCESS; 00284 } 00285 00286 ReturnCode_t BaseEmuISP::cmd_s(vec_int_t ¶m) { 00287 mode = M_CMD_S; 00288 return CMD_SUCCESS; 00289 } 00290 00291 void uudecode(vec_byte_t &dst, const char* src) { 00292 dst.clear(); 00293 int len = strlen(src); 00294 if (len > 0) { 00295 size_t size = (src[0]^0x20)&0x3f; 00296 uint8_t b[4]; 00297 int k = 0; 00298 for(int i = 1; i < len && dst.size() < size; i++) { 00299 b[k] = (src[i]^0x20)&0x3f; 00300 if (k == 0) { 00301 k++; 00302 } else if (k == 1) { 00303 dst.push_back(b[0]<<2|b[1]>>4); 00304 k++; 00305 } else if (k == 2) { 00306 dst.push_back(b[1]<<4|b[2]>>2); 00307 k++; 00308 } else { 00309 dst.push_back(b[2]<<6|b[3]); 00310 k = 0; 00311 } 00312 } 00313 } 00314 } 00315 00316 bool BaseEmuISP::cmd_w_data() { 00317 int c; 00318 switch(seq) { 00319 case 0: 00320 data.Current = 0; 00321 if (UuencodeMode()) { 00322 seq = 2; 00323 } else { 00324 seq = 1; 00325 } 00326 break; 00327 case 1: // binary mode 00328 if (data.Current >= data.Count) { 00329 return true; 00330 } 00331 c = Getch(); 00332 if (c != (-1)) { 00333 if (echoFlag) { 00334 Putch(c); 00335 } 00336 WriteData(addr++, c); 00337 data.Current++; 00338 } 00339 break; 00340 case 2: // uuencode mode 00341 data.Line = 0; 00342 data.Cksum = 0; 00343 line.clear(); 00344 seq++; 00345 break; 00346 case 3: // uu data start 00347 if (lineProc()) { 00348 uudecode(data.Buf, line.c_str()); 00349 for(size_t i = 0; i < data.Buf.size(); i++) { 00350 int c = data.Buf[i]; 00351 WriteData(addr++, c); 00352 data.Cksum += c; 00353 data.Current++; 00354 } 00355 data.Line++; 00356 if (data.Line >= 20 || data.Current>= data.Count) { 00357 seq++; 00358 } 00359 line.clear(); 00360 } 00361 break; 00362 case 4: // check sum 00363 if (lineProc()) { 00364 if (atoi(line.c_str()) == data.Cksum) { 00365 putln("OK"); 00366 if (data.Current >= data.Count) { 00367 mode = M_CMD; 00368 } else { 00369 seq = 2; 00370 } 00371 } else { 00372 putln("RESEND"); 00373 seq = 2; 00374 } 00375 } 00376 break; 00377 } 00378 return false; 00379 } 00380 00381 bool BaseEmuISP::cmd_r_data() { 00382 int c; 00383 switch(seq) { 00384 case 0: 00385 data.Current = 0; 00386 if (UuencodeMode()) { 00387 data.Line = 0; 00388 data.Cksum = 0; 00389 line.clear(); 00390 seq = 2; 00391 } else { 00392 seq = 1; 00393 } 00394 break; 00395 case 1: // binary mode 00396 if (data.Current >= data.Count) { 00397 return true; 00398 } 00399 c = ReadData(addr++); 00400 Putch(c); 00401 data.Current++; 00402 break; 00403 case 2: 00404 break; 00405 } 00406 return false; 00407 } 00408 00409 00410 void BaseEmuISP::putln(const char *s) { 00411 debugPrintf("send: %s<CR><LF>\n", s); 00412 while(*s) { 00413 Putch(*s++); 00414 } 00415 Putch('\r'); 00416 Putch('\n'); 00417 } 00418 00419 bool BaseEmuISP::lineProc() { 00420 int c = Getch(); 00421 if (c != (-1)) { 00422 if (echoFlag) { 00423 if (version.Major >= 4 || c != '\n') { 00424 Putch(c); 00425 } 00426 } 00427 if (c == '\n') { 00428 debugPrintf("<LF>\n"); 00429 return true; 00430 } else if (c == '\r') { 00431 debugPrintf("<CR>"); 00432 } else { 00433 if (line.size() == 0) { 00434 debugPrintf("recv: "); 00435 } 00436 debugPrintf("%c", c); 00437 line += c; 00438 } 00439 } 00440 return false; 00441 } 00442 00443 void BaseEmuISP::debugPrintf(const char *format, ...) { 00444 char buf[256]; 00445 va_list args; 00446 va_start(args, format); 00447 vsprintf(buf, format, args); 00448 for(const char *s = buf; *s; s++) { 00449 DebugPutch(*s); 00450 } 00451 va_end(args); 00452 } 00453
Generated on Wed Jan 17 2024 08:13:46 by
1.7.2