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
00045
00046
00047
00048
00049
00050
00051
00061 #include <string.h>
00062 #include <stdlib.h>
00063 #include <stdio.h>
00064 #include <unistd.h>
00065 #include <errno.h>
00066
00067 #ifdef HAVE_GETOPT_LONG
00068 #include <getopt.h>
00069 #endif
00070
00071 #include "ezusb_loader.h"
00072 #include "jtag_order.h"
00073 #include "jtag.h"
00074 #include "filemanager.h"
00075
00076
00077 EzUSB::EzUSB(const char *filename)
00078 {
00079 idVendor=0x547;
00080 idProduct=0x2131;
00081 if (filename)
00082 {
00083 strncpy(this->filename, filename, 1024);
00084 this->filename[sizeof(this->filename)-1]=0;
00085 }
00086 else
00087 this->filename[0]=0;
00088 devHandle=NULL;
00089 };
00090
00091 EzUSB::~EzUSB(void)
00092 {
00093 forceClose();
00094 }
00095
00096 void EzUSB::forceClose(void)
00097 {
00098 if (devHandle)
00099 {
00100
00101
00102
00103 printf("USB : Reseting device\n");
00104 usb_reset(devHandle);
00105 }
00106 }
00107
00108 void EzUSB::parseCmdLine(int argc, char *argv[])
00109 {
00110 #ifdef HAVE_GETOPT_LONG
00111 int ch;
00112
00113 struct option longOptions[] =
00114 {
00115 {"idvendor", 1, 0, 'v'},
00116 {"idproduct", 1, 0, 'p'},
00117 {"filaname", 1, 0, 'f'},
00118 {0, 0, 0, 0}
00119 };
00120
00121
00122 while((ch = getopt_long(argc, argv, "vpf", longOptions, NULL)) != -1)
00123 {
00124 switch (ch)
00125 {
00126 case 'v':
00127 idVendor=atoi(optarg);
00128 break;
00129 case 'p':
00130 idProduct=atoi(optarg);
00131 break;
00132 case 'f':
00133 if (optarg)
00134 {
00135 strncpy(filename, optarg, 1024);
00136 filename[sizeof(filename)-1]=0;
00137 }
00138 break;
00139 default:
00140 break;
00141 };
00142 }
00143 #else
00144 if (argc>1)
00145 fprintf(stderr, "WARNING ignoring arguments for EzUSB"
00146 " initialisation: getopt_long is not available !\n");
00147 #endif
00148 }
00149
00150 bool EzUSB::findDevice(void)
00151 {
00152 struct usb_bus* bus;
00153 struct usb_device* device;
00154
00155 if (devHandle)
00156 {
00157
00158
00159
00160
00161
00162
00163 }
00164 usb_init();
00165 usb_find_busses();
00166 usb_find_devices();
00167
00168 printf("USB : Enumerating USB\n");
00169 for( bus=usb_busses; bus; bus=bus->next )
00170 {
00171 for( device=bus->devices; device; device=device->next )
00172 {
00173 printf(" Device found : Vendor=0x%x Product=0x%x\n", device->descriptor.idVendor, device->descriptor.idProduct );
00174 if (device->descriptor.idVendor==idVendor && device->descriptor.idProduct==idProduct)
00175 {
00176 printf(" Correct device found :-)\n");
00177 devHandle = usb_open( device );
00178 if (devHandle)
00179 {
00180 printf(" Device has been opened\n");
00181 return true;
00182 }
00183 else
00184 {
00185 fprintf(stderr, " Can't open device handle : %s\n", usb_strerror());
00186 return false;
00187 }
00188 }
00189 }
00190 }
00191 fprintf(stderr, "USB : Device %x, %x can't be found\n", idVendor, idProduct);
00192 return false;
00193 }
00194
00195 bool EzUSB::downloadFirmware(const char *fn)
00196 {
00197
00198
00199
00200 #define CPUCS 0x7f92
00201 #define USBSC 0x7fd6
00202
00203 FILE *f=NULL;
00204 struct intels *hx, *d;
00205 char b[2];
00206 int count;
00207
00208 if (!devHandle)
00209 return false;
00210
00211
00212
00213
00214 if (usb_claim_interface(devHandle, 0)<0)
00215 {
00216 fprintf(stderr, "USB : Can't claim interface : %s\n", usb_strerror());
00217 return false;
00218 }
00219
00220
00221 if (usb_set_altinterface(devHandle,0) < 0 )
00222 {
00223 fprintf(stderr, "USB : Can't set alternate interface : %s\n", usb_strerror());
00224 return false;
00225 }
00226
00227
00228 const char *firmware = fn;
00229 if (filename && filename[0] != 0)
00230 firmware = filename;
00231 if (!(f=fileManagerPtr->openFP(firmware, "r")))
00232 {
00233 fprintf(stderr, "USB : Can't open HEX file '%s' : %s\n", firmware, strerror(errno));
00234 return false;
00235 }
00236
00237
00238 hx = NULL;
00239 if (!read_head(f, &hx))
00240 {
00241 fprintf(stderr, "USB : Can't read HEX file\n");
00242 fclose(f);
00243 return false;
00244 }
00245 fclose(f);
00246
00247
00248 b[0] = 1;
00249 if (shunt(devHandle, CPUCS, (void *) b, 1)<0)
00250 {
00251 fprintf(stderr, "USB : Could not send command to bring device in reset: %s\n", usb_strerror());
00252 return false;
00253 }
00254 else
00255 {
00256 printf("USB : Command to bring 8051 to reset sent.\n");
00257 }
00258
00259
00260 usleep(250000);
00261 printf("USB : Downloading ");
00262 count=0;
00263 for( d = hx; d; d = d->nxt)
00264 {
00265 #if 0
00266 if ((d->len == 1) && (plen == 64) && (d->nxt == NULL))
00267 fprintf(stderr,"Warning - Some chips cannot cope with 64*n+1 downloads\n"
00268 "See the erratum on the anchorchip.com site\n");
00269 #endif
00270 if (shunt(devHandle, d->addr, (void *) (d->data), d->len)<0)
00271 {
00272 fprintf(stderr, "USB : Download failed : %s\n", usb_strerror());
00273 return false;
00274 }
00275
00276 printf(".");
00277 fflush(stdout);
00278 count++;
00279 }
00280
00281 printf("\nUSB : All %d packets downloaded.\n", count);
00282 usleep(250000);
00283
00284 b[0] = 0;
00285 if (shunt(devHandle, CPUCS, (void *) b, 1)<0)
00286 {
00287 fprintf(stderr, "USB : Warning: Could not send command to get the device out of reset: %s\n", usb_strerror());
00288 return false;
00289 }
00290 else
00291 printf("USB : Command to bring 8051 out of reset sent.\n");
00292
00293 usleep(100000);
00294
00295
00296
00297
00298 return true;
00299 }
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 int EzUSB::read_head(FILE * fh, struct intels * * doutp )
00319 {
00320 unsigned char crc;
00321 unsigned char buff[256*2 + 9 + 2 + 1];
00322 unsigned char tmp[5];
00323 unsigned char data[256];
00324 char *last;
00325 int len, type, c, i;
00326 int line = 1;
00327 int comment = 0;
00328 int addr;
00329
00330 #define WHITESPACE " \t_-\a"
00331 #define LFCR "\r\n"
00332 #define COMMENT "#;
00333
00334
00335 #define BAIL(x) \
00336 do { \
00337 fprintf(stderr, "USB : %s at line %d\n", x, line); \
00338 return 0; \
00339 } while(0)
00340
00341
00342
00343
00344
00345
00346 while(!feof(fh))
00347 {
00348
00349
00350
00351
00352
00353
00354 for(i = 0; i < 9 && (c = fgetc(fh)) != EOF; ) {
00355 if (index(LFCR, c)) {
00356 line++;
00357 comment = 0;
00358 continue;
00359 } else if (index(WHITESPACE, c)) {
00360 continue;
00361 } else if (index(COMMENT, c)) {
00362 comment = 1;
00363 }
00364
00365 if (comment)
00366 continue;
00367
00368 buff[i] = c;
00369 i++;
00370 }
00371
00372 if (ferror(fh)) {
00373 BAIL(strerror(errno));
00374 } else if (feof(fh)) {
00375 if (i)
00376 BAIL("HDR Truncated");
00377 else
00378 BAIL("EOF before a type 1 line");
00379 }
00380
00381
00382 if (buff[0] != ':')
00383 BAIL("Colon expected");
00384
00385
00386 if (!isxdigit(buff[1]) || !isxdigit(buff[2]))
00387 BAIL("Len malformed");
00388
00389 memcpy(tmp, buff+1, 2);
00390 tmp[2]='\0';
00391 len = strtol((const char *)tmp, &last, 16);
00392
00393 if (last[0] != '\0')
00394 BAIL("Could not convert len");
00395 if (len < 0 || len > 255)
00396 BAIL("Bad len (>255)");
00397
00398
00399 if (!isxdigit(buff[3]) || !isxdigit(buff[4]) ||
00400 !isxdigit(buff[5]) || !isxdigit(buff[6]) )
00401 BAIL("Addr malformed");
00402
00403 memcpy(tmp, buff+3, 4);
00404 tmp[4]='\0';
00405 addr = strtol((const char *)tmp, &last, 16);
00406 if (last[0])
00407 BAIL("Could not convert addr");
00408
00409
00410 if (!isxdigit(buff[7]) || !isxdigit(buff[8]))
00411 BAIL("Type malformed");
00412
00413 memcpy(tmp, buff+7, 2);
00414 tmp[2]='\0';
00415 type = strtol((const char *)tmp, &last, 16);
00416 if (last[0] != '\0')
00417 BAIL("Could not convert type");
00418 if (type < 0 || type > 1)
00419 BAIL("Unkown type (not one of 00, 01)");
00420
00421
00422 for(i = 0; i < 2*(len)+2 && (c = fgetc(fh)) != EOF;) {
00423 if (index(LFCR, c)) {
00424 line++;
00425 continue;
00426 } else if (index(WHITESPACE, c)) {
00427 continue;
00428 }
00429
00430 if (!isxdigit(c))
00431 BAIL("Malformed hex data");
00432
00433 buff[9+i] = c;
00434 i++;
00435 }
00436
00437 if (ferror(fh)) {
00438 BAIL(strerror(errno));
00439 } else if (i != 2*(len)+2) {
00440 BAIL("data or CRC block Truncated");
00441 }
00442
00443 for(i = 0; i < len+1+4; i++) {
00444 memcpy(tmp, buff+1+i*2, 2);
00445 tmp[2]='\0';
00446 data[i] = strtol((const char *)tmp, &last, 16);
00447 if (last[0] != '\0')
00448 BAIL("Could not convert data or crc pair");
00449 }
00450
00451 for(crc = 0, i = 0; i < 4+len;i++)
00452 crc += data[i];
00453
00454 crc = ~crc + 1;
00455 if (crc != data[len+4])
00456 BAIL("Checksum mismatch");
00457
00458 if (len && type == 0) {
00459 *doutp = (struct intels *)malloc(sizeof(intels));
00460 (*doutp)->addr = addr;
00461 (*doutp)->len = len;
00462 (*doutp)->data = (unsigned char *)malloc(len);
00463 memcpy((*doutp)->data, data+4, len);
00464 doutp = &( (*doutp)->nxt );
00465 } else if (type == 1) {
00466 break;
00467 } else {
00468 BAIL("Unkown intel type");
00469 }
00470 }
00471
00472 return 1;
00473 }
00474
00475 int EzUSB::shunt(usb_dev_handle *pdev, int at, void *d, int len)
00476 {
00477 int err;
00478 err = usb_control_msg( pdev, 0x40,0xA0, at, 0, (char*)d, len, 1000 );
00479 return err;
00480 }