/**
* \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-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, "<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;
}
#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;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(strupr(tok), textFilterU)) &&
(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;
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 if(HwID==5) PrintMessage(" (18F25K50 all-in-one variant)\r\n\r\n");
else PrintMessage(" (?)\r\n\r\n");
// Disable 3.3V check and hide the option for all-in-one board. Enable and show for others
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b_V33check), HwID==5 ? TRUE : FALSE);
gtk_widget_set_visible(GTK_WIDGET(b_V33check), HwID==5 ? FALSE : TRUE);
}
///
///Check if a 3.3V regulator is present
int CheckV33Regulator()
{
int i,j=0;
if(skipV33check) return 1;
bufferU[j++]=WRITE_RAM;
bufferU[j++]=0x0F;
bufferU[j++]=0x93;
bufferU[j++]=0xFE; //B0 = output
bufferU[j++]=EXT_PORT;
bufferU[j++]=0x01; //B0=1
bufferU[j++]=0;
bufferU[j++]=READ_RAM;
bufferU[j++]=0x0F;
bufferU[j++]=0x81; //Check if B1=1
bufferU[j++]=EXT_PORT;
bufferU[j++]=0x00; //B0=0
bufferU[j++]=0;
bufferU[j++]=READ_RAM;
bufferU[j++]=0x0F;
bufferU[j++]=0x81; //Check if B1=0
bufferU[j++]=WRITE_RAM;
bufferU[j++]=0x0F;
bufferU[j++]=0x93;
bufferU[j++]=0xFF; //BX = input
bufferU[j++]=FLUSH;
for(;j<DIMBUF;j++) bufferU[j]=0x0;
PacketIO(5);
for(j=0;j<DIMBUF-3&&bufferI[j]!=READ_RAM;j++);
i=bufferI[j+3]&0x2; //B1 should be high
for(j+=3;j<DIMBUF-3&&bufferI[j]!=READ_RAM;j++);
return (i+(bufferI[j+3]&0x2))==2?1:0;
}
///
///Check if S1 is pressed
int CheckS1()
{
int i,j=0;
bufferU[j++]=READ_RAM;
bufferU[j++]=0x0F;
if (HwID==5) { //all-in-one board
bufferU[j++]=0x80; // Read PORTA
}
else { //std board
bufferU[j++]=0x84; //READ PORTE
}
bufferU[j++]=FLUSH;
for(;j<DIMBUF;j++) bufferU[j]=0x0;
PacketIO(5);
for(j=0;j<DIMBUF-3&&bufferI[j]!=READ_RAM;j++);
if (HwID==5) { //all-in-one board
i=bufferI[j+3]&0x80; //i=A7
return i?1:0; //A7=1 when switch pressed (active high)
}
else { //std board
i=bufferI[j+3]&0x8; //i=E3
return i?0:1; //S1 open -> E3=1 (active low)
}
}
///
///Execute hardware test
void TestHw(GtkWidget *widget,GtkWindow* parent)
{
#ifndef DEBUG
if(DeviceDetected!=1) return;
#endif
char str[256];
StartHVReg(13);
int j=0;
MsgBox(strings[I_TestHW]); //"Test hardware ..."
bufferU[j++]=SET_CK_D;
bufferU[j++]=0x0;
bufferU[j++]=EN_VPP_VCC; //VDD+VPP
bufferU[j++]=0x5;
bufferU[j++]=FLUSH;
for(;j<DIMBUF;j++) bufferU[j]=0x0;
PacketIO(5);
strcpy(str,strings[I_TestMSG]);
strcat(str,"\n VDDU=5V\n VPPU=13V\n PGD(RB5)=0V\n PGC(RB6)=0V\n PGM(RB7)=0V");
MsgBox(str);
j=0;
bufferU[j++]=SET_CK_D;
bufferU[j++]=0x15;
bufferU[j++]=EN_VPP_VCC;
bufferU[j++]=0x1; //VDD
bufferU[j++]=FLUSH;
for(;j<DIMBUF;j++) bufferU[j]=0x0;
PacketIO(5);
strcpy(str,strings[I_TestMSG]);
strcat(str,"\n VDDU=5V\n VPPU=0V\n PGD(RB5)=5V\n PGC(RB6)=5V\n PGM(RB7)=5V");
MsgBox(str);
j=0;
bufferU[j++]=SET_CK_D;
bufferU[j++]=0x1;
bufferU[j++]=EN_VPP_VCC;
bufferU[j++]=0x4; //VPP
bufferU[j++]=FLUSH;
for(;j<DIMBUF;j++) bufferU[j]=0x0;
PacketIO(5);
strcpy(str,strings[I_TestMSG]);
strcat(str,"\n VDDU=0V\n VPPU=13V\n PGD(RB5)=5V\n PGC(RB6)=0V\n PGM(RB7)=0V");
MsgBox(str);
j=0;
bufferU[j++]=SET_CK_D;
bufferU[j++]=0x4;
bufferU[j++]=EN_VPP_VCC;
bufferU[j++]=0x0;
bufferU[j++]=FLUSH;
for(;j<DIMBUF;j++) bufferU[j]=0x0;
PacketIO(5);
strcpy(str,strings[I_TestMSG]);
strcat(str,"\n VDDU=0V\n VPPU=0V\n PGD(RB5)=0V\n PGC(RB6)=5V\n PGM(RB7)=0V");
MsgBox(str);
j=0;
bufferU[j++]=SET_CK_D;
bufferU[j++]=0x0;
bufferU[j++]=EN_VPP_VCC;
bufferU[j++]=0x0;
bufferU[j++]=FLUSH;
for(;j<DIMBUF;j++) bufferU[j]=0x0;
PacketIO(5);
if(FWVersion>=0x900){ //IO test
int j=0,i,x,r;
strcpy(str,"0000000000000");
PrintMessage("IO test\nRC|RA|--RB--|\n");
for(i=0;i<13;i++){
x=1<<i;
j=0;
bufferU[j++]=EN_VPP_VCC;
bufferU[j++]=0x0;
bufferU[j++]=SET_PORT_DIR;
bufferU[j++]=0x0; //TRISB
bufferU[j++]=0x0; //TRISA-C (RC7:RC6:RA5:RA4:RA3:X:X:X)
bufferU[j++]=EXT_PORT;
bufferU[j++]=x&0xFF; //PORTB
bufferU[j++]=(x>>5)&0xFF; //PORTA-C
bufferU[j++]=READ_B;
bufferU[j++]=READ_AC;
bufferU[j++]=FLUSH;
for(;j<DIMBUF;j++) bufferU[j]=0x0;
PacketIO(5);
for(j=0;j<DIMBUF-1&&bufferI[j]!=READ_B;j++);
r=bufferI[j+1];
for(j+=2;j<DIMBUF-1&&bufferI[j]!=READ_AC;j++);
r+=(bufferI[j+1]&0xF8)<<5;
for(j=0;j<13;j++) str[12-j]=x&(1<<j)?'1':'0';
PrintMessage(str);
PrintMessage1(" (%s)\n",r==x?"OK":strings[S_ErrSing]);
}
}
}
///
///Wait for X milliseconds
void msDelay(double delay)
{
#if !defined _WIN32 && !defined __CYGWIN__
long x=(int)(delay*1000.0);
usleep(x>MinDly?x:MinDly);
#else
// Sleep((long)ceil(delay)>MinDly?(long)ceil(delay):MinDly);
__int64 stop,freq,timeout;
QueryPerformanceCounter((LARGE_INTEGER *)&stop);
QueryPerformanceFrequency((LARGE_INTEGER *)&freq);
timeout=stop+delay*freq/1000.0;
while(stop<timeout) QueryPerformanceCounter((LARGE_INTEGER *)&stop);
#endif
}
#if !defined _WIN32 && !defined __CYGWIN__ //Linux
///
/// Get system time
DWORD GetTickCount(){
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec*1000+tv.tv_usec/1000;
/*
struct timeb now;
ftime(&now);
return now.time*1000+now.millitm;
*/
}
#endif
///
///Write data packet, wait for X milliseconds, read response
///real waiting happens only if the desired delay is greater than 40ms;
///in case of smaller delays the function simply waits for a response (up to 50ms)
///
void PacketIO(double delay){
#define TIMEOUT 50
if(saveLog&&logfile) fprintf(logfile,"PacketIO(%.2f)\n",delay);
int delay0=delay;
#if !defined _WIN32 && !defined __CYGWIN__ //Linux
struct timespec ts;
uint64_t start,stop;
fd_set set;
struct timeval timeout;
int rv,i;
FD_ZERO(&set); /* clear the set */
FD_SET(fd, &set); /* add our file descriptor to the set */
timeout.tv_sec = 0;
timeout.tv_usec = TIMEOUT*1000;
clock_gettime( CLOCK_REALTIME, &ts );
start=ts.tv_nsec/1000;
delay-=TIMEOUT-10; //shorter delays are covered by 50ms timeout
if(delay<MinDly) delay=MinDly;
#ifndef hiddevIO //use raw USB device
//wait before writing
/* rv = select(fd + 1, NULL, &set, NULL, &timeout); //wait for write event
if(rv == -1){
PrintMessage(strings[S_ErrSing]); //error
if(saveLog&&logfile) fprintf(logfile,strings[S_ErrSing]);
return;
}
else if(rv == 0){
PrintMessage(strings[S_comTimeout]); //"comm timeout\r\n"
if(saveLog&&logfile) fprintf(logfile,strings[S_comTimeout]);
return;
}*/
//write
int res = write(fd,bufferU,DIMBUF);
if (res < 0) {
printf("Error: %d\n", errno);
perror("write");
}
usleep((int)(delay*1000.0));
//wait before reading
rv = select(fd + 1, &set, NULL, NULL, &timeout); //wait for event
if(rv == -1){
PrintMessage(strings[S_ErrSing]); /*error*/
if(saveLog&&logfile) fprintf(logfile,strings[S_ErrSing]);
return;
}
else if(rv == 0){
PrintMessage(strings[S_comTimeout]); /*"comm timeout\r\n"*/
if(saveLog&&logfile) fprintf(logfile,strings[S_comTimeout]);
return;
}
//read
res = read(fd, bufferI, DIMBUF);
if (res < 0) {
perror("read");
}
#else //use hiddev device (old method)
struct hiddev_event ev[80];
int n=DIMBUF;
for(i=0;i<DIMBUF;i++) ref_multi_u.values[i]=bufferU[i];
//write
ioctl(fd, HIDIOCSUSAGES, &ref_multi_u);
ioctl(fd,HIDIOCSREPORT, &rep_info_u);
usleep((int)(delay*1000.0));
//read
rv = select(fd + 1, &set, NULL, NULL, &timeout); //wait for event
if(rv == -1){
PrintMessage(strings[S_ErrSing]); /*error*/
if(saveLog&&logfile) fprintf(logfile,strings[S_ErrSing]);
}
else if(rv == 0){
PrintMessage(strings[S_comTimeout]); /*"comm timeout\r\n"*/
if(saveLog&&logfile) fprintf(logfile,strings[S_comTimeout]);
}
else{
// ioctl(fd, HIDIOCGUSAGES, &ref_multi_i);
// ioctl(fd,HIDIOCGREPORT, &rep_info_i);
#undef read()
rv=read(fd, ev,sizeof(struct hiddev_event) *n);
for(i=0;(ev[0].value!=bufferU[0])&&i<40;i++){ //read too early; try again after 5ms
msDelay(5);
rv=read(fd, ev,sizeof(struct hiddev_event) *n);
if(saveLog&&logfile) fprintf(logfile,"Packet not ready, wait extra time\n");
}
if(i==40) fprintf(logfile,"Cannot read correct packet!!\n");
for(i=0;i<n;i++) bufferI[i]=ev[i].value&0xFF;
}
#endif
clock_gettime( CLOCK_REALTIME, &ts );
stop = ts.tv_nsec / 1000;
if(saveLog&&logfile){
WriteLogIO();
fprintf(logfile,"T=%.2f ms (%+.2f ms)\n",(stop-start)/1000.0,(stop-start)/1000.0-delay0);
if(bufferU[0]!=bufferI[0]) fprintf(logfile,"Cannot read correct packet!!\n");
}
#else //Windows
__int64 start,stop,freq,timeout;
QueryPerformanceCounter((LARGE_INTEGER *)&start);
QueryPerformanceFrequency((LARGE_INTEGER *)&freq);
delay-=TIMEOUT-10; //shorter delays are covered by 50ms timeout
if(delay<MinDly) delay=MinDly;
//write
Result = WriteFile(WriteHandle,bufferU0,DIMBUF+1,&BytesWritten,NULL);
QueryPerformanceCounter((LARGE_INTEGER *)&stop);
timeout=stop+delay*freq/1000.0;
while(stop<timeout) QueryPerformanceCounter((LARGE_INTEGER *)&stop);
//read
Result = ReadFile(ReadHandle,bufferI0,DIMBUF+1,&NumberOfBytesRead,(LPOVERLAPPED) &HIDOverlapped);
Result = WaitForSingleObject(hEventObject,TIMEOUT);
if(saveLog&&logfile) WriteLogIO();
ResetEvent(hEventObject);
if(Result!=WAIT_OBJECT_0){
PrintMessage(strings[S_comTimeout]); /*"comm timeout\r\n"*/
if(saveLog&&logfile) fprintf(logfile,strings[S_comTimeout]);
}
QueryPerformanceCounter((LARGE_INTEGER *)&stop);
if(saveLog&&logfile) fprintf(logfile,"T=%.2f ms (%+.2f ms)\n",(stop-start)*1000.0/freq,(stop-start)*1000.0/freq-delay0);
#endif
}
///-----------------------------------
///Main function
///-----------------------------------
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<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_TypeFilt]); //"Filter by type"
gtk_label_set_text(GTK_LABEL(GTK_WIDGET(gtk_builder_get_object(builder,"DEV_SRC_L"))),strings[I_Filt]); //"Filter"
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); //"Type"
gtk_tree_view_column_set_fixed_width(gtk_tree_view_get_column(GTK_TREE_VIEW(devTree),0),125);
gtk_tree_view_column_set_fixed_width(gtk_tree_view_get_column(GTK_TREE_VIEW(devTree),1),125);
// 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;
}