diff options
Diffstat (limited to 'opgui.c')
-rw-r--r-- | opgui.c | 2503 |
1 files changed, 2503 insertions, 0 deletions
@@ -0,0 +1,2503 @@ +/** + * \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 <http://www.gnu.org/licenses/> + */ +#include "common.h" +#include "I2CSPI.h" +#include "coff.h" +#include "icd.h" +#include "deviceRW.h" +#include "fileIO.h" +#include "progAVR.h" +#include <string.h> + +#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-2022\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; + char str2[256],str3[64],strF[32]; + double x; + GetSelectedDevice(); + if (strlen(dev) == 0) return; // None selected + info=GetDevInfo(dev); + sprintf(str, "<b>%s: %s</b>", 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; +} +/// +///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; + for(i=0;i<NDEVLIST;i++) { + if(devices) free(devices); + devices=malloc(strlen(DEVLIST[i].device)+1); + strcpy(devices,DEVLIST[i].device); + struct DevInfo info; + populateDevInfo(&info, &(DEVLIST[i])); + for(tok=strtok(devices,", \t");tok;tok=strtok(NULL,", \t")) { + //info.device=malloc(strlen(tok)+1); + //strcpy(info.device,tok); + info.group=nameToGroup(tok); + if(info.group!=-1&&(!textFilter || strlen(textFilter) == 0 || strstr(tok, textFilter)) && + (groupFilter == -1 || info.group == groupFilter)) { + gtk_list_store_insert_with_values(devStore, NULL, -1, + DEVICE_ID_COLUMN, j++, + DEVICE_NAME_COLUMN, tok, + DEVICE_GROUP_COLUMN, groupNames[info.group], -1); + } + } + } + free(devices); + if(GTK_IS_TREE_SELECTION(devSel)) { + gtk_tree_selection_unselect_all(devSel); + } + else { + devSel = gtk_tree_view_get_selection(GTK_TREE_VIEW(devTree)); + gtk_tree_selection_set_mode(devSel, GTK_SELECTION_SINGLE); + } + g_signal_connect(G_OBJECT(devSel),"changed",G_CALLBACK(onDevSel_Changed),NULL); + gtk_tree_model_foreach(GTK_TREE_MODEL(devStore), + (GtkTreeModelForeachFunc)selectDev_ForeachFunc, + dev); +} +/// +///Filter device list (in gtk_tree) according to type selected +void FilterDevType(GtkWidget *widget,GtkWidget *window) +{ + char *selGroupName = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(devTypeCombo)); + const char *filtText = gtk_entry_get_text(GTK_ENTRY(devFiltEntry)); + enum group_t selGroup = -1; + for (int i=0; i<NUM_GROUPS; i++) { + if (strcmp(selGroupName, groupNames[i]) == 0) { + selGroup = i; + i = NUM_GROUPS; + } + } + // If no specific group selected, ALL should be selected + if (selGroup == -1 && strcmp(GROUP_ALL, selGroupName)) { + PrintMessage1("ERR: group name '%s' invalid", selGroupName); + return; + } + AddDevices(selGroup, filtText); + g_free(selGroupName); + onDevSel_Changed(NULL, NULL); +} +/// +/// Check or set IO signals according to IO tab controls +void IOchanged(GtkWidget *widget,GtkWidget *window) +{ + if(progress) return; +#ifndef DEBUG + if(DeviceDetected!=1) return; +#endif + if(!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_io_active))) return; + int i,j=0; + int trisa=1,trisb=0,trisc=0x30,latac=0,latb=0; + int port=0,z; + //char str[128]="IO:"; + char s2[64]; + str[0]=0; + for(i=0;i<sizeof(ioButtons)/sizeof(ioButtons[0]);i++){ + if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ioButtons[i].r_0))){ + //strcat(str,"0"); + } + else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ioButtons[i].r_1))){ + //strcat(str,"1"); + if(i<8) latb|=1<<i; + else if(i==8) latac|=0x80; //RC7 + else if(i==9) latac|=0x40; //RC6 + else if(i==10) latac|=0x20; //RA5 + else if(i==11) latac|=0x10; //RA4 + else if(i==12) latac|=0x08; //RA3 + } + else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ioButtons[i].r_I))){ + //strcat(str,"I"); + if(i<8) trisb|=1<<i; + else if(i==8) trisc|=0x80; //RC7 + else if(i==9) trisc|=0x40; //RC6 + else if(i==10) trisa|=0x20; //RA5 + else if(i==11) trisa|=0x10; //RA4 + else if(i==12) trisa|=0x8; //RA3 + } + } + //sprintf(s2," trisb=%02X latb=%02X trisc=%02X trisa=%02X latac=%02X",trisb,latb,trisc,trisa,latac); + //strcat(str,s2); + //gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,str); + bufferU[j++]=READ_RAM; + bufferU[j++]=0x0F; + bufferU[j++]=0x80; //PORTA + bufferU[j++]=READ_RAM; + bufferU[j++]=0x0F; + bufferU[j++]=0x81; //PORTB + bufferU[j++]=READ_RAM; + bufferU[j++]=0x0F; + bufferU[j++]=0x82; //PORTC + bufferU[j++]=WRITE_RAM; + bufferU[j++]=0x0F; + bufferU[j++]=0x92; //TRISA + bufferU[j++]=trisa; + bufferU[j++]=WRITE_RAM; + bufferU[j++]=0x0F; + bufferU[j++]=0x93; //TRISB + bufferU[j++]=trisb; + bufferU[j++]=WRITE_RAM; + bufferU[j++]=0x0F; + bufferU[j++]=0x94; //TRISC + bufferU[j++]=trisc; + bufferU[j++]=EXT_PORT; + bufferU[j++]=latb; + bufferU[j++]=latac; + bufferU[j++]=READ_ADC; + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(2); + for(z=0;z<DIMBUF-3&&bufferI[z]!=READ_RAM;z++); + port=bufferI[z+3]; //PORTA + //sprintf(s2," porta=%02X",port); + //strcat(str,s2); + //gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,str); + gtk_label_set_text(GTK_LABEL(ioButtons[10].e_I),(port&0x20)?"1":"0"); + gtk_label_set_text(GTK_LABEL(ioButtons[11].e_I),(port&0x10)?"1":"0"); + gtk_label_set_text(GTK_LABEL(ioButtons[12].e_I),(port&0x8)?"1":"0"); + for(z+=4;z<DIMBUF-3&&bufferI[z]!=READ_RAM;z++); + port=bufferI[z+3]; //PORTB + for(i=0;i<8;i++) gtk_label_set_text(GTK_LABEL(ioButtons[i].e_I),(port&(1<<i))?"1":"0"); + for(z+=4;z<DIMBUF-3&&bufferI[z]!=READ_RAM;z++); + port=bufferI[z+3]; //PORTC + gtk_label_set_text(GTK_LABEL(ioButtons[8].e_I),(port&0x80)?"1":"0"); + gtk_label_set_text(GTK_LABEL(ioButtons[9].e_I),(port&0x40)?"1":"0"); + for(z+=4;z<DIMBUF-2&&bufferI[z]!=READ_ADC;z++); + double vpp=((bufferI[z+1]<<8)+bufferI[z+2])/1024.0*5*34/12; //VPP + sprintf(str,"VPP=%.2fV",vpp); + gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,str); + return; +} +/// +/// Start/stop timer to check for IO status +void IOactive(GtkWidget *widget,GtkWidget *window) +{ + if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b_io_active))&&!icdTimer){ + IOTimer=g_timeout_add(100,(GSourceFunc)IOchanged,NULL); + } + else if(IOTimer){ + g_source_remove(IOTimer); + } +} +/// +/// Enable/disable VPP and VCC from IO tab +void VPPVDDactive(GtkWidget *widget,GtkWidget *window) +{ +#ifndef DEBUG + if(DeviceDetected!=1) return; +#endif + int j=0,vdd_vpp=0; + char str[16]=""; + if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(VPP_ON))){ + vdd_vpp+=4; + strcat(str,"VPP "); + } + if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(VDD_ON))){ + vdd_vpp+=1; + strcat(str,"VDD "); + } + gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,str); + bufferU[j++]=EN_VPP_VCC; //VDD+VPP + bufferU[j++]=vdd_vpp; + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(2); +} +/// +/// Enable/disable DCDC from IO tab or update DCDC voltage +void DCDCactive(GtkWidget *widget,GtkWidget *window) +{ +#ifndef DEBUG + if(DeviceDetected!=1) return; +#endif + if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(DCDC_ON))){ + int j=0,vreg=0; + char str[16]; + double voltage=gtk_range_get_value(GTK_RANGE(DCDC_voltage)); + vreg=voltage*10.0; + sprintf(str,"DCDC %.1fV",voltage); + gtk_statusbar_push(GTK_STATUSBAR(status_bar),statusID,str); + bufferU[j++]=VREG_EN; //enable HV regulator + bufferU[j++]=SET_VPP; + bufferU[j++]=vreg; + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(2); + } + else{ + int j=0; + bufferU[j++]=VREG_DIS; //disable HV regulator + bufferU[j++]=FLUSH; + for(;j<DIMBUF;j++) bufferU[j]=0x0; + PacketIO(2); + } +} +/// +/// convert hex line +void HexConvert(GtkWidget *widget,GtkWidget *window) +{ + char hex[256],str[256],s2[32]; + int i,address,length,sum=0; + strncpy(hex,(const char *)gtk_entry_get_text(GTK_ENTRY(Hex_entry)),sizeof(hex)); + if(strlen(hex)>0){ + 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;i<length;i++){ + sprintf(s2,"%02X",htoi(hex+9+i*2,2)); + strcat(str,s2); + } + gtk_entry_set_text(GTK_ENTRY(Hex_data),str); + break; + case 4: //extended linear address record + if(strlen(hex)>14){ + 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<length;i+=2){ + x=htoi(hex+i,2); + //x&=0xFF; + sum+=x; + sprintf(s2,"%02X",x); + strcat(str,s2); + } + sprintf(s2,"%02X",i/2); + str[1]=s2[0]; + str[2]=s2[1]; + x=sum; + sum+=i/2+(address&0xff)+((address>>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<DIMBUF;tok=strtok(NULL," ")){ + if(sscanf(tok,"%x",&x)){ + bufferU[i] = (BYTE)x; + i++; + } + } + for(;i<DIMBUF;i++) bufferU[i]=0x0; + PacketIO(150); + sprintf(tokbuf,">["); + for(i=0;i<DIMBUF;i++){ + sprintf(str," %02X",bufferU[i]); + strcat(tokbuf,str); + if(i%32==31&&i!=DIMBUF-1)strcat(tokbuf,"\n "); + } + strcat(tokbuf," ]\n<["); + for(i=0;i<DIMBUF;i++){ + sprintf(str," %02X",bufferI[i]); + strcat(tokbuf,str); + if(i%32==31&&i!=DIMBUF-1)strcat(tokbuf,"\n "); + } + strcat(tokbuf," ]"); + PrintMessageCMD(tokbuf); +} +/// +///Display contents of EEprom memory +void DisplayEE(){ + char s[256],t[256],v[256],*aux,*g; + int valid=0,empty=1,lines=0; + int i,j,max; + s[0]=0; + v[0]=0; + aux=malloc((sizeEE/COL+1)*(16+COL*5)); + aux[0]=0; + PrintMessage(strings[S_EEMem]); //"\r\nEEPROM memory:\r\n" + max=sizeEE>7000?7000:sizeEE; + for(i=0;i<max;i+=COL){ + valid=0; + for(j=i;j<i+COL&&j<sizeEE;j++){ + sprintf(t,"%02X ",memEE[j]); + strcat(s,t); + sprintf(t,"%c",isprint(memEE[j])&&(memEE[j]<0xFF)?memEE[j]:'.'); + g=g_locale_to_utf8(t,-1,NULL,NULL,NULL); + if(g) strcat(v,g); + g_free(g); + if(memEE[j]<0xff) valid=1; + } + if(valid){ + sprintf(t,"%04X: %s %s\r\n",i,s,v); + strcat(aux,t); + empty=0; + lines++; + if(lines>500){ //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<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(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 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 +///----------------------------------- +int main( int argc, char *argv[]) +{ + //int langID=GetUserDefaultLangID(); + DWORD t0=GetTickCount(); + FILE *f; + gchar *homedir,*config_dir,*fname=0; + char lang[32]=""; + int langfile=0; + homedir = (gchar *) g_get_home_dir (); + if(homedir){ + config_dir=g_build_path(G_DIR_SEPARATOR_S,homedir,CONFIG_DIR, NULL); + if(!g_file_test(config_dir,G_FILE_TEST_IS_DIR)) + #if defined _WIN32 + mkdir(config_dir); + #else + mkdir(config_dir,0755); + #endif + fname = g_build_path(G_DIR_SEPARATOR_S,config_dir,CONFIG_FILE, NULL); + f=fopen(fname,"r"); + if(f){ + char temp[256],line[256]; + int X; + for(;fgets(line,256,f);){ + if(sscanf(line,"device %s",temp)>0) 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; + char c; + 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'&&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; + } + 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<DIMBUF;i++) bufferU[i]=(char) tmpbuf[i-1]; + PacketIO(100); + printf("> "); + for(i=1;i<DIMBUF;i++) printf("%02X ",bufferU[i]); + printf("\n< "); + for(i=1;i<DIMBUF;i++) printf("%02X ",bufferI[i]); + printf("\n"); + } + else printf(strings[S_noprog]); + exit(0); + } + + GtkBuilder *builder = NULL; + builder=gtk_builder_new_from_resource ("/res/opgui.glade"); + window = GTK_WIDGET(gtk_builder_get_object (builder,"window")); + g_signal_connect (window, "destroy", G_CALLBACK (Xclose), NULL); + gtk_window_set_icon(GTK_WINDOW(window),gdk_pixbuf_new_from_resource("/res/sys.png", NULL)); + GtkCssProvider *cssProvider = gtk_css_provider_new(); + gtk_css_provider_load_from_resource(cssProvider, "/res/style.css"); + gtk_style_context_add_provider_for_screen(gdk_screen_get_default(),GTK_STYLE_PROVIDER(cssProvider),GTK_STYLE_PROVIDER_PRIORITY_USER); + GtkWidget* w=NULL; + sprintf(str,"opgui v%s",VERSION); + gtk_window_set_title(GTK_WINDOW(window),str); + notebook = GTK_WIDGET(gtk_builder_get_object(builder,"NOTEBOOK")); +//------toolbar------------- + w=GTK_WIDGET(gtk_builder_get_object(builder,"OPEN_T")); + gtk_widget_set_tooltip_text(w,strings[I_Fopen]);//"Open File" + g_signal_connect(w,"clicked",G_CALLBACK(Fopen), NULL); + w=GTK_WIDGET(gtk_builder_get_object(builder,"SAVE_T")); + gtk_widget_set_tooltip_text(w,strings[I_Fsave]);//"Save File" + g_signal_connect(w,"clicked",G_CALLBACK(Fsave), NULL); + readBtn=GTK_WIDGET(gtk_builder_get_object(builder,"READ_T")); + gtk_widget_set_tooltip_text(readBtn,strings[I_DevR]);//"Read device" + g_signal_connect(readBtn,"clicked",G_CALLBACK(DevRead), NULL); + writeBtn=GTK_WIDGET(gtk_builder_get_object(builder,"WRITE_T")); + gtk_widget_set_tooltip_text(writeBtn,strings[I_DevW]);//"Write device" + g_signal_connect(writeBtn,"clicked",G_CALLBACK(DevWrite), NULL); + stopBtn=GTK_WIDGET(gtk_builder_get_object(builder,"STOP_T")); + gtk_widget_set_tooltip_text(stopBtn,strings[I_ICD_STOP]);//"Stop" + g_signal_connect(stopBtn,"clicked",G_CALLBACK(Stop), NULL); + w=GTK_WIDGET(gtk_builder_get_object(builder,"CONNECT_T")); + gtk_widget_set_tooltip_text(w,strings[I_CONN]);//"Reconnect" + g_signal_connect(w,"clicked",G_CALLBACK(Connect), NULL); + w=GTK_WIDGET(gtk_builder_get_object(builder,"INFO_T")); + gtk_widget_set_tooltip_text(w,strings[I_Info]);//"Info" + g_signal_connect(w,"clicked",G_CALLBACK(info), NULL); + w=GTK_WIDGET(gtk_builder_get_object(builder,"QUIT_T")); + gtk_widget_set_tooltip_text(w,strings[I_QUIT]);//"Quit" + g_signal_connect(w,"clicked",G_CALLBACK(Quit), NULL); +//------data tab------------- + gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"DATA_T_L"))),strings[I_Data]); //"Data" + data=GTK_WIDGET(gtk_builder_get_object(builder,"DATA")); + dataBuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(data)); +//------device tab------------- + gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"DEVICE_L"))),strings[I_Dev]); //"Device" + gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"TYPE_L"))),strings[I_Type]); //"Type" + devTypeCombo=GTK_WIDGET(gtk_builder_get_object(builder,"TYPE_C")); + g_signal_connect(G_OBJECT(devTypeCombo),"changed",G_CALLBACK(FilterDevType),NULL); + devFiltEntry=GTK_WIDGET(gtk_builder_get_object(builder,"DEV_SRC_E")); + g_signal_connect(G_OBJECT(devFiltEntry),"changed",G_CALLBACK(FilterDevType),NULL); + devTree = GTK_WIDGET(gtk_builder_get_object(builder,"DEV_TREE")); + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(devTree), + -1, strings[I_Dev], gtk_cell_renderer_text_new(), "text", DEVICE_NAME_COLUMN, NULL); + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(devTree), + -1, strings[I_Type], gtk_cell_renderer_text_new(), "text", DEVICE_GROUP_COLUMN, NULL); + // AddDevices() gets called when an entry in devTypeCombo is selected during init + devFrame = GTK_WIDGET(gtk_builder_get_object(builder,"DEVICE_NAME")); + devinfo = GTK_WIDGET(gtk_builder_get_object(builder,"DEV_INFO")); + EEPROM_RW = GTK_WIDGET(gtk_builder_get_object(builder,"EE_RW")); + gtk_button_set_label(GTK_BUTTON(EEPROM_RW),strings[I_EE]); //"Read and write EEPROM" + ReadReserved = GTK_WIDGET(gtk_builder_get_object(builder,"RES_READ")); + gtk_button_set_label(GTK_BUTTON(ReadReserved),strings[I_ReadRes]); //"Read reserved area" + Write_ID_BKCal = GTK_WIDGET(gtk_builder_get_object(builder,"PROG_ID")); + gtk_button_set_label(GTK_BUTTON(Write_ID_BKCal),strings[I_ID_BKo_W]); //"Write ID and BKOscCal" + WriteCalib12 = GTK_WIDGET(gtk_builder_get_object(builder,"PROG_CAL12")); + gtk_button_set_label(GTK_BUTTON(WriteCalib12),strings[I_CalW]); //"Write Calib 1 and 2" + gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"OSCCAL_L"))),strings[I_OSCW]); //"Write OscCal" + UseOSCCAL = GTK_WIDGET(gtk_builder_get_object(builder,"OSCCAL")); + gtk_button_set_label(GTK_BUTTON(UseOSCCAL),strings[I_OSC]); //"OSCCal" + UseBKOSCCAL = GTK_WIDGET(gtk_builder_get_object(builder,"BKOSCCAL")); + gtk_button_set_label(GTK_BUTTON(UseBKOSCCAL),strings[I_BKOSC]); //"Backup OSCCal" + UseFileCal = GTK_WIDGET(gtk_builder_get_object(builder,"FILECAL")); + gtk_button_set_label(GTK_BUTTON(UseFileCal),strings[I_OSCF]); //"From file" + ICD_check = GTK_WIDGET(gtk_builder_get_object(builder,"ICD")); + gtk_button_set_label(GTK_BUTTON(ICD_check),strings[I_ICD_ENABLE]); //"Enable ICD" + gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"ICD_ADDR_L"))),strings[I_ICD_ADDRESS]); //"ICD routine address" + ICD_addr_entry = GTK_WIDGET(gtk_builder_get_object(builder,"ICD_ADDR")); + ConfigForce = GTK_WIDGET(gtk_builder_get_object(builder,"FORCE_CW")); + gtk_button_set_label(GTK_BUTTON(ConfigForce),strings[I_PIC_FORCECW]); //"force config word" + CW1_entry = GTK_WIDGET(gtk_builder_get_object(builder,"CW1")); + CW2_entry = GTK_WIDGET(gtk_builder_get_object(builder,"CW2")); + CW3_entry = GTK_WIDGET(gtk_builder_get_object(builder,"CW3")); + CW4_entry = GTK_WIDGET(gtk_builder_get_object(builder,"CW4")); + CW5_entry = GTK_WIDGET(gtk_builder_get_object(builder,"CW5")); + CW6_entry = GTK_WIDGET(gtk_builder_get_object(builder,"CW6")); + CW7_entry = GTK_WIDGET(gtk_builder_get_object(builder,"CW7")); + AVR_FuseLow = GTK_WIDGET(gtk_builder_get_object(builder,"FUSEL")); + AVR_FuseLowWrite = GTK_WIDGET(gtk_builder_get_object(builder,"FUSEL_C")); + gtk_button_set_label(GTK_BUTTON(AVR_FuseLowWrite),strings[I_AT_FUSE]); //"Write Fuse Low" + AVR_FuseHigh = GTK_WIDGET(gtk_builder_get_object(builder,"FUSEH")); + AVR_FuseHighWrite = GTK_WIDGET(gtk_builder_get_object(builder,"FUSEH_C")); + gtk_button_set_label(GTK_BUTTON(AVR_FuseHighWrite),strings[I_AT_FUSEH]); //"Write Fuse High" + AVR_FuseExt = GTK_WIDGET(gtk_builder_get_object(builder,"FUSEX")); + AVR_FuseExtWrite = GTK_WIDGET(gtk_builder_get_object(builder,"FUSEX_C")); + gtk_button_set_label(GTK_BUTTON(AVR_FuseExtWrite),strings[I_AT_FUSEX]); //"Write Extended Fuse" + AVR_Lock = GTK_WIDGET(gtk_builder_get_object(builder,"FUSELCK")); + AVR_LockWrite = GTK_WIDGET(gtk_builder_get_object(builder,"FUSELCK_C")); + gtk_button_set_label(GTK_BUTTON(AVR_LockWrite),strings[I_AT_LOCK]); //"Write Lock" + b_WfuseLF = GTK_WIDGET(gtk_builder_get_object(builder,"FUSEL_W3K")); + gtk_button_set_label(GTK_BUTTON(b_WfuseLF),strings[I_AT_FUSELF]); //"Write Fuse Low @3kHz" + g_signal_connect(G_OBJECT(b_WfuseLF),"clicked",G_CALLBACK(WriteATfuseLowLF),window); + devFramePIC = GTK_WIDGET(gtk_builder_get_object(builder,"PIC_OPT")); + devFrameAVR = GTK_WIDGET(gtk_builder_get_object(builder,"AVR_OPT")); + devFrameConfigW = GTK_WIDGET(gtk_builder_get_object(builder,"CW_OPT")); + devFrameICD = GTK_WIDGET(gtk_builder_get_object(builder,"ICD_OPT")); + devFrameOsc = GTK_WIDGET(gtk_builder_get_object(builder,"OSC_OPT")); + devPIC_CW1 = GTK_WIDGET(gtk_builder_get_object(builder,"CW1_OPT")); + devPIC_CW2 = GTK_WIDGET(gtk_builder_get_object(builder,"CW2_OPT")); + devPIC_CW3 = GTK_WIDGET(gtk_builder_get_object(builder,"CW3_OPT")); + devPIC_CW4 = GTK_WIDGET(gtk_builder_get_object(builder,"CW4_OPT")); + devPIC_CW5 = GTK_WIDGET(gtk_builder_get_object(builder,"CW5_OPT")); + devPIC_CW6 = GTK_WIDGET(gtk_builder_get_object(builder,"CW6_OPT")); + devPIC_CW7 = GTK_WIDGET(gtk_builder_get_object(builder,"CW7_OPT")); + devPIC_CW8 = GTK_WIDGET(gtk_builder_get_object(builder,"CW8_OPT")); + gtk_widget_hide(GTK_WIDGET(devFrameAVR)); + gtk_widget_hide(GTK_WIDGET(devFramePIC)); +//------options tab------------- + gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"OPTIONS_L"))),strings[I_Opt]); //"Options" + VID_entry=GTK_WIDGET(gtk_builder_get_object(builder,"VID")); + PID_entry=GTK_WIDGET(gtk_builder_get_object(builder,"PID")); + Errors_entry=GTK_WIDGET(gtk_builder_get_object(builder,"MAXERR")); + b_connect = GTK_WIDGET(gtk_builder_get_object(builder,"CONNECT")); + gtk_button_set_label(GTK_BUTTON(b_connect),strings[I_CONN]); //"Reconnect" + g_signal_connect(G_OBJECT(b_connect),"clicked",G_CALLBACK(Connect),window); + b_testhw = GTK_WIDGET(gtk_builder_get_object(builder,"TEST")); + gtk_button_set_label(GTK_BUTTON(b_testhw),strings[I_TestHWB]); //"Hardware test" + g_signal_connect(G_OBJECT(b_testhw),"clicked",G_CALLBACK(TestHw),window); + b_log = GTK_WIDGET(gtk_builder_get_object(builder,"LOG")); + gtk_button_set_label(GTK_BUTTON(b_log),strings[I_LOG]); //"Log activity" + b_V33check = GTK_WIDGET(gtk_builder_get_object(builder,"3VCHECK")); + gtk_button_set_label(GTK_BUTTON(b_V33check),strings[I_CK_V33]); //"Don't check for 3.3V regulator" + b_WaitS1 = GTK_WIDGET(gtk_builder_get_object(builder,"S1")); + gtk_button_set_label(GTK_BUTTON(b_WaitS1),strings[I_WAITS1]); //"Wait for S1 before read/write" + gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"MAXERR_L"))),strings[I_MAXERR]); //"Max errors" +//------I2C tab------------- + gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"I2CMODE"))),strings[I_I2CMode]); //"Mode" + I2C8bit = GTK_WIDGET(gtk_builder_get_object(builder,"I2C8BIT")); + I2C16bit = GTK_WIDGET(gtk_builder_get_object(builder,"I2C16BIT")); + SPI00 = GTK_WIDGET(gtk_builder_get_object(builder,"SPI00")); + SPI01 = GTK_WIDGET(gtk_builder_get_object(builder,"SPI01")); + SPI10 = GTK_WIDGET(gtk_builder_get_object(builder,"SPI10")); + SPI11 = GTK_WIDGET(gtk_builder_get_object(builder,"SPI11")); + gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"DATASEND_L"))),strings[I_I2CDATAOUT]); //"Data to send" + I2CDataSend = GTK_WIDGET(gtk_builder_get_object(builder,"DATASEND")); + gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"DATATR_L"))),strings[I_I2CDATATR]); //"Data transferred" + I2CDataReceive = GTK_WIDGET(gtk_builder_get_object(builder,"DATATR")); + gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"NBYTE_L"))),strings[I_I2C_NB]); //"Byes to read/write" + I2CNbyte = GTK_WIDGET(gtk_builder_get_object(builder,"NBYTE_S")); + gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"SPEED_L"))),strings[I_Speed]); //"Speed" + I2CSpeed = GTK_WIDGET(gtk_builder_get_object(builder,"SPEED_C")); + I2CSendBtn = GTK_WIDGET(gtk_builder_get_object(builder,"SEND_B")); + gtk_button_set_label(GTK_BUTTON(I2CSendBtn),strings[I_I2CSend]); //"Send" + g_signal_connect(G_OBJECT(I2CSendBtn),"clicked",G_CALLBACK(I2cspiS),window); + I2CReceiveBtn = GTK_WIDGET(gtk_builder_get_object(builder,"RECEIVE_B")); + gtk_button_set_label(GTK_BUTTON(I2CReceiveBtn),strings[I_I2CReceive]); //"Receive" + g_signal_connect(G_OBJECT(I2CReceiveBtn),"clicked",G_CALLBACK(I2cspiR),window); +//------ICD tab------------- + GtkWidget* loadCoffBtn = GTK_WIDGET(gtk_builder_get_object(builder,"LOADCOFF_B")); + gtk_tool_button_set_label(GTK_TOOL_BUTTON(loadCoffBtn),strings[I_LOAD_COFF]); //"load COFF file..." + g_signal_connect(G_OBJECT(loadCoffBtn),"clicked",G_CALLBACK(loadCoff),window); + g_signal_connect(GTK_WIDGET(gtk_builder_get_object(builder,"ICD_TAB")),"key_press_event",G_CALLBACK(icd_key_event),NULL); + //menu + gtk_menu_item_set_label(GTK_MENU_ITEM(gtk_builder_get_object(builder,"OPTIONS_M")),strings[I_Opt]); //"Options"; + icdMenuPC = GTK_WIDGET(gtk_builder_get_object(builder,"PCOUNT_M")); + gtk_menu_item_set_label(GTK_MENU_ITEM(icdMenuPC),strings[I_SHOW_PC]); //"show Program Counter" + icdMenuSTAT = GTK_WIDGET(gtk_builder_get_object(builder,"STATUS_M")); + gtk_menu_item_set_label(GTK_MENU_ITEM(icdMenuSTAT),strings[I_SHOW_STATUS]); //"show status registers" + icdMenuBank0 = GTK_WIDGET(gtk_builder_get_object(builder,"BANK0_M")); + gtk_menu_item_set_label(GTK_MENU_ITEM(icdMenuBank0),strings[I_SHOW_BANK0]); //"show memory bank 0" + icdMenuBank1 = GTK_WIDGET(gtk_builder_get_object(builder,"BANK1_M")); + gtk_menu_item_set_label(GTK_MENU_ITEM(icdMenuBank1),strings[I_SHOW_BANK1]); //"show memory bank 1" + icdMenuBank2 = GTK_WIDGET(gtk_builder_get_object(builder,"BANK2_M")); + gtk_menu_item_set_label(GTK_MENU_ITEM(icdMenuBank2),strings[I_SHOW_BANK2]); //"show memory bank 2" + icdMenuBank3 = GTK_WIDGET(gtk_builder_get_object(builder,"BANK3_M")); + gtk_menu_item_set_label(GTK_MENU_ITEM(icdMenuBank3),strings[I_SHOW_BANK3]); //"show memory bank 3" + icdMenuEE = GTK_WIDGET(gtk_builder_get_object(builder,"EE_M")); + gtk_menu_item_set_label(GTK_MENU_ITEM(icdMenuEE),strings[I_SHOW_EE]); //"show EEPROM" + //toolbar + w=GTK_WIDGET(gtk_builder_get_object(builder,"ICD_RUN")); + gtk_widget_set_tooltip_text(w,strings[I_ICD_RUN]); + g_signal_connect(w,"clicked",G_CALLBACK(icdRun), NULL); + w=GTK_WIDGET(gtk_builder_get_object(builder,"ICD_HALT")); + gtk_widget_set_tooltip_text(w,strings[I_ICD_HALT]); + g_signal_connect(w,"clicked",G_CALLBACK(icdHalt), NULL); + w=GTK_WIDGET(gtk_builder_get_object(builder,"ICD_STEP")); + gtk_widget_set_tooltip_text(w,strings[I_ICD_STEP]); + g_signal_connect(w,"clicked",G_CALLBACK(icdStep), NULL); + w=GTK_WIDGET(gtk_builder_get_object(builder,"ICD_STEPOVER")); + gtk_widget_set_tooltip_text(w,strings[I_ICD_STEPOVER]); + g_signal_connect(w,"clicked",G_CALLBACK(icdStepOver), NULL); + w=GTK_WIDGET(gtk_builder_get_object(builder,"ICD_STOP")); + gtk_widget_set_tooltip_text(w,strings[I_ICD_STOP]); + g_signal_connect(w,"clicked",G_CALLBACK(icdStop), NULL); + w=GTK_WIDGET(gtk_builder_get_object(builder,"ICD_REFRESH")); + gtk_widget_set_tooltip_text(w,strings[I_ICD_REFRESH]);//"refresh" + g_signal_connect(w,"clicked",G_CALLBACK(icdRefresh), NULL); + icdCommand = GTK_WIDGET(gtk_builder_get_object(builder,"ICD_CMD_E")); + gtk_widget_set_tooltip_text(icdCommand,strings[I_ICD_CMD]);//"command-line" + g_signal_connect(G_OBJECT(icdCommand),"key_press_event",G_CALLBACK(icdCommand_key_event),NULL); + w=GTK_WIDGET(gtk_builder_get_object(builder,"ICD_HELP")); + gtk_widget_set_tooltip_text(w,strings[I_ICD_HELP]);//"help" + g_signal_connect(w,"clicked",G_CALLBACK(ICDHelp), NULL); + //source + gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"ICD_SOURCE_L"))),strings[I_ICD_SOURCE]); //"Source" + sourceTxt = GTK_WIDGET(gtk_builder_get_object(builder,"ICD_SOURCE")); + sourceBuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sourceTxt)); + g_signal_connect(G_OBJECT(sourceTxt),"button_press_event",G_CALLBACK(source_mouse_event),NULL); + //status + gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"ICD_STAT_L"))),strings[I_ICD_STATUS]); //"Status" + statusTxt = GTK_WIDGET(gtk_builder_get_object(builder,"ICD_STATUS")); + statusBuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(statusTxt)); + g_signal_connect(G_OBJECT(statusTxt),"button_press_event",G_CALLBACK(icdStatus_mouse_event),NULL); +//------IO tab------------- + b_io_active = GTK_WIDGET(gtk_builder_get_object(builder,"IOEN")); + gtk_button_set_label(GTK_BUTTON(b_io_active),strings[I_IO_Enable]); //"Enable IO" + g_signal_connect(G_OBJECT(b_io_active),"toggled",G_CALLBACK(IOactive),NULL); + ioButtons[0].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RB0_0")); + ioButtons[0].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RB0_1")); + ioButtons[0].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB0_I")); + ioButtons[0].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB0_L")); + ioButtons[1].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RB1_0")); + ioButtons[1].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RB1_1")); + ioButtons[1].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB1_I")); + ioButtons[1].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB1_L")); + ioButtons[2].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RB2_0")); + ioButtons[2].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RB2_1")); + ioButtons[2].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB2_I")); + ioButtons[2].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB2_L")); + ioButtons[3].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RB3_0")); + ioButtons[3].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RB3_1")); + ioButtons[3].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB3_I")); + ioButtons[3].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB3_L")); + ioButtons[4].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RB4_0")); + ioButtons[4].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RB4_1")); + ioButtons[4].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB4_I")); + ioButtons[4].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB4_L")); + ioButtons[5].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RB5_0")); + ioButtons[5].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RB5_1")); + ioButtons[5].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB5_I")); + ioButtons[5].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB5_L")); + ioButtons[6].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RB6_0")); + ioButtons[6].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RB6_1")); + ioButtons[6].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB6_I")); + ioButtons[6].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB6_L")); + ioButtons[7].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RB7_0")); + ioButtons[7].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RB7_1")); + ioButtons[7].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB7_I")); + ioButtons[7].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RB7_L")); + ioButtons[8].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RC7_0")); + ioButtons[8].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RC7_1")); + ioButtons[8].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RC7_I")); + ioButtons[8].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RC7_L")); + ioButtons[9].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RC6_0")); + ioButtons[9].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RC6_1")); + ioButtons[9].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RC6_I")); + ioButtons[9].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RC6_L")); + ioButtons[10].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RA5_0")); + ioButtons[10].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RA5_1")); + ioButtons[10].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RA5_I")); + ioButtons[10].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RA5_L")); + ioButtons[11].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RA4_0")); + ioButtons[11].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RA4_1")); + ioButtons[11].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RA4_I")); + ioButtons[11].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RA4_L")); + ioButtons[12].r_0 = GTK_WIDGET(gtk_builder_get_object(builder,"RA3_0")); + ioButtons[12].r_1 = GTK_WIDGET(gtk_builder_get_object(builder,"RA3_1")); + ioButtons[12].r_I = GTK_WIDGET(gtk_builder_get_object(builder,"RA3_I")); + ioButtons[12].e_I = GTK_WIDGET(gtk_builder_get_object(builder,"RA3_L")); + for(int ii=0;ii<sizeof(ioButtons)/sizeof(ioButtons[0]);ii++){ + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ioButtons[ii].r_I),TRUE); + g_signal_connect(G_OBJECT(ioButtons[ii].r_0),"toggled",G_CALLBACK(IOchanged),NULL); + g_signal_connect(G_OBJECT(ioButtons[ii].r_1),"toggled",G_CALLBACK(IOchanged),NULL); + g_signal_connect(G_OBJECT(ioButtons[ii].r_I),"toggled",G_CALLBACK(IOchanged),NULL); + } + VDD_ON = GTK_WIDGET(gtk_builder_get_object(builder,"VDDUEN")); + VPP_ON = GTK_WIDGET(gtk_builder_get_object(builder,"VPPUEN")); + DCDC_ON = GTK_WIDGET(gtk_builder_get_object(builder,"DCDCEN")); + DCDC_voltage = GTK_WIDGET(gtk_builder_get_object(builder,"DCDC_S")); + gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"CMD_L"))),strings[I_IO_Commands]); //"Manual commands" + gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"CMDSEND_L"))),strings[I_I2CDATAOUT]); //"Data to send" + commandSend = GTK_WIDGET(gtk_builder_get_object(builder,"CMDSEND")); + gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"CMDTR_L"))),strings[I_I2CDATATR]); //"Data transferred" + commandTransfer = GTK_WIDGET(gtk_builder_get_object(builder,"CMDTR")); + w = GTK_WIDGET(gtk_builder_get_object(builder,"CMDTR_B")); + gtk_button_set_label(GTK_BUTTON(w),strings[I_I2CSend]); //"Send" + g_signal_connect(w,"clicked",G_CALLBACK(CommandIO),window); + g_signal_connect(G_OBJECT(VDD_ON),"toggled",G_CALLBACK(VPPVDDactive),NULL); + g_signal_connect(G_OBJECT(VPP_ON),"toggled",G_CALLBACK(VPPVDDactive),NULL); + g_signal_connect(G_OBJECT(DCDC_ON),"toggled",G_CALLBACK(DCDCactive),NULL); + g_signal_connect(G_OBJECT(DCDC_voltage),"value_changed",G_CALLBACK(DCDCactive),NULL); +//------Utility tab------------- + Hex_entry = GTK_WIDGET(gtk_builder_get_object(builder,"HEXIN")); + Hex_data = GTK_WIDGET(gtk_builder_get_object(builder,"DATAOUT")); + Address_entry = GTK_WIDGET(gtk_builder_get_object(builder,"ADDRIN")); + Data_entry = GTK_WIDGET(gtk_builder_get_object(builder,"DATAIN")); + Hex_data2 = GTK_WIDGET(gtk_builder_get_object(builder,"HEXOUT")); + w = GTK_WIDGET(gtk_builder_get_object(builder,"HEXSAVE")); + gtk_button_set_label(GTK_BUTTON(w),strings[I_Fsave]); + g_signal_connect(w,"clicked",G_CALLBACK(HexSave),window); + g_signal_connect(G_OBJECT(Hex_entry),"changed",G_CALLBACK(HexConvert),NULL); + g_signal_connect(G_OBJECT(Address_entry),"changed",G_CALLBACK(DataToHexConvert),NULL); + g_signal_connect(G_OBJECT(Data_entry),"changed",G_CALLBACK(DataToHexConvert),NULL); +//------status bar------------- + status_bar = GTK_WIDGET(gtk_builder_get_object(builder,"STATUS_B")); + statusID=gtk_statusbar_get_context_id(GTK_STATUSBAR(status_bar),"ID"); + //printf("load time: %dms\n",GetTickCount()-t0);fflush(stdout); + gtk_widget_show_all(window); + +//********Init************* + char text[16]; + sprintf(text,"%04X",vid); + gtk_entry_set_text(GTK_ENTRY(VID_entry),text); + sprintf(text,"%04X",pid); + gtk_entry_set_text(GTK_ENTRY(PID_entry),text); + sprintf(text,"%d",max_err); + gtk_entry_set_text(GTK_ENTRY(Errors_entry),text); + sizeW=0x8400; + memCODE_W=malloc(sizeW*sizeof(WORD)); + initVar(); + for(i=0;i<0x8400;i++) memCODE_W[i]=0x3fff; + strncpy(LogFileName,strings[S_LogFile],sizeof(LogFileName)); + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(devTypeCombo), GROUP_ALL, GROUP_ALL); + for (int i=0;i<NUM_GROUPS;i++) + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(devTypeCombo), groupNames[i], groupNames[i]); + // These will trigger AddDevices to populate the device tree + if (strlen(dev)>0) { + 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; +} |