cycfx2prog-0.47.orig/0000700000000000000000000000000011306770020011341 5ustar cycfx2prog-0.47.orig/Makefile0000600000000000000000000000133011306770020013000 0ustar CC = gcc -pipe VERSION = 0.47 CFLAGS = -O2 -fno-rtti -fno-exceptions -DCYCFX2PROG_VERSION=\"$(VERSION)\" \ -W -Wall -Wformat LDFLAGS = -lusb DIST_DEST = cycfx2prog-$(VERSION) all: cycfx2prog # NOTE: Also add sources to the "dist:" target! cycfx2prog: cycfx2prog.o cycfx2dev.o $(CC) $(LDFLAGS) cycfx2prog.o cycfx2dev.o -o cycfx2prog clean: -rm -f *.o distclean: clean -rm -f cycfx2prog dist: mkdir -p "$(DIST_DEST)" cp Makefile "$(DIST_DEST)" cp cycfx2dev.cc cycfx2dev.h "$(DIST_DEST)" cp cycfx2prog.cc "$(DIST_DEST)" tar -c "$(DIST_DEST)" | gzip -9 > "cycfx2prog-$(VERSION).tar.gz" rm -r "$(DIST_DEST)" .cc.o: $(CC) -c $(CFLAGS) $< cycfx2dev.o: cycfx2dev.cc cycfx2dev.h cycfx2prog.o: cycfx2prog.cc cycfx2dev.h cycfx2prog-0.47.orig/cycfx2dev.h0000600000000000000000000000720411306770020013414 0ustar /* * cycfx2dev.h - Cypress FX2 device class: low-level routines. * * Copyright (c) 2006--2009 by Wolfgang Wieser ] wwieser (a) gmx <*> de [ * * This file may be distributed and/or modified under the terms of the * GNU General Public License version 2 as published by the Free Software * Foundation. (See COPYING.GPL for details.) * * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * */ #ifndef _CYCFX2PROG_CYCFX2DEVICE_ #define _CYCFX2PROG_CYCFX2DEVICE_ 1 #include extern struct usb_device *USBFindDevice(const char *bus,const char *dev); extern struct usb_device *USBFindDevice(int vendor,int product,int nth=0); class CypressFX2Device { private: struct usb_device *usbdev; struct usb_dev_handle *usbhdl; // Force a certail "alt" interface; -1 for none. int force_alt_interface; // Internally used: Program one line of an Intel HEX file. // The arguments path and line are just needed for error reporting. int _ProgramIHexLine(const char *buf,const char *path,int line); private: CypressFX2Device(const CypressFX2Device &); void operator=(const CypressFX2Device &); public: CypressFX2Device() { usbdev=NULL; usbhdl=NULL; force_alt_interface=-1; } ~CypressFX2Device() { close(); } // Is opened? inline bool IsOpen() const { return(usbhdl); } // Open usb device; will close previous one. // Returns 0 on success; 1 on error. Errors written to stderr. int open(struct usb_device *_usbdev); // Close device. Returns 0 on success. Errors written to stderr. int close(); // Read an intel hex file and download it. // Returns 0 on success; 1 on error. Errors written to stderr. int ProgramIHexFile(const char *path); // Like ProgramIHexFile() but Intel HEX is supplied as NULL-terminated // array of strings; each line of the hex file as string element. int ProgramStaticIHex(const char **ihex); // Read a flat binary file and download it. int ProgramBinFile(const char *path,size_t start_addr=0); // Download/write a chunk of ram into the device. int WriteRAM(size_t addr,const unsigned char *data,size_t nbytes); // Read a portion of ram from the device. int ReadRAM(size_t addr,unsigned char *data,size_t nbytes); // Put the Cypress FX2 into reset or release reset. // running=1 -> running; running=0 -> reset. int FX2Reset(bool running); // Read from endpoint. // type: 'b','B' -> bulk; 'i','I' -> interrupt // Capital letters mean that data may be shorter than expected. // endpoint must be address (like 0x86 for EP 6 in). // Returns number of read bytes. See source comment!! int BlockRead(int endpoint,unsigned char *buf,size_t nbytes, char type='b'); // Counterpart for BlockRead; type is 'b' or 'i' but not 'B'/'I'. int BlockWrite(int endpoint,const unsigned char *buf,size_t nbytes, char type='b'); // Returns number of written bytes. See source comment!! // Benchmark block (bulk/interrupt) reading. // type: 'b' -> bulk; 'i' -> interrupt // endpoint must be address (like 0x86 for EP 6 in). int BenchBlockRead(int endpoint,size_t nbytes,size_t chunk_size, char type='b'); // Set the alt interface to use at next block read/write. // Use -1 for automatic FX2-default values. int ForceAltInterface(int alt_if=-1) { force_alt_interface=alt_if; return(0); } // Send a USB control message. int CtrlMsg(unsigned char requesttype, unsigned char request,int value,int index, const unsigned char *ctl_buf=NULL,size_t ctl_buf_size=0); }; #endif /* _CYCFX2PROG_CYCFX2DEVICE_ */ cycfx2prog-0.47.orig/cycfx2dev.cc0000600000000000000000000003171311306770020013554 0ustar /* * cycfx2dev.cc - Cypress FX2 device class: low-level routines. * * Copyright (c) 2006--2009 by Wolfgang Wieser ] wwieser (a) gmx <*> de [ * * This file may be distributed and/or modified under the terms of the * GNU General Public License version 2 as published by the Free Software * Foundation. (See COPYING.GPL for details.) * * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * */ #include #include #include #include #include #include #include #include "cycfx2dev.h" struct usb_device *USBFindDevice(const char *bus,const char *dev) { for(usb_bus *b=usb_busses; b; b=b->next) { if(strcmp(b->dirname,bus)) continue; for(struct usb_device *d=b->devices; d; d=d->next) { if(strcmp(d->filename,dev)) continue; return(d); } } return(NULL); } struct usb_device *USBFindDevice(int vendor,int product,int nth) { for(usb_bus *b=usb_busses; b; b=b->next) { for(struct usb_device *d=b->devices; d; d=d->next) { if(d->descriptor.idVendor==vendor && d->descriptor.idProduct==product) { if(!nth--) { return(d); } } } } return(NULL); } //------------------------------------------------------------------------------ int CypressFX2Device::BlockRead(int endpoint,unsigned char *buf,size_t nbytes, char type) { // FIXME: This function is somewhat bugged concerning reliable delivery // and correct handling of return values for short reads and . // timeout handling. Reason: Not sure what libusb is meant to // return and to do in non-standard cases. if(!IsOpen()) { fprintf(stderr,"BlockRead: Not connected!\n"); return(-1); } bool may_be_short=0; switch(type) { case 'b': break; case 'i': break; case 'B': may_be_short=1; type='b'; break; case 'I': may_be_short=1; type='i'; break; default: assert(0); } int interface=0; int alt_interface=(type=='i' ? 2 : 1); if(force_alt_interface>=0) alt_interface=force_alt_interface; if(usb_claim_interface(usbhdl,interface)<0) { fprintf(stderr,"Failed to claim interface %d: %s\n", interface,usb_strerror()); return(-1); } size_t chunk_size=nbytes; int error=0; size_t left=nbytes; do { if(usb_set_altinterface(usbhdl,alt_interface)<0) { fprintf(stderr,"Failed to set altinterface %d: %s\n", alt_interface,usb_strerror()); ++error; break; } int ncalls=0; while(left) { size_t bs = left>chunk_size ? chunk_size : left; ssize_t rv; if(type=='i') { rv=usb_interrupt_read(usbhdl,endpoint,(char*)buf,bs, /*timeout=*/1000/*msec*/); } else { rv=usb_bulk_read(usbhdl,endpoint,(char*)buf,bs, /*timeout=*/1000/*msec*/); } ++ncalls; if(rv<0) { fprintf(stderr,"Reading %zu bytes from EP 0x%02x: " "USB: %s SYS: %s\n", bs,endpoint,usb_strerror(),strerror(-rv)); ++error; goto breakout; } assert((size_t)rv<=left); left-=rv; if((size_t)rv=0) alt_interface=force_alt_interface; if(usb_claim_interface(usbhdl,interface)<0) { fprintf(stderr,"Failed to claim interface %d: %s\n", interface,usb_strerror()); return(-1); } size_t chunk_size=nbytes; int error=0; size_t left=nbytes; do { if(usb_set_altinterface(usbhdl,alt_interface)<0) { fprintf(stderr,"Failed to set altinterface %d: %s\n", alt_interface,usb_strerror()); ++error; break; } int ncalls=0; while(left) { size_t bs = left>chunk_size ? chunk_size : left; ssize_t rv; if(type=='i') { rv=usb_interrupt_write(usbhdl,endpoint,(char*)buf,bs, /*timeout=*/1000/*msec*/); } else { rv=usb_bulk_write(usbhdl,endpoint,(char*)buf,bs, /*timeout=*/1000/*msec*/); } ++ncalls; if(rv<0) { fprintf(stderr,"Writing %zu bytes to EP 0x%02x: " "USB: %s SYS: %s\n", bs,endpoint,usb_strerror(),strerror(-rv)); ++error; goto breakout; } assert((size_t)rv<=left); left-=rv; if((size_t)rv=0) alt_interface=force_alt_interface; if(usb_claim_interface(usbhdl,interface)<0) { fprintf(stderr,"Failed to claim interface %d: %s\n", interface,usb_strerror()); return(1); } int error=0; char *buf=(char*)malloc(chunk_size); assert(buf); do { if(usb_set_altinterface(usbhdl,alt_interface)<0) { fprintf(stderr,"Failed to set altinterface %d: %s\n", alt_interface,usb_strerror()); ++error; break; } // Start benchmark: timeval start_tv,end_tv; gettimeofday(&start_tv,NULL); size_t left=nbytes; int ncalls=0; while(left) { size_t bs = left>chunk_size ? chunk_size : left; ssize_t rv; if(type=='i') { rv=usb_interrupt_read(usbhdl,endpoint,buf,bs, /*timeout=*/1000/*msec*/); } else { rv=usb_bulk_read(usbhdl,endpoint,buf,bs, /*timeout=*/1000/*msec*/); } ++ncalls; if(rv<0) { fprintf(stderr,"Reading %zu bytes from EP 0x%02x: " "USB: %s SYS: %s\n", bs,endpoint,usb_strerror(),strerror(-rv)); ++error; goto breakout; } if((size_t)rvchunk_size) bs=chunk_size; size_t dl_addr=addr+(d-data); int rv=usb_control_msg(usbhdl,0x40,0xa0, /*addr=*/dl_addr,0, /*buf=*/(char*)d,/*size=*/bs, /*timeout=*/1000/*msec*/); if(rv<0) { fprintf(stderr,"Writing %zu bytes at 0x%zx: %s\n", bs,dl_addr,usb_strerror()); ++n_errors; } d+=bs; } return(n_errors); } int CypressFX2Device::ReadRAM(size_t addr,unsigned char *data,size_t nbytes) { if(!IsOpen()) { fprintf(stderr,"ReadRAM: Not connected!\n"); return(1); } int n_errors=0; const size_t chunk_size=16; unsigned char *d=data; unsigned char *dend=data+nbytes; while(dchunk_size) bs=chunk_size; size_t rd_addr=addr+(d-data); int rv=usb_control_msg(usbhdl,0xc0,0xa0, /*addr=*/rd_addr,0, /*buf=*/(char*)d,/*size=*/bs, /*timeout=*/1000/*msec*/); if(rv<0) { fprintf(stderr,"Reading %zu bytes at 0x%zx: %s\n", bs,rd_addr,usb_strerror()); ++n_errors; } d+=bs; } return(n_errors); } int CypressFX2Device::_ProgramIHexLine(const char *buf, const char *path,int line) { const char *s=buf; if(*s!=':') { fprintf(stderr,"%s:%d: format violation (1)\n",path,line); return(1); } ++s; unsigned int nbytes=0,addr=0,type=0; if(sscanf(s,"%02x%04x%02x",&nbytes,&addr,&type)!=3) { fprintf(stderr,"%s:%d: format violation (2)\n",path,line); return(1); } s+=8; if(type==0) { //printf(" Writing nbytes=%d at addr=0x%04x\n",nbytes,addr); assert(nbytes>=0 && nbytes<256); unsigned char data[nbytes]; unsigned char cksum=nbytes+addr+(addr>>8)+type; for(unsigned int i=0; i=0) { ::close(fd); fd=-1; } return(n_errors ? -1 : 0); } int CypressFX2Device::CtrlMsg(unsigned char requesttype, unsigned char request,int value,int index, const unsigned char *ctl_buf,size_t ctl_buf_size) { if(!IsOpen()) { fprintf(stderr,"CtrlMsg: Not connected!\n"); return(1); } int n_errors=0; int rv=usb_control_msg(usbhdl,requesttype,request, value,index, (char*)ctl_buf,ctl_buf_size, /*timeout=*/1000/*msec*/); if(rv<0) { fprintf(stderr,"Sending USB control message: %s\n", usb_strerror()); ++n_errors; } return(n_errors); } int CypressFX2Device::open(struct usb_device *_usbdev) { close(); usbdev=_usbdev; usbhdl=usb_open(usbdev); if(!usbhdl) { fprintf(stderr,"Failed to open device: %s\n",usb_strerror()); return(1); } return(0); } int CypressFX2Device::close() { int rv=0; if(usbhdl) { rv=usb_close(usbhdl); usbhdl=NULL; if(rv) { fprintf(stderr,"closing USB device: %s\n",usb_strerror()); } } usbdev=NULL; return(rv); } cycfx2prog-0.47.orig/cycfx2prog.cc0000600000000000000000000003360211306770020013744 0ustar /* * cycfx2prog.cc - Cypress FX2(LP) programmer. * * Copyright (c) 2006--2009 by Wolfgang Wieser ] wwieser (a) gmx <*> de [ * * This file may be distributed and/or modified under the terms of the * GNU General Public License version 2 as published by the Free Software * Foundation. (See COPYING.GPL for details.) * * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * */ #include #include #include #include #include #include #include #include #include "cycfx2dev.h" // The version is set in Makefile. #ifndef CYCFX2PROG_VERSION # error CYCFX2PROG_VERSION undefined #endif // Global FX2 device we're connected to. CypressFX2Device cycfx2; static void *CheckMalloc(void *ptr) { if(!ptr) { fprintf(stderr,"malloc failed\n"); exit(1); } return(ptr); } // FIXME: What to do with these: // HMMM.... There is usb_device::num_children and **usb_device::children. void USBDumpBusses(FILE *out) { for(usb_bus *b=usb_busses; b; b=b->next) { for(struct usb_device *d=b->devices; d; d=d->next) { bool is_fx2_dev = (d->descriptor.idVendor==0x4b4 && d->descriptor.idProduct==0x8613); fprintf(out,"Bus %s Device %s: ID %04x:%04x%s\n", b->dirname,d->filename, d->descriptor.idVendor,d->descriptor.idProduct, is_fx2_dev ? " (unconfigured FX2)" : ""); } } } static inline void _HexdumpPutChar(FILE *out,unsigned char x) { if(isprint(x)) { fprintf(out,"%c",x); } else { fprintf(out,"."); } } static void HexDumpBuffer(FILE *out,const unsigned char *data,size_t size, int with_ascii) { //ssize_t skip_start=-1; for(size_t i=0; i=0) { printf(" [skipping 0x%04x..0x%04x: " "%u words 0xffff]\n", size_t(skip_start),i-1,i-size_t(skip_start)); skip_start=-1; } #endif printf(" 0x%04zx ",i); size_t oldi=i; for(j=0; j<32 && i=0 && size>0) { printf(" [skipping 0x%04x..0x%04x: " "%u words 0xffff]\n", size_t(skip_start),size-1,size-size_t(skip_start)); skip_start=-1; } #endif fflush(out); } static void PrintHelp() { fprintf(stderr, "Usage: cycfx2prog [-d=BUS.DEV] [id=VV.PP[.N]] [commands...]\n" "Options:\n" " --help print this and then exit\n" " --version print version information and then exit\n" " --list list devices and busses and then exit\n" " -d=BBB.DDD set device to use e.g. 006.003; if not specified, first\n" " unconfigured Cypress FX2 is used. Use --list to get BBB\n" " and DDD (bus and device number, not ID).\n" " -id=VV.PP[.N] set vendor and product ID in hex; default 04b4.8613 for\n" " unconfigured FX2. N is the n-th device to use, default 0.\n" "Commands: Must be specified after all options.\n" " reset reset 8051 by putting reset low\n" " run start the 8051 by putting reset high\n" " prg:FILE program 8051; FILE is an Intel hex file (.ihx); will\n" " reset the 8051 before download; use \"run\" afterwards\n" " delay:NN make a delay for NN msec\n" " set:ADR,VAL set byte at address ADR to value VAL\n" " dram:ADR,LEN dump RAM content: LEN bytes starting at ADR\n" " dbulk:EP,L[,N] bulk read N (default: 1) buffers of size L from endpoint\n" " EP (1,2,4,6,8) and dump them; L<0 to allow short reads\n" " sbulk:EP,STR send string STR as bulk message to endpoint EP (1,2,4,6,8)\n" " fbulk:EP,FILE[,CS] send FILE as bulk message to endpoint EP (1,2,4,6,8)\n" " stdin if no file specified; chunk size CS with default 64\n" " bench_bulk:EP,L[,CS] bench reading L bytes from endpoint EP (chunk size CS)\n" " NOTE: This uses libusb and is slow on the host side!\n" " altif:[IF] set alt interface for next bulk IO; none for FX2 default\n" " ctrl:TYPE,REQUEST[,VALUE[,INDEX]] send a zero-length control message\n" "Cypress FX2(LP) programmer tool v%s copyright (c) 2006--2009 by Wolfgang Wieser\n" ,CYCFX2PROG_VERSION); } int main(int argc,char **arg) { int errors=0; const char *arg_bus_dev=NULL; bool do_list=0; int arg_vend=0x4b4,arg_prod=0x8613,arg_nth=0,arg_id_specified=0; for(int i=1; i=16) break; // Prevents buffer overflows. const char *p=strchr(arg_bus_dev,'.'); if(!p) break; strncpy(bus,arg_bus_dev,p-arg_bus_dev); bus[p-arg_bus_dev]='\0'; strcpy(dev,p+1); usbdev=USBFindDevice(bus,dev); } while(0); if(!usbdev) { fprintf(stderr,"Illegal/nonexistant device %s.\n",arg_bus_dev); return(1); } } else { usbdev=USBFindDevice(arg_vend,arg_prod,arg_nth); if(!usbdev) { if(arg_id_specified) { fprintf(stderr,"Device with vendorID=0x%04x, productID=" "0x%04x, nth=%d not attached.\n",arg_vend,arg_prod,arg_nth); } else { fprintf(stderr,"No unconfigured Cypress FX2 attached.\n"); } return(1); } } fprintf(stderr,"Using ID %04x:%04x on %s.%s.\n", usbdev->descriptor.idVendor,usbdev->descriptor.idProduct, usbdev->bus->dirname,usbdev->filename); if(cycfx2.open(usbdev)) { return(1); } // Execute all the user commands. for(int argc_i=1; argc_i=MAXARGS) { fprintf(stderr,"Too many arguments for command \"%s\" " "(further args ignored)\n",cmd); ++errors; break; } a[nargs++]=first_arg; first_arg=strchr(first_arg,','); } while(first_arg); } #if 0 // Debug: printf("Command: <%s>",cmd); for(int j=0; j",a[j]); } printf("\n"); #endif if(!strcmp(cmd,"reset")) { fprintf(stderr,"Putting 8051 into reset.\n"); errors+=cycfx2.FX2Reset(/*running=*/0); } else if(!strcmp(cmd,"run")) { fprintf(stderr,"Putting 8051 out of reset.\n"); errors+=cycfx2.FX2Reset(/*running=*/1); } else if(!strcmp(cmd,"prg")) { // NOTE: We put the 8051 into reset prior to downloading but // we won't put it out of reset afterwards. fprintf(stderr,"Putting 8051 into reset.\n"); errors+=cycfx2.FX2Reset(/*running=*/0); const char *file=a[0]; if(!file) { fprintf(stderr,"Command \"dl\" requires file to download.\n"); ++errors; } else { fprintf(stderr,"Programming 8051 using \"%s\".\n",file); errors+=cycfx2.ProgramIHexFile(file); } } else if(!strcmp(cmd,"delay")) { long delay=-1; if(a[0] && *a[0]) { delay=strtol(a[0],NULL,0); } if(delay<0) delay=250; fprintf(stderr,"Delay: %ld msec\n",delay); usleep(delay*1000); } else if(!strcmp(cmd,"dram")) { int adr=0; int len=1; if(a[0] && *a[0]) { adr=strtol(a[0],NULL,0); } if(adr<0) adr=0; if(a[1] && *a[1]) { len=strtol(a[1],NULL,0); } if(len<1) len=1; if(len>1024*1024) len=1024*1024; fprintf(stderr,"Dumping %u bytes of RAM at 0x%x:\n",len,adr); unsigned char *buf=(unsigned char*)CheckMalloc(malloc(len)); memset(buf,0,len); errors+=cycfx2.ReadRAM(adr,buf,len); HexDumpBuffer(stdout,buf,len,/*with_ascii=*/1); if(buf) free(buf); } else if(!strcmp(cmd,"set")) { int adr=-1; int val=-1; if(a[0] && *a[0]) { adr=strtol(a[0],NULL,0); } if(a[1] && *a[1]) { val=strtol(a[1],NULL,0); } if(adr<0 || val<0 || val>=256) { fprintf(stderr,"Command set: Illegal/missing address " "and/or value.\n"); ++errors; } else { fprintf(stderr,"Setting value at 0x%x to 0x%x\n",adr,val); unsigned char cval=val; errors+=cycfx2.WriteRAM(adr,&cval,1); } } else if(!strcmp(cmd,"dbulk")) { int ep=-1; int len=512; int num=1; char type='b'; if(a[0] && *a[0]) { ep=strtol(a[0],NULL,0); } if(a[1] && *a[1]) { len=strtol(a[1],NULL,0); } if(a[2] && *a[2]) { num=strtol(a[2],NULL,0); } // If len<0, allow short reads. if(len<0) { type='B'; len=-len; } if(ep<0 || ep>=127 || len<=0 || len>32*1024*1024 || num<1) { fprintf(stderr,"Command dbulk: Illegal/missing " "endpoint/length/number.\n"); ++errors; } else { // IN endpoints have the bit 7 set. ep|=0x80; unsigned char *buf=(unsigned char*)CheckMalloc(malloc(len)); memset(buf,0,len); for(int i=0; i0) { HexDumpBuffer(stdout,buf,rv,/*with_ascii=*/1); } } if(buf) free(buf); } } else if(!strcmp(cmd,"sbulk")) { int ep=-1; char type='b'; const char *str=a[1]; int len=str ? strlen(str) : 0; if(a[0] && *a[0]) { ep=strtol(a[0],NULL,0); } if(ep<0 || ep>=127) { fprintf(stderr,"Command sbulk: Illegal/missing " "endpoint.\n"); ++errors; } else { fprintf(stderr,"Sending %d bytes to EP adr 0x%02x\n",len,ep); int rv=cycfx2.BlockWrite(ep,(const unsigned char*)str,len,type); errors += rv<0 ? 1 : 0; } } else if(!strcmp(cmd,"fbulk")) { char type='b'; const char *filename = a[1]; int ep=-1; int chunk_size=64; do { if(a[0] && *a[0]) { ep=strtol(a[0],NULL,0); } if(ep<0 || ep>=127) { fprintf(stderr,"Command fbulk: Illegal/missing " "endpoint.\n"); ++errors; break; } if(a[2] && *a[2]) { chunk_size=strtol(a[2],NULL,0); } if(chunk_size<1 || chunk_size>2048) { fprintf(stderr,"Command fbulk: Illegal chunk size %d.\n", chunk_size); ++errors; break; } FILE *stream = filename ? fopen(filename,"r") : stdin; if(!stream) { fprintf(stderr,"Failed to open \"%s\" for reading: %s\n", filename ? filename : "[stdin]",strerror(errno)); ++errors; break; } int len; int tot_bytes=0; unsigned char buf[chunk_size]; fprintf(stderr,"Sending \"%s\" in chunks of %d bytes to EP adr " "0x%02x\n", filename ? filename : "[stdin]",chunk_size,ep); while((len=fread(buf,1,chunk_size,stream))>0) { int rv=cycfx2.BlockWrite(ep,buf,len,type); if(rv<0) { ++errors; break; } tot_bytes += len; } if(filename) fclose(stream); fprintf(stderr,"Sent %d bytes to EP adr 0x%02x\n",tot_bytes,ep); } while(0); } else if(!strcmp(cmd,"bench_bulk")) { int ep=-1; int len=1024*1024; int cs=65536; if(a[0] && *a[0]) { ep=strtol(a[0],NULL,0); } if(a[1] && *a[1]) { len=strtol(a[1],NULL,0); } if(a[2] && *a[2]) { cs=strtol(a[2],NULL,0); } // If len<0, allow short reads. if(ep<0 || ep>=127 || len<=0 || len>32*1024*1024 || cs<1 || cs>32*1024*1024) { fprintf(stderr,"Command bench_bulk: Illegal/missing " "endpoint/length/number.\n"); ++errors; } else { // IN endpoints have the bit 7 set. ep|=0x80; int rv=cycfx2.BenchBlockRead(ep,len,cs,'b'); errors += rv ? 1 : 0; } } else if(!strcmp(cmd,"altif")) { int af=-1; if(a[0] && *a[0]) { af=strtol(a[0],NULL,0); } cycfx2.ForceAltInterface(af); } else if(!strcmp(cmd,"ctrl")) { int requesttype=0,request=0; int value=0,index=0; if(a[0] && *a[0]) requesttype=strtol(a[0],NULL,0); if(a[1] && *a[1]) request=strtol(a[1],NULL,0); if(a[2] && *a[2]) value=strtol(a[2],NULL,0); if(a[3] && *a[3]) index=strtol(a[3],NULL,0); fprintf(stderr,"Sending control message type 0x%02x, request " "0x%02x (value=%d,index=%d)\n", requesttype,request,value,index); errors+=cycfx2.CtrlMsg(requesttype,request,value,index); } else { fprintf(stderr,"Ignoring unknown command \"%s\".\n",cmd); ++errors; } if(cmd) { free(cmd); cmd=NULL; } } return(errors ? 1 : 0); }