From 925d0670c45e1100e412070fa0ce2405604f219a Mon Sep 17 00:00:00 2001 From: Attila Veghelyi Date: Thu, 29 Jun 2023 16:24:54 +0200 Subject: Init repo --- op.c | 1358 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1358 insertions(+) create mode 100644 op.c (limited to 'op.c') diff --git a/op.c b/op.c new file mode 100644 index 0000000..3e55dbc --- /dev/null +++ b/op.c @@ -0,0 +1,1358 @@ +/* + * op.c - control program for the open programmer + * Copyright (C) 2009-2020 Alberto Maccioni + * for detailed info see: + * http://openprog.altervista.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA + * or see + */ + + +#include "common.h" +#include "I2CSPI.h" +#include "deviceRW.h" +#include "fileIO.h" +#include "progAVR.h" + + +#if !defined _WIN32 && !defined __CYGWIN__ +DWORD GetTickCount(); +#include +int kbhit() +{ + struct timeval tv; + fd_set read_fd; + tv.tv_sec=0; + tv.tv_usec=0; + FD_ZERO(&read_fd); + FD_SET(0,&read_fd); + if(select(1, &read_fd, NULL, NULL, &tv) == -1) return 0; + if(FD_ISSET(0,&read_fd)) return 1; + return 0; +} +#define getch getchar +#else +#include "conio.h" +#endif +#define MinDly 0 + +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) { + + int ee=0,r=0,ver=0,c=0,support=0,i2c=0,spi_mode=0,i,j,testhw=0,s1=0; + int spi_speed=0,command=0,langfile=0,help=0; + char lang[32]=""; + unsigned char tmpbuf[128]; + opterr = 0; + int option_index = 0; + int fuse3k=0; + char* langid=0; + int cw1,cw2,cw3,cw4,cw5,cw6,cw7; + cw1=cw2=cw3=cw4=cw5=cw6=cw7=0x10000; +#if defined _WIN32 || defined __CYGWIN__ //Windows + bufferI=bufferI0+1; + bufferU=bufferU0+1; + bufferI0[0]=0; + bufferU0[0]=0; +#endif + + struct option long_options[] = + { + {"BKosccal", no_argument, &load_BKosccal, 1}, + {"calib", no_argument, &load_calibword, 1}, + {"command", no_argument, &command, 1}, + {"cw1", required_argument, 0, '1'}, + {"cw2", required_argument, 0, '2'}, + {"cw3", required_argument, 0, '3'}, + {"cw4", required_argument, 0, '4'}, + {"cw5", required_argument, 0, '5'}, + {"cw6", required_argument, 0, '6'}, + {"cw7", required_argument, 0, '7'}, + {"d", required_argument, 0, 'd'}, + {"device", required_argument, 0, 'd'}, + {"ee", no_argument, &ee, 1}, + {"err", required_argument, 0, 'e'}, + {"fuse", required_argument, 0, 'f'}, + {"fuseh", required_argument, 0, 'F'}, + {"fusex", required_argument, 0, 'X'}, + {"fuse3k", required_argument, 0, 'k'}, + {"h", no_argument, &help,1}, + {"help", no_argument, &help,1}, + {"HWtest", no_argument, &testhw, 1}, + {"info", no_argument, &info, 1}, + {"i", no_argument, &info, 1}, + {"i2c_r", no_argument, &i2c, 1}, + {"i2c_r2", no_argument, &i2c, 2}, + {"i2c_w", no_argument, &i2c, 3}, + {"i2c_w2", no_argument, &i2c, 4}, + {"i2cspeed", required_argument, 0, 'D'}, + {"id", no_argument, &programID, 1}, + {"icd", required_argument, 0, 'I'}, + {"l", optional_argument, 0, 'l'}, //-l=val + {"log", optional_argument, 0, 'l'}, + {"lang", required_argument, 0, 'n'}, + {"langfile", no_argument, &langfile, 1}, + {"lock", required_argument, 0, 'L'}, + {"mode", required_argument, 0, 'm'}, + {"nolvcheck", no_argument, &skipV33check, 1}, + {"osccal", no_argument, &load_osccal, 1}, +#if !defined _WIN32 && !defined __CYGWIN__ + {"p", required_argument, 0, 'p'}, + {"path", required_argument, 0, 'p'}, +#endif + {"pid", required_argument, 0, 'P'}, + {"rep" , required_argument, 0, 'R'}, + {"reserved", no_argument, &r, 1}, + {"r", no_argument, &r, 1}, + {"s1", no_argument, &s1, 1}, + {"S1", no_argument, &s1, 1}, + {"s", required_argument, 0, 's'}, + {"save", required_argument, 0, 's'}, + {"saveEE", required_argument, 0, 'S'}, + {"se", required_argument, 0, 'S'}, + {"spi_r", no_argument, &i2c, 5}, + {"spi_w", no_argument, &i2c, 6}, + {"spispeed", required_argument, 0, 'D'}, + {"support", no_argument, &support, 1}, + {"use_BKosccal", no_argument, &use_BKosccal, 1}, + {"version", no_argument, &ver, 1}, + {"v", no_argument, &ver, 1}, + {"vid", required_argument, 0, 'V'}, + {"w", required_argument, 0, 'w'}, + {"write", required_argument, 0, 'w'}, + {"we", required_argument, 0, 'W'}, + {"writeEE", required_argument, 0, 'W'}, + {0, 0, 0, 0} + }; + while ((c = getopt_long_only (argc, argv, "",long_options,&option_index)) != -1) + /*{ printf("optarg=%X\n",optarg); + if(optarg) printf("%s\n",optarg); + printf("c=%X %c\noption_index=%d name=%s\n",c,c,option_index,long_options[option_index].name); } + exit(0);*/ + switch (c) + { + case '1': //force config word 1 + i=sscanf(optarg, "%x", &cw1); + if(i!=1||cw1<0||cw1>0x3FFF) cw1=0x10000; + break; + case '2': //force config word 2 + i=sscanf(optarg, "%x", &cw2); + if(i!=1||cw2<0||cw2>0x3FFF) cw2=0x10000; + break; + case '3': //force config word 3 + i=sscanf(optarg, "%x", &cw3); + if(i!=1||cw3<0||cw3>0x3FFF) cw3=0x10000; + break; + case '4': //force config word 4 + i=sscanf(optarg, "%x", &cw4); + if(i!=1||cw4<0||cw4>0x3FFF) cw4=0x10000; + break; + case '5': //force config word 5 + i=sscanf(optarg, "%x", &cw5); + if(i!=1||cw5<0||cw5>0x3FFF) cw5=0x10000; + break; + case '6': //force config word 6 + i=sscanf(optarg, "%x", &cw6); + if(i!=1||cw6<0||cw6>0x3FFF) cw6=0x10000; + break; + case '7': //force config word 7 + i=sscanf(optarg, "%x", &cw7); + if(i!=1||cw7<0||cw7>0x3FFF) cw7=0x10000; + break; + case 'd': //device + strncpy(dev,optarg,sizeof(dev)-1); + break; + case 'e': //max write errors + max_err = atoi(optarg); + break; + case 'D': //spi speed + spi_speed = atoi(optarg); + if(spi_speed<0)spi_speed=0; + if(spi_speed>3)spi_speed=3; + break; + case 'f': //Atmel FUSE low + i=sscanf(optarg, "%x", &AVRfuse); + if(i!=1||AVRfuse<0||AVRfuse>0xFF) AVRfuse=0x100; + break; + case 'F': //Atmel FUSE high + i=sscanf(optarg, "%x", &AVRfuse_h); + if(i!=1||AVRfuse_h<0||AVRfuse_h>0xFF) AVRfuse_h=0x100; + break; + case 'I': //ICD routine address + i=sscanf(optarg, "%x", &ICDaddr); + if(i!=1||ICDaddr<0||ICDaddr>0xFFFF) ICDaddr=0x1F00; + ICDenable=1; + break; + case 'k': //Atmel FUSE low @ 3kHz + i=sscanf(optarg, "%x", &AVRfuse); + if(i!=1||AVRfuse<0||AVRfuse>0xFF) AVRfuse=0x100; + else fuse3k=1; + break; + case 'l': //save Log + saveLog=1; + if(optarg) strncpy(LogFileName,optarg,sizeof(LogFileName)); + break; + case 'L': //Atmel LOCK + i=sscanf(optarg, "%x", &AVRlock); + if(i!=1||AVRlock<0||AVRlock>0xFF) AVRlock=0x100; + break; + case 'm': //SPI mode + spi_mode = atoi(optarg); + if(spi_mode<0) spi_mode=0; + if(spi_mode>3) spi_mode=3; + break; + case 'n': //language + strncpy(lang,optarg,sizeof(lang)-1); + break; +#if !defined _WIN32 && !defined __CYGWIN__ + case 'p': //hiddev path + strncpy(path,optarg,sizeof(path)-1); + break; +#endif + case 'P': //pid + sscanf(optarg, "%x", &pid); + break; + case 'R': //USB HID report size + //DIMBUF = atoi(optarg); + break; + case 's': //save + strncpy(savefile,optarg,sizeof(savefile)-1); + break; + case 'S': //save EE + strncpy(savefileEE,optarg,sizeof(savefileEE)-1); + break; + case 'V': //vid + sscanf(optarg, "%x", &vid); + break; + case 'X': //Atmel extended FUSE + i=sscanf(optarg, "%x", &AVRfuse_x); + if(i!=1||AVRfuse_x<0||AVRfuse_x>0xFF) AVRfuse_x=0x100; + break; + case 'w': //write file + strncpy(loadfile,optarg,sizeof(loadfile)-1); + break; + case 'W': //write EE file + strncpy(loadfileEE,optarg,sizeof(loadfileEE)-1); + break; + case '?': + fprintf (stderr,strings[L_OPTERR]); //errore opzioni + return 1; + default: + + break; + } + + for(j=0,i = optind; i < argc&&i<128; i++,j++) sscanf(argv[i], "%x", &tmpbuf[j]); + for(;j<128;j++) tmpbuf[j]=0; + + strinit(); + i=0; + if(lang[0]){ //explicit language selection + if(lang[0]=='i'&&langid[1]=='t'){ //built-in + strings=strings_it; + i=1; + } + else if(lang[0]=='e'&&lang[1]=='n'){ //built-in + strings=strings_en; + i=1; + } + else i=strfind(lang,"languages.rc"); //file look-up + } + if(i==0){ + #if defined _WIN32 + langid=malloc(19); + int n=GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_SISO639LANGNAME,langid,9); + langid[n-1] = '-'; + GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_SISO3166CTRYNAME,langid+n, 9); + //printf("%d >%s<\n",n,langid); + #else + langid=getenv("LANG"); + #endif + if(langid){ + if(langid[0]=='i'&&langid[1]=='t') strings=strings_it; + else if(langid[0]=='e'&&langid[1]=='n') strings=strings_en; + else if(strfind(langid,"languages.rc")); //first try full code + else { //then only first language code + char* p=strchr(langid,'-'); + if(p) *p=0; + if(!strfind(langid,"languages.rc")) strings=strings_en; + } + } + else strings=strings_en; + } + + strncpy(LogFileName,strings[S_LogFile],sizeof(LogFileName)); + if(argc==1){ + printf(strings[L_HELP]); + exit(1); + } + + if(help){ + printf(strings[L_HELP]); + return 1; + } + + if(langfile) GenerateLangFile(langid,"languages.rc"); + + if (ver){ + printf("OP v%s\nCopyright (C) Alberto Maccioni 2009-2022\ +\n For detailed info see http://openprog.altervista.org/\ +\nThis program is free software; you can redistribute it and/or modify it under \ +the terms of the GNU General Public License as published by the Free Software \ +Foundation; either version 2 of the License, or (at your option) any later version.\ + \n",VERSION); + return 0; + } + if (support){ + char list[20000]; //make sure list is long enough!! + AddDevices(list); + printf("%s\n",list); + return 0; + } + DeviceDetected=FindDevice(vid,pid); //connect to USB programmer + if(!DeviceDetected){ + DeviceDetected=FindDevice(new_vid,new_pid); //try default + if(DeviceDetected){ + vid=new_vid; + pid=new_pid; + } + } + if(!DeviceDetected) DeviceDetected=FindDevice(old_vid,old_pid); //try old one + if(!DeviceDetected) exit(1); + ProgID(); //get firmware version and reset + +#if !defined _WIN32 && !defined __CYGWIN__ + if(info){ + #ifndef hiddevIO //use raw USB device + struct hidraw_devinfo device_info; + char name[256],path[256]; + ioctl(fd, HIDIOCGRAWINFO, &device_info); + ioctl(fd, HIDIOCGRAWNAME(256), name); + ioctl(fd, HIDIOCGRAWPHYS(256), path); + printf("VID 0x%04X PID 0x%04X\n",device_info.vendor, device_info.product); + printf(strings[L_NAME], path, name);//"The device on %s says its name is %s\n" + #else //use hiddev device (old method) + struct hiddev_devinfo device_info; + ioctl(fd, HIDIOCGDEVINFO, &device_info); + printf(strings[L_INFO1],device_info.vendor, device_info.product, device_info.version); + printf(strings[L_INFO2],device_info.busnum, device_info.devnum, device_info.ifnum); + char name[256]; + strcpy(name,strings[L_UNKNOWN]);//"Unknown" + if(ioctl(fd, HIDIOCGNAME(sizeof(name)), name) < 0) perror("evdev ioctl"); + printf(strings[L_NAME], path, name);//"The device on %s says its name is %s\n" + #endif + return 0; + } +#endif + + DWORD t0,t; + t=t0=GetTickCount(); + if(testhw){ + TestHw(); + return 0; + } + + if(command){ + //bufferU[0]=0; + for(i=0;i "); + for(i=0;i0x8008){ //16F1xxx + if(cw1<=0x3FFF){ + memCODE_W[0x8007]=cw1; + PrintMessage3(strings[S_ForceConfigWx],1,0x8007,cw1); //"forcing config word%d [0x%04X]=0x%04X" + } + if(cw2<=0x3FFF){ + memCODE_W[0x8008]=cw2; + PrintMessage3(strings[S_ForceConfigWx],2,0x8008,cw2); //"forcing config word%d [0x%04X]=0x%04X" + } + } + else{ //16Fxxx + if(cw1<=0x3FFF&&sizeW>0x2007){ + memCODE_W[0x2007]=cw1; + PrintMessage3(strings[S_ForceConfigWx],1,0x2007,cw1); //"forcing config word%d [0x%04X]=0x%04X" + } + if(cw2<=0x3FFF&&sizeW>0x2008){ + memCODE_W[0x2008]=cw2; + printf("2\n"); + PrintMessage3(strings[S_ForceConfigWx],2,0x2008,cw2); //"forcing config word%d [0x%04X]=0x%04X" + } + } + } + else if(devType==PIC12){ //12Fxxx + if(cw1<=0xFFF&&sizeW>0xFFF){ + memCODE_W[0xFFF]=cw1; + PrintMessage3(strings[S_ForceConfigWx],1,0xFFF,cw1); //"forcing config word%d [0x%04X]=0x%04X" + } + } + else if(devType==PIC18){ //18Fxxx + if(cw1<=0xFFFF){ + memCONFIG[0]=cw1&0xFF; + memCONFIG[1]=(cw1>>8)&0xFF; + } + if(cw2<=0xFFFF){ + memCONFIG[2]=cw2&0xFF; + memCONFIG[3]=(cw2>>8)&0xFF; + } + if(cw3<=0xFFFF){ + memCONFIG[4]=cw3&0xFF; + memCONFIG[5]=(cw3>>8)&0xFF; + } + if(cw4<=0xFFFF){ + memCONFIG[6]=cw4&0xFF; + memCONFIG[7]=(cw4>>8)&0xFF; + } + if(cw5<=0xFFFF){ + memCONFIG[8]=cw5&0xFF; + memCONFIG[9]=(cw5>>8)&0xFF; + } + if(cw6<=0xFFFF){ + memCONFIG[10]=cw6&0xFF; + memCONFIG[11]=(cw6>>8)&0xFF; + } + if(cw7<=0xFFFF){ + memCONFIG[12]=cw7&0xFF; + memCONFIG[13]=(cw7>>8)&0xFF; + } + PrintMessage(strings[S_ForceConfigW]); //"forcing config words" + for(i=0;i<7;i++){ + PrintMessage2(strings[S_ConfigWordH],i+1,memCONFIG[i*2+1]); //"CONFIG%dH: 0x%02X\t" + PrintMessage2(strings[S_ConfigWordL],i+1,memCONFIG[i*2]); //"CONFIG%dL: 0x%02X\r\n" + } + } +/* if(CW1_force!=-1||CW2_force!=-1){ + if((!strncmp(dev,"16F1",4)||!strncmp(dev,"12F1",4))){ //16F1xxx + if(CW1_force!=-1&&sizeW>0x8007) memCODE_W[0x8007]=CW1_force; + if(CW2_force!=-1&&sizeW>0x8008) memCODE_W[0x8008]=CW2_force; + } + else if((!strncmp(dev,"16F",3)||!strncmp(dev,"12F6",4))&&strncmp(dev,"16F5",4)){ //16Fxxx + if(CW1_force!=-1&&sizeW>0x2007) memCODE_W[0x2007]=CW1_force; + if(CW2_force!=-1&&sizeW>0x2008) memCODE_W[0x2008]=CW2_force; + } + else if((!strncmp(dev,"12F",3)||!strncmp(dev,"10F",3)||!strncmp(dev,"16F5",4))){ //12Fxxx + if(CW1_force!=-1&&sizeW>0xFFF) memCODE_W[0xFFF]=CW1_force&0xFFF; + } + if(CW1_force!=-1) PrintMessage1(strings[S_ForceConfigWx],CW1_force); //"forcing config word1 (0x%04X)" + if(CW2_force!=-1) PrintMessage1(strings[S_ForceConfigWx],CW2_force); //"forcing config word2 (0x%04X)" + } +*/ + //Start with button + if(s1){ + PrintMessage(strings[S_WaitS1W]); //"Press S1 to program, any key to exit" + fflush(stdout); + for(;!kbhit();msDelay(50)){ + if(CheckS1()){ //wait for S1 + Write(dev,ee); //choose the right function + PrintMessage(strings[S_WaitS1W]); //"Press S1 to program, any key to exit" + fflush(stdout); + for(;CheckS1();msDelay(50)); //wait for S1 open + } + } + getch(); + } + else Write(dev,ee); //choose the right function + } + else{ //read + if(s1){ + PrintMessage(strings[S_WaitS1R]); //"Press S1 to read, any key to exit" + fflush(stdout); + for(;!kbhit();msDelay(50)){ + if(CheckS1()){ //wait for S1 + Read(dev,ee,r); //choose the right function + PrintMessage(strings[S_WaitS1R]); //"Press S1 to read, any key to exit" + fflush(stdout); + for(;CheckS1();msDelay(50)); //wait for S1 open + } + } + getch(); + } + else Read(dev,ee,r); //choose the right function + + if(savefile[0]) Save(dev,savefile); + if(!strncmp(dev,"AT",2)&&savefileEE[0]) SaveEE(dev,savefileEE); + } + +#if !defined _WIN32 && !defined __CYGWIN__ //Linux + close(fd); +#endif + return 0 ; +} + + +/// +///Display contents of EEprom memory +void DisplayEE(){ + char s[256],t[256],v[256]; + int valid=0,empty=1; + int i,j; + s[0]=0; + v[0]=0; + PrintMessage(strings[S_EEMem]); //"\r\nmemoria EEPROM:\r\n" + for(i=0;i>8; + bufferU[j++]=2000&0xff; + bufferU[j++]=WAIT_T3; + bufferU[j++]=READ_ADC; + bufferU[j++]=FLUSH; + for(;j(vreg/10.0+1)*G)&&t>=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 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=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<>5)&0xFF; //PORTA-C + bufferU[j++]=READ_B; + bufferU[j++]=READ_AC; + bufferU[j++]=FLUSH; + for(;jMinDly?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(stop0){ //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; +} \ No newline at end of file -- cgit v1.2.3-54-g00ecf