diff options
author | Attila Veghelyi <aveghelyi@dension.com> | 2024-10-16 16:09:02 +0200 |
---|---|---|
committer | Attila Veghelyi <aveghelyi@dension.com> | 2024-10-16 16:09:02 +0200 |
commit | 14d0fa4556e81763fd2a1e8fe4870a746186595e (patch) | |
tree | a2a45614875d4d23e3b6c0116299495e47605239 | |
parent | 5f686d5179d6a23a37378550b8c1122453d240c1 (diff) | |
download | OpenProgrammer-14d0fa4556e81763fd2a1e8fe4870a746186595e.tar.gz OpenProgrammer-14d0fa4556e81763fd2a1e8fe4870a746186595e.zip |
Use common functions from one file - not works yet
-rw-r--r-- | Makefile_op | 1 | ||||
-rw-r--r-- | Makefile_opgui | 1 | ||||
-rw-r--r-- | common_functions.c | 820 | ||||
-rw-r--r-- | common_functions.h | 17 | ||||
-rw-r--r-- | op.c | 795 | ||||
-rw-r--r-- | opgui.c | 792 |
6 files changed, 854 insertions, 1572 deletions
diff --git a/Makefile_op b/Makefile_op index 5fff89a..792653f 100644 --- a/Makefile_op +++ b/Makefile_op @@ -5,6 +5,7 @@ CFLAGS = '-DVERSION="$(VERSION)"' -w -Os -s #size #CFLAGS = -w -O3 -s #CFLAGS = -w -g #debug SOURCES = op.c \ + common_functions.c \ progP12.c \ progP16.c \ progP18.c \ diff --git a/Makefile_opgui b/Makefile_opgui index cd0f5a3..3ec07f3 100644 --- a/Makefile_opgui +++ b/Makefile_opgui @@ -12,6 +12,7 @@ CFLAGS += -Os -s #size LDLAGS = `pkg-config --libs gtk+-3.0` SOURCES = opgui.c \ + common_functions.c \ deviceRW.c \ progP12.c \ progP16.c \ diff --git a/common_functions.c b/common_functions.c new file mode 100644 index 0000000..388b4b0 --- /dev/null +++ b/common_functions.c @@ -0,0 +1,820 @@ +#include "common.h" +#include "common_functions.h" +#include "I2CSPI.h" +#include "deviceRW.h" +#include "fileIO.h" +#include "progAVR.h" + + +#define FALSE 0 +#define TRUE (!0) +#define MinDly 0 + + +void ProgID(); +int CheckS1(); +char** strings; //!localized strings +int saveLog=0,programID=0,load_osccal=0,load_BKosccal=0; +int use_osccal=1,use_BKosccal=0; +int load_calibword=0,max_err=200; +int AVRlock=0x100,AVRfuse=0x100,AVRfuse_h=0x100,AVRfuse_x=0x100; +int ICDenable=0,ICDaddr=0x1FF0; +int FWVersion=0,HwID=0; +FILE* logfile=0; +char LogFileName[512]=""; +char loadfile[512]="",savefile[512]=""; +char CoffFileName[512]=""; +WORD *memCODE_W=0; +int size=0,sizeW=0,sizeEE=0,sizeCONFIG=0,sizeUSERID=0; +unsigned char *memCODE=0,*memEE=0,memID[64],memCONFIG[48],memUSERID[8]; +double hvreg=0; +int RWstop=0; +int forceConfig=0; +char str[4096]; + +void printMsg(const char* msg) +{ +#ifdef OPGUI + MsgBox(msg); +#else + PrintMessage(msg); + fflush(stdout); + getchar(); +#endif +} + +#if !defined _WIN32 && !defined __CYGWIN__ //Linux + int fd = -1; + #if defined hiddevIO && defined OPGUI + struct hiddev_report_info rep_info_i,rep_info_u; + struct hiddev_usage_ref_multi ref_multi_i,ref_multi_u; + #endif + unsigned char bufferU[128],bufferI[128]; +#else //Windows + unsigned char bufferU0[128],bufferI0[128]; + unsigned char *bufferU,*bufferI; + DWORD NumberOfBytesRead,BytesWritten; + ULONG Result; + HANDLE WriteHandle,ReadHandle; + OVERLAPPED HIDOverlapped; + HANDLE hEventObject; +#endif + +/// +///Start HV regulator +int StartHVReg(double V){ + int j=0,z; + int vreg=(int)(V*10.0); + if(saveLog&&logfile) fprintf(logfile,"StartHVReg(%.2f)\n",V); + DWORD t0,t; + if(V==-1){ + bufferU[j++]=VREG_DIS; //disable HV regulator + bufferU[j++]=FLUSH; + PacketIO(5); + msDelay(40); + return -1; + } + t=t0=GetTickCount(); + bufferU[j++]=VREG_EN; //enable HV regulator + bufferU[j++]=SET_VPP; + bufferU[j++]=vreg; + bufferU[j++]=SET_PARAMETER; + bufferU[j++]=SET_T3; + bufferU[j++]=2000>>8; + bufferU[j++]=2000&0xff; + bufferU[j++]=WAIT_T3; + bufferU[j++]=READ_ADC; + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(5); + msDelay(20); + for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_ADC;z++); + int v=(bufferI[z+1]<<8)+bufferI[z+2]; +// PrintMessage2("v=%d=%fV\n",v,v/G); + if(v==0){ + PrintMessage(strings[S_lowUsbV]); //"Tensione USB troppo bassa (VUSB<4.5V)\r\n" + return 0; + } + j=0; + bufferU[j++]=WAIT_T3; + bufferU[j++]=READ_ADC; + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + for(;(v<(vreg/10.0-1)*G||v>(vreg/10.0+1)*G)&&t<t0+1500;t=GetTickCount()){ + PacketIO(5); + msDelay(20); + for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_ADC;z++); + v=(bufferI[z+1]<<8)+bufferI[z+2]; + if(HwID==3) v>>=2; //if 12 bit ADC +// PrintMessage2("v=%d=%fV\n",v,v/G); + } + if(v>(vreg/10.0+1)*G){ + PrintMessage(strings[S_HiVPP]); //"Attenzione: tensione regolatore troppo alta\r\n\r\n" + return 0; + } + else if(v<(vreg/10.0-1)*G){ + PrintMessage(strings[S_LowVPP]); //"Attenzione: tensione regolatore troppo bassa\r\n\r\n" + return 0; + } + else if(v==0){ + PrintMessage(strings[S_lowUsbV]); //"Tensione USB troppo bassa (VUSB<4.5V)\r\n" + return 0; + } + else{ + PrintMessage2(strings[S_reg],t-t0,v/G); //"Regolatore avviato e funzionante dopo T=%d ms VPP=%.1f\r\n\r\n" + if(saveLog&&logfile) fprintf(logfile,strings[S_reg],t-t0,v/G); + return vreg; + } +} + +/// +///Read programmer ID +void ProgID() +{ + if(DeviceDetected!=1) return; + int j=0; + bufferU[j++]=PROG_RST; + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(2); + for(j=0;j<DIMBUF-7&&bufferI[j]!=PROG_RST;j++); + PrintMessage3(strings[S_progver],bufferI[j+1],bufferI[j+2],bufferI[j+3]); //"FW versione %d.%d.%d\r\n" + FWVersion=(bufferI[j+1]<<16)+(bufferI[j+2]<<8)+bufferI[j+3]; + PrintMessage3(strings[S_progid],bufferI[j+4],bufferI[j+5],bufferI[j+6]); //"ID Hw: %d.%d.%d" + HwID=bufferI[j+6]; + if(HwID==1) PrintMessage(" (18F2550)\r\n\r\n"); + else if(HwID==2) PrintMessage(" (18F2450)\r\n\r\n"); + else if(HwID==3) PrintMessage(" (18F2458/2553)\r\n\r\n"); + else if(HwID==4) PrintMessage(" (18F25K50)\r\n\r\n"); + else if(HwID==5) PrintMessage(" (18F25K50 all-in-one variant)\r\n\r\n"); + else PrintMessage(" (?)\r\n\r\n"); +#ifdef OPGUI + // Disable 3.3V check and hide the option for all-in-one board. Enable and show for others + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b_V33check), HwID==5 ? TRUE : FALSE); + gtk_widget_set_visible(GTK_WIDGET(b_V33check), HwID==5 ? FALSE : TRUE); +#endif +} +/// +///Check if a 3.3V regulator is present +int CheckV33Regulator() +{ + int i,j=0; + if(skipV33check) return 1; + bufferU[j++]=WRITE_RAM; + bufferU[j++]=0x0F; + bufferU[j++]=0x93; + bufferU[j++]=0xFE; //B0 = output + bufferU[j++]=EXT_PORT; + bufferU[j++]=0x01; //B0=1 + bufferU[j++]=0; + bufferU[j++]=READ_RAM; + bufferU[j++]=0x0F; + bufferU[j++]=0x81; //Check if B1=1 + bufferU[j++]=EXT_PORT; + bufferU[j++]=0x00; //B0=0 + bufferU[j++]=0; + bufferU[j++]=READ_RAM; + bufferU[j++]=0x0F; + bufferU[j++]=0x81; //Check if B1=0 + bufferU[j++]=WRITE_RAM; + bufferU[j++]=0x0F; + bufferU[j++]=0x93; + bufferU[j++]=0xFF; //BX = input + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(5); + for(j=0;j<DIMBUF-3&&bufferI[j]!=READ_RAM;j++); + i=bufferI[j+3]&0x2; //B1 should be high + for(j+=3;j<DIMBUF-3&&bufferI[j]!=READ_RAM;j++); + return (i+(bufferI[j+3]&0x2))==2?1:0; +} + +/// +///Check if S1 is pressed +int CheckS1() +{ + int i,j=0; + bufferU[j++]=READ_RAM; + bufferU[j++]=0x0F; + if (HwID==5) { //all-in-one board + bufferU[j++]=0x80; // Read PORTA + } + else { //std board + bufferU[j++]=0x84; //READ PORTE + } + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(5); + for(j=0;j<DIMBUF-3&&bufferI[j]!=READ_RAM;j++); + if (HwID==5) { //all-in-one board + i=bufferI[j+3]&0x80; //i=A7 + return i?1:0; //A7=1 when switch pressed (active high) + } + else { //std board + i=bufferI[j+3]&0x8; //i=E3 + return i?0:1; //S1 open -> E3=1 (active low) + } +} + +/// +///Execute hardware test +#ifdef OPGUI +void TestHw(GtkWidget *widget,GtkWindow* parent) +#else +void TestHw(void) +#endif +{ +#ifndef DEBUG + if(DeviceDetected!=1) return; +#endif + char str[256]; + StartHVReg(13); + int j=0; + printMsg(strings[I_TestHW]); //"Test hardware ..." + bufferU[j++]=SET_CK_D; + bufferU[j++]=0x0; + bufferU[j++]=EN_VPP_VCC; //VDD+VPP + bufferU[j++]=0x5; + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(5); + strcpy(str,strings[I_TestMSG]); + strcat(str,"\n VDDU=5V\n VPPU=13V\n PGD(RB5)=0V\n PGC(RB6)=0V\n PGM(RB7)=0V"); + printMsg(str); + j=0; + bufferU[j++]=SET_CK_D; + bufferU[j++]=0x15; + bufferU[j++]=EN_VPP_VCC; + bufferU[j++]=0x1; //VDD + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(5); + strcpy(str,strings[I_TestMSG]); + strcat(str,"\n VDDU=5V\n VPPU=0V\n PGD(RB5)=5V\n PGC(RB6)=5V\n PGM(RB7)=5V"); + printMsg(str); + j=0; + bufferU[j++]=SET_CK_D; + bufferU[j++]=0x1; + bufferU[j++]=EN_VPP_VCC; + bufferU[j++]=0x4; //VPP + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(5); + strcpy(str,strings[I_TestMSG]); + strcat(str,"\n VDDU=0V\n VPPU=13V\n PGD(RB5)=5V\n PGC(RB6)=0V\n PGM(RB7)=0V"); + printMsg(str); + j=0; + bufferU[j++]=SET_CK_D; + bufferU[j++]=0x4; + bufferU[j++]=EN_VPP_VCC; + bufferU[j++]=0x0; + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(5); + strcpy(str,strings[I_TestMSG]); + strcat(str,"\n VDDU=0V\n VPPU=0V\n PGD(RB5)=0V\n PGC(RB6)=5V\n PGM(RB7)=0V"); + printMsg(str); + j=0; + bufferU[j++]=SET_CK_D; + bufferU[j++]=0x0; + bufferU[j++]=EN_VPP_VCC; + bufferU[j++]=0x0; + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(5); + if(FWVersion>=0x900){ //IO test + int j=0,i,x,r; + strcpy(str,"0000000000000"); + PrintMessage("IO test\nRC|RA|--RB--|\n"); + for(i=0;i<13;i++){ + x=1<<i; + j=0; + bufferU[j++]=EN_VPP_VCC; + bufferU[j++]=0x0; + bufferU[j++]=SET_PORT_DIR; + bufferU[j++]=0x0; //TRISB + bufferU[j++]=0x0; //TRISA-C (RC7:RC6:RA5:RA4:RA3:X:X:X) + bufferU[j++]=EXT_PORT; + bufferU[j++]=x&0xFF; //PORTB + bufferU[j++]=(x>>5)&0xFF; //PORTA-C + bufferU[j++]=READ_B; + bufferU[j++]=READ_AC; + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(5); + for(j=0;j<DIMBUF-1&&bufferI[j]!=READ_B;j++); + r=bufferI[j+1]; + for(j+=2;j<DIMBUF-1&&bufferI[j]!=READ_AC;j++); + r+=(bufferI[j+1]&0xF8)<<5; + for(j=0;j<13;j++) str[12-j]=x&(1<<j)?'1':'0'; + PrintMessage(str); + PrintMessage1(" (%s)\n",r==x?"OK":strings[S_ErrSing]); + } + } +} + +/// +///Wait for X milliseconds +void msDelay(double delay) +{ +#if !defined _WIN32 && !defined __CYGWIN__ + long x=(int)(delay*1000.0); + usleep(x>MinDly?x:MinDly); +#else +// Sleep((long)ceil(delay)>MinDly?(long)ceil(delay):MinDly); + __int64 stop,freq,timeout; + QueryPerformanceCounter((LARGE_INTEGER *)&stop); + QueryPerformanceFrequency((LARGE_INTEGER *)&freq); + timeout=stop+delay*freq/1000.0; + while(stop<timeout) QueryPerformanceCounter((LARGE_INTEGER *)&stop); +#endif +} + +#if !defined _WIN32 && !defined __CYGWIN__ //Linux +/// +/// Get system time +DWORD GetTickCount(){ + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec*1000+tv.tv_usec/1000; +/* + struct timeb now; + ftime(&now); + return now.time*1000+now.millitm; +*/ +} +#endif + +/// +///Write data packet, wait for X milliseconds, read response +///real waiting happens only if the desired delay is greater than 40ms; +///in case of smaller delays the function simply waits for a response (up to 50ms) +/// +void PacketIO(double delay){ + #define TIMEOUT 50 + if(saveLog&&logfile) fprintf(logfile,"PacketIO(%.2f)\n",delay); + int delay0=delay; +#if !defined _WIN32 && !defined __CYGWIN__ //Linux + struct timespec ts; + uint64_t start,stop; + fd_set set; + struct timeval timeout; + int rv,i; + FD_ZERO(&set); /* clear the set */ + FD_SET(fd, &set); /* add our file descriptor to the set */ + timeout.tv_sec = 0; + timeout.tv_usec = TIMEOUT*1000; + clock_gettime( CLOCK_REALTIME, &ts ); + start=ts.tv_nsec/1000; + delay-=TIMEOUT-10; //shorter delays are covered by 50ms timeout + if(delay<MinDly) delay=MinDly; + #ifndef hiddevIO //use raw USB device + //wait before writing +/* rv = select(fd + 1, NULL, &set, NULL, &timeout); //wait for write event + if(rv == -1){ + PrintMessage(strings[S_ErrSing]); //error + if(saveLog&&logfile) fprintf(logfile,strings[S_ErrSing]); + return; + } + else if(rv == 0){ + PrintMessage(strings[S_comTimeout]); //"comm timeout\r\n" + if(saveLog&&logfile) fprintf(logfile,strings[S_comTimeout]); + return; + }*/ + //write + int res = write(fd,bufferU,DIMBUF); + if (res < 0) { + printf("Error: %d\n", errno); + perror("write"); + } + usleep((int)(delay*1000.0)); + //wait before reading + rv = select(fd + 1, &set, NULL, NULL, &timeout); //wait for event + if(rv == -1){ + PrintMessage(strings[S_ErrSing]); /*error*/ + if(saveLog&&logfile) fprintf(logfile,strings[S_ErrSing]); + return; + } + else if(rv == 0){ + PrintMessage(strings[S_comTimeout]); /*"comm timeout\r\n"*/ + if(saveLog&&logfile) fprintf(logfile,strings[S_comTimeout]); + return; + } + //read + res = read(fd, bufferI, DIMBUF); + if (res < 0) { + perror("read"); + } + #else //use hiddev device (old method) + struct hiddev_event ev[80]; + int n=DIMBUF; + for(i=0;i<DIMBUF;i++) ref_multi_u.values[i]=bufferU[i]; + //write + ioctl(fd, HIDIOCSUSAGES, &ref_multi_u); + ioctl(fd,HIDIOCSREPORT, &rep_info_u); + usleep((int)(delay*1000.0)); + //read + rv = select(fd + 1, &set, NULL, NULL, &timeout); //wait for event + if(rv == -1){ + PrintMessage(strings[S_ErrSing]); /*error*/ + if(saveLog&&logfile) fprintf(logfile,strings[S_ErrSing]); + } + else if(rv == 0){ + PrintMessage(strings[S_comTimeout]); /*"comm timeout\r\n"*/ + if(saveLog&&logfile) fprintf(logfile,strings[S_comTimeout]); + } + else{ + // ioctl(fd, HIDIOCGUSAGES, &ref_multi_i); + // ioctl(fd,HIDIOCGREPORT, &rep_info_i); + #undef read() + rv=read(fd, ev,sizeof(struct hiddev_event) *n); + for(i=0;(ev[0].value!=bufferU[0])&&i<40;i++){ //read too early; try again after 5ms + msDelay(5); + rv=read(fd, ev,sizeof(struct hiddev_event) *n); + if(saveLog&&logfile) fprintf(logfile,"Packet not ready, wait extra time\n"); + } + if(i==40) fprintf(logfile,"Cannot read correct packet!!\n"); + for(i=0;i<n;i++) bufferI[i]=ev[i].value&0xFF; + } + #endif + clock_gettime( CLOCK_REALTIME, &ts ); + stop = ts.tv_nsec / 1000; + if(saveLog&&logfile){ + WriteLogIO(); + fprintf(logfile,"T=%.2f ms (%+.2f ms)\n",(stop-start)/1000.0,(stop-start)/1000.0-delay0); + if(bufferU[0]!=bufferI[0]) fprintf(logfile,"Cannot read correct packet!!\n"); + } +#else //Windows + __int64 start,stop,freq,timeout; + QueryPerformanceCounter((LARGE_INTEGER *)&start); + QueryPerformanceFrequency((LARGE_INTEGER *)&freq); + delay-=TIMEOUT-10; //shorter delays are covered by 50ms timeout + if(delay<MinDly) delay=MinDly; + //write + Result = WriteFile(WriteHandle,bufferU0,DIMBUF+1,&BytesWritten,NULL); + QueryPerformanceCounter((LARGE_INTEGER *)&stop); + timeout=stop+delay*freq/1000.0; + while(stop<timeout) QueryPerformanceCounter((LARGE_INTEGER *)&stop); + //read + Result = ReadFile(ReadHandle,bufferI0,DIMBUF+1,&NumberOfBytesRead,(LPOVERLAPPED) &HIDOverlapped); + Result = WaitForSingleObject(hEventObject,TIMEOUT); + if(saveLog&&logfile) WriteLogIO(); + ResetEvent(hEventObject); + if(Result!=WAIT_OBJECT_0){ + PrintMessage(strings[S_comTimeout]); /*"comm timeout\r\n"*/ + if(saveLog&&logfile) fprintf(logfile,strings[S_comTimeout]); + } + QueryPerformanceCounter((LARGE_INTEGER *)&stop); + if(saveLog&&logfile) fprintf(logfile,"T=%.2f ms (%+.2f ms)\n",(stop-start)*1000.0/freq,(stop-start)*1000.0/freq-delay0); +#endif +} + + +/// +///Find the USB peripheral with proper vid&pid code +/// return 0 if not found +int FindDevice(int vid,int pid){ + int MyDeviceDetected = FALSE; +#if !defined _WIN32 && !defined __CYGWIN__ //Linux + #ifndef hiddevIO //use raw USB device + struct hidraw_devinfo device_info; + int i=-1; + if(path[0]==0){ //search all devices + if((fd = open("/dev/openprogrammer", O_RDWR|O_NONBLOCK))>0){ //try with this first + sprintf(path,"/dev/openprogrammer"); + ioctl(fd, HIDIOCGRAWINFO, &device_info); + if(device_info.vendor==vid&&device_info.product==pid) i=0; + else{ + close(fd); + i=-1; + } + } + if(i){ + for(i=0;i<16;i++){ + sprintf(path,"/dev/hidraw%d",i); + if((fd = open(path, O_RDWR|O_NONBLOCK))>0){ + ioctl(fd, HIDIOCGRAWINFO, &device_info); + if(device_info.vendor==vid&&device_info.product==pid) break; + else close(fd); + } + } + } + if(i==16){ + PrintMessage(strings[S_noprog]); + path[0]=0; + return 0; + } + } + else{ //user supplied path + if((fd = open(path, O_RDWR|O_NONBLOCK)) < 0) { + PrintMessage1(strings[S_DevPermission],path); //"cannot open %s, make sure you have read permission on it",path); + return 0; + } + ioctl(fd, HIDIOCGRAWINFO, &device_info); + if(device_info.vendor!=vid||device_info.product!=pid){ + PrintMessage(strings[S_noprog]); + return 0; + } + } + printf(strings[S_progDev],path); + return 1; + #else //use hiddev device (old method) + struct hiddev_devinfo device_info; + int i=-1; + if(path[0]==0){ //search all devices + if((fd = open("/dev/openprogrammer", O_RDONLY ))>0){ //try with this first + ioctl(fd, HIDIOCGDEVINFO, &device_info); + if(device_info.vendor==vid&&device_info.product==pid) i=0; + else{ + close(fd); + i=-1; + } + } + if(i){ + for(i=0;i<16;i++){ + sprintf(path,"/dev/usb/hiddev%d",i); + if((fd = open(path, O_RDONLY ))>0){ + ioctl(fd, HIDIOCGDEVINFO, &device_info); + if(device_info.vendor==vid&&device_info.product==pid) break; + else close(fd); + } + } + } + if(i==16){ + PrintMessage(strings[S_noprog]); + path[0]=0; + return 0; + } + } + else{ //user supplied path + if ((fd = open(path, O_RDONLY )) < 0) { + PrintMessage1(strings[S_DevPermission],path); //"cannot open %s, make sure you have read permission on it",path); + return 0; + } + ioctl(fd, HIDIOCGDEVINFO, &device_info); + if(device_info.vendor!=vid||device_info.product!=pid){ + PrintMessage(strings[S_noprog]); + return 0; + } + } + #ifndef OPGUI + printf(strings[S_progDev],path); + #endif + MyDeviceDetected = TRUE; + rep_info_u.report_type=HID_REPORT_TYPE_OUTPUT; + rep_info_i.report_type=HID_REPORT_TYPE_INPUT; + rep_info_u.report_id=rep_info_i.report_id=HID_REPORT_ID_FIRST; + rep_info_u.num_fields=rep_info_i.num_fields=1; + ref_multi_u.uref.report_type=HID_REPORT_TYPE_OUTPUT; + ref_multi_i.uref.report_type=HID_REPORT_TYPE_INPUT; + ref_multi_u.uref.report_id=ref_multi_i.uref.report_id=HID_REPORT_ID_FIRST; + ref_multi_u.uref.field_index=ref_multi_i.uref.field_index=0; + ref_multi_u.uref.usage_index=ref_multi_i.uref.usage_index=0; + ref_multi_u.num_values=ref_multi_i.num_values=DIMBUF; + #endif +#else //Windows + PSP_DEVICE_INTERFACE_DETAIL_DATA detailData; + HANDLE DeviceHandle; + HANDLE hDevInfo; + GUID HidGuid; + char MyDevicePathName[1024]; + ULONG Length; + ULONG Required; + typedef struct _HIDD_ATTRIBUTES { + ULONG Size; + USHORT VendorID; + USHORT ProductID; + USHORT VersionNumber; + } HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES; + typedef void (__stdcall*GETHIDGUID) (OUT LPGUID HidGuid); + typedef BOOLEAN (__stdcall*GETATTRIBUTES)(IN HANDLE HidDeviceObject,OUT PHIDD_ATTRIBUTES Attributes); + typedef BOOLEAN (__stdcall*SETNUMINPUTBUFFERS)(IN HANDLE HidDeviceObject,OUT ULONG NumberBuffers); + typedef BOOLEAN (__stdcall*GETNUMINPUTBUFFERS)(IN HANDLE HidDeviceObject,OUT PULONG NumberBuffers); + typedef BOOLEAN (__stdcall*GETFEATURE) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength); + typedef BOOLEAN (__stdcall*SETFEATURE) (IN HANDLE HidDeviceObject, IN PVOID ReportBuffer, IN ULONG ReportBufferLength); + typedef BOOLEAN (__stdcall*GETREPORT) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength); + typedef BOOLEAN (__stdcall*SETREPORT) (IN HANDLE HidDeviceObject, IN PVOID ReportBuffer, IN ULONG ReportBufferLength); + typedef BOOLEAN (__stdcall*GETMANUFACTURERSTRING) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength); + typedef BOOLEAN (__stdcall*GETPRODUCTSTRING) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength); + typedef BOOLEAN (__stdcall*GETINDEXEDSTRING) (IN HANDLE HidDeviceObject, IN ULONG StringIndex, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength); + HIDD_ATTRIBUTES Attributes; + SP_DEVICE_INTERFACE_DATA devInfoData; + int LastDevice = FALSE; + int MemberIndex = 0; + LONG Result; + Length=0; + detailData=NULL; + DeviceHandle=NULL; + HMODULE hHID=0; + GETHIDGUID HidD_GetHidGuid=0; + GETATTRIBUTES HidD_GetAttributes=0; + SETNUMINPUTBUFFERS HidD_SetNumInputBuffers=0; + GETNUMINPUTBUFFERS HidD_GetNumInputBuffers=0; + GETFEATURE HidD_GetFeature=0; + SETFEATURE HidD_SetFeature=0; + GETREPORT HidD_GetInputReport=0; + SETREPORT HidD_SetOutputReport=0; + GETMANUFACTURERSTRING HidD_GetManufacturerString=0; + GETPRODUCTSTRING HidD_GetProductString=0; + hHID = LoadLibrary("hid.dll"); + if(!hHID){ + PrintMessage("Can't find hid.dll"); + return 0; + } + HidD_GetHidGuid=(GETHIDGUID)GetProcAddress(hHID,"HidD_GetHidGuid"); + HidD_GetAttributes=(GETATTRIBUTES)GetProcAddress(hHID,"HidD_GetAttributes"); + HidD_SetNumInputBuffers=(SETNUMINPUTBUFFERS)GetProcAddress(hHID,"HidD_SetNumInputBuffers"); + HidD_GetNumInputBuffers=(GETNUMINPUTBUFFERS)GetProcAddress(hHID,"HidD_GetNumInputBuffers"); + HidD_GetFeature=(GETFEATURE)GetProcAddress(hHID,"HidD_GetFeature"); + HidD_SetFeature=(SETFEATURE)GetProcAddress(hHID,"HidD_SetFeature"); + HidD_GetInputReport=(GETREPORT)GetProcAddress(hHID,"HidD_GetInputReport"); + HidD_SetOutputReport=(SETREPORT)GetProcAddress(hHID,"HidD_SetOutputReport"); + HidD_GetManufacturerString=(GETMANUFACTURERSTRING)GetProcAddress(hHID,"HidD_GetManufacturerString"); + HidD_GetProductString=(GETPRODUCTSTRING)GetProcAddress(hHID,"HidD_GetProductString"); + if(HidD_GetHidGuid==NULL\ + ||HidD_GetAttributes==NULL\ + ||HidD_GetFeature==NULL\ + ||HidD_SetFeature==NULL\ + ||HidD_GetInputReport==NULL\ + ||HidD_SetOutputReport==NULL\ + ||HidD_GetManufacturerString==NULL\ + ||HidD_GetProductString==NULL\ + ||HidD_SetNumInputBuffers==NULL\ + ||HidD_GetNumInputBuffers==NULL) return 0; + HMODULE hSAPI=0; + hSAPI = LoadLibrary("setupapi.dll"); + if(!hSAPI){ + PrintMessage("Can't find setupapi.dll"); + return 0; + } + typedef HDEVINFO (WINAPI* SETUPDIGETCLASSDEVS) (CONST GUID*,PCSTR,HWND,DWORD); + typedef BOOL (WINAPI* SETUPDIENUMDEVICEINTERFACES) (HDEVINFO,PSP_DEVINFO_DATA,CONST GUID*,DWORD,PSP_DEVICE_INTERFACE_DATA); + typedef BOOL (WINAPI* SETUPDIGETDEVICEINTERFACEDETAIL) (HDEVINFO,PSP_DEVICE_INTERFACE_DATA,PSP_DEVICE_INTERFACE_DETAIL_DATA_A,DWORD,PDWORD,PSP_DEVINFO_DATA); + typedef BOOL (WINAPI* SETUPDIDESTROYDEVICEINFOLIST) (HDEVINFO); + SETUPDIGETCLASSDEVS SetupDiGetClassDevsA=0; + SETUPDIENUMDEVICEINTERFACES SetupDiEnumDeviceInterfaces=0; + SETUPDIGETDEVICEINTERFACEDETAIL SetupDiGetDeviceInterfaceDetailA=0; + SETUPDIDESTROYDEVICEINFOLIST SetupDiDestroyDeviceInfoList=0; + SetupDiGetClassDevsA=(SETUPDIGETCLASSDEVS) GetProcAddress(hSAPI,"SetupDiGetClassDevsA"); + SetupDiEnumDeviceInterfaces=(SETUPDIENUMDEVICEINTERFACES) GetProcAddress(hSAPI,"SetupDiEnumDeviceInterfaces"); + SetupDiGetDeviceInterfaceDetailA=(SETUPDIGETDEVICEINTERFACEDETAIL) GetProcAddress(hSAPI,"SetupDiGetDeviceInterfaceDetailA"); + SetupDiDestroyDeviceInfoList=(SETUPDIDESTROYDEVICEINFOLIST) GetProcAddress(hSAPI,"SetupDiDestroyDeviceInfoList"); + if(SetupDiGetClassDevsA==NULL\ + ||SetupDiEnumDeviceInterfaces==NULL\ + ||SetupDiDestroyDeviceInfoList==NULL\ + ||SetupDiGetDeviceInterfaceDetailA==NULL) return 0; + /* + The following code is adapted from Usbhidio_vc6 application example by Jan Axelson + for more information see see http://www.lvr.com/hidpage.htm + */ + /* + API function: HidD_GetHidGuid + Get the GUID for all system HIDs. + Returns: the GUID in HidGuid. + */ + HidD_GetHidGuid(&HidGuid); + /* + API function: SetupDiGetClassDevs + Returns: a handle to a device information set for all installed devices. + Requires: the GUID returned by GetHidGuid. + */ + hDevInfo=SetupDiGetClassDevs(&HidGuid,NULL,NULL,DIGCF_PRESENT|DIGCF_INTERFACEDEVICE); + devInfoData.cbSize = sizeof(devInfoData); + //Step through the available devices looking for the one we want. + //Quit on detecting the desired device or checking all available devices without success. + MemberIndex = 0; + LastDevice = FALSE; + do + { + /* + API function: SetupDiEnumDeviceInterfaces + On return, MyDeviceInterfaceData contains the handle to a + SP_DEVICE_INTERFACE_DATA structure for a detected device. + Requires: + The DeviceInfoSet returned in SetupDiGetClassDevs. + The HidGuid returned in GetHidGuid. + An index to specify a device. + */ + Result=SetupDiEnumDeviceInterfaces (hDevInfo, 0, &HidGuid, MemberIndex, &devInfoData); + if (Result != 0) + { + //A device has been detected, so get more information about it. + /* + API function: SetupDiGetDeviceInterfaceDetail + Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure + containing information about a device. + To retrieve the information, call this function twice. + The first time returns the size of the structure in Length. + The second time returns a pointer to the data in DeviceInfoSet. + Requires: + A DeviceInfoSet returned by SetupDiGetClassDevs + The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces. + The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure. + This application doesn't retrieve or use the structure. + If retrieving the structure, set + MyDeviceInfoData.cbSize = length of MyDeviceInfoData. + and pass the structure's address. + */ + //Get the Length value. + //The call will return with a "buffer too small" error which can be ignored. + Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, NULL, 0, &Length, NULL); + //Allocate memory for the hDevInfo structure, using the returned Length. + detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length); + //Set cbSize in the detailData structure. + detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); + //Call the function again, this time passing it the returned buffer size. + Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, detailData, Length,&Required, NULL); + // Open a handle to the device. + // To enable retrieving information about a system mouse or keyboard, + // don't request Read or Write access for this handle. + /* + API function: CreateFile + Returns: a handle that enables reading and writing to the device. + Requires: + The DevicePath in the detailData structure + returned by SetupDiGetDeviceInterfaceDetail. + */ + DeviceHandle=CreateFile(detailData->DevicePath, + 0, FILE_SHARE_READ|FILE_SHARE_WRITE, + (LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING, 0, NULL); + /* + API function: HidD_GetAttributes + Requests information from the device. + Requires: the handle returned by CreateFile. + Returns: a HIDD_ATTRIBUTES structure containing + the Vendor ID, Product ID, and Product Version Number. + Use this information to decide if the detected device is + the one we're looking for. + */ + //Set the Size to the number of bytes in the structure. + Attributes.Size = sizeof(Attributes); + Result = HidD_GetAttributes(DeviceHandle,&Attributes); + //Is it the desired device? + MyDeviceDetected = FALSE; + if (Attributes.VendorID == vid) + { + if (Attributes.ProductID == pid) + { + //Both the Vendor ID and Product ID match. + MyDeviceDetected = TRUE; + strcpy(MyDevicePathName,detailData->DevicePath); + // Get a handle for writing Output reports. + WriteHandle=CreateFile(detailData->DevicePath, + GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, + (LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING,0,NULL); + //Get a handle to the device for the overlapped ReadFiles. + ReadHandle=CreateFile(detailData->DevicePath, + GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,(LPSECURITY_ATTRIBUTES)NULL, + OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL); + if (hEventObject) CloseHandle(hEventObject); + hEventObject = CreateEvent(NULL,TRUE,TRUE,""); + //Set the members of the overlapped structure. + HIDOverlapped.hEvent = hEventObject; + HIDOverlapped.Offset = 0; + HIDOverlapped.OffsetHigh = 0; + Result=HidD_SetNumInputBuffers(DeviceHandle,64); + } + else + //The Product ID doesn't match. + CloseHandle(DeviceHandle); + } + else + //The Vendor ID doesn't match. + CloseHandle(DeviceHandle); + //Free the memory used by the detailData structure (no longer needed). + free(detailData); + } + else + //SetupDiEnumDeviceInterfaces returned 0, so there are no more devices to check. + LastDevice=TRUE; + //If we haven't found the device yet, and haven't tried every available device, + //try the next one. + MemberIndex = MemberIndex + 1; + } //do + while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE)); + //Free the memory reserved for hDevInfo by SetupDiClassDevs. + SetupDiDestroyDeviceInfoList(hDevInfo); + + #ifndef OPGUI + if(info&&MyDeviceDetected == TRUE){ + char string[1024]; + PrintMessage3("Device detected: vid=0x%04X pid=0x%04X\nPath: %s\n",vid,pid,MyDevicePathName); + if(HidD_GetManufacturerString(DeviceHandle,string,sizeof(string))==TRUE) wprintf(L"Manufacturer string: %s\n",string); + if(HidD_GetProductString(DeviceHandle,string,sizeof(string))==TRUE) wprintf(L"Product string: %s\n",string); + } + #endif +#endif + if (MyDeviceDetected == FALSE){ + PrintMessage(strings[S_noprog]); //"Programmer not detected\r\n" + //gtk_statusbar_push(status_bar,statusID,strings[S_noprog]); + } + else{ + PrintMessage(strings[S_prog]); //"Programmer detected\r\n"); +#ifdef OPGUI + PrintMessage2("VID=0x%04X PID=0x%04X\r\n",vid,pid); +#endif + //gtk_statusbar_push(status_bar,statusID,strings[S_prog]); + } + return MyDeviceDetected; +} + diff --git a/common_functions.h b/common_functions.h new file mode 100644 index 0000000..8521dd8 --- /dev/null +++ b/common_functions.h @@ -0,0 +1,17 @@ +#ifndef COMMON_FUNCTIONS_H +#define COMMON_FUNCTIONS_H + +extern int skipV33check=0; +extern char loadfileEE[512]="",savefileEE[512]=""; +extern int vid=0x1209,pid=0x5432; +extern int DeviceDetected=0; +extern int new_vid=0x1209,new_pid=0x5432; +extern int old_vid=0x04D8,old_pid=0x0100; +#if !defined _WIN32 && !defined __CYGWIN__ //Linux + extern char path[512]=""; +#endif +#ifdef OPGUI + extern GtkWidget * b_V33check; +#endif + +#endif // COMMON_FUNCTIONS_H @@ -22,6 +22,7 @@ #include "common.h" +#include "common_functions.h" #include "I2CSPI.h" #include "deviceRW.h" #include "fileIO.h" @@ -45,63 +46,17 @@ int kbhit() #else #include "conio.h" #endif -#define MinDly 0 + +int info=0; +int devType=0x10000; +char dev[64]=""; void msDelay(double delay); void TestHw(); int StartHVReg(double V); -void ProgID(); + void DisplayEE(); int FindDevice(); -int CheckS1(); - -char** strings; -int saveLog=0,programID=0,load_osccal=0,load_BKosccal=0; -int use_osccal=1,use_BKosccal=0; -int load_calibword=0,max_err=200; -int AVRlock=0x100,AVRfuse=0x100,AVRfuse_h=0x100,AVRfuse_x=0x100; -int ICDenable=0,ICDaddr=0x1FF0; -int FWVersion=0,HwID=0; - -FILE* logfile=0; -char LogFileName[512]=""; -char loadfile[512]="",savefile[512]=""; -char loadfileEE[512]="",savefileEE[512]=""; -int info=0; -int vid=0x1209,pid=0x5432; -int new_vid=0x1209,new_pid=0x5432; -int old_vid=0x04D8,old_pid=0x0100; - -WORD *memCODE_W=0; -int size=0,sizeW=0,sizeEE=0,sizeCONFIG=0,sizeUSERID=0; -unsigned char *memCODE=0,*memEE=0,memID[64],memCONFIG[48],memUSERID[8]; -double hvreg=0; -int DeviceDetected=0; -int skipV33check=0; -int progress=0; -int RWstop=0; -int forceConfig=0; -char dev[64]=""; -int devType=0x10000; -char str[4096]; - -#if !defined _WIN32 && !defined __CYGWIN__ //Linux - int fd = -1; - struct hiddev_report_info rep_info_i,rep_info_u; - struct hiddev_usage_ref_multi ref_multi_i,ref_multi_u; - char path[512]=""; - unsigned char bufferU[128],bufferI[128]; -#else //Windows - unsigned char bufferU0[128],bufferI0[128]; - unsigned char *bufferU,*bufferI; - DWORD NumberOfBytesRead,BytesWritten; - ULONG Result; - HANDLE WriteHandle,ReadHandle; - OVERLAPPED HIDOverlapped; - HANDLE hEventObject; -#endif - - int main (int argc, char **argv) { @@ -622,741 +577,3 @@ void DisplayEE(){ } if(empty) PrintMessage(strings[S_Empty]); //empty } - -/// -///Start HV regulator -int StartHVReg(double V){ - int j=0,z; - int vreg=(int)(V*10.0); - if(saveLog&&logfile) fprintf(logfile,"StartHVReg(%.2f)\n",V); - DWORD t0,t; - if(V==-1){ - bufferU[j++]=VREG_DIS; //disable HV regulator - bufferU[j++]=FLUSH; - PacketIO(5); - msDelay(40); - return -1; - } - t=t0=GetTickCount(); - bufferU[j++]=VREG_EN; //enable HV regulator - bufferU[j++]=SET_VPP; - bufferU[j++]=vreg; - bufferU[j++]=SET_PARAMETER; - bufferU[j++]=SET_T3; - bufferU[j++]=2000>>8; - bufferU[j++]=2000&0xff; - bufferU[j++]=WAIT_T3; - bufferU[j++]=READ_ADC; - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - PacketIO(5); - msDelay(20); - for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_ADC;z++); - int v=(bufferI[z+1]<<8)+bufferI[z+2]; -// PrintMessage2("v=%d=%fV\n",v,v/G); - if(v==0){ - PrintMessage(strings[S_lowUsbV]); //"Tensione USB troppo bassa (VUSB<4.5V)\r\n" - return 0; - } - j=0; - bufferU[j++]=WAIT_T3; - bufferU[j++]=READ_ADC; - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - for(;(v<(vreg/10.0-1)*G||v>(vreg/10.0+1)*G)&&t<t0+1500;t=GetTickCount()){ - PacketIO(5); - msDelay(20); - for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_ADC;z++); - v=(bufferI[z+1]<<8)+bufferI[z+2]; - if(HwID==3) v>>=2; //if 12 bit ADC -// PrintMessage2("v=%d=%fV\n",v,v/G); - } - if(v>(vreg/10.0+1)*G){ - PrintMessage(strings[S_HiVPP]); //"Attenzione: tensione regolatore troppo alta\r\n\r\n" - return 0; - } - else if(v<(vreg/10.0-1)*G){ - PrintMessage(strings[S_LowVPP]); //"Attenzione: tensione regolatore troppo bassa\r\n\r\n" - return 0; - } - else if(v==0){ - PrintMessage(strings[S_lowUsbV]); //"Tensione USB troppo bassa (VUSB<4.5V)\r\n" - return 0; - } - else{ - PrintMessage2(strings[S_reg],t-t0,v/G); //"Regolatore avviato e funzionante dopo T=%d ms VPP=%.1f\r\n\r\n" - if(saveLog&&logfile) fprintf(logfile,strings[S_reg],t-t0,v/G); - return vreg; - } -} - -/// -///Read programmer ID -void ProgID() -{ - if(DeviceDetected!=1) return; - int j=0; - bufferU[j++]=PROG_RST; - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - PacketIO(2); - for(j=0;j<DIMBUF-7&&bufferI[j]!=PROG_RST;j++); - PrintMessage3(strings[S_progver],bufferI[j+1],bufferI[j+2],bufferI[j+3]); //"FW versione %d.%d.%d\r\n" - FWVersion=(bufferI[j+1]<<16)+(bufferI[j+2]<<8)+bufferI[j+3]; - PrintMessage3(strings[S_progid],bufferI[j+4],bufferI[j+5],bufferI[j+6]); //"ID Hw: %d.%d.%d" - HwID=bufferI[j+6]; - if(HwID==1) PrintMessage(" (18F2550)\r\n\r\n"); - else if(HwID==2) PrintMessage(" (18F2450)\r\n\r\n"); - else if(HwID==3) PrintMessage(" (18F2458/2553)\r\n\r\n"); - else if(HwID==4) PrintMessage(" (18F25K50)\r\n\r\n"); - else PrintMessage(" (?)\r\n\r\n"); -} - -/// -///Check if a 3.3V regulator is present -int CheckV33Regulator() -{ - int i,j=0; - if(skipV33check) return 1; - bufferU[j++]=WRITE_RAM; - bufferU[j++]=0x0F; - bufferU[j++]=0x93; - bufferU[j++]=0xFE; //B0 = output - bufferU[j++]=EXT_PORT; - bufferU[j++]=0x01; //B0=1 - bufferU[j++]=0; - bufferU[j++]=READ_RAM; - bufferU[j++]=0x0F; - bufferU[j++]=0x81; //Check if B1=1 - bufferU[j++]=EXT_PORT; - bufferU[j++]=0x00; //B0=0 - bufferU[j++]=0; - bufferU[j++]=READ_RAM; - bufferU[j++]=0x0F; - bufferU[j++]=0x81; //Check if B1=0 - bufferU[j++]=WRITE_RAM; - bufferU[j++]=0x0F; - bufferU[j++]=0x93; - bufferU[j++]=0xFF; //BX = input - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - PacketIO(5); - for(j=0;j<DIMBUF-3&&bufferI[j]!=READ_RAM;j++); - i=bufferI[j+3]&0x2; //B1 should be high - for(j+=3;j<DIMBUF-3&&bufferI[j]!=READ_RAM;j++); - return (i+(bufferI[j+3]&0x2))==2?1:0; -} - -/// -///Check if S1 is pressed -int CheckS1() -{ - int i,j=0; - bufferU[j++]=READ_RAM; - bufferU[j++]=0x0F; - bufferU[j++]=0x84; //READ PORTE - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - PacketIO(5); - for(j=0;j<DIMBUF-3&&bufferI[j]!=READ_RAM;j++); - i=bufferI[j+3]&0x8; //i=E3 - return i?0:1; //S1 open -> E3=1 -} - -/// -///Execute hardware test -void TestHw() -{ -#ifndef DEBUG - if(DeviceDetected!=1) return; -#endif - char str[256]; - StartHVReg(13); - int j=0; - PrintMessage(strings[I_TestHW]); //"Test hardware ..." - fflush(stdout); - getchar(); - bufferU[j++]=SET_CK_D; - bufferU[j++]=0x0; - bufferU[j++]=EN_VPP_VCC; //VDD+VPP - bufferU[j++]=0x5; - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - PacketIO(5); - strcpy(str,strings[I_TestMSG]); - strcat(str,"\n VDD=5V\n VPP=13V\n PGD(RB5)=0V\n PGC(RB6)=0V\n PGM(RB7)=0V"); - PrintMessage(str); - fflush(stdout); - getchar(); - j=0; - bufferU[j++]=SET_CK_D; - bufferU[j++]=0x15; - bufferU[j++]=EN_VPP_VCC; - bufferU[j++]=0x1; //VDD - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - PacketIO(5); - strcpy(str,strings[I_TestMSG]); - strcat(str,"\n VDD=5V\n VPP=0V\n PGD(RB5)=5V\n PGC(RB6)=5V\n PGM(RB7)=5V"); - PrintMessage(str); - fflush(stdout); - getchar(); - j=0; - bufferU[j++]=SET_CK_D; - bufferU[j++]=0x1; - bufferU[j++]=EN_VPP_VCC; - bufferU[j++]=0x4; //VPP - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - PacketIO(5); - strcpy(str,strings[I_TestMSG]); - strcat(str,"\n VDD=0V\n VPP=13V\n PGD(RB5)=5V\n PGC(RB6)=0V\n PGM(RB7)=0V"); - PrintMessage(str); - fflush(stdout); - getchar(); - j=0; - bufferU[j++]=SET_CK_D; - bufferU[j++]=0x4; - bufferU[j++]=EN_VPP_VCC; - bufferU[j++]=0x0; - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - PacketIO(5); - strcpy(str,strings[I_TestMSG]); - strcat(str,"\n VDD=0V\n VPP=0V\n PGD(RB5)=0V\n PGC(RB6)=5V\n PGM(RB7)=0V"); - PrintMessage(str); - fflush(stdout); - getchar(); - j=0; - bufferU[j++]=SET_CK_D; - bufferU[j++]=0x0; - bufferU[j++]=EN_VPP_VCC; - bufferU[j++]=0x0; - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - PacketIO(5); - if(FWVersion>=0x900){ //IO test - int j=0,i,x,r; - strcpy(str,"0000000000000"); - PrintMessage("IO test\nRC|RA|--RB--|\n"); - for(i=0;i<13;i++){ - x=1<<i; - j=0; - bufferU[j++]=EN_VPP_VCC; - bufferU[j++]=0x0; - bufferU[j++]=SET_PORT_DIR; - bufferU[j++]=0x0; //TRISB - bufferU[j++]=0x0; //TRISA-C (RC7:RC6:RA5:RA4:RA3:X:X:X) - bufferU[j++]=EXT_PORT; - bufferU[j++]=x&0xFF; //PORTB - bufferU[j++]=(x>>5)&0xFF; //PORTA-C - bufferU[j++]=READ_B; - bufferU[j++]=READ_AC; - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - PacketIO(5); - for(j=0;j<DIMBUF-1&&bufferI[j]!=READ_B;j++); - r=bufferI[j+1]; - for(j+=2;j<DIMBUF-1&&bufferI[j]!=READ_AC;j++); - r+=(bufferI[j+1]&0xF8)<<5; - for(j=0;j<13;j++) str[12-j]=x&(1<<j)?'1':'0'; - PrintMessage(str); - PrintMessage1(" (%s)\n",r==x?"OK":strings[S_ErrSing]); - } - } -} - -/// -///Wait for X milliseconds -void msDelay(double delay) -{ -#if !defined _WIN32 && !defined __CYGWIN__ - long x=(int)(delay*1000.0); - usleep(x>MinDly?x:MinDly); -#else -// Sleep((long)ceil(delay)>MinDly?(long)ceil(delay):MinDly); - __int64 stop,freq,timeout; - QueryPerformanceCounter((LARGE_INTEGER *)&stop); - QueryPerformanceFrequency((LARGE_INTEGER *)&freq); - timeout=stop+delay*freq/1000.0; - while(stop<timeout) QueryPerformanceCounter((LARGE_INTEGER *)&stop); -#endif -} - -#if !defined _WIN32 && !defined __CYGWIN__ //Linux -/// -/// Get system time -DWORD GetTickCount(){ - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec*1000+tv.tv_usec/1000; -/* - struct timeb now; - ftime(&now); - return now.time*1000+now.millitm; -*/ -} -#endif - -/// -///Write data packet, wait for X milliseconds, read response -void PacketIO(double delay){ - #define TIMEOUT 50 - if(saveLog&&logfile) fprintf(logfile,"PacketIO(%.2f)\n",delay); - int delay0=delay; -#if !defined _WIN32 && !defined __CYGWIN__ //Linux - struct timespec ts; - uint64_t start,stop; - fd_set set; - struct timeval timeout; - int rv,i; - FD_ZERO(&set); /* clear the set */ - FD_SET(fd, &set); /* add our file descriptor to the set */ - timeout.tv_sec = 0; - timeout.tv_usec = TIMEOUT*1000; - clock_gettime( CLOCK_REALTIME, &ts ); - start=ts.tv_nsec/1000; - delay-=TIMEOUT-10; //shorter delays are covered by 50ms timeout - if(delay<MinDly) delay=MinDly; - #ifndef hiddevIO //use raw USB device - //wait before writing -/* rv = select(fd + 1, NULL, &set, NULL, &timeout); //wait for write event - if(rv == -1){ - PrintMessage(strings[S_ErrSing]); //error - if(saveLog&&logfile) fprintf(logfile,strings[S_ErrSing]); - return; - } - else if(rv == 0){ - PrintMessage(strings[S_comTimeout]); //"comm timeout\r\n" - if(saveLog&&logfile) fprintf(logfile,strings[S_comTimeout]); - return; - }*/ - //write - int res = write(fd,bufferU,DIMBUF); - if (res < 0) { - printf("Error: %d\n", errno); - perror("write"); - } - usleep((int)(delay*1000.0)); - //wait before reading - rv = select(fd + 1, &set, NULL, NULL, &timeout); //wait for event - if(rv == -1){ - PrintMessage(strings[S_ErrSing]); /*error*/ - if(saveLog&&logfile) fprintf(logfile,strings[S_ErrSing]); - return; - } - else if(rv == 0){ - PrintMessage(strings[S_comTimeout]); /*"comm timeout\r\n"*/ - if(saveLog&&logfile) fprintf(logfile,strings[S_comTimeout]); - return; - } - //read - res = read(fd, bufferI, DIMBUF); - if (res < 0) { - perror("read"); - } - #else //use hiddev device (old method) - struct hiddev_event ev[80]; - int n=DIMBUF; - for(i=0;i<DIMBUF;i++) ref_multi_u.values[i]=bufferU[i]; - //write - ioctl(fd, HIDIOCSUSAGES, &ref_multi_u); - ioctl(fd,HIDIOCSREPORT, &rep_info_u); - usleep((int)(delay*1000.0)); - //read - rv = select(fd + 1, &set, NULL, NULL, &timeout); //wait for event - if(rv == -1){ - PrintMessage(strings[S_ErrSing]); /*error*/ - if(saveLog&&logfile) fprintf(logfile,strings[S_ErrSing]); - } - else if(rv == 0){ - PrintMessage(strings[S_comTimeout]); /*"comm timeout\r\n"*/ - if(saveLog&&logfile) fprintf(logfile,strings[S_comTimeout]); - } - else{ - // ioctl(fd, HIDIOCGUSAGES, &ref_multi_i); - // ioctl(fd,HIDIOCGREPORT, &rep_info_i); - #undef read() - rv=read(fd, ev,sizeof(struct hiddev_event) *n); - for(i=0;(ev[0].value!=bufferU[0])&&i<40;i++){ //read too early; try again after 5ms - msDelay(5); - rv=read(fd, ev,sizeof(struct hiddev_event) *n); - if(saveLog&&logfile) fprintf(logfile,"Packet not ready, wait extra time\n"); - } - if(i==40) fprintf(logfile,"Cannot read correct packet!!\n"); - for(i=0;i<n;i++) bufferI[i]=ev[i].value&0xFF; - } - #endif - clock_gettime( CLOCK_REALTIME, &ts ); - stop = ts.tv_nsec / 1000; - if(saveLog&&logfile){ - WriteLogIO(); - fprintf(logfile,"T=%.2f ms (%+.2f ms)\n",(stop-start)/1000.0,(stop-start)/1000.0-delay0); - if(bufferU[0]!=bufferI[0]) fprintf(logfile,"Cannot read correct packet!!\n"); - } -#else //Windows - __int64 start,stop,freq,timeout; - QueryPerformanceCounter((LARGE_INTEGER *)&start); - QueryPerformanceFrequency((LARGE_INTEGER *)&freq); - delay-=TIMEOUT-10; //shorter delays are covered by 50ms timeout - if(delay<MinDly) delay=MinDly; - //write - Result = WriteFile(WriteHandle,bufferU0,DIMBUF+1,&BytesWritten,NULL); - QueryPerformanceCounter((LARGE_INTEGER *)&stop); - timeout=stop+delay*freq/1000.0; - while(stop<timeout) QueryPerformanceCounter((LARGE_INTEGER *)&stop); - //read - Result = ReadFile(ReadHandle,bufferI0,DIMBUF+1,&NumberOfBytesRead,(LPOVERLAPPED) &HIDOverlapped); - Result = WaitForSingleObject(hEventObject,TIMEOUT); - if(saveLog&&logfile) WriteLogIO(); - ResetEvent(hEventObject); - if(Result!=WAIT_OBJECT_0){ - PrintMessage(strings[S_comTimeout]); /*"comm timeout\r\n"*/ - if(saveLog&&logfile) fprintf(logfile,strings[S_comTimeout]); - } - QueryPerformanceCounter((LARGE_INTEGER *)&stop); - if(saveLog&&logfile) fprintf(logfile,"T=%.2f ms (%+.2f ms)\n",(stop-start)*1000.0/freq,(stop-start)*1000.0/freq-delay0); -#endif -} - -/// -///Find the USB peripheral with proper vid&pid code -/// return 0 if not found - #define FALSE 0 -int FindDevice(int vid,int pid){ - int MyDeviceDetected = FALSE; -#if !defined _WIN32 && !defined __CYGWIN__ //Linux - #ifndef hiddevIO //use raw USB device - struct hidraw_devinfo device_info; - int i=-1; - if(path[0]==0){ //search all devices - if((fd = open("/dev/openprogrammer", O_RDWR|O_NONBLOCK))>0){ //try with this first - sprintf(path,"/dev/openprogrammer"); - ioctl(fd, HIDIOCGRAWINFO, &device_info); - if(device_info.vendor==vid&&device_info.product==pid) i=0; - else{ - close(fd); - i=-1; - } - } - if(i){ - for(i=0;i<16;i++){ - sprintf(path,"/dev/hidraw%d",i); - if((fd = open(path, O_RDWR|O_NONBLOCK))>0){ - ioctl(fd, HIDIOCGRAWINFO, &device_info); - if(device_info.vendor==vid&&device_info.product==pid) break; - else close(fd); - } - } - } - if(i==16){ - PrintMessage(strings[S_noprog]); - path[0]=0; - return 0; - } - } - else{ //user supplied path - if((fd = open(path, O_RDWR|O_NONBLOCK)) < 0) { - PrintMessage1(strings[S_DevPermission],path); //"cannot open %s, make sure you have read permission on it",path); - return 0; - } - ioctl(fd, HIDIOCGRAWINFO, &device_info); - if(device_info.vendor!=vid||device_info.product!=pid){ - PrintMessage(strings[S_noprog]); - return 0; - } - } - printf(strings[S_progDev],path); - return 1; - #else //use hiddev device (old method) - struct hiddev_devinfo device_info; - int i=-1; - if(path[0]==0){ //search all devices - if((fd = open("/dev/openprogrammer", O_RDONLY ))>0){ //try with this first - ioctl(fd, HIDIOCGDEVINFO, &device_info); - if(device_info.vendor==vid&&device_info.product==pid) i=0; - else{ - close(fd); - i=-1; - } - } - if(i){ - for(i=0;i<16;i++){ - sprintf(path,"/dev/usb/hiddev%d",i); - if((fd = open(path, O_RDONLY ))>0){ - ioctl(fd, HIDIOCGDEVINFO, &device_info); - if(device_info.vendor==vid&&device_info.product==pid) break; - else close(fd); - } - } - } - if(i==16){ - PrintMessage(strings[S_noprog]); - path[0]=0; - return 0; - } - } - else{ //user supplied path - if ((fd = open(path, O_RDONLY )) < 0) { - PrintMessage1(strings[S_DevPermission],path); //"cannot open %s, make sure you have read permission on it",path); - return 0; - } - ioctl(fd, HIDIOCGDEVINFO, &device_info); - if(device_info.vendor!=vid||device_info.product!=pid){ - PrintMessage(strings[S_noprog]); - return 0; - } - } - printf(strings[S_progDev],path); - MyDeviceDetected = TRUE; - rep_info_u.report_type=HID_REPORT_TYPE_OUTPUT; - rep_info_i.report_type=HID_REPORT_TYPE_INPUT; - rep_info_u.report_id=rep_info_i.report_id=HID_REPORT_ID_FIRST; - rep_info_u.num_fields=rep_info_i.num_fields=1; - ref_multi_u.uref.report_type=HID_REPORT_TYPE_OUTPUT; - ref_multi_i.uref.report_type=HID_REPORT_TYPE_INPUT; - ref_multi_u.uref.report_id=ref_multi_i.uref.report_id=HID_REPORT_ID_FIRST; - ref_multi_u.uref.field_index=ref_multi_i.uref.field_index=0; - ref_multi_u.uref.usage_index=ref_multi_i.uref.usage_index=0; - ref_multi_u.num_values=ref_multi_i.num_values=DIMBUF; - #endif -#else //Windows - PSP_DEVICE_INTERFACE_DETAIL_DATA detailData; - HANDLE DeviceHandle; - HANDLE hDevInfo; - GUID HidGuid; - char MyDevicePathName[1024]; - ULONG Length; - ULONG Required; - typedef struct _HIDD_ATTRIBUTES { - ULONG Size; - USHORT VendorID; - USHORT ProductID; - USHORT VersionNumber; - } HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES; - typedef void (__stdcall*GETHIDGUID) (OUT LPGUID HidGuid); - typedef BOOLEAN (__stdcall*GETATTRIBUTES)(IN HANDLE HidDeviceObject,OUT PHIDD_ATTRIBUTES Attributes); - typedef BOOLEAN (__stdcall*SETNUMINPUTBUFFERS)(IN HANDLE HidDeviceObject,OUT ULONG NumberBuffers); - typedef BOOLEAN (__stdcall*GETNUMINPUTBUFFERS)(IN HANDLE HidDeviceObject,OUT PULONG NumberBuffers); - typedef BOOLEAN (__stdcall*GETFEATURE) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength); - typedef BOOLEAN (__stdcall*SETFEATURE) (IN HANDLE HidDeviceObject, IN PVOID ReportBuffer, IN ULONG ReportBufferLength); - typedef BOOLEAN (__stdcall*GETREPORT) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength); - typedef BOOLEAN (__stdcall*SETREPORT) (IN HANDLE HidDeviceObject, IN PVOID ReportBuffer, IN ULONG ReportBufferLength); - typedef BOOLEAN (__stdcall*GETMANUFACTURERSTRING) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength); - typedef BOOLEAN (__stdcall*GETPRODUCTSTRING) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength); - typedef BOOLEAN (__stdcall*GETINDEXEDSTRING) (IN HANDLE HidDeviceObject, IN ULONG StringIndex, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength); - HIDD_ATTRIBUTES Attributes; - SP_DEVICE_INTERFACE_DATA devInfoData; - int LastDevice = FALSE; - int MemberIndex = 0; - LONG Result; - Length=0; - detailData=NULL; - DeviceHandle=NULL; - HMODULE hHID=0; - GETHIDGUID HidD_GetHidGuid=0; - GETATTRIBUTES HidD_GetAttributes=0; - SETNUMINPUTBUFFERS HidD_SetNumInputBuffers=0; - GETNUMINPUTBUFFERS HidD_GetNumInputBuffers=0; - GETFEATURE HidD_GetFeature=0; - SETFEATURE HidD_SetFeature=0; - GETREPORT HidD_GetInputReport=0; - SETREPORT HidD_SetOutputReport=0; - GETMANUFACTURERSTRING HidD_GetManufacturerString=0; - GETPRODUCTSTRING HidD_GetProductString=0; - hHID = LoadLibrary("hid.dll"); - if(!hHID){ - PrintMessage("Can't find hid.dll"); - return 0; - } - HidD_GetHidGuid=(GETHIDGUID)GetProcAddress(hHID,"HidD_GetHidGuid"); - HidD_GetAttributes=(GETATTRIBUTES)GetProcAddress(hHID,"HidD_GetAttributes"); - HidD_SetNumInputBuffers=(SETNUMINPUTBUFFERS)GetProcAddress(hHID,"HidD_SetNumInputBuffers"); - HidD_GetNumInputBuffers=(GETNUMINPUTBUFFERS)GetProcAddress(hHID,"HidD_GetNumInputBuffers"); - HidD_GetFeature=(GETFEATURE)GetProcAddress(hHID,"HidD_GetFeature"); - HidD_SetFeature=(SETFEATURE)GetProcAddress(hHID,"HidD_SetFeature"); - HidD_GetInputReport=(GETREPORT)GetProcAddress(hHID,"HidD_GetInputReport"); - HidD_SetOutputReport=(SETREPORT)GetProcAddress(hHID,"HidD_SetOutputReport"); - HidD_GetManufacturerString=(GETMANUFACTURERSTRING)GetProcAddress(hHID,"HidD_GetManufacturerString"); - HidD_GetProductString=(GETPRODUCTSTRING)GetProcAddress(hHID,"HidD_GetProductString"); - if(HidD_GetHidGuid==NULL\ - ||HidD_GetAttributes==NULL\ - ||HidD_GetFeature==NULL\ - ||HidD_SetFeature==NULL\ - ||HidD_GetInputReport==NULL\ - ||HidD_SetOutputReport==NULL\ - ||HidD_GetManufacturerString==NULL\ - ||HidD_GetProductString==NULL\ - ||HidD_SetNumInputBuffers==NULL\ - ||HidD_GetNumInputBuffers==NULL) return 0; - HMODULE hSAPI=0; - hSAPI = LoadLibrary("setupapi.dll"); - if(!hSAPI){ - PrintMessage("Can't find setupapi.dll"); - return 0; - } - typedef HDEVINFO (WINAPI* SETUPDIGETCLASSDEVS) (CONST GUID*,PCSTR,HWND,DWORD); - typedef BOOL (WINAPI* SETUPDIENUMDEVICEINTERFACES) (HDEVINFO,PSP_DEVINFO_DATA,CONST GUID*,DWORD,PSP_DEVICE_INTERFACE_DATA); - typedef BOOL (WINAPI* SETUPDIGETDEVICEINTERFACEDETAIL) (HDEVINFO,PSP_DEVICE_INTERFACE_DATA,PSP_DEVICE_INTERFACE_DETAIL_DATA_A,DWORD,PDWORD,PSP_DEVINFO_DATA); - typedef BOOL (WINAPI* SETUPDIDESTROYDEVICEINFOLIST) (HDEVINFO); - SETUPDIGETCLASSDEVS SetupDiGetClassDevsA=0; - SETUPDIENUMDEVICEINTERFACES SetupDiEnumDeviceInterfaces=0; - SETUPDIGETDEVICEINTERFACEDETAIL SetupDiGetDeviceInterfaceDetailA=0; - SETUPDIDESTROYDEVICEINFOLIST SetupDiDestroyDeviceInfoList=0; - SetupDiGetClassDevsA=(SETUPDIGETCLASSDEVS) GetProcAddress(hSAPI,"SetupDiGetClassDevsA"); - SetupDiEnumDeviceInterfaces=(SETUPDIENUMDEVICEINTERFACES) GetProcAddress(hSAPI,"SetupDiEnumDeviceInterfaces"); - SetupDiGetDeviceInterfaceDetailA=(SETUPDIGETDEVICEINTERFACEDETAIL) GetProcAddress(hSAPI,"SetupDiGetDeviceInterfaceDetailA"); - SetupDiDestroyDeviceInfoList=(SETUPDIDESTROYDEVICEINFOLIST) GetProcAddress(hSAPI,"SetupDiDestroyDeviceInfoList"); - if(SetupDiGetClassDevsA==NULL\ - ||SetupDiEnumDeviceInterfaces==NULL\ - ||SetupDiDestroyDeviceInfoList==NULL\ - ||SetupDiGetDeviceInterfaceDetailA==NULL) return 0; - /* - The following code is adapted from Usbhidio_vc6 application example by Jan Axelson - for more information see see http://www.lvr.com/hidpage.htm - */ - /* - API function: HidD_GetHidGuid - Get the GUID for all system HIDs. - Returns: the GUID in HidGuid. - */ - HidD_GetHidGuid(&HidGuid); - /* - API function: SetupDiGetClassDevs - Returns: a handle to a device information set for all installed devices. - Requires: the GUID returned by GetHidGuid. - */ - hDevInfo=SetupDiGetClassDevs(&HidGuid,NULL,NULL,DIGCF_PRESENT|DIGCF_INTERFACEDEVICE); - devInfoData.cbSize = sizeof(devInfoData); - //Step through the available devices looking for the one we want. - //Quit on detecting the desired device or checking all available devices without success. - MemberIndex = 0; - LastDevice = FALSE; - do - { - /* - API function: SetupDiEnumDeviceInterfaces - On return, MyDeviceInterfaceData contains the handle to a - SP_DEVICE_INTERFACE_DATA structure for a detected device. - Requires: - The DeviceInfoSet returned in SetupDiGetClassDevs. - The HidGuid returned in GetHidGuid. - An index to specify a device. - */ - Result=SetupDiEnumDeviceInterfaces (hDevInfo, 0, &HidGuid, MemberIndex, &devInfoData); - if (Result != 0) - { - //A device has been detected, so get more information about it. - /* - API function: SetupDiGetDeviceInterfaceDetail - Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure - containing information about a device. - To retrieve the information, call this function twice. - The first time returns the size of the structure in Length. - The second time returns a pointer to the data in DeviceInfoSet. - Requires: - A DeviceInfoSet returned by SetupDiGetClassDevs - The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces. - The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure. - This application doesn't retrieve or use the structure. - If retrieving the structure, set - MyDeviceInfoData.cbSize = length of MyDeviceInfoData. - and pass the structure's address. - */ - //Get the Length value. - //The call will return with a "buffer too small" error which can be ignored. - Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, NULL, 0, &Length, NULL); - //Allocate memory for the hDevInfo structure, using the returned Length. - detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length); - //Set cbSize in the detailData structure. - detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); - //Call the function again, this time passing it the returned buffer size. - Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, detailData, Length,&Required, NULL); - // Open a handle to the device. - // To enable retrieving information about a system mouse or keyboard, - // don't request Read or Write access for this handle. - /* - API function: CreateFile - Returns: a handle that enables reading and writing to the device. - Requires: - The DevicePath in the detailData structure - returned by SetupDiGetDeviceInterfaceDetail. - */ - DeviceHandle=CreateFile(detailData->DevicePath, - 0, FILE_SHARE_READ|FILE_SHARE_WRITE, - (LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING, 0, NULL); - /* - API function: HidD_GetAttributes - Requests information from the device. - Requires: the handle returned by CreateFile. - Returns: a HIDD_ATTRIBUTES structure containing - the Vendor ID, Product ID, and Product Version Number. - Use this information to decide if the detected device is - the one we're looking for. - */ - //Set the Size to the number of bytes in the structure. - Attributes.Size = sizeof(Attributes); - Result = HidD_GetAttributes(DeviceHandle,&Attributes); - //Is it the desired device? - MyDeviceDetected = FALSE; - if (Attributes.VendorID == vid) - { - if (Attributes.ProductID == pid) - { - //Both the Vendor ID and Product ID match. - MyDeviceDetected = TRUE; - strcpy(MyDevicePathName,detailData->DevicePath); - // Get a handle for writing Output reports. - WriteHandle=CreateFile(detailData->DevicePath, - GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, - (LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING,0,NULL); - //Get a handle to the device for the overlapped ReadFiles. - ReadHandle=CreateFile(detailData->DevicePath, - GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,(LPSECURITY_ATTRIBUTES)NULL, - OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL); - if (hEventObject) CloseHandle(hEventObject); - hEventObject = CreateEvent(NULL,TRUE,TRUE,""); - //Set the members of the overlapped structure. - HIDOverlapped.hEvent = hEventObject; - HIDOverlapped.Offset = 0; - HIDOverlapped.OffsetHigh = 0; - Result=HidD_SetNumInputBuffers(DeviceHandle,64); - } - else - //The Product ID doesn't match. - CloseHandle(DeviceHandle); - } - else - //The Vendor ID doesn't match. - CloseHandle(DeviceHandle); - //Free the memory used by the detailData structure (no longer needed). - free(detailData); - } - else - //SetupDiEnumDeviceInterfaces returned 0, so there are no more devices to check. - LastDevice=TRUE; - //If we haven't found the device yet, and haven't tried every available device, - //try the next one. - MemberIndex = MemberIndex + 1; - } //do - while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE)); - //Free the memory reserved for hDevInfo by SetupDiClassDevs. - SetupDiDestroyDeviceInfoList(hDevInfo); - - if(info&&MyDeviceDetected == TRUE){ - char string[1024]; - PrintMessage3("Device detected: vid=0x%04X pid=0x%04X\nPath: %s\n",vid,pid,MyDevicePathName); - if(HidD_GetManufacturerString(DeviceHandle,string,sizeof(string))==TRUE) wprintf(L"Manufacturer string: %s\n",string); - if(HidD_GetProductString(DeviceHandle,string,sizeof(string))==TRUE) wprintf(L"Product string: %s\n",string); - } -#endif - if (MyDeviceDetected == FALSE){ - PrintMessage(strings[S_noprog]); //"Programmer not detected\r\n" - //gtk_statusbar_push(status_bar,statusID,strings[S_noprog]); - } - else{ - PrintMessage(strings[S_prog]); //"Programmer detected\r\n"); - //gtk_statusbar_push(status_bar,statusID,strings[S_prog]); - } - return MyDeviceDetected; -} @@ -22,6 +22,7 @@ * or see <http://www.gnu.org/licenses/> */ #include "common.h" +#include "common_functions.h" #include "I2CSPI.h" #include "coff.h" #include "icd.h" @@ -33,44 +34,17 @@ #define MAXLINES 600 #define CONFIG_FILE "opgui.ini" #define CONFIG_DIR ".opgui" -#define MinDly 0 + void Connect(GtkWidget *widget,GtkWidget *window); void Quit(GtkWidget *widget,GtkWidget *window) { gtk_main_quit(); } void I2cspiR(); void I2cspiS(); -void ProgID(); + void PrintMessageI2C(const char *msg); void ShowContext(); int FindDevice(int vid,int pid); void TestHw(); -int CheckS1(); -char** strings; //!localized strings -int cmdline=0; -int saveLog=0,programID=0,load_osccal=0,load_BKosccal=0; -int use_osccal=1,use_BKosccal=0; -int load_calibword=0,max_err=200; -int AVRlock=0x100,AVRfuse=0x100,AVRfuse_h=0x100,AVRfuse_x=0x100; -int ICDenable=0,ICDaddr=0x1FF0; -int FWVersion=0,HwID=0; -FILE* logfile=0; -char LogFileName[512]=""; -char loadfile[512]="",savefile[512]=""; -char loadfileEE[512]="",savefileEE[512]=""; -char CoffFileName[512]=""; -int vid=0x1209,pid=0x5432; -int new_vid=0x1209,new_pid=0x5432; -int old_vid=0x04D8,old_pid=0x0100; -WORD *memCODE_W=0; -int size=0,sizeW=0,sizeEE=0,sizeCONFIG=0,sizeUSERID=0; -unsigned char *memCODE=0,*memEE=0,memID[64],memCONFIG[48],memUSERID[8]; -double hvreg=0; -int DeviceDetected=0; -int IOTimer=0; -int skipV33check=0; -int waitS1=0,waitingS1=0; -int progress=0; -int RWstop=0; -int forceConfig=0; + #ifdef DEBUG int addrDebug=0; unsigned short dataDebug=0; @@ -131,7 +105,6 @@ GtkWidget * VDD_ON; GtkWidget * b_io_active; GtkWidget * commandSend; GtkWidget * commandTransfer; -GtkWidget * b_V33check; GtkWidget * Hex_entry; GtkWidget * Address_entry; GtkWidget * Data_entry; @@ -203,23 +176,11 @@ char *groupNames[NUM_GROUPS] = { }; char *GROUP_ALL="*"; -#if !defined _WIN32 && !defined __CYGWIN__ //Linux - int fd = -1; -#ifdef hiddevIO - struct hiddev_report_info rep_info_i,rep_info_u; - struct hiddev_usage_ref_multi ref_multi_i,ref_multi_u; -#endif - char path[512]=""; - unsigned char bufferU[128],bufferI[128]; -#else //Windows - unsigned char bufferU0[128],bufferI0[128]; - unsigned char *bufferU,*bufferI; - DWORD NumberOfBytesRead,BytesWritten; - ULONG Result; - HANDLE WriteHandle,ReadHandle; - OVERLAPPED HIDOverlapped; - HANDLE hEventObject; -#endif +int progress=0; +int waitS1=0,waitingS1=0; +int IOTimer=0; +int cmdline=0; + /// ///Exit gint delete_event( GtkWidget *widget,GdkEvent *event,gpointer data ) @@ -1298,403 +1259,6 @@ void DisplayEE(){ } free(aux); } -/// -///Start HV regulator -int StartHVReg(double V){ - int j=0,z; - int vreg=(int)(V*10.0); - if(saveLog&&logfile) fprintf(logfile,"StartHVReg(%.2f)\n",V); - DWORD t0,t; - if(V==-1){ - bufferU[j++]=VREG_DIS; //disable HV regulator - bufferU[j++]=FLUSH; - PacketIO(5); - msDelay(40); - return -1; - } - t=t0=GetTickCount(); - bufferU[j++]=VREG_EN; //enable HV regulator - bufferU[j++]=SET_VPP; - bufferU[j++]=vreg; - bufferU[j++]=SET_PARAMETER; - bufferU[j++]=SET_T3; - bufferU[j++]=2000>>8; - bufferU[j++]=2000&0xff; - bufferU[j++]=WAIT_T3; - bufferU[j++]=READ_ADC; - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - PacketIO(5); - msDelay(20); - for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_ADC;z++); - int v=(bufferI[z+1]<<8)+bufferI[z+2]; -// PrintMessage2("v=%d=%fV\n",v,v/G); - if(v==0){ - PrintMessage(strings[S_lowUsbV]); //"Tensione USB troppo bassa (VUSB<4.5V)\r\n" - return 0; - } - j=0; - bufferU[j++]=WAIT_T3; - bufferU[j++]=READ_ADC; - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - for(;(v<(vreg/10.0-1)*G||v>(vreg/10.0+1)*G)&&t<t0+1500;t=GetTickCount()){ - PacketIO(5); - msDelay(20); - for(z=0;z<DIMBUF-2&&bufferI[z]!=READ_ADC;z++); - v=(bufferI[z+1]<<8)+bufferI[z+2]; - if(HwID==3) v>>=2; //if 12 bit ADC -// PrintMessage2("v=%d=%fV\n",v,v/G); - } - if(v>(vreg/10.0+1)*G){ - PrintMessage(strings[S_HiVPP]); //"Attenzione: tensione regolatore troppo alta\r\n\r\n" - return 0; - } - else if(v<(vreg/10.0-1)*G){ - PrintMessage(strings[S_LowVPP]); //"Attenzione: tensione regolatore troppo bassa\r\n\r\n" - return 0; - } - else if(v==0){ - PrintMessage(strings[S_lowUsbV]); //"Tensione USB troppo bassa (VUSB<4.5V)\r\n" - return 0; - } - else{ - PrintMessage2(strings[S_reg],t-t0,v/G); //"Regolatore avviato e funzionante dopo T=%d ms VPP=%.1f\r\n\r\n" - if(saveLog&&logfile) fprintf(logfile,strings[S_reg],t-t0,v/G); - return vreg; - } -} -/// -///Read programmer ID -void ProgID() -{ - if(DeviceDetected!=1) return; - int j=0; - bufferU[j++]=PROG_RST; - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - PacketIO(2); - for(j=0;j<DIMBUF-7&&bufferI[j]!=PROG_RST;j++); - PrintMessage3(strings[S_progver],bufferI[j+1],bufferI[j+2],bufferI[j+3]); //"FW versione %d.%d.%d\r\n" - FWVersion=(bufferI[j+1]<<16)+(bufferI[j+2]<<8)+bufferI[j+3]; - PrintMessage3(strings[S_progid],bufferI[j+4],bufferI[j+5],bufferI[j+6]); //"ID Hw: %d.%d.%d" - HwID=bufferI[j+6]; - if(HwID==1) PrintMessage(" (18F2550)\r\n\r\n"); - else if(HwID==2) PrintMessage(" (18F2450)\r\n\r\n"); - else if(HwID==3) PrintMessage(" (18F2458/2553)\r\n\r\n"); - else if(HwID==4) PrintMessage(" (18F25K50)\r\n\r\n"); - else if(HwID==5) PrintMessage(" (18F25K50 all-in-one variant)\r\n\r\n"); - else PrintMessage(" (?)\r\n\r\n"); - // Disable 3.3V check and hide the option for all-in-one board. Enable and show for others - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b_V33check), HwID==5 ? TRUE : FALSE); - gtk_widget_set_visible(GTK_WIDGET(b_V33check), HwID==5 ? FALSE : TRUE); -} -/// -///Check if a 3.3V regulator is present -int CheckV33Regulator() -{ - int i,j=0; - if(skipV33check) return 1; - bufferU[j++]=WRITE_RAM; - bufferU[j++]=0x0F; - bufferU[j++]=0x93; - bufferU[j++]=0xFE; //B0 = output - bufferU[j++]=EXT_PORT; - bufferU[j++]=0x01; //B0=1 - bufferU[j++]=0; - bufferU[j++]=READ_RAM; - bufferU[j++]=0x0F; - bufferU[j++]=0x81; //Check if B1=1 - bufferU[j++]=EXT_PORT; - bufferU[j++]=0x00; //B0=0 - bufferU[j++]=0; - bufferU[j++]=READ_RAM; - bufferU[j++]=0x0F; - bufferU[j++]=0x81; //Check if B1=0 - bufferU[j++]=WRITE_RAM; - bufferU[j++]=0x0F; - bufferU[j++]=0x93; - bufferU[j++]=0xFF; //BX = input - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - PacketIO(5); - for(j=0;j<DIMBUF-3&&bufferI[j]!=READ_RAM;j++); - i=bufferI[j+3]&0x2; //B1 should be high - for(j+=3;j<DIMBUF-3&&bufferI[j]!=READ_RAM;j++); - return (i+(bufferI[j+3]&0x2))==2?1:0; -} -/// -///Check if S1 is pressed -int CheckS1() -{ - int i,j=0; - bufferU[j++]=READ_RAM; - bufferU[j++]=0x0F; - if (HwID==5) { //all-in-one board - bufferU[j++]=0x80; // Read PORTA - } - else { //std board - bufferU[j++]=0x84; //READ PORTE - } - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - PacketIO(5); - for(j=0;j<DIMBUF-3&&bufferI[j]!=READ_RAM;j++); - if (HwID==5) { //all-in-one board - i=bufferI[j+3]&0x80; //i=A7 - return i?1:0; //A7=1 when switch pressed (active high) - } - else { //std board - i=bufferI[j+3]&0x8; //i=E3 - return i?0:1; //S1 open -> E3=1 (active low) - } -} -/// -///Execute hardware test -void TestHw(GtkWidget *widget,GtkWindow* parent) -{ -#ifndef DEBUG - if(DeviceDetected!=1) return; -#endif - char str[256]; - StartHVReg(13); - int j=0; - MsgBox(strings[I_TestHW]); //"Test hardware ..." - bufferU[j++]=SET_CK_D; - bufferU[j++]=0x0; - bufferU[j++]=EN_VPP_VCC; //VDD+VPP - bufferU[j++]=0x5; - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - PacketIO(5); - strcpy(str,strings[I_TestMSG]); - strcat(str,"\n VDDU=5V\n VPPU=13V\n PGD(RB5)=0V\n PGC(RB6)=0V\n PGM(RB7)=0V"); - MsgBox(str); - j=0; - bufferU[j++]=SET_CK_D; - bufferU[j++]=0x15; - bufferU[j++]=EN_VPP_VCC; - bufferU[j++]=0x1; //VDD - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - PacketIO(5); - strcpy(str,strings[I_TestMSG]); - strcat(str,"\n VDDU=5V\n VPPU=0V\n PGD(RB5)=5V\n PGC(RB6)=5V\n PGM(RB7)=5V"); - MsgBox(str); - j=0; - bufferU[j++]=SET_CK_D; - bufferU[j++]=0x1; - bufferU[j++]=EN_VPP_VCC; - bufferU[j++]=0x4; //VPP - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - PacketIO(5); - strcpy(str,strings[I_TestMSG]); - strcat(str,"\n VDDU=0V\n VPPU=13V\n PGD(RB5)=5V\n PGC(RB6)=0V\n PGM(RB7)=0V"); - MsgBox(str); - j=0; - bufferU[j++]=SET_CK_D; - bufferU[j++]=0x4; - bufferU[j++]=EN_VPP_VCC; - bufferU[j++]=0x0; - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - PacketIO(5); - strcpy(str,strings[I_TestMSG]); - strcat(str,"\n VDDU=0V\n VPPU=0V\n PGD(RB5)=0V\n PGC(RB6)=5V\n PGM(RB7)=0V"); - MsgBox(str); - j=0; - bufferU[j++]=SET_CK_D; - bufferU[j++]=0x0; - bufferU[j++]=EN_VPP_VCC; - bufferU[j++]=0x0; - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - PacketIO(5); - if(FWVersion>=0x900){ //IO test - int j=0,i,x,r; - strcpy(str,"0000000000000"); - PrintMessage("IO test\nRC|RA|--RB--|\n"); - for(i=0;i<13;i++){ - x=1<<i; - j=0; - bufferU[j++]=EN_VPP_VCC; - bufferU[j++]=0x0; - bufferU[j++]=SET_PORT_DIR; - bufferU[j++]=0x0; //TRISB - bufferU[j++]=0x0; //TRISA-C (RC7:RC6:RA5:RA4:RA3:X:X:X) - bufferU[j++]=EXT_PORT; - bufferU[j++]=x&0xFF; //PORTB - bufferU[j++]=(x>>5)&0xFF; //PORTA-C - bufferU[j++]=READ_B; - bufferU[j++]=READ_AC; - bufferU[j++]=FLUSH; - for(;j<DIMBUF;j++) bufferU[j]=0x0; - PacketIO(5); - for(j=0;j<DIMBUF-1&&bufferI[j]!=READ_B;j++); - r=bufferI[j+1]; - for(j+=2;j<DIMBUF-1&&bufferI[j]!=READ_AC;j++); - r+=(bufferI[j+1]&0xF8)<<5; - for(j=0;j<13;j++) str[12-j]=x&(1<<j)?'1':'0'; - PrintMessage(str); - PrintMessage1(" (%s)\n",r==x?"OK":strings[S_ErrSing]); - } - } -} -/// -///Wait for X milliseconds -void msDelay(double delay) -{ -#if !defined _WIN32 && !defined __CYGWIN__ - long x=(int)(delay*1000.0); - usleep(x>MinDly?x:MinDly); -#else -// Sleep((long)ceil(delay)>MinDly?(long)ceil(delay):MinDly); - __int64 stop,freq,timeout; - QueryPerformanceCounter((LARGE_INTEGER *)&stop); - QueryPerformanceFrequency((LARGE_INTEGER *)&freq); - timeout=stop+delay*freq/1000.0; - while(stop<timeout) QueryPerformanceCounter((LARGE_INTEGER *)&stop); -#endif -} -#if !defined _WIN32 && !defined __CYGWIN__ //Linux -/// -/// Get system time -DWORD GetTickCount(){ - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec*1000+tv.tv_usec/1000; -/* - struct timeb now; - ftime(&now); - return now.time*1000+now.millitm; -*/ -} -#endif - -/// -///Write data packet, wait for X milliseconds, read response -///real waiting happens only if the desired delay is greater than 40ms; -///in case of smaller delays the function simply waits for a response (up to 50ms) -/// -void PacketIO(double delay){ - #define TIMEOUT 50 - if(saveLog&&logfile) fprintf(logfile,"PacketIO(%.2f)\n",delay); - int delay0=delay; -#if !defined _WIN32 && !defined __CYGWIN__ //Linux - struct timespec ts; - uint64_t start,stop; - fd_set set; - struct timeval timeout; - int rv,i; - FD_ZERO(&set); /* clear the set */ - FD_SET(fd, &set); /* add our file descriptor to the set */ - timeout.tv_sec = 0; - timeout.tv_usec = TIMEOUT*1000; - clock_gettime( CLOCK_REALTIME, &ts ); - start=ts.tv_nsec/1000; - delay-=TIMEOUT-10; //shorter delays are covered by 50ms timeout - if(delay<MinDly) delay=MinDly; - #ifndef hiddevIO //use raw USB device - //wait before writing -/* rv = select(fd + 1, NULL, &set, NULL, &timeout); //wait for write event - if(rv == -1){ - PrintMessage(strings[S_ErrSing]); //error - if(saveLog&&logfile) fprintf(logfile,strings[S_ErrSing]); - return; - } - else if(rv == 0){ - PrintMessage(strings[S_comTimeout]); //"comm timeout\r\n" - if(saveLog&&logfile) fprintf(logfile,strings[S_comTimeout]); - return; - }*/ - //write - int res = write(fd,bufferU,DIMBUF); - if (res < 0) { - printf("Error: %d\n", errno); - perror("write"); - } - usleep((int)(delay*1000.0)); - //wait before reading - rv = select(fd + 1, &set, NULL, NULL, &timeout); //wait for event - if(rv == -1){ - PrintMessage(strings[S_ErrSing]); /*error*/ - if(saveLog&&logfile) fprintf(logfile,strings[S_ErrSing]); - return; - } - else if(rv == 0){ - PrintMessage(strings[S_comTimeout]); /*"comm timeout\r\n"*/ - if(saveLog&&logfile) fprintf(logfile,strings[S_comTimeout]); - return; - } - //read - res = read(fd, bufferI, DIMBUF); - if (res < 0) { - perror("read"); - } - #else //use hiddev device (old method) - struct hiddev_event ev[80]; - int n=DIMBUF; - for(i=0;i<DIMBUF;i++) ref_multi_u.values[i]=bufferU[i]; - //write - ioctl(fd, HIDIOCSUSAGES, &ref_multi_u); - ioctl(fd,HIDIOCSREPORT, &rep_info_u); - usleep((int)(delay*1000.0)); - //read - rv = select(fd + 1, &set, NULL, NULL, &timeout); //wait for event - if(rv == -1){ - PrintMessage(strings[S_ErrSing]); /*error*/ - if(saveLog&&logfile) fprintf(logfile,strings[S_ErrSing]); - } - else if(rv == 0){ - PrintMessage(strings[S_comTimeout]); /*"comm timeout\r\n"*/ - if(saveLog&&logfile) fprintf(logfile,strings[S_comTimeout]); - } - else{ - // ioctl(fd, HIDIOCGUSAGES, &ref_multi_i); - // ioctl(fd,HIDIOCGREPORT, &rep_info_i); - #undef read() - rv=read(fd, ev,sizeof(struct hiddev_event) *n); - for(i=0;(ev[0].value!=bufferU[0])&&i<40;i++){ //read too early; try again after 5ms - msDelay(5); - rv=read(fd, ev,sizeof(struct hiddev_event) *n); - if(saveLog&&logfile) fprintf(logfile,"Packet not ready, wait extra time\n"); - } - if(i==40) fprintf(logfile,"Cannot read correct packet!!\n"); - for(i=0;i<n;i++) bufferI[i]=ev[i].value&0xFF; - } - #endif - clock_gettime( CLOCK_REALTIME, &ts ); - stop = ts.tv_nsec / 1000; - if(saveLog&&logfile){ - WriteLogIO(); - fprintf(logfile,"T=%.2f ms (%+.2f ms)\n",(stop-start)/1000.0,(stop-start)/1000.0-delay0); - if(bufferU[0]!=bufferI[0]) fprintf(logfile,"Cannot read correct packet!!\n"); - } -#else //Windows - __int64 start,stop,freq,timeout; - QueryPerformanceCounter((LARGE_INTEGER *)&start); - QueryPerformanceFrequency((LARGE_INTEGER *)&freq); - delay-=TIMEOUT-10; //shorter delays are covered by 50ms timeout - if(delay<MinDly) delay=MinDly; - //write - Result = WriteFile(WriteHandle,bufferU0,DIMBUF+1,&BytesWritten,NULL); - QueryPerformanceCounter((LARGE_INTEGER *)&stop); - timeout=stop+delay*freq/1000.0; - while(stop<timeout) QueryPerformanceCounter((LARGE_INTEGER *)&stop); - //read - Result = ReadFile(ReadHandle,bufferI0,DIMBUF+1,&NumberOfBytesRead,(LPOVERLAPPED) &HIDOverlapped); - Result = WaitForSingleObject(hEventObject,TIMEOUT); - if(saveLog&&logfile) WriteLogIO(); - ResetEvent(hEventObject); - if(Result!=WAIT_OBJECT_0){ - PrintMessage(strings[S_comTimeout]); /*"comm timeout\r\n"*/ - if(saveLog&&logfile) fprintf(logfile,strings[S_comTimeout]); - } - QueryPerformanceCounter((LARGE_INTEGER *)&stop); - if(saveLog&&logfile) fprintf(logfile,"T=%.2f ms (%+.2f ms)\n",(stop-start)*1000.0/freq,(stop-start)*1000.0/freq-delay0); -#endif -} ///----------------------------------- ///Main function @@ -2192,341 +1756,3 @@ int main( int argc, char *argv[]) return 0; } -/// -///Find the USB peripheral with proper vid&pid code -/// return 0 if not found -int FindDevice(int vid,int pid){ - int MyDeviceDetected = FALSE; -#if !defined _WIN32 && !defined __CYGWIN__ //Linux - #ifndef hiddevIO //use raw USB device - struct hidraw_devinfo device_info; - int i=-1; - if(path[0]==0){ //search all devices - if((fd = open("/dev/openprogrammer", O_RDWR|O_NONBLOCK))>0){ //try with this first - sprintf(path,"/dev/openprogrammer"); - ioctl(fd, HIDIOCGRAWINFO, &device_info); - if(device_info.vendor==vid&&device_info.product==pid) i=0; - else{ - close(fd); - i=-1; - } - } - if(i){ - for(i=0;i<16;i++){ - sprintf(path,"/dev/hidraw%d",i); - if((fd = open(path, O_RDWR|O_NONBLOCK))>0){ - ioctl(fd, HIDIOCGRAWINFO, &device_info); - if(device_info.vendor==vid&&device_info.product==pid) break; - else close(fd); - } - } - } - if(i==16){ - PrintMessage(strings[S_noprog]); - path[0]=0; - return 0; - } - } - else{ //user supplied path - if((fd = open(path, O_RDWR|O_NONBLOCK)) < 0) { - PrintMessage1(strings[S_DevPermission],path); //"cannot open %s, make sure you have read permission on it",path); - return 0; - } - ioctl(fd, HIDIOCGRAWINFO, &device_info); - if(device_info.vendor!=vid||device_info.product!=pid){ - PrintMessage(strings[S_noprog]); - return 0; - } - } - printf(strings[S_progDev],path); - return 1; - #else //use hiddev device (old method) - struct hiddev_devinfo device_info; - int i=-1; - if(path[0]==0){ //search all devices - if((fd = open("/dev/openprogrammer", O_RDONLY ))>0){ //try with this first - ioctl(fd, HIDIOCGDEVINFO, &device_info); - if(device_info.vendor==vid&&device_info.product==pid) i=0; - else{ - close(fd); - i=-1; - } - } - if(i){ - for(i=0;i<16;i++){ - sprintf(path,"/dev/usb/hiddev%d",i); - if((fd = open(path, O_RDONLY ))>0){ - ioctl(fd, HIDIOCGDEVINFO, &device_info); - if(device_info.vendor==vid&&device_info.product==pid) break; - else close(fd); - } - } - } - if(i==16){ - PrintMessage(strings[S_noprog]); - path[0]=0; - return 0; - } - } - else{ //user supplied path - if ((fd = open(path, O_RDONLY )) < 0) { - PrintMessage1(strings[S_DevPermission],path); //"cannot open %s, make sure you have read permission on it",path); - return 0; - } - ioctl(fd, HIDIOCGDEVINFO, &device_info); - if(device_info.vendor!=vid||device_info.product!=pid){ - PrintMessage(strings[S_noprog]); - return 0; - } - } - MyDeviceDetected = TRUE; - rep_info_u.report_type=HID_REPORT_TYPE_OUTPUT; - rep_info_i.report_type=HID_REPORT_TYPE_INPUT; - rep_info_u.report_id=rep_info_i.report_id=HID_REPORT_ID_FIRST; - rep_info_u.num_fields=rep_info_i.num_fields=1; - ref_multi_u.uref.report_type=HID_REPORT_TYPE_OUTPUT; - ref_multi_i.uref.report_type=HID_REPORT_TYPE_INPUT; - ref_multi_u.uref.report_id=ref_multi_i.uref.report_id=HID_REPORT_ID_FIRST; - ref_multi_u.uref.field_index=ref_multi_i.uref.field_index=0; - ref_multi_u.uref.usage_index=ref_multi_i.uref.usage_index=0; - ref_multi_u.num_values=ref_multi_i.num_values=DIMBUF; - #endif -#else //Windows - PSP_DEVICE_INTERFACE_DETAIL_DATA detailData; - HANDLE DeviceHandle; - HANDLE hDevInfo; - GUID HidGuid; - char MyDevicePathName[1024]; - ULONG Length; - ULONG Required; - typedef struct _HIDD_ATTRIBUTES { - ULONG Size; - USHORT VendorID; - USHORT ProductID; - USHORT VersionNumber; - } HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES; - typedef void (__stdcall*GETHIDGUID) (OUT LPGUID HidGuid); - typedef BOOLEAN (__stdcall*GETATTRIBUTES)(IN HANDLE HidDeviceObject,OUT PHIDD_ATTRIBUTES Attributes); - typedef BOOLEAN (__stdcall*SETNUMINPUTBUFFERS)(IN HANDLE HidDeviceObject,OUT ULONG NumberBuffers); - typedef BOOLEAN (__stdcall*GETNUMINPUTBUFFERS)(IN HANDLE HidDeviceObject,OUT PULONG NumberBuffers); - typedef BOOLEAN (__stdcall*GETFEATURE) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength); - typedef BOOLEAN (__stdcall*SETFEATURE) (IN HANDLE HidDeviceObject, IN PVOID ReportBuffer, IN ULONG ReportBufferLength); - typedef BOOLEAN (__stdcall*GETREPORT) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength); - typedef BOOLEAN (__stdcall*SETREPORT) (IN HANDLE HidDeviceObject, IN PVOID ReportBuffer, IN ULONG ReportBufferLength); - typedef BOOLEAN (__stdcall*GETMANUFACTURERSTRING) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength); - typedef BOOLEAN (__stdcall*GETPRODUCTSTRING) (IN HANDLE HidDeviceObject, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength); -// typedef BOOLEAN (__stdcall*GETINDEXEDSTRING) (IN HANDLE HidDeviceObject, IN ULONG StringIndex, OUT PVOID ReportBuffer, IN ULONG ReportBufferLength); - HIDD_ATTRIBUTES Attributes; - SP_DEVICE_INTERFACE_DATA devInfoData; - int LastDevice = FALSE; - int MemberIndex = 0; - LONG Result; - Length=0; - detailData=NULL; - DeviceHandle=NULL; - HMODULE hHID=0; - GETHIDGUID HidD_GetHidGuid=0; - GETATTRIBUTES HidD_GetAttributes=0; - SETNUMINPUTBUFFERS HidD_SetNumInputBuffers=0; - GETNUMINPUTBUFFERS HidD_GetNumInputBuffers=0; - GETFEATURE HidD_GetFeature=0; - SETFEATURE HidD_SetFeature=0; - GETREPORT HidD_GetInputReport=0; - SETREPORT HidD_SetOutputReport=0; - GETMANUFACTURERSTRING HidD_GetManufacturerString=0; - GETPRODUCTSTRING HidD_GetProductString=0; - hHID = LoadLibrary("hid.dll"); - if(!hHID){ - PrintMessage("Can't find hid.dll"); - return 0; - } - HidD_GetHidGuid=(GETHIDGUID)GetProcAddress(hHID,"HidD_GetHidGuid"); - HidD_GetAttributes=(GETATTRIBUTES)GetProcAddress(hHID,"HidD_GetAttributes"); - HidD_SetNumInputBuffers=(SETNUMINPUTBUFFERS)GetProcAddress(hHID,"HidD_SetNumInputBuffers"); - HidD_GetNumInputBuffers=(GETNUMINPUTBUFFERS)GetProcAddress(hHID,"HidD_GetNumInputBuffers"); - HidD_GetFeature=(GETFEATURE)GetProcAddress(hHID,"HidD_GetFeature"); - HidD_SetFeature=(SETFEATURE)GetProcAddress(hHID,"HidD_SetFeature"); - HidD_GetInputReport=(GETREPORT)GetProcAddress(hHID,"HidD_GetInputReport"); - HidD_SetOutputReport=(SETREPORT)GetProcAddress(hHID,"HidD_SetOutputReport"); - HidD_GetManufacturerString=(GETMANUFACTURERSTRING)GetProcAddress(hHID,"HidD_GetManufacturerString"); - HidD_GetProductString=(GETPRODUCTSTRING)GetProcAddress(hHID,"HidD_GetProductString"); - if(HidD_GetHidGuid==NULL\ - ||HidD_GetAttributes==NULL\ - ||HidD_GetFeature==NULL\ - ||HidD_SetFeature==NULL\ - ||HidD_GetInputReport==NULL\ - ||HidD_SetOutputReport==NULL\ - ||HidD_GetManufacturerString==NULL\ - ||HidD_GetProductString==NULL\ - ||HidD_SetNumInputBuffers==NULL\ - ||HidD_GetNumInputBuffers==NULL) return 0; - HMODULE hSAPI=0; - hSAPI = LoadLibrary("setupapi.dll"); - if(!hSAPI){ - PrintMessage("Can't find setupapi.dll"); - return 0; - } - typedef HDEVINFO (WINAPI* SETUPDIGETCLASSDEVS) (CONST GUID*,PCSTR,HWND,DWORD); - typedef BOOL (WINAPI* SETUPDIENUMDEVICEINTERFACES) (HDEVINFO,PSP_DEVINFO_DATA,CONST GUID*,DWORD,PSP_DEVICE_INTERFACE_DATA); - typedef BOOL (WINAPI* SETUPDIGETDEVICEINTERFACEDETAIL) (HDEVINFO,PSP_DEVICE_INTERFACE_DATA,PSP_DEVICE_INTERFACE_DETAIL_DATA_A,DWORD,PDWORD,PSP_DEVINFO_DATA); - typedef BOOL (WINAPI* SETUPDIDESTROYDEVICEINFOLIST) (HDEVINFO); - SETUPDIGETCLASSDEVS SetupDiGetClassDevsA=0; - SETUPDIENUMDEVICEINTERFACES SetupDiEnumDeviceInterfaces=0; - SETUPDIGETDEVICEINTERFACEDETAIL SetupDiGetDeviceInterfaceDetailA=0; - SETUPDIDESTROYDEVICEINFOLIST SetupDiDestroyDeviceInfoList=0; - SetupDiGetClassDevsA=(SETUPDIGETCLASSDEVS) GetProcAddress(hSAPI,"SetupDiGetClassDevsA"); - SetupDiEnumDeviceInterfaces=(SETUPDIENUMDEVICEINTERFACES) GetProcAddress(hSAPI,"SetupDiEnumDeviceInterfaces"); - SetupDiGetDeviceInterfaceDetailA=(SETUPDIGETDEVICEINTERFACEDETAIL) GetProcAddress(hSAPI,"SetupDiGetDeviceInterfaceDetailA"); - SetupDiDestroyDeviceInfoList=(SETUPDIDESTROYDEVICEINFOLIST) GetProcAddress(hSAPI,"SetupDiDestroyDeviceInfoList"); - if(SetupDiGetClassDevsA==NULL\ - ||SetupDiEnumDeviceInterfaces==NULL\ - ||SetupDiDestroyDeviceInfoList==NULL\ - ||SetupDiGetDeviceInterfaceDetailA==NULL) return 0; - /* - The following code is adapted from Usbhidio_vc6 application example by Jan Axelson - for more information see see http://www.lvr.com/hidpage.htm - */ - /* - API function: HidD_GetHidGuid - Get the GUID for all system HIDs. - Returns: the GUID in HidGuid. - */ - HidD_GetHidGuid(&HidGuid); - /* - API function: SetupDiGetClassDevs - Returns: a handle to a device information set for all installed devices. - Requires: the GUID returned by GetHidGuid. - */ - hDevInfo=SetupDiGetClassDevs(&HidGuid,NULL,NULL,DIGCF_PRESENT|DIGCF_INTERFACEDEVICE); - devInfoData.cbSize = sizeof(devInfoData); - //Step through the available devices looking for the one we want. - //Quit on detecting the desired device or checking all available devices without success. - MemberIndex = 0; - LastDevice = FALSE; - do - { - /* - API function: SetupDiEnumDeviceInterfaces - On return, MyDeviceInterfaceData contains the handle to a - SP_DEVICE_INTERFACE_DATA structure for a detected device. - Requires: - The DeviceInfoSet returned in SetupDiGetClassDevs. - The HidGuid returned in GetHidGuid. - An index to specify a device. - */ - Result=SetupDiEnumDeviceInterfaces (hDevInfo, 0, &HidGuid, MemberIndex, &devInfoData); - if (Result != 0) - { - //A device has been detected, so get more information about it. - /* - API function: SetupDiGetDeviceInterfaceDetail - Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure - containing information about a device. - To retrieve the information, call this function twice. - The first time returns the size of the structure in Length. - The second time returns a pointer to the data in DeviceInfoSet. - Requires: - A DeviceInfoSet returned by SetupDiGetClassDevs - The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces. - The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure. - This application doesn't retrieve or use the structure. - If retrieving the structure, set - MyDeviceInfoData.cbSize = length of MyDeviceInfoData. - and pass the structure's address. - */ - //Get the Length value. - //The call will return with a "buffer too small" error which can be ignored. - Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, NULL, 0, &Length, NULL); - //Allocate memory for the hDevInfo structure, using the returned Length. - detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length); - //Set cbSize in the detailData structure. - detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); - //Call the function again, this time passing it the returned buffer size. - Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, detailData, Length,&Required, NULL); - // Open a handle to the device. - // To enable retrieving information about a system mouse or keyboard, - // don't request Read or Write access for this handle. - /* - API function: CreateFile - Returns: a handle that enables reading and writing to the device. - Requires: - The DevicePath in the detailData structure - returned by SetupDiGetDeviceInterfaceDetail. - */ - DeviceHandle=CreateFile(detailData->DevicePath, - 0, FILE_SHARE_READ|FILE_SHARE_WRITE, - (LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING, 0, NULL); - /* - API function: HidD_GetAttributes - Requests information from the device. - Requires: the handle returned by CreateFile. - Returns: a HIDD_ATTRIBUTES structure containing - the Vendor ID, Product ID, and Product Version Number. - Use this information to decide if the detected device is - the one we're looking for. - */ - //Set the Size to the number of bytes in the structure. - Attributes.Size = sizeof(Attributes); - Result = HidD_GetAttributes(DeviceHandle,&Attributes); - //Is it the desired device? - MyDeviceDetected = FALSE; - if (Attributes.VendorID == vid) - { - if (Attributes.ProductID == pid) - { - //Both the Vendor ID and Product ID match. - MyDeviceDetected = TRUE; - strcpy(MyDevicePathName,detailData->DevicePath); - // Get a handle for writing Output reports. - WriteHandle=CreateFile(detailData->DevicePath, - GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, - (LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING,0,NULL); - //Get a handle to the device for the overlapped ReadFiles. - ReadHandle=CreateFile(detailData->DevicePath, - GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,(LPSECURITY_ATTRIBUTES)NULL, - OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL); - if (hEventObject) CloseHandle(hEventObject); - hEventObject = CreateEvent(NULL,TRUE,TRUE,""); - //Set the members of the overlapped structure. - HIDOverlapped.hEvent = hEventObject; - HIDOverlapped.Offset = 0; - HIDOverlapped.OffsetHigh = 0; - Result=HidD_SetNumInputBuffers(DeviceHandle,64); - } - else - //The Product ID doesn't match. - CloseHandle(DeviceHandle); - } - else - //The Vendor ID doesn't match. - CloseHandle(DeviceHandle); - //Free the memory used by the detailData structure (no longer needed). - free(detailData); - } - else - //SetupDiEnumDeviceInterfaces returned 0, so there are no more devices to check. - LastDevice=TRUE; - //If we haven't found the device yet, and haven't tried every available device, - //try the next one. - MemberIndex = MemberIndex + 1; - } //do - while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE)); - //Free the memory reserved for hDevInfo by SetupDiClassDevs. - SetupDiDestroyDeviceInfoList(hDevInfo); -/* if(info){ - PrintMessage3("Device detected: vid=0x%04X pid=0x%04X\nPath: %s\n",vid,pid,MyDevicePathName); - if(HidD_GetManufacturerString(DeviceHandle,string,sizeof(string))==TRUE) wprintf(L"Manufacturer string: %s\n",string); - if(HidD_GetProductString(DeviceHandle,string,sizeof(string))==TRUE) wprintf(L"Product string: %s\n",string); - }*/ -#endif - if (MyDeviceDetected == FALSE){ - PrintMessage(strings[S_noprog]); //"Programmer not detected\r\n" - //gtk_statusbar_push(status_bar,statusID,strings[S_noprog]); - } - else{ - PrintMessage(strings[S_prog]); //"Programmer detected\r\n"); - PrintMessage2("VID=0x%04X PID=0x%04X\r\n",vid,pid); - //gtk_statusbar_push(status_bar,statusID,strings[S_prog]); - } - return MyDeviceDetected; -} |