/** * \file opgui.c * main control program for the open programmer * * Copyright (C) 2009-2023 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 "coff.h" #include "icd.h" #include "deviceRW.h" #include "fileIO.h" #include "progAVR.h" #include #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; unsigned short statusDebug=0x3FFF; #endif //List of gtk controls GtkTextBuffer * dataBuf; GtkWidget * data,*data_scroll; GtkWidget * window; GtkWidget * toolbar; GtkWidget * button; GtkWidget * b_open; GtkWidget * b_save; GtkWidget * b_read; GtkWidget * b_write; GtkWidget * notebook; GtkWidget * label; GtkWidget * status_bar; GtkWidget * img; GtkWidget * devTree; GtkWidget * devTypeCombo; GtkWidget * devFramePIC; GtkWidget * ICD_check; GtkWidget * ICD_addr_entry; GtkWidget * EEPROM_RW; GtkWidget * ReadReserved; GtkWidget * Write_ID_BKCal; GtkWidget * WriteCalib12; GtkWidget * UseOSCCAL; GtkWidget * UseBKOSCCAL; GtkWidget * UseFileCal; GtkWidget * devFrameAVR; GtkWidget * AVR_FuseLow,* AVR_FuseLowWrite,* AVR_FuseHigh,* AVR_FuseHighWrite,* AVR_FuseExt; GtkWidget * AVR_FuseExtWrite,* AVR_Lock,* AVR_LockWrite; GtkWidget * b_WfuseLF; GtkWidget * b_connect; GtkWidget * b_testhw; GtkWidget * b_log; GtkWidget * VID_entry; GtkWidget * PID_entry; GtkWidget * Errors_entry; GtkWidget * I2C8bit; GtkWidget * I2C16bit; GtkWidget * SPI00; GtkWidget * SPI01; GtkWidget * SPI10; GtkWidget * SPI11; GtkWidget * I2CDataSend; GtkWidget * I2CDataReceive; GtkWidget * I2CSendBtn; GtkWidget * I2CReceiveBtn; GtkWidget * I2CNbyte; GtkWidget * I2CSpeed; GtkWidget * DCDC_ON; GtkWidget * DCDC_voltage; GtkWidget * VPP_ON; GtkWidget * VDD_ON; GtkWidget * b_io_active; GtkWidget * commandSend; GtkWidget * commandTransfer; GtkWidget * b_V33check; GtkWidget * Hex_entry; GtkWidget * Address_entry; GtkWidget * Data_entry; GtkWidget * Hex_data; GtkWidget * Hex_data2; GtkWidget * CW1_entry; GtkWidget * CW2_entry; GtkWidget * CW3_entry; GtkWidget * CW4_entry; GtkWidget * CW5_entry; GtkWidget * CW6_entry; GtkWidget * CW7_entry; GtkWidget * ConfigForce; GtkWidget * b_WaitS1; GtkWidget * devFrameConfigW; GtkWidget * devFrameICD; GtkWidget * devFrameOsc; GtkWidget * devPIC_CW1; GtkWidget * devPIC_CW2; GtkWidget * devPIC_CW3; GtkWidget * devPIC_CW4; GtkWidget * devPIC_CW5; GtkWidget * devPIC_CW6; GtkWidget * devPIC_CW7; GtkWidget * devPIC_CW8; GtkWidget * devinfo; GtkWidget* stopBtn; GtkWidget* readBtn; GtkWidget* writeBtn; GtkListStore *devStore; GtkWidget *devTree, *devFiltEntry, *devFrame; GtkTreeSelection *devSel; ///array of radio buttons for IO manual control struct io_btn { char * name; int x; int y; GtkWidget * r_0; //radio button 0 GtkWidget * r_1; //radio button 1 GtkWidget * r_I; //radio button I GtkWidget * e_I; //entry } ioButtons[13]; int statusID; int ee = 0; int readRes=0; char dev[64]=""; int devType=-1; char str[4096]=""; char* cur_path=0; char* cur_pathEE=0; enum dev_column_t { DEVICE_ID_COLUMN = 0, DEVICE_NAME_COLUMN, DEVICE_GROUP_COLUMN, DEVICE_N_COLUMNS }; enum sort_type_t { SORT_STRING_NAME = 0, SORT_STRING_GROUP }; enum sort_data_type_t { SDT_STRING = 0 }; char *groupNames[NUM_GROUPS] = { "PIC10/12", "PIC16", "PIC18", "PIC24", "PIC30/33", "ATMEL AVR", "MEMORY" }; 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 /// ///Exit gint delete_event( GtkWidget *widget,GdkEvent *event,gpointer data ) { gtk_main_quit (); return FALSE; } /// ///Show program info window void info(GtkWidget *widget,GtkWidget *window) { const gchar *license = "This program is free software; you can redistribute it and/or\n" "modify it under the terms of the GNU Library General Public License as\n" "published by the Free Software Foundation; either version 2 of the\n" "License, or (at your option) any later version.\n" "\n" "This program is distributed in the hope that it will be useful,\n" "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" "Library General Public License for more details.\n" "\n" "You should have received a copy of the GNU Library General Public\n" "License along with the Gnome Library; see the file COPYING.LIB. If not,\n" "write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n" "Boston, MA 02111-1307, USA.\n"; gtk_show_about_dialog (NULL, //"artists" GStrv* : Read / Write //"authors" GStrv* : Read / Write //"authors","Alberto Maccioni",NULL, "comments", "A graphical interface for the Open Programmer", "copyright", "Copyright (C) Alberto Maccioni 2009-2023\n\n" "This program is free software; you can \n" "redistribute it and/or modify it under \n" "the terms of the GNU General Public License \n" "as published by the Free Software Foundation;\n" "either version 2 of the License, or \n" "(at your option) any later version.", //"documenters" GStrv* : Read / Write "license",license, "logo",gdk_pixbuf_new_from_resource("/res/sys.png", NULL), // "logo-icon-name" gchar* : Read / Write "program-name", "OPGUI", // "translator-credits" gchar* : Read / Write "version",VERSION, "website","www.openprog.altervista.org", // "website-label" gchar* : Read / Write "wrap-license",TRUE, "title","Info about OPGUI", NULL); } /// ///Append a message on the data tab; shorten the length of the entry field to MAXLINES void PrintMessage(const char *msg){ if(cmdline) return; //do not print anything if using command line mode GtkTextIter iter,iter2; gtk_text_buffer_get_end_iter(dataBuf,&iter); gtk_text_buffer_insert(dataBuf,&iter,msg,-1); gtk_text_buffer_get_start_iter(dataBuf,&iter2); gtk_text_buffer_get_end_iter(dataBuf,&iter); int l=gtk_text_buffer_get_line_count(dataBuf); if(l>MAXLINES+10){ //MAXLINES gtk_text_iter_set_line(&iter,l-MAXLINES); gtk_text_buffer_delete(dataBuf,&iter2,&iter); } while (gtk_events_pending ()) gtk_main_iteration(); gtk_text_buffer_get_end_iter(dataBuf,&iter); gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(data),&iter,0.0,FALSE,0,0); } /// ///Print a message on the I2C data field void PrintMessageI2C(const char *msg){ GtkTextIter iter; GtkTextBuffer * dataBuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(I2CDataReceive)); gtk_text_buffer_set_text(dataBuf,msg,-1); gtk_text_buffer_get_end_iter(dataBuf,&iter); gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(I2CDataReceive),&iter,0.0,FALSE,0,0); while (gtk_events_pending ()) gtk_main_iteration(); } /// ///Print a message on the "command" data field void PrintMessageCMD(const char *msg){ GtkTextIter iter; GtkTextBuffer * dataBuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(commandTransfer)); gtk_text_buffer_set_text(dataBuf,msg,-1); gtk_text_buffer_get_end_iter(dataBuf,&iter); gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(commandTransfer),&iter,0.0,FALSE,0,0); } /// ///Update option variables according to actual control values void getOptions() { vid=htoi(gtk_entry_get_text(GTK_ENTRY(VID_entry)),4); pid=htoi(gtk_entry_get_text(GTK_ENTRY(PID_entry)),4); saveLog = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_log)); ee = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(EEPROM_RW))?0xFFFF:0; programID = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(Write_ID_BKCal)); max_err=atoi(gtk_entry_get_text(GTK_ENTRY(Errors_entry))); load_calibword= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(WriteCalib12)); load_osccal= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(UseOSCCAL)); load_BKosccal= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(UseBKOSCCAL)); ICDenable= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ICD_check)); readRes= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ReadReserved)); skipV33check=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_V33check)); waitS1=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_WaitS1)); int i=sscanf(gtk_entry_get_text(GTK_ENTRY(ICD_addr_entry)),"%x",&ICDaddr); if(i!=1||ICDaddr<0||ICDaddr>0xFFFF) ICDaddr=0x1FF0; char *str=0;//gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(devCombo)); if(str) strncpy(dev,str,sizeof(dev)-1); g_free(str); AVRfuse=AVRfuse_h=AVRfuse_x=AVRlock=0x100; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(AVR_FuseLowWrite))){ i=sscanf(gtk_entry_get_text(GTK_ENTRY(AVR_FuseLow)),"%x",&AVRfuse); if(i!=1||AVRfuse<0||AVRfuse>0xFF) AVRfuse=0x100; } if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(AVR_FuseHighWrite))){ i=sscanf(gtk_entry_get_text(GTK_ENTRY(AVR_FuseHigh)),"%x",&AVRfuse_h); if(i!=1||AVRfuse_h<0||AVRfuse_h>0xFF) AVRfuse_h=0x100; } if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(AVR_FuseExtWrite))){ i=sscanf(gtk_entry_get_text(GTK_ENTRY(AVR_FuseExt)),"%x",&AVRfuse_x); if(i!=1||AVRfuse_x<0||AVRfuse_x>0xFF) AVRfuse_x=0x100; } if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(AVR_LockWrite))){ i=sscanf(gtk_entry_get_text(GTK_ENTRY(AVR_Lock)),"%x",&AVRlock); if(i!=1||AVRlock<0||AVRlock>0xFF) AVRlock=0x100; } str=malloc(128); if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ConfigForce))){ int cw1,cw2,cw3,cw4,cw5,cw6,cw7; cw1=cw2=cw3=cw4=cw5=cw6=cw7=0x10000; i=sscanf(gtk_entry_get_text(GTK_ENTRY(CW1_entry)),"%x",&cw1); i=sscanf(gtk_entry_get_text(GTK_ENTRY(CW2_entry)),"%x",&cw2); i=sscanf(gtk_entry_get_text(GTK_ENTRY(CW3_entry)),"%x",&cw3); i=sscanf(gtk_entry_get_text(GTK_ENTRY(CW4_entry)),"%x",&cw4); i=sscanf(gtk_entry_get_text(GTK_ENTRY(CW5_entry)),"%x",&cw5); i=sscanf(gtk_entry_get_text(GTK_ENTRY(CW6_entry)),"%x",&cw6); i=sscanf(gtk_entry_get_text(GTK_ENTRY(CW7_entry)),"%x",&cw7); if(devType==PIC16){ if((!strncmp(dev,"16F1",4)||!strncmp(dev,"12F1",4))&&sizeW>0x8008){ //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" } } } free(str); } /// ///Check GUI for selected device and put in variable 'dev'. Also enable/disable R/W buttons void GetSelectedDevice() { GtkTreeModel *tmpModel; GtkTreeIter tmpIter; char *devName; if (!GTK_IS_TREE_SELECTION(devSel)) { // Not initialised yet return; } if (gtk_tree_selection_get_selected(devSel, &tmpModel, &tmpIter)) { gtk_tree_model_get(tmpModel, &tmpIter, DEVICE_NAME_COLUMN, &devName, -1); strcpy(dev,devName); gtk_widget_set_sensitive(GTK_WIDGET(readBtn), TRUE); gtk_widget_set_sensitive(GTK_WIDGET(writeBtn), TRUE); g_free(devName); } else { // Shouldn't ever happen, but just in case dev[0] = '\0'; gtk_widget_set_sensitive(GTK_WIDGET(readBtn), FALSE); gtk_widget_set_sensitive(GTK_WIDGET(writeBtn), FALSE); } } /// ///Choose a file to open and call Load() void Fopen(GtkWidget *widget,GtkWidget *window) { GetSelectedDevice(); if(progress) return; progress=1; GtkFileChooser *dialog; dialog = (GtkFileChooser*) gtk_file_chooser_dialog_new (strings[I_Fopen], //"Open File" GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN, strings[I_CANCEL], GTK_RESPONSE_CANCEL, strings[I_OPEN], GTK_RESPONSE_ACCEPT, NULL); if(cur_path) gtk_file_chooser_set_current_folder(dialog,cur_path); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT){ char *filename; filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); if(cur_path) free(cur_path); cur_path = gtk_file_chooser_get_current_folder(dialog); Load(dev,filename); g_free (filename); if(!strncmp(dev,"AT",2)){ //load EEPROM from separate file for ATMEL chips GtkFileChooser *dialog2; dialog2 = (GtkFileChooser*) gtk_file_chooser_dialog_new (strings[S_openEEfile], GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN, strings[I_CANCEL],GTK_RESPONSE_CANCEL, strings[I_OPEN],GTK_RESPONSE_ACCEPT, NULL); if(!cur_pathEE) cur_pathEE = gtk_file_chooser_get_current_folder(dialog); if(cur_pathEE) gtk_file_chooser_set_current_folder(dialog2,cur_pathEE); if (gtk_dialog_run (GTK_DIALOG (dialog2)) == GTK_RESPONSE_ACCEPT){ char *filename2; filename2 = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog2)); if(cur_pathEE) free(cur_pathEE); cur_pathEE = gtk_file_chooser_get_current_folder(dialog2); LoadEE(dev,filename2); g_free (filename2); } gtk_widget_destroy(GTK_WIDGET(dialog2)); } } gtk_widget_destroy (GTK_WIDGET(dialog)); progress=0; } /// ///Choose a file to save and call Save() void Fsave(GtkWidget *widget,GtkWidget *window) { if(progress) return; progress=1; GtkFileChooser *dialog; dialog = (GtkFileChooser*) gtk_file_chooser_dialog_new (strings[I_Fsave], //"Save File", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_SAVE, strings[I_CANCEL], GTK_RESPONSE_CANCEL, strings[I_SAVE], GTK_RESPONSE_ACCEPT, NULL); if(cur_path) gtk_file_chooser_set_current_folder(dialog,cur_path); gtk_file_chooser_set_do_overwrite_confirmation(dialog,TRUE); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { char *filename; filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); if(cur_path) free(cur_path); cur_path = gtk_file_chooser_get_current_folder(dialog); Save(dev,filename); PrintMessage1(strings[S_FileSaved],filename); g_free (filename); if(!strncmp(dev,"AT",2)&&sizeEE){ //save EEPROM on separate file for ATMEL chips GtkFileChooser *dialog2; dialog2 = (GtkFileChooser*) gtk_file_chooser_dialog_new (strings[S_saveEEfile], GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_SAVE, strings[I_CANCEL], GTK_RESPONSE_CANCEL, strings[I_SAVE], GTK_RESPONSE_ACCEPT, NULL); if(!cur_pathEE) cur_pathEE = gtk_file_chooser_get_current_folder(dialog); if(cur_pathEE) gtk_file_chooser_set_current_folder(dialog2,cur_pathEE); gtk_file_chooser_set_do_overwrite_confirmation(dialog2,TRUE); if (gtk_dialog_run (GTK_DIALOG (dialog2)) == GTK_RESPONSE_ACCEPT){ char *filename2; filename2 = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog2)); if(cur_pathEE) free(cur_pathEE); cur_pathEE = gtk_file_chooser_get_current_folder(dialog2); SaveEE(dev,filename2); PrintMessage1(strings[S_FileSaved],filename2); g_free (filename2); } gtk_widget_destroy(GTK_WIDGET(dialog2)); } } gtk_widget_destroy (GTK_WIDGET(dialog)); progress=0; } /// ///Select data tab void selectDataTab() { gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 0); } /// ///Call device write function void DevWrite(GtkWidget *widget,GtkWidget *window) { #ifndef DEBUG if(DeviceDetected!=1) return; #endif selectDataTab(); gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,""); RWstop=0; getOptions(); if(!waitingS1&&waitS1){ waitingS1=1; int i,S1=0; PrintMessage(strings[I_PRESSS1]); //"press S1 to start" for(i=0;!S1&&waitS1&&waitingS1;i++){ S1=CheckS1(); msDelay(50); PrintMessage("."); if(i%64==63) PrintMessage(strings[S_NL]); //"\n" while (gtk_events_pending ()) gtk_main_iteration(); //handle UI events, including write button msDelay(50); } PrintMessage(strings[S_NL]); //"\n" if(!progress&&S1){ gtk_widget_set_sensitive(stopBtn,TRUE); progress=1; Write(dev,ee); //choose the right function progress=0; gtk_widget_set_sensitive(stopBtn,FALSE); } waitingS1=0; } else if(waitingS1) waitingS1=0; else if(!progress){ gtk_widget_set_sensitive(stopBtn,TRUE); progress=1; Write(dev,ee); //choose the right function progress=0; gtk_widget_set_sensitive(stopBtn,FALSE); } } /// ///Call device read function void DevRead(GtkWidget *widget,GtkWidget *window) { #ifndef DEBUG if(DeviceDetected!=1) return; #endif selectDataTab(); gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,""); getOptions(); RWstop=0; if(!waitingS1&&waitS1){ waitingS1=1; int i,S1=0; PrintMessage(strings[I_PRESSS1]); //"press S1 to start" for(i=0;!S1&&waitS1&&waitingS1;i++){ S1=CheckS1(); msDelay(50); PrintMessage("."); if(i%64==63) PrintMessage(strings[S_NL]); //"\n" while (gtk_events_pending ()) gtk_main_iteration(); //handle UI events, including write button msDelay(50); } PrintMessage(strings[S_NL]); //"\n" if(!progress&&S1){ gtk_widget_set_sensitive(stopBtn,TRUE); progress=1; Read(dev,ee,readRes); //choose the right function progress=0; gtk_widget_set_sensitive(stopBtn,FALSE); } waitingS1=0; } else if(waitingS1) waitingS1=0; else if(!progress){ gtk_widget_set_sensitive(stopBtn,TRUE); progress=1; Read(dev,ee,readRes); //choose the right function progress=0; gtk_widget_set_sensitive(stopBtn,FALSE); } } /// /// Write fuse low byte at low frequency void WriteATfuseLowLF(GtkWidget *widget,GtkWidget *window){ #ifndef DEBUG if(DeviceDetected!=1) return; #endif if(progress) return; getOptions(); if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(AVR_FuseLowWrite))){ progress=1; if(AVRfuse<0x100) WriteATfuseSlow(AVRfuse); progress=0; } } /// ///Callback function to set available options for each device type void onDevSel_Changed(GtkWidget *widget,GtkWidget *window) { struct DevInfo info; GetSelectedDevice(); if (strlen(dev) == 0) return; // None selected info=GetDevInfo(dev); sprintf(str, "%s: %s", strings[I_Dev], dev); gtk_label_set_markup(GTK_LABEL(devFrame), str); devType=info.family; gtk_label_set_text(GTK_LABEL(devinfo),info.features); if(devType==PIC12||devType==PIC16||devType==PIC18||devType==PIC24){ gtk_widget_show_all(GTK_WIDGET(devFramePIC)); gtk_widget_hide(GTK_WIDGET(devFrameAVR)); gtk_widget_show_all(GTK_WIDGET(EEPROM_RW)); } else if(devType==AVR){ //ATMEL gtk_widget_hide(GTK_WIDGET(devFramePIC)); gtk_widget_show_all(GTK_WIDGET(devFrameAVR)); gtk_widget_show_all(GTK_WIDGET(EEPROM_RW)); } else{ gtk_widget_hide(GTK_WIDGET(devFramePIC)); gtk_widget_hide(GTK_WIDGET(devFrameAVR)); gtk_widget_hide(GTK_WIDGET(EEPROM_RW)); } if(devType==PIC16) //ICD gtk_widget_show_all(GTK_WIDGET(devFrameICD)); else gtk_widget_hide(GTK_WIDGET(devFrameICD)); if(devType==PIC12||devType==PIC16) //Osc options gtk_widget_show_all(GTK_WIDGET(devFrameOsc)); else gtk_widget_hide(GTK_WIDGET(devFrameOsc)); if(devType==PIC12||devType==PIC16||devType==PIC18) //program ID gtk_widget_show_all(GTK_WIDGET(Write_ID_BKCal)); else gtk_widget_hide(GTK_WIDGET(Write_ID_BKCal)); if(devType==PIC16) //Program Calib gtk_widget_show_all(GTK_WIDGET(WriteCalib12)); else gtk_widget_hide(GTK_WIDGET(WriteCalib12)); if(devType==PIC12||devType==PIC16||devType==PIC18){ //Force config gtk_widget_show_all(GTK_WIDGET(devFrameConfigW)); gtk_widget_hide(GTK_WIDGET(devPIC_CW2)); gtk_widget_hide(GTK_WIDGET(devPIC_CW3)); gtk_widget_hide(GTK_WIDGET(devPIC_CW4)); gtk_widget_hide(GTK_WIDGET(devPIC_CW5)); gtk_widget_hide(GTK_WIDGET(devPIC_CW6)); gtk_widget_hide(GTK_WIDGET(devPIC_CW7)); gtk_widget_hide(GTK_WIDGET(devPIC_CW8)); if(devType==PIC16){ gtk_widget_show_all(GTK_WIDGET(devPIC_CW2)); } else if(devType==PIC18){ gtk_widget_show_all(GTK_WIDGET(devPIC_CW2)); gtk_widget_show_all(GTK_WIDGET(devPIC_CW3)); gtk_widget_show_all(GTK_WIDGET(devPIC_CW4)); gtk_widget_show_all(GTK_WIDGET(devPIC_CW5)); gtk_widget_show_all(GTK_WIDGET(devPIC_CW6)); gtk_widget_show_all(GTK_WIDGET(devPIC_CW7)); gtk_widget_show_all(GTK_WIDGET(devPIC_CW8)); } } else{ gtk_widget_hide(GTK_WIDGET(devFrameConfigW)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ConfigForce),FALSE); } gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,dev); } /// Walk the TreeModel until we find an entry with the passed device name /// Select that entry and then stop walking gboolean selectDev_ForeachFunc(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, char *devNameToSelect) { char *thisEntryDevName; gtk_tree_model_get(model, iter, DEVICE_NAME_COLUMN, &thisEntryDevName, -1); int matched = (strcmp(thisEntryDevName, devNameToSelect) == 0); if (matched) gtk_tree_selection_select_iter(devSel, iter); g_free(thisEntryDevName); return matched; } /// /// Comparison function used when sorting the device tree int sortIterCompareFunc(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer userdata) { enum sort_type_t sortcol = GPOINTER_TO_INT(userdata); int ret = 0; enum sort_data_type_t sortDataType; int dataCol; switch (sortcol) { case SORT_STRING_NAME: sortDataType = SDT_STRING; dataCol = DEVICE_NAME_COLUMN; break; case SORT_STRING_GROUP: sortDataType = SDT_STRING; dataCol = DEVICE_GROUP_COLUMN; break; default: return 0; } switch (sortDataType) { case SDT_STRING: { char *nameA, *nameB; gtk_tree_model_get(model, a, dataCol, &nameA, -1); gtk_tree_model_get(model, b, dataCol, &nameB, -1); if (nameA == NULL || nameB == NULL) { if (nameA == NULL && nameB == NULL) break; // Both null. return 0 (no need to free) ret = (nameA == NULL) ? -1 : 1; } else { ret = g_utf8_collate(nameA,nameB); } g_free(nameA); g_free(nameB); break; } default: g_return_val_if_reached(0); } return ret; } #ifndef strupr char* strupr( char* s ){ char* p = s; while (*p = toupper( *p )) p++; return s; } #endif /// ///Add devices to the device ListStore (which may not have been created) ///groupFilter: add devices in this group (-1 for all) ///textFilter: only add devices containing this string (NULL for all) void AddDevices(enum group_t groupFilter, const char *textFilter) { if (GTK_IS_TREE_SELECTION(devSel)) g_signal_handlers_disconnect_by_func(G_OBJECT(devSel),G_CALLBACK(onDevSel_Changed),NULL); if (!GTK_IS_LIST_STORE(devStore)) { devStore = gtk_list_store_new (DEVICE_N_COLUMNS, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING); gtk_tree_view_set_model(GTK_TREE_VIEW(devTree), GTK_TREE_MODEL(devStore)); gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(devStore), SORT_STRING_NAME, sortIterCompareFunc, GINT_TO_POINTER(SORT_STRING_NAME), NULL); gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(devStore), SORT_STRING_GROUP, sortIterCompareFunc, GINT_TO_POINTER(SORT_STRING_GROUP), NULL); gtk_tree_view_column_set_sort_column_id( gtk_tree_view_get_column(GTK_TREE_VIEW(devTree), 0), SORT_STRING_NAME); gtk_tree_view_column_set_sort_column_id( gtk_tree_view_get_column(GTK_TREE_VIEW(devTree), 1), SORT_STRING_GROUP); g_object_unref (G_OBJECT(devStore)); } else gtk_list_store_clear(devStore); int i,j=0; char *devices=0,*tok; char textFilterU[32]; strupr(strncpy(textFilterU,textFilter,32)); for(i=0;i0){ if(hex[0]==':'&&strlen(hex)>8){ length=htoi(hex+1,2); address=htoi(hex+3,4); if(strlen(hex)<11+length*2) gtk_entry_set_text(GTK_ENTRY(Hex_data),"__line too short"); else{ for (i=1;i<=length*2+9;i+=2) sum += htoi(hex+i,2); if ((sum & 0xff)!=0){ sprintf(str,"__checksum error, expected 0x%02X",(-sum+htoi(hex+9+length*2,2))&0xFF); gtk_entry_set_text(GTK_ENTRY(Hex_data),str); } else{ switch(htoi(hex+7,2)){ case 0: //Data record sprintf(str,"address: 0x%04X ",address); if(i&&length) strcat(str,"data: 0x"); for (i=0;i14){ sprintf(str,"extended linear address = %04X",htoi(hex+9,4)); gtk_entry_set_text(GTK_ENTRY(Hex_data),str); } break; default: gtk_entry_set_text(GTK_ENTRY(Hex_data),"__unknown record type"); break; } } } } else gtk_entry_set_text(GTK_ENTRY(Hex_data),"__invalid line"); } else gtk_entry_set_text(GTK_ENTRY(Hex_entry),""); } /// /// convert address & data to hex line void DataToHexConvert(GtkWidget *widget,GtkWidget *window) { char hex[256],str[256],s2[32]; int i,address,length,sum=0,x; i=sscanf(gtk_entry_get_text(GTK_ENTRY(Address_entry)),"%x",&address); if(i!=1) address=0; strncpy(hex,(const char *)gtk_entry_get_text(GTK_ENTRY(Data_entry)),sizeof(hex)); length=strlen(hex); length&=0xFF; if(length>0){ sprintf(str,":--%04X00",address&0xFFFF); for(i=0;i+1>8)&0xff); sprintf(s2,"%02X",(-sum)&0xFF); strcat(str,s2); gtk_entry_set_text(GTK_ENTRY(Hex_data2),str); } } /// ///Choose a file to save a hex line void HexSave(GtkWidget *widget,GtkWidget *window) { GtkFileChooser *dialog; if(strlen((const char *)gtk_entry_get_text(GTK_ENTRY(Hex_data2)))<11) return; dialog = (GtkFileChooser*) gtk_file_chooser_dialog_new (strings[I_Fsave], //"Save File", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_SAVE, strings[I_CANCEL], GTK_RESPONSE_CANCEL, strings[I_SAVE], GTK_RESPONSE_ACCEPT, NULL); if(cur_path) gtk_file_chooser_set_current_folder(dialog,cur_path); gtk_file_chooser_set_do_overwrite_confirmation(dialog,TRUE); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { char *filename; filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); if(cur_path) free(cur_path); cur_path = gtk_file_chooser_get_current_folder(dialog); FILE* f=fopen(filename,"w"); if(f){ fprintf(f,(const char *)gtk_entry_get_text(GTK_ENTRY(Hex_data2))); fclose(f); } g_free (filename); } gtk_widget_destroy (GTK_WIDGET(dialog)); } /// /// Stop read or write void Stop(GtkWidget *widget,GtkWidget *window) { #ifndef DEBUG if(DeviceDetected!=1) return; #endif if(progress==1&&RWstop==0){ RWstop=1; PrintMessage(strings[I_STOP]); } } /// ///Close program void Xclose(){ // char *str=gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(devCombo)); // if(str) strncpy(dev,str,sizeof(dev)-1); gtk_main_quit(); } /// /// Show a message box void MsgBox(const char* msg) { GtkWidget * dialog = gtk_message_dialog_new (GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, msg); gtk_window_set_title(GTK_WINDOW(dialog)," "); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); } /// /// Find the programmer and setup communication void Connect(GtkWidget *widget,GtkWidget *window){ vid=htoi(gtk_entry_get_text(GTK_ENTRY(VID_entry)),4); pid=htoi(gtk_entry_get_text(GTK_ENTRY(PID_entry)),4); 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 hvreg=0; ProgID(); } /// /// I2C/SPI receive void I2cspiR() { //if(DeviceDetected!=1) return; gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,""); saveLog = (int) gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_log)); int nbyte=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(I2CNbyte)); if(nbyte<0) nbyte=0; if(nbyte>60) nbyte=60; int mode=0; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(I2C16bit))) mode=1; //I2C mode if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(SPI00))) mode=2; //SPI mode 00 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(SPI01))) mode=3; //SPI mode 01 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(SPI10))) mode=4; //SPI mode 10 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(SPI11))) mode=5; //SPI mode 11 char* tok; char tokbuf[512]; BYTE tmpbuf[128]; int i=0,x; strncpy(tokbuf, (const char *)gtk_entry_get_text(GTK_ENTRY(I2CDataSend)), sizeof(tokbuf)); for(tok=strtok(tokbuf," ");tok&&i<128;tok=strtok(NULL," ")){ if(sscanf(tok,"%x",&x)){ tmpbuf[i] = (BYTE)x; i++; } } for(;i<128;i++) tmpbuf[i]=0; I2CReceive(mode,gtk_combo_box_get_active(GTK_COMBO_BOX(I2CSpeed)),nbyte,tmpbuf); } /// /// I2C/SPI send void I2cspiS() { //if(DeviceDetected!=1) return; gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,""); saveLog = (int) gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_log)); int nbyte=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(I2CNbyte)); if(nbyte<0) nbyte=0; if(nbyte>57) nbyte=57; int mode=0; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(I2C16bit))) mode=1; //I2C mode if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(SPI00))) mode=2; //SPI mode 00 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(SPI01))) mode=3; //SPI mode 01 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(SPI10))) mode=4; //SPI mode 10 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(SPI11))) mode=5; //SPI mode 11 char* tok; char tokbuf[512]; BYTE tmpbuf[128]; int i=0,x; strncpy(tokbuf, (const char *)gtk_entry_get_text(GTK_ENTRY(I2CDataSend)), sizeof(tokbuf)); for(tok=strtok(tokbuf," ");tok&&i<128;tok=strtok(NULL," ")){ if(sscanf(tok,"%x",&x)){ tmpbuf[i] = (BYTE)x; i++; } } for(;i<128;i++) tmpbuf[i]=0; I2CSend(mode,gtk_combo_box_get_active(GTK_COMBO_BOX(I2CSpeed)),nbyte,tmpbuf); } /// /// send manual command void CommandIO() { if(DeviceDetected!=1) return; gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,""); saveLog = (int) gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_log)); char* tok; char tokbuf[512],str[16]; int i=0,x; strncpy(tokbuf, (const char *)gtk_entry_get_text(GTK_ENTRY(commandSend)), sizeof(tokbuf)); for(tok=strtok(tokbuf," ");tok&&i["); for(i=0;i7000?7000:sizeEE; for(i=0;i500){ //limit number of lines printed strcat(aux,"(...)\r\n"); i=max-COL*2; lines=490; } } s[0]=0; v[0]=0; } if(empty) PrintMessage(strings[S_Empty]); //empty else{ PrintMessage(aux); if(sizeEE>max) PrintMessage("(...)\r\n"); } 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(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 (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=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) strcpy(dev,temp); else if(sscanf(line,"vid %X",&X)>0) vid=X; else if(sscanf(line,"pid %X",&X)>0) pid=X; else sscanf(line,"maxerr %d",&max_err); } fclose(f); } } char dev_ini[64]; strncpy(dev_ini,dev,sizeof(dev_ini)); int vid_ini=vid,pid_ini=pid,max_err_ini=max_err; vid_ini=vid; pid_ini=pid; max_err_ini=max_err; #if defined _WIN32 || defined __CYGWIN__ //Windows bufferI=bufferI0+1; bufferU=bufferU0+1; bufferI0[0]=0; bufferU0[0]=0; #endif gtk_init(&argc, &argv); unsigned int tmpbuf[128]; opterr = 0; int option_index = 0; int help=0,command=0,i,j; struct option long_options[] = { {"?", no_argument, &help, 1}, {"h", no_argument, &help, 1}, {"help", no_argument, &help, 1}, {"c", no_argument, &command, 1}, {"command", no_argument, &command, 1}, {"lang", required_argument, 0, 'l'}, {"langfile", no_argument, &langfile, 1}, {0, 0, 0, 0} }; while ((j = getopt_long_only (argc, argv, "",long_options,&option_index)) != -1){ if(j=='l'){ //language strncpy(lang,optarg,sizeof(lang)-1); } } 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(); char* langid=0; i=0; if(lang[0]){ //explicit language selection if(lang[0]=='i'&&lang[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; } if(langfile) GenerateLangFile(langid,"languages.rc"); if(help){ printf(strings[I_GUI_CMD_HELP]); exit(0); } if(command){ cmdline=1; 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){ bufferU[0]=0; for(i=1;i "); for(i=1;i0) { struct DevInfo info = GetDevInfo(dev); gtk_combo_box_set_active_id(GTK_COMBO_BOX(devTypeCombo), groupNames[info.group]); } else { gtk_combo_box_set_active_id(GTK_COMBO_BOX(devTypeCombo), GROUP_ALL); } 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 ProgID(); //get firmware version and reset gtk_main(); // printf(ListDevices()); //******Save ini file****** // only if parameters are changed if(strcmp(dev_ini,dev)||vid_ini!=vid||pid_ini!=pid||max_err_ini!=max_err){ if(homedir){ f=fopen(fname,"w"); if(f){ fprintf(f,"device %s\n",dev); fprintf(f,"maxerr %d\n",max_err); fprintf(f,"vid %X\n",vid); fprintf(f,"pid %X\n",pid); } fclose(f); } } 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; }