summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile_op1
-rw-r--r--Makefile_opgui1
-rw-r--r--common_functions.c820
-rw-r--r--common_functions.h17
-rw-r--r--op.c795
-rw-r--r--opgui.c792
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
diff --git a/op.c b/op.c
index 8c39cec..bc32f94 100644
--- a/op.c
+++ b/op.c
@@ -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;
-}
diff --git a/opgui.c b/opgui.c
index a6c550e..cf8255f 100644
--- a/opgui.c
+++ b/opgui.c
@@ -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;
-}