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